Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2013 NVIDIA Corporation
0004  */
0005 
0006 #include <linux/clk.h>
0007 #include <linux/delay.h>
0008 #include <linux/interrupt.h>
0009 #include <linux/io.h>
0010 #include <linux/module.h>
0011 #include <linux/of_device.h>
0012 #include <linux/pinctrl/pinconf-generic.h>
0013 #include <linux/pinctrl/pinctrl.h>
0014 #include <linux/pinctrl/pinmux.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/pm_runtime.h>
0017 #include <linux/regulator/consumer.h>
0018 #include <linux/reset.h>
0019 #include <linux/workqueue.h>
0020 
0021 #include <drm/display/drm_dp_helper.h>
0022 #include <drm/display/drm_dp_aux_bus.h>
0023 #include <drm/drm_panel.h>
0024 
0025 #include "dp.h"
0026 #include "dpaux.h"
0027 #include "drm.h"
0028 #include "trace.h"
0029 
0030 static DEFINE_MUTEX(dpaux_lock);
0031 static LIST_HEAD(dpaux_list);
0032 
0033 struct tegra_dpaux_soc {
0034     unsigned int cmh;
0035     unsigned int drvz;
0036     unsigned int drvi;
0037 };
0038 
0039 struct tegra_dpaux {
0040     struct drm_dp_aux aux;
0041     struct device *dev;
0042 
0043     const struct tegra_dpaux_soc *soc;
0044 
0045     void __iomem *regs;
0046     int irq;
0047 
0048     struct tegra_output *output;
0049 
0050     struct reset_control *rst;
0051     struct clk *clk_parent;
0052     struct clk *clk;
0053 
0054     struct regulator *vdd;
0055 
0056     struct completion complete;
0057     struct work_struct work;
0058     struct list_head list;
0059 
0060 #ifdef CONFIG_GENERIC_PINCONF
0061     struct pinctrl_dev *pinctrl;
0062     struct pinctrl_desc desc;
0063 #endif
0064 };
0065 
0066 static inline struct tegra_dpaux *to_dpaux(struct drm_dp_aux *aux)
0067 {
0068     return container_of(aux, struct tegra_dpaux, aux);
0069 }
0070 
0071 static inline struct tegra_dpaux *work_to_dpaux(struct work_struct *work)
0072 {
0073     return container_of(work, struct tegra_dpaux, work);
0074 }
0075 
0076 static inline u32 tegra_dpaux_readl(struct tegra_dpaux *dpaux,
0077                     unsigned int offset)
0078 {
0079     u32 value = readl(dpaux->regs + (offset << 2));
0080 
0081     trace_dpaux_readl(dpaux->dev, offset, value);
0082 
0083     return value;
0084 }
0085 
0086 static inline void tegra_dpaux_writel(struct tegra_dpaux *dpaux,
0087                       u32 value, unsigned int offset)
0088 {
0089     trace_dpaux_writel(dpaux->dev, offset, value);
0090     writel(value, dpaux->regs + (offset << 2));
0091 }
0092 
0093 static void tegra_dpaux_write_fifo(struct tegra_dpaux *dpaux, const u8 *buffer,
0094                    size_t size)
0095 {
0096     size_t i, j;
0097 
0098     for (i = 0; i < DIV_ROUND_UP(size, 4); i++) {
0099         size_t num = min_t(size_t, size - i * 4, 4);
0100         u32 value = 0;
0101 
0102         for (j = 0; j < num; j++)
0103             value |= buffer[i * 4 + j] << (j * 8);
0104 
0105         tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXDATA_WRITE(i));
0106     }
0107 }
0108 
0109 static void tegra_dpaux_read_fifo(struct tegra_dpaux *dpaux, u8 *buffer,
0110                   size_t size)
0111 {
0112     size_t i, j;
0113 
0114     for (i = 0; i < DIV_ROUND_UP(size, 4); i++) {
0115         size_t num = min_t(size_t, size - i * 4, 4);
0116         u32 value;
0117 
0118         value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXDATA_READ(i));
0119 
0120         for (j = 0; j < num; j++)
0121             buffer[i * 4 + j] = value >> (j * 8);
0122     }
0123 }
0124 
0125 static ssize_t tegra_dpaux_transfer(struct drm_dp_aux *aux,
0126                     struct drm_dp_aux_msg *msg)
0127 {
0128     unsigned long timeout = msecs_to_jiffies(250);
0129     struct tegra_dpaux *dpaux = to_dpaux(aux);
0130     unsigned long status;
0131     ssize_t ret = 0;
0132     u8 reply = 0;
0133     u32 value;
0134 
0135     /* Tegra has 4x4 byte DP AUX transmit and receive FIFOs. */
0136     if (msg->size > 16)
0137         return -EINVAL;
0138 
0139     /*
0140      * Allow zero-sized messages only for I2C, in which case they specify
0141      * address-only transactions.
0142      */
0143     if (msg->size < 1) {
0144         switch (msg->request & ~DP_AUX_I2C_MOT) {
0145         case DP_AUX_I2C_WRITE_STATUS_UPDATE:
0146         case DP_AUX_I2C_WRITE:
0147         case DP_AUX_I2C_READ:
0148             value = DPAUX_DP_AUXCTL_CMD_ADDRESS_ONLY;
0149             break;
0150 
0151         default:
0152             return -EINVAL;
0153         }
0154     } else {
0155         /* For non-zero-sized messages, set the CMDLEN field. */
0156         value = DPAUX_DP_AUXCTL_CMDLEN(msg->size - 1);
0157     }
0158 
0159     switch (msg->request & ~DP_AUX_I2C_MOT) {
0160     case DP_AUX_I2C_WRITE:
0161         if (msg->request & DP_AUX_I2C_MOT)
0162             value |= DPAUX_DP_AUXCTL_CMD_MOT_WR;
0163         else
0164             value |= DPAUX_DP_AUXCTL_CMD_I2C_WR;
0165 
0166         break;
0167 
0168     case DP_AUX_I2C_READ:
0169         if (msg->request & DP_AUX_I2C_MOT)
0170             value |= DPAUX_DP_AUXCTL_CMD_MOT_RD;
0171         else
0172             value |= DPAUX_DP_AUXCTL_CMD_I2C_RD;
0173 
0174         break;
0175 
0176     case DP_AUX_I2C_WRITE_STATUS_UPDATE:
0177         if (msg->request & DP_AUX_I2C_MOT)
0178             value |= DPAUX_DP_AUXCTL_CMD_MOT_RQ;
0179         else
0180             value |= DPAUX_DP_AUXCTL_CMD_I2C_RQ;
0181 
0182         break;
0183 
0184     case DP_AUX_NATIVE_WRITE:
0185         value |= DPAUX_DP_AUXCTL_CMD_AUX_WR;
0186         break;
0187 
0188     case DP_AUX_NATIVE_READ:
0189         value |= DPAUX_DP_AUXCTL_CMD_AUX_RD;
0190         break;
0191 
0192     default:
0193         return -EINVAL;
0194     }
0195 
0196     tegra_dpaux_writel(dpaux, msg->address, DPAUX_DP_AUXADDR);
0197     tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXCTL);
0198 
0199     if ((msg->request & DP_AUX_I2C_READ) == 0) {
0200         tegra_dpaux_write_fifo(dpaux, msg->buffer, msg->size);
0201         ret = msg->size;
0202     }
0203 
0204     /* start transaction */
0205     value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXCTL);
0206     value |= DPAUX_DP_AUXCTL_TRANSACTREQ;
0207     tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXCTL);
0208 
0209     status = wait_for_completion_timeout(&dpaux->complete, timeout);
0210     if (!status)
0211         return -ETIMEDOUT;
0212 
0213     /* read status and clear errors */
0214     value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXSTAT);
0215     tegra_dpaux_writel(dpaux, 0xf00, DPAUX_DP_AUXSTAT);
0216 
0217     if (value & DPAUX_DP_AUXSTAT_TIMEOUT_ERROR)
0218         return -ETIMEDOUT;
0219 
0220     if ((value & DPAUX_DP_AUXSTAT_RX_ERROR) ||
0221         (value & DPAUX_DP_AUXSTAT_SINKSTAT_ERROR) ||
0222         (value & DPAUX_DP_AUXSTAT_NO_STOP_ERROR))
0223         return -EIO;
0224 
0225     switch ((value & DPAUX_DP_AUXSTAT_REPLY_TYPE_MASK) >> 16) {
0226     case 0x00:
0227         reply = DP_AUX_NATIVE_REPLY_ACK;
0228         break;
0229 
0230     case 0x01:
0231         reply = DP_AUX_NATIVE_REPLY_NACK;
0232         break;
0233 
0234     case 0x02:
0235         reply = DP_AUX_NATIVE_REPLY_DEFER;
0236         break;
0237 
0238     case 0x04:
0239         reply = DP_AUX_I2C_REPLY_NACK;
0240         break;
0241 
0242     case 0x08:
0243         reply = DP_AUX_I2C_REPLY_DEFER;
0244         break;
0245     }
0246 
0247     if ((msg->size > 0) && (msg->reply == DP_AUX_NATIVE_REPLY_ACK)) {
0248         if (msg->request & DP_AUX_I2C_READ) {
0249             size_t count = value & DPAUX_DP_AUXSTAT_REPLY_MASK;
0250 
0251             /*
0252              * There might be a smarter way to do this, but since
0253              * the DP helpers will already retry transactions for
0254              * an -EBUSY return value, simply reuse that instead.
0255              */
0256             if (count != msg->size) {
0257                 ret = -EBUSY;
0258                 goto out;
0259             }
0260 
0261             tegra_dpaux_read_fifo(dpaux, msg->buffer, count);
0262             ret = count;
0263         }
0264     }
0265 
0266     msg->reply = reply;
0267 
0268 out:
0269     return ret;
0270 }
0271 
0272 static void tegra_dpaux_hotplug(struct work_struct *work)
0273 {
0274     struct tegra_dpaux *dpaux = work_to_dpaux(work);
0275 
0276     if (dpaux->output)
0277         drm_helper_hpd_irq_event(dpaux->output->connector.dev);
0278 }
0279 
0280 static irqreturn_t tegra_dpaux_irq(int irq, void *data)
0281 {
0282     struct tegra_dpaux *dpaux = data;
0283     u32 value;
0284 
0285     /* clear interrupts */
0286     value = tegra_dpaux_readl(dpaux, DPAUX_INTR_AUX);
0287     tegra_dpaux_writel(dpaux, value, DPAUX_INTR_AUX);
0288 
0289     if (value & (DPAUX_INTR_PLUG_EVENT | DPAUX_INTR_UNPLUG_EVENT))
0290         schedule_work(&dpaux->work);
0291 
0292     if (value & DPAUX_INTR_IRQ_EVENT) {
0293         /* TODO: handle this */
0294     }
0295 
0296     if (value & DPAUX_INTR_AUX_DONE)
0297         complete(&dpaux->complete);
0298 
0299     return IRQ_HANDLED;
0300 }
0301 
0302 enum tegra_dpaux_functions {
0303     DPAUX_PADCTL_FUNC_AUX,
0304     DPAUX_PADCTL_FUNC_I2C,
0305     DPAUX_PADCTL_FUNC_OFF,
0306 };
0307 
0308 static void tegra_dpaux_pad_power_down(struct tegra_dpaux *dpaux)
0309 {
0310     u32 value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
0311 
0312     value |= DPAUX_HYBRID_SPARE_PAD_POWER_DOWN;
0313 
0314     tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_SPARE);
0315 }
0316 
0317 static void tegra_dpaux_pad_power_up(struct tegra_dpaux *dpaux)
0318 {
0319     u32 value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
0320 
0321     value &= ~DPAUX_HYBRID_SPARE_PAD_POWER_DOWN;
0322 
0323     tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_SPARE);
0324 }
0325 
0326 static int tegra_dpaux_pad_config(struct tegra_dpaux *dpaux, unsigned function)
0327 {
0328     u32 value;
0329 
0330     switch (function) {
0331     case DPAUX_PADCTL_FUNC_AUX:
0332         value = DPAUX_HYBRID_PADCTL_AUX_CMH(dpaux->soc->cmh) |
0333             DPAUX_HYBRID_PADCTL_AUX_DRVZ(dpaux->soc->drvz) |
0334             DPAUX_HYBRID_PADCTL_AUX_DRVI(dpaux->soc->drvi) |
0335             DPAUX_HYBRID_PADCTL_AUX_INPUT_RCV |
0336             DPAUX_HYBRID_PADCTL_MODE_AUX;
0337         break;
0338 
0339     case DPAUX_PADCTL_FUNC_I2C:
0340         value = DPAUX_HYBRID_PADCTL_I2C_SDA_INPUT_RCV |
0341             DPAUX_HYBRID_PADCTL_I2C_SCL_INPUT_RCV |
0342             DPAUX_HYBRID_PADCTL_AUX_CMH(dpaux->soc->cmh) |
0343             DPAUX_HYBRID_PADCTL_AUX_DRVZ(dpaux->soc->drvz) |
0344             DPAUX_HYBRID_PADCTL_AUX_DRVI(dpaux->soc->drvi) |
0345             DPAUX_HYBRID_PADCTL_MODE_I2C;
0346         break;
0347 
0348     case DPAUX_PADCTL_FUNC_OFF:
0349         tegra_dpaux_pad_power_down(dpaux);
0350         return 0;
0351 
0352     default:
0353         return -ENOTSUPP;
0354     }
0355 
0356     tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_PADCTL);
0357     tegra_dpaux_pad_power_up(dpaux);
0358 
0359     return 0;
0360 }
0361 
0362 #ifdef CONFIG_GENERIC_PINCONF
0363 static const struct pinctrl_pin_desc tegra_dpaux_pins[] = {
0364     PINCTRL_PIN(0, "DP_AUX_CHx_P"),
0365     PINCTRL_PIN(1, "DP_AUX_CHx_N"),
0366 };
0367 
0368 static const unsigned tegra_dpaux_pin_numbers[] = { 0, 1 };
0369 
0370 static const char * const tegra_dpaux_groups[] = {
0371     "dpaux-io",
0372 };
0373 
0374 static const char * const tegra_dpaux_functions[] = {
0375     "aux",
0376     "i2c",
0377     "off",
0378 };
0379 
0380 static int tegra_dpaux_get_groups_count(struct pinctrl_dev *pinctrl)
0381 {
0382     return ARRAY_SIZE(tegra_dpaux_groups);
0383 }
0384 
0385 static const char *tegra_dpaux_get_group_name(struct pinctrl_dev *pinctrl,
0386                           unsigned int group)
0387 {
0388     return tegra_dpaux_groups[group];
0389 }
0390 
0391 static int tegra_dpaux_get_group_pins(struct pinctrl_dev *pinctrl,
0392                       unsigned group, const unsigned **pins,
0393                       unsigned *num_pins)
0394 {
0395     *pins = tegra_dpaux_pin_numbers;
0396     *num_pins = ARRAY_SIZE(tegra_dpaux_pin_numbers);
0397 
0398     return 0;
0399 }
0400 
0401 static const struct pinctrl_ops tegra_dpaux_pinctrl_ops = {
0402     .get_groups_count = tegra_dpaux_get_groups_count,
0403     .get_group_name = tegra_dpaux_get_group_name,
0404     .get_group_pins = tegra_dpaux_get_group_pins,
0405     .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
0406     .dt_free_map = pinconf_generic_dt_free_map,
0407 };
0408 
0409 static int tegra_dpaux_get_functions_count(struct pinctrl_dev *pinctrl)
0410 {
0411     return ARRAY_SIZE(tegra_dpaux_functions);
0412 }
0413 
0414 static const char *tegra_dpaux_get_function_name(struct pinctrl_dev *pinctrl,
0415                          unsigned int function)
0416 {
0417     return tegra_dpaux_functions[function];
0418 }
0419 
0420 static int tegra_dpaux_get_function_groups(struct pinctrl_dev *pinctrl,
0421                        unsigned int function,
0422                        const char * const **groups,
0423                        unsigned * const num_groups)
0424 {
0425     *num_groups = ARRAY_SIZE(tegra_dpaux_groups);
0426     *groups = tegra_dpaux_groups;
0427 
0428     return 0;
0429 }
0430 
0431 static int tegra_dpaux_set_mux(struct pinctrl_dev *pinctrl,
0432                    unsigned int function, unsigned int group)
0433 {
0434     struct tegra_dpaux *dpaux = pinctrl_dev_get_drvdata(pinctrl);
0435 
0436     return tegra_dpaux_pad_config(dpaux, function);
0437 }
0438 
0439 static const struct pinmux_ops tegra_dpaux_pinmux_ops = {
0440     .get_functions_count = tegra_dpaux_get_functions_count,
0441     .get_function_name = tegra_dpaux_get_function_name,
0442     .get_function_groups = tegra_dpaux_get_function_groups,
0443     .set_mux = tegra_dpaux_set_mux,
0444 };
0445 #endif
0446 
0447 static int tegra_dpaux_probe(struct platform_device *pdev)
0448 {
0449     struct tegra_dpaux *dpaux;
0450     struct resource *regs;
0451     u32 value;
0452     int err;
0453 
0454     dpaux = devm_kzalloc(&pdev->dev, sizeof(*dpaux), GFP_KERNEL);
0455     if (!dpaux)
0456         return -ENOMEM;
0457 
0458     dpaux->soc = of_device_get_match_data(&pdev->dev);
0459     INIT_WORK(&dpaux->work, tegra_dpaux_hotplug);
0460     init_completion(&dpaux->complete);
0461     INIT_LIST_HEAD(&dpaux->list);
0462     dpaux->dev = &pdev->dev;
0463 
0464     regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0465     dpaux->regs = devm_ioremap_resource(&pdev->dev, regs);
0466     if (IS_ERR(dpaux->regs))
0467         return PTR_ERR(dpaux->regs);
0468 
0469     dpaux->irq = platform_get_irq(pdev, 0);
0470     if (dpaux->irq < 0)
0471         return -ENXIO;
0472 
0473     if (!pdev->dev.pm_domain) {
0474         dpaux->rst = devm_reset_control_get(&pdev->dev, "dpaux");
0475         if (IS_ERR(dpaux->rst)) {
0476             dev_err(&pdev->dev,
0477                 "failed to get reset control: %ld\n",
0478                 PTR_ERR(dpaux->rst));
0479             return PTR_ERR(dpaux->rst);
0480         }
0481     }
0482 
0483     dpaux->clk = devm_clk_get(&pdev->dev, NULL);
0484     if (IS_ERR(dpaux->clk)) {
0485         dev_err(&pdev->dev, "failed to get module clock: %ld\n",
0486             PTR_ERR(dpaux->clk));
0487         return PTR_ERR(dpaux->clk);
0488     }
0489 
0490     dpaux->clk_parent = devm_clk_get(&pdev->dev, "parent");
0491     if (IS_ERR(dpaux->clk_parent)) {
0492         dev_err(&pdev->dev, "failed to get parent clock: %ld\n",
0493             PTR_ERR(dpaux->clk_parent));
0494         return PTR_ERR(dpaux->clk_parent);
0495     }
0496 
0497     err = clk_set_rate(dpaux->clk_parent, 270000000);
0498     if (err < 0) {
0499         dev_err(&pdev->dev, "failed to set clock to 270 MHz: %d\n",
0500             err);
0501         return err;
0502     }
0503 
0504     dpaux->vdd = devm_regulator_get_optional(&pdev->dev, "vdd");
0505     if (IS_ERR(dpaux->vdd)) {
0506         if (PTR_ERR(dpaux->vdd) != -ENODEV) {
0507             if (PTR_ERR(dpaux->vdd) != -EPROBE_DEFER)
0508                 dev_err(&pdev->dev,
0509                     "failed to get VDD supply: %ld\n",
0510                     PTR_ERR(dpaux->vdd));
0511 
0512             return PTR_ERR(dpaux->vdd);
0513         }
0514 
0515         dpaux->vdd = NULL;
0516     }
0517 
0518     platform_set_drvdata(pdev, dpaux);
0519     pm_runtime_enable(&pdev->dev);
0520     pm_runtime_get_sync(&pdev->dev);
0521 
0522     err = devm_request_irq(dpaux->dev, dpaux->irq, tegra_dpaux_irq, 0,
0523                    dev_name(dpaux->dev), dpaux);
0524     if (err < 0) {
0525         dev_err(dpaux->dev, "failed to request IRQ#%u: %d\n",
0526             dpaux->irq, err);
0527         return err;
0528     }
0529 
0530     disable_irq(dpaux->irq);
0531 
0532     dpaux->aux.transfer = tegra_dpaux_transfer;
0533     dpaux->aux.dev = &pdev->dev;
0534 
0535     drm_dp_aux_init(&dpaux->aux);
0536 
0537     /*
0538      * Assume that by default the DPAUX/I2C pads will be used for HDMI,
0539      * so power them up and configure them in I2C mode.
0540      *
0541      * The DPAUX code paths reconfigure the pads in AUX mode, but there
0542      * is no possibility to perform the I2C mode configuration in the
0543      * HDMI path.
0544      */
0545     err = tegra_dpaux_pad_config(dpaux, DPAUX_PADCTL_FUNC_I2C);
0546     if (err < 0)
0547         return err;
0548 
0549 #ifdef CONFIG_GENERIC_PINCONF
0550     dpaux->desc.name = dev_name(&pdev->dev);
0551     dpaux->desc.pins = tegra_dpaux_pins;
0552     dpaux->desc.npins = ARRAY_SIZE(tegra_dpaux_pins);
0553     dpaux->desc.pctlops = &tegra_dpaux_pinctrl_ops;
0554     dpaux->desc.pmxops = &tegra_dpaux_pinmux_ops;
0555     dpaux->desc.owner = THIS_MODULE;
0556 
0557     dpaux->pinctrl = devm_pinctrl_register(&pdev->dev, &dpaux->desc, dpaux);
0558     if (IS_ERR(dpaux->pinctrl)) {
0559         dev_err(&pdev->dev, "failed to register pincontrol\n");
0560         return PTR_ERR(dpaux->pinctrl);
0561     }
0562 #endif
0563     /* enable and clear all interrupts */
0564     value = DPAUX_INTR_AUX_DONE | DPAUX_INTR_IRQ_EVENT |
0565         DPAUX_INTR_UNPLUG_EVENT | DPAUX_INTR_PLUG_EVENT;
0566     tegra_dpaux_writel(dpaux, value, DPAUX_INTR_EN_AUX);
0567     tegra_dpaux_writel(dpaux, value, DPAUX_INTR_AUX);
0568 
0569     mutex_lock(&dpaux_lock);
0570     list_add_tail(&dpaux->list, &dpaux_list);
0571     mutex_unlock(&dpaux_lock);
0572 
0573     err = devm_of_dp_aux_populate_ep_devices(&dpaux->aux);
0574     if (err < 0) {
0575         dev_err(dpaux->dev, "failed to populate AUX bus: %d\n", err);
0576         return err;
0577     }
0578 
0579     return 0;
0580 }
0581 
0582 static int tegra_dpaux_remove(struct platform_device *pdev)
0583 {
0584     struct tegra_dpaux *dpaux = platform_get_drvdata(pdev);
0585 
0586     cancel_work_sync(&dpaux->work);
0587 
0588     /* make sure pads are powered down when not in use */
0589     tegra_dpaux_pad_power_down(dpaux);
0590 
0591     pm_runtime_put_sync(&pdev->dev);
0592     pm_runtime_disable(&pdev->dev);
0593 
0594     mutex_lock(&dpaux_lock);
0595     list_del(&dpaux->list);
0596     mutex_unlock(&dpaux_lock);
0597 
0598     return 0;
0599 }
0600 
0601 #ifdef CONFIG_PM
0602 static int tegra_dpaux_suspend(struct device *dev)
0603 {
0604     struct tegra_dpaux *dpaux = dev_get_drvdata(dev);
0605     int err = 0;
0606 
0607     if (dpaux->rst) {
0608         err = reset_control_assert(dpaux->rst);
0609         if (err < 0) {
0610             dev_err(dev, "failed to assert reset: %d\n", err);
0611             return err;
0612         }
0613     }
0614 
0615     usleep_range(1000, 2000);
0616 
0617     clk_disable_unprepare(dpaux->clk_parent);
0618     clk_disable_unprepare(dpaux->clk);
0619 
0620     return err;
0621 }
0622 
0623 static int tegra_dpaux_resume(struct device *dev)
0624 {
0625     struct tegra_dpaux *dpaux = dev_get_drvdata(dev);
0626     int err;
0627 
0628     err = clk_prepare_enable(dpaux->clk);
0629     if (err < 0) {
0630         dev_err(dev, "failed to enable clock: %d\n", err);
0631         return err;
0632     }
0633 
0634     err = clk_prepare_enable(dpaux->clk_parent);
0635     if (err < 0) {
0636         dev_err(dev, "failed to enable parent clock: %d\n", err);
0637         goto disable_clk;
0638     }
0639 
0640     usleep_range(1000, 2000);
0641 
0642     if (dpaux->rst) {
0643         err = reset_control_deassert(dpaux->rst);
0644         if (err < 0) {
0645             dev_err(dev, "failed to deassert reset: %d\n", err);
0646             goto disable_parent;
0647         }
0648 
0649         usleep_range(1000, 2000);
0650     }
0651 
0652     return 0;
0653 
0654 disable_parent:
0655     clk_disable_unprepare(dpaux->clk_parent);
0656 disable_clk:
0657     clk_disable_unprepare(dpaux->clk);
0658     return err;
0659 }
0660 #endif
0661 
0662 static const struct dev_pm_ops tegra_dpaux_pm_ops = {
0663     SET_RUNTIME_PM_OPS(tegra_dpaux_suspend, tegra_dpaux_resume, NULL)
0664 };
0665 
0666 static const struct tegra_dpaux_soc tegra124_dpaux_soc = {
0667     .cmh = 0x02,
0668     .drvz = 0x04,
0669     .drvi = 0x18,
0670 };
0671 
0672 static const struct tegra_dpaux_soc tegra210_dpaux_soc = {
0673     .cmh = 0x02,
0674     .drvz = 0x04,
0675     .drvi = 0x30,
0676 };
0677 
0678 static const struct tegra_dpaux_soc tegra194_dpaux_soc = {
0679     .cmh = 0x02,
0680     .drvz = 0x04,
0681     .drvi = 0x2c,
0682 };
0683 
0684 static const struct of_device_id tegra_dpaux_of_match[] = {
0685     { .compatible = "nvidia,tegra194-dpaux", .data = &tegra194_dpaux_soc },
0686     { .compatible = "nvidia,tegra186-dpaux", .data = &tegra210_dpaux_soc },
0687     { .compatible = "nvidia,tegra210-dpaux", .data = &tegra210_dpaux_soc },
0688     { .compatible = "nvidia,tegra124-dpaux", .data = &tegra124_dpaux_soc },
0689     { },
0690 };
0691 MODULE_DEVICE_TABLE(of, tegra_dpaux_of_match);
0692 
0693 struct platform_driver tegra_dpaux_driver = {
0694     .driver = {
0695         .name = "tegra-dpaux",
0696         .of_match_table = tegra_dpaux_of_match,
0697         .pm = &tegra_dpaux_pm_ops,
0698     },
0699     .probe = tegra_dpaux_probe,
0700     .remove = tegra_dpaux_remove,
0701 };
0702 
0703 struct drm_dp_aux *drm_dp_aux_find_by_of_node(struct device_node *np)
0704 {
0705     struct tegra_dpaux *dpaux;
0706 
0707     mutex_lock(&dpaux_lock);
0708 
0709     list_for_each_entry(dpaux, &dpaux_list, list)
0710         if (np == dpaux->dev->of_node) {
0711             mutex_unlock(&dpaux_lock);
0712             return &dpaux->aux;
0713         }
0714 
0715     mutex_unlock(&dpaux_lock);
0716 
0717     return NULL;
0718 }
0719 
0720 int drm_dp_aux_attach(struct drm_dp_aux *aux, struct tegra_output *output)
0721 {
0722     struct tegra_dpaux *dpaux = to_dpaux(aux);
0723     unsigned long timeout;
0724     int err;
0725 
0726     aux->drm_dev = output->connector.dev;
0727     err = drm_dp_aux_register(aux);
0728     if (err < 0)
0729         return err;
0730 
0731     output->connector.polled = DRM_CONNECTOR_POLL_HPD;
0732     dpaux->output = output;
0733 
0734     if (output->panel) {
0735         enum drm_connector_status status;
0736 
0737         if (dpaux->vdd) {
0738             err = regulator_enable(dpaux->vdd);
0739             if (err < 0)
0740                 return err;
0741         }
0742 
0743         timeout = jiffies + msecs_to_jiffies(250);
0744 
0745         while (time_before(jiffies, timeout)) {
0746             status = drm_dp_aux_detect(aux);
0747 
0748             if (status == connector_status_connected)
0749                 break;
0750 
0751             usleep_range(1000, 2000);
0752         }
0753 
0754         if (status != connector_status_connected)
0755             return -ETIMEDOUT;
0756     }
0757 
0758     enable_irq(dpaux->irq);
0759     return 0;
0760 }
0761 
0762 int drm_dp_aux_detach(struct drm_dp_aux *aux)
0763 {
0764     struct tegra_dpaux *dpaux = to_dpaux(aux);
0765     unsigned long timeout;
0766     int err;
0767 
0768     drm_dp_aux_unregister(aux);
0769     disable_irq(dpaux->irq);
0770 
0771     if (dpaux->output->panel) {
0772         enum drm_connector_status status;
0773 
0774         if (dpaux->vdd) {
0775             err = regulator_disable(dpaux->vdd);
0776             if (err < 0)
0777                 return err;
0778         }
0779 
0780         timeout = jiffies + msecs_to_jiffies(250);
0781 
0782         while (time_before(jiffies, timeout)) {
0783             status = drm_dp_aux_detect(aux);
0784 
0785             if (status == connector_status_disconnected)
0786                 break;
0787 
0788             usleep_range(1000, 2000);
0789         }
0790 
0791         if (status != connector_status_disconnected)
0792             return -ETIMEDOUT;
0793 
0794         dpaux->output = NULL;
0795     }
0796 
0797     return 0;
0798 }
0799 
0800 enum drm_connector_status drm_dp_aux_detect(struct drm_dp_aux *aux)
0801 {
0802     struct tegra_dpaux *dpaux = to_dpaux(aux);
0803     u32 value;
0804 
0805     value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXSTAT);
0806 
0807     if (value & DPAUX_DP_AUXSTAT_HPD_STATUS)
0808         return connector_status_connected;
0809 
0810     return connector_status_disconnected;
0811 }
0812 
0813 int drm_dp_aux_enable(struct drm_dp_aux *aux)
0814 {
0815     struct tegra_dpaux *dpaux = to_dpaux(aux);
0816 
0817     return tegra_dpaux_pad_config(dpaux, DPAUX_PADCTL_FUNC_AUX);
0818 }
0819 
0820 int drm_dp_aux_disable(struct drm_dp_aux *aux)
0821 {
0822     struct tegra_dpaux *dpaux = to_dpaux(aux);
0823 
0824     tegra_dpaux_pad_power_down(dpaux);
0825 
0826     return 0;
0827 }