Lines Matching +full:aux +full:- +full:output +full:- +full:power
1 // SPDX-License-Identifier: GPL-2.0-only
12 #include <linux/pinctrl/pinconf-generic.h>
40 struct drm_dp_aux aux;
48 struct tegra_output *output;
66 static inline struct tegra_dpaux *to_dpaux(struct drm_dp_aux *aux)
68 return container_of(aux, struct tegra_dpaux, aux);
79 u32 value = readl(dpaux->regs + (offset << 2));
81 trace_dpaux_readl(dpaux->dev, offset, value);
89 trace_dpaux_writel(dpaux->dev, offset, value);
90 writel(value, dpaux->regs + (offset << 2));
99 size_t num = min_t(size_t, size - i * 4, 4);
115 size_t num = min_t(size_t, size - i * 4, 4);
125 static ssize_t tegra_dpaux_transfer(struct drm_dp_aux *aux,
129 struct tegra_dpaux *dpaux = to_dpaux(aux);
135 /* Tegra has 4x4 byte DP AUX transmit and receive FIFOs. */
136 if (msg->size > 16)
137 return -EINVAL;
140 * Allow zero-sized messages only for I2C, in which case they specify
141 * address-only transactions.
143 if (msg->size < 1) {
144 switch (msg->request & ~DP_AUX_I2C_MOT) {
152 return -EINVAL;
155 /* For non-zero-sized messages, set the CMDLEN field. */
156 value = DPAUX_DP_AUXCTL_CMDLEN(msg->size - 1);
159 switch (msg->request & ~DP_AUX_I2C_MOT) {
161 if (msg->request & DP_AUX_I2C_MOT)
169 if (msg->request & DP_AUX_I2C_MOT)
177 if (msg->request & DP_AUX_I2C_MOT)
193 return -EINVAL;
196 tegra_dpaux_writel(dpaux, msg->address, DPAUX_DP_AUXADDR);
199 if ((msg->request & DP_AUX_I2C_READ) == 0) {
200 tegra_dpaux_write_fifo(dpaux, msg->buffer, msg->size);
201 ret = msg->size;
209 status = wait_for_completion_timeout(&dpaux->complete, timeout);
211 return -ETIMEDOUT;
218 return -ETIMEDOUT;
223 return -EIO;
247 if ((msg->size > 0) && (msg->reply == DP_AUX_NATIVE_REPLY_ACK)) {
248 if (msg->request & DP_AUX_I2C_READ) {
254 * an -EBUSY return value, simply reuse that instead.
256 if (count != msg->size) {
257 ret = -EBUSY;
261 tegra_dpaux_read_fifo(dpaux, msg->buffer, count);
266 msg->reply = reply;
276 if (dpaux->output)
277 drm_helper_hpd_irq_event(dpaux->output->connector.dev);
290 schedule_work(&dpaux->work);
297 complete(&dpaux->complete);
332 value = DPAUX_HYBRID_PADCTL_AUX_CMH(dpaux->soc->cmh) |
333 DPAUX_HYBRID_PADCTL_AUX_DRVZ(dpaux->soc->drvz) |
334 DPAUX_HYBRID_PADCTL_AUX_DRVI(dpaux->soc->drvi) |
342 DPAUX_HYBRID_PADCTL_AUX_CMH(dpaux->soc->cmh) |
343 DPAUX_HYBRID_PADCTL_AUX_DRVZ(dpaux->soc->drvz) |
344 DPAUX_HYBRID_PADCTL_AUX_DRVI(dpaux->soc->drvi) |
353 return -ENOTSUPP;
371 "dpaux-io",
375 "aux",
453 dpaux = devm_kzalloc(&pdev->dev, sizeof(*dpaux), GFP_KERNEL);
455 return -ENOMEM;
457 dpaux->soc = of_device_get_match_data(&pdev->dev);
458 INIT_WORK(&dpaux->work, tegra_dpaux_hotplug);
459 init_completion(&dpaux->complete);
460 INIT_LIST_HEAD(&dpaux->list);
461 dpaux->dev = &pdev->dev;
463 dpaux->regs = devm_platform_ioremap_resource(pdev, 0);
464 if (IS_ERR(dpaux->regs))
465 return PTR_ERR(dpaux->regs);
467 dpaux->irq = platform_get_irq(pdev, 0);
468 if (dpaux->irq < 0)
469 return dpaux->irq;
471 if (!pdev->dev.pm_domain) {
472 dpaux->rst = devm_reset_control_get(&pdev->dev, "dpaux");
473 if (IS_ERR(dpaux->rst)) {
474 dev_err(&pdev->dev,
476 PTR_ERR(dpaux->rst));
477 return PTR_ERR(dpaux->rst);
481 dpaux->clk = devm_clk_get(&pdev->dev, NULL);
482 if (IS_ERR(dpaux->clk)) {
483 dev_err(&pdev->dev, "failed to get module clock: %ld\n",
484 PTR_ERR(dpaux->clk));
485 return PTR_ERR(dpaux->clk);
488 dpaux->clk_parent = devm_clk_get(&pdev->dev, "parent");
489 if (IS_ERR(dpaux->clk_parent)) {
490 dev_err(&pdev->dev, "failed to get parent clock: %ld\n",
491 PTR_ERR(dpaux->clk_parent));
492 return PTR_ERR(dpaux->clk_parent);
495 err = clk_set_rate(dpaux->clk_parent, 270000000);
497 dev_err(&pdev->dev, "failed to set clock to 270 MHz: %d\n",
502 dpaux->vdd = devm_regulator_get_optional(&pdev->dev, "vdd");
503 if (IS_ERR(dpaux->vdd)) {
504 if (PTR_ERR(dpaux->vdd) != -ENODEV)
505 return dev_err_probe(&pdev->dev, PTR_ERR(dpaux->vdd),
508 dpaux->vdd = NULL;
512 pm_runtime_enable(&pdev->dev);
513 pm_runtime_get_sync(&pdev->dev);
515 err = devm_request_irq(dpaux->dev, dpaux->irq, tegra_dpaux_irq, 0,
516 dev_name(dpaux->dev), dpaux);
518 dev_err(dpaux->dev, "failed to request IRQ#%u: %d\n",
519 dpaux->irq, err);
523 disable_irq(dpaux->irq);
525 dpaux->aux.transfer = tegra_dpaux_transfer;
526 dpaux->aux.dev = &pdev->dev;
528 drm_dp_aux_init(&dpaux->aux);
532 * so power them up and configure them in I2C mode.
534 * The DPAUX code paths reconfigure the pads in AUX mode, but there
543 dpaux->desc.name = dev_name(&pdev->dev);
544 dpaux->desc.pins = tegra_dpaux_pins;
545 dpaux->desc.npins = ARRAY_SIZE(tegra_dpaux_pins);
546 dpaux->desc.pctlops = &tegra_dpaux_pinctrl_ops;
547 dpaux->desc.pmxops = &tegra_dpaux_pinmux_ops;
548 dpaux->desc.owner = THIS_MODULE;
550 dpaux->pinctrl = devm_pinctrl_register(&pdev->dev, &dpaux->desc, dpaux);
551 if (IS_ERR(dpaux->pinctrl)) {
552 dev_err(&pdev->dev, "failed to register pincontrol\n");
553 err = PTR_ERR(dpaux->pinctrl);
564 list_add_tail(&dpaux->list, &dpaux_list);
567 err = devm_of_dp_aux_populate_ep_devices(&dpaux->aux);
569 dev_err(dpaux->dev, "failed to populate AUX bus: %d\n", err);
576 pm_runtime_put_sync(&pdev->dev);
577 pm_runtime_disable(&pdev->dev);
585 cancel_work_sync(&dpaux->work);
590 pm_runtime_put_sync(&pdev->dev);
591 pm_runtime_disable(&pdev->dev);
594 list_del(&dpaux->list);
603 if (dpaux->rst) {
604 err = reset_control_assert(dpaux->rst);
613 clk_disable_unprepare(dpaux->clk_parent);
614 clk_disable_unprepare(dpaux->clk);
624 err = clk_prepare_enable(dpaux->clk);
630 err = clk_prepare_enable(dpaux->clk_parent);
638 if (dpaux->rst) {
639 err = reset_control_deassert(dpaux->rst);
651 clk_disable_unprepare(dpaux->clk_parent);
653 clk_disable_unprepare(dpaux->clk);
680 { .compatible = "nvidia,tegra194-dpaux", .data = &tegra194_dpaux_soc },
681 { .compatible = "nvidia,tegra186-dpaux", .data = &tegra210_dpaux_soc },
682 { .compatible = "nvidia,tegra210-dpaux", .data = &tegra210_dpaux_soc },
683 { .compatible = "nvidia,tegra124-dpaux", .data = &tegra124_dpaux_soc },
690 .name = "tegra-dpaux",
705 if (np == dpaux->dev->of_node) {
707 return &dpaux->aux;
715 int drm_dp_aux_attach(struct drm_dp_aux *aux, struct tegra_output *output)
717 struct tegra_dpaux *dpaux = to_dpaux(aux);
721 aux->drm_dev = output->connector.dev;
722 err = drm_dp_aux_register(aux);
726 output->connector.polled = DRM_CONNECTOR_POLL_HPD;
727 dpaux->output = output;
729 if (output->panel) {
732 if (dpaux->vdd) {
733 err = regulator_enable(dpaux->vdd);
741 status = drm_dp_aux_detect(aux);
750 return -ETIMEDOUT;
753 enable_irq(dpaux->irq);
757 int drm_dp_aux_detach(struct drm_dp_aux *aux)
759 struct tegra_dpaux *dpaux = to_dpaux(aux);
763 drm_dp_aux_unregister(aux);
764 disable_irq(dpaux->irq);
766 if (dpaux->output->panel) {
769 if (dpaux->vdd) {
770 err = regulator_disable(dpaux->vdd);
778 status = drm_dp_aux_detect(aux);
787 return -ETIMEDOUT;
789 dpaux->output = NULL;
795 enum drm_connector_status drm_dp_aux_detect(struct drm_dp_aux *aux)
797 struct tegra_dpaux *dpaux = to_dpaux(aux);
808 int drm_dp_aux_enable(struct drm_dp_aux *aux)
810 struct tegra_dpaux *dpaux = to_dpaux(aux);
815 int drm_dp_aux_disable(struct drm_dp_aux *aux)
817 struct tegra_dpaux *dpaux = to_dpaux(aux);