Merge tag 'drm-misc-next-2021-04-09' of git://anongit.freedesktop.org/drm/drm-misc...
[linux-2.6-microblaze.git] / drivers / gpu / drm / tegra / dpaux.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2013 NVIDIA Corporation
4  */
5
6 #include <linux/clk.h>
7 #include <linux/delay.h>
8 #include <linux/interrupt.h>
9 #include <linux/io.h>
10 #include <linux/module.h>
11 #include <linux/of_device.h>
12 #include <linux/pinctrl/pinconf-generic.h>
13 #include <linux/pinctrl/pinctrl.h>
14 #include <linux/pinctrl/pinmux.h>
15 #include <linux/platform_device.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/regulator/consumer.h>
18 #include <linux/reset.h>
19 #include <linux/workqueue.h>
20
21 #include <drm/drm_dp_helper.h>
22 #include <drm/drm_panel.h>
23
24 #include "dp.h"
25 #include "dpaux.h"
26 #include "drm.h"
27 #include "trace.h"
28
29 static DEFINE_MUTEX(dpaux_lock);
30 static LIST_HEAD(dpaux_list);
31
32 struct tegra_dpaux_soc {
33         unsigned int cmh;
34         unsigned int drvz;
35         unsigned int drvi;
36 };
37
38 struct tegra_dpaux {
39         struct drm_dp_aux aux;
40         struct device *dev;
41
42         const struct tegra_dpaux_soc *soc;
43
44         void __iomem *regs;
45         int irq;
46
47         struct tegra_output *output;
48
49         struct reset_control *rst;
50         struct clk *clk_parent;
51         struct clk *clk;
52
53         struct regulator *vdd;
54
55         struct completion complete;
56         struct work_struct work;
57         struct list_head list;
58
59 #ifdef CONFIG_GENERIC_PINCONF
60         struct pinctrl_dev *pinctrl;
61         struct pinctrl_desc desc;
62 #endif
63 };
64
65 static inline struct tegra_dpaux *to_dpaux(struct drm_dp_aux *aux)
66 {
67         return container_of(aux, struct tegra_dpaux, aux);
68 }
69
70 static inline struct tegra_dpaux *work_to_dpaux(struct work_struct *work)
71 {
72         return container_of(work, struct tegra_dpaux, work);
73 }
74
75 static inline u32 tegra_dpaux_readl(struct tegra_dpaux *dpaux,
76                                     unsigned int offset)
77 {
78         u32 value = readl(dpaux->regs + (offset << 2));
79
80         trace_dpaux_readl(dpaux->dev, offset, value);
81
82         return value;
83 }
84
85 static inline void tegra_dpaux_writel(struct tegra_dpaux *dpaux,
86                                       u32 value, unsigned int offset)
87 {
88         trace_dpaux_writel(dpaux->dev, offset, value);
89         writel(value, dpaux->regs + (offset << 2));
90 }
91
92 static void tegra_dpaux_write_fifo(struct tegra_dpaux *dpaux, const u8 *buffer,
93                                    size_t size)
94 {
95         size_t i, j;
96
97         for (i = 0; i < DIV_ROUND_UP(size, 4); i++) {
98                 size_t num = min_t(size_t, size - i * 4, 4);
99                 u32 value = 0;
100
101                 for (j = 0; j < num; j++)
102                         value |= buffer[i * 4 + j] << (j * 8);
103
104                 tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXDATA_WRITE(i));
105         }
106 }
107
108 static void tegra_dpaux_read_fifo(struct tegra_dpaux *dpaux, u8 *buffer,
109                                   size_t size)
110 {
111         size_t i, j;
112
113         for (i = 0; i < DIV_ROUND_UP(size, 4); i++) {
114                 size_t num = min_t(size_t, size - i * 4, 4);
115                 u32 value;
116
117                 value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXDATA_READ(i));
118
119                 for (j = 0; j < num; j++)
120                         buffer[i * 4 + j] = value >> (j * 8);
121         }
122 }
123
124 static ssize_t tegra_dpaux_transfer(struct drm_dp_aux *aux,
125                                     struct drm_dp_aux_msg *msg)
126 {
127         unsigned long timeout = msecs_to_jiffies(250);
128         struct tegra_dpaux *dpaux = to_dpaux(aux);
129         unsigned long status;
130         ssize_t ret = 0;
131         u8 reply = 0;
132         u32 value;
133
134         /* Tegra has 4x4 byte DP AUX transmit and receive FIFOs. */
135         if (msg->size > 16)
136                 return -EINVAL;
137
138         /*
139          * Allow zero-sized messages only for I2C, in which case they specify
140          * address-only transactions.
141          */
142         if (msg->size < 1) {
143                 switch (msg->request & ~DP_AUX_I2C_MOT) {
144                 case DP_AUX_I2C_WRITE_STATUS_UPDATE:
145                 case DP_AUX_I2C_WRITE:
146                 case DP_AUX_I2C_READ:
147                         value = DPAUX_DP_AUXCTL_CMD_ADDRESS_ONLY;
148                         break;
149
150                 default:
151                         return -EINVAL;
152                 }
153         } else {
154                 /* For non-zero-sized messages, set the CMDLEN field. */
155                 value = DPAUX_DP_AUXCTL_CMDLEN(msg->size - 1);
156         }
157
158         switch (msg->request & ~DP_AUX_I2C_MOT) {
159         case DP_AUX_I2C_WRITE:
160                 if (msg->request & DP_AUX_I2C_MOT)
161                         value |= DPAUX_DP_AUXCTL_CMD_MOT_WR;
162                 else
163                         value |= DPAUX_DP_AUXCTL_CMD_I2C_WR;
164
165                 break;
166
167         case DP_AUX_I2C_READ:
168                 if (msg->request & DP_AUX_I2C_MOT)
169                         value |= DPAUX_DP_AUXCTL_CMD_MOT_RD;
170                 else
171                         value |= DPAUX_DP_AUXCTL_CMD_I2C_RD;
172
173                 break;
174
175         case DP_AUX_I2C_WRITE_STATUS_UPDATE:
176                 if (msg->request & DP_AUX_I2C_MOT)
177                         value |= DPAUX_DP_AUXCTL_CMD_MOT_RQ;
178                 else
179                         value |= DPAUX_DP_AUXCTL_CMD_I2C_RQ;
180
181                 break;
182
183         case DP_AUX_NATIVE_WRITE:
184                 value |= DPAUX_DP_AUXCTL_CMD_AUX_WR;
185                 break;
186
187         case DP_AUX_NATIVE_READ:
188                 value |= DPAUX_DP_AUXCTL_CMD_AUX_RD;
189                 break;
190
191         default:
192                 return -EINVAL;
193         }
194
195         tegra_dpaux_writel(dpaux, msg->address, DPAUX_DP_AUXADDR);
196         tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXCTL);
197
198         if ((msg->request & DP_AUX_I2C_READ) == 0) {
199                 tegra_dpaux_write_fifo(dpaux, msg->buffer, msg->size);
200                 ret = msg->size;
201         }
202
203         /* start transaction */
204         value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXCTL);
205         value |= DPAUX_DP_AUXCTL_TRANSACTREQ;
206         tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXCTL);
207
208         status = wait_for_completion_timeout(&dpaux->complete, timeout);
209         if (!status)
210                 return -ETIMEDOUT;
211
212         /* read status and clear errors */
213         value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXSTAT);
214         tegra_dpaux_writel(dpaux, 0xf00, DPAUX_DP_AUXSTAT);
215
216         if (value & DPAUX_DP_AUXSTAT_TIMEOUT_ERROR)
217                 return -ETIMEDOUT;
218
219         if ((value & DPAUX_DP_AUXSTAT_RX_ERROR) ||
220             (value & DPAUX_DP_AUXSTAT_SINKSTAT_ERROR) ||
221             (value & DPAUX_DP_AUXSTAT_NO_STOP_ERROR))
222                 return -EIO;
223
224         switch ((value & DPAUX_DP_AUXSTAT_REPLY_TYPE_MASK) >> 16) {
225         case 0x00:
226                 reply = DP_AUX_NATIVE_REPLY_ACK;
227                 break;
228
229         case 0x01:
230                 reply = DP_AUX_NATIVE_REPLY_NACK;
231                 break;
232
233         case 0x02:
234                 reply = DP_AUX_NATIVE_REPLY_DEFER;
235                 break;
236
237         case 0x04:
238                 reply = DP_AUX_I2C_REPLY_NACK;
239                 break;
240
241         case 0x08:
242                 reply = DP_AUX_I2C_REPLY_DEFER;
243                 break;
244         }
245
246         if ((msg->size > 0) && (msg->reply == DP_AUX_NATIVE_REPLY_ACK)) {
247                 if (msg->request & DP_AUX_I2C_READ) {
248                         size_t count = value & DPAUX_DP_AUXSTAT_REPLY_MASK;
249
250                         /*
251                          * There might be a smarter way to do this, but since
252                          * the DP helpers will already retry transactions for
253                          * an -EBUSY return value, simply reuse that instead.
254                          */
255                         if (count != msg->size) {
256                                 ret = -EBUSY;
257                                 goto out;
258                         }
259
260                         tegra_dpaux_read_fifo(dpaux, msg->buffer, count);
261                         ret = count;
262                 }
263         }
264
265         msg->reply = reply;
266
267 out:
268         return ret;
269 }
270
271 static void tegra_dpaux_hotplug(struct work_struct *work)
272 {
273         struct tegra_dpaux *dpaux = work_to_dpaux(work);
274
275         if (dpaux->output)
276                 drm_helper_hpd_irq_event(dpaux->output->connector.dev);
277 }
278
279 static irqreturn_t tegra_dpaux_irq(int irq, void *data)
280 {
281         struct tegra_dpaux *dpaux = data;
282         irqreturn_t ret = IRQ_HANDLED;
283         u32 value;
284
285         /* clear interrupts */
286         value = tegra_dpaux_readl(dpaux, DPAUX_INTR_AUX);
287         tegra_dpaux_writel(dpaux, value, DPAUX_INTR_AUX);
288
289         if (value & (DPAUX_INTR_PLUG_EVENT | DPAUX_INTR_UNPLUG_EVENT))
290                 schedule_work(&dpaux->work);
291
292         if (value & DPAUX_INTR_IRQ_EVENT) {
293                 /* TODO: handle this */
294         }
295
296         if (value & DPAUX_INTR_AUX_DONE)
297                 complete(&dpaux->complete);
298
299         return ret;
300 }
301
302 enum tegra_dpaux_functions {
303         DPAUX_PADCTL_FUNC_AUX,
304         DPAUX_PADCTL_FUNC_I2C,
305         DPAUX_PADCTL_FUNC_OFF,
306 };
307
308 static void tegra_dpaux_pad_power_down(struct tegra_dpaux *dpaux)
309 {
310         u32 value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
311
312         value |= DPAUX_HYBRID_SPARE_PAD_POWER_DOWN;
313
314         tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_SPARE);
315 }
316
317 static void tegra_dpaux_pad_power_up(struct tegra_dpaux *dpaux)
318 {
319         u32 value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
320
321         value &= ~DPAUX_HYBRID_SPARE_PAD_POWER_DOWN;
322
323         tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_SPARE);
324 }
325
326 static int tegra_dpaux_pad_config(struct tegra_dpaux *dpaux, unsigned function)
327 {
328         u32 value;
329
330         switch (function) {
331         case DPAUX_PADCTL_FUNC_AUX:
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) |
335                         DPAUX_HYBRID_PADCTL_AUX_INPUT_RCV |
336                         DPAUX_HYBRID_PADCTL_MODE_AUX;
337                 break;
338
339         case DPAUX_PADCTL_FUNC_I2C:
340                 value = DPAUX_HYBRID_PADCTL_I2C_SDA_INPUT_RCV |
341                         DPAUX_HYBRID_PADCTL_I2C_SCL_INPUT_RCV |
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) |
345                         DPAUX_HYBRID_PADCTL_MODE_I2C;
346                 break;
347
348         case DPAUX_PADCTL_FUNC_OFF:
349                 tegra_dpaux_pad_power_down(dpaux);
350                 return 0;
351
352         default:
353                 return -ENOTSUPP;
354         }
355
356         tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_PADCTL);
357         tegra_dpaux_pad_power_up(dpaux);
358
359         return 0;
360 }
361
362 #ifdef CONFIG_GENERIC_PINCONF
363 static const struct pinctrl_pin_desc tegra_dpaux_pins[] = {
364         PINCTRL_PIN(0, "DP_AUX_CHx_P"),
365         PINCTRL_PIN(1, "DP_AUX_CHx_N"),
366 };
367
368 static const unsigned tegra_dpaux_pin_numbers[] = { 0, 1 };
369
370 static const char * const tegra_dpaux_groups[] = {
371         "dpaux-io",
372 };
373
374 static const char * const tegra_dpaux_functions[] = {
375         "aux",
376         "i2c",
377         "off",
378 };
379
380 static int tegra_dpaux_get_groups_count(struct pinctrl_dev *pinctrl)
381 {
382         return ARRAY_SIZE(tegra_dpaux_groups);
383 }
384
385 static const char *tegra_dpaux_get_group_name(struct pinctrl_dev *pinctrl,
386                                               unsigned int group)
387 {
388         return tegra_dpaux_groups[group];
389 }
390
391 static int tegra_dpaux_get_group_pins(struct pinctrl_dev *pinctrl,
392                                       unsigned group, const unsigned **pins,
393                                       unsigned *num_pins)
394 {
395         *pins = tegra_dpaux_pin_numbers;
396         *num_pins = ARRAY_SIZE(tegra_dpaux_pin_numbers);
397
398         return 0;
399 }
400
401 static const struct pinctrl_ops tegra_dpaux_pinctrl_ops = {
402         .get_groups_count = tegra_dpaux_get_groups_count,
403         .get_group_name = tegra_dpaux_get_group_name,
404         .get_group_pins = tegra_dpaux_get_group_pins,
405         .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
406         .dt_free_map = pinconf_generic_dt_free_map,
407 };
408
409 static int tegra_dpaux_get_functions_count(struct pinctrl_dev *pinctrl)
410 {
411         return ARRAY_SIZE(tegra_dpaux_functions);
412 }
413
414 static const char *tegra_dpaux_get_function_name(struct pinctrl_dev *pinctrl,
415                                                  unsigned int function)
416 {
417         return tegra_dpaux_functions[function];
418 }
419
420 static int tegra_dpaux_get_function_groups(struct pinctrl_dev *pinctrl,
421                                            unsigned int function,
422                                            const char * const **groups,
423                                            unsigned * const num_groups)
424 {
425         *num_groups = ARRAY_SIZE(tegra_dpaux_groups);
426         *groups = tegra_dpaux_groups;
427
428         return 0;
429 }
430
431 static int tegra_dpaux_set_mux(struct pinctrl_dev *pinctrl,
432                                unsigned int function, unsigned int group)
433 {
434         struct tegra_dpaux *dpaux = pinctrl_dev_get_drvdata(pinctrl);
435
436         return tegra_dpaux_pad_config(dpaux, function);
437 }
438
439 static const struct pinmux_ops tegra_dpaux_pinmux_ops = {
440         .get_functions_count = tegra_dpaux_get_functions_count,
441         .get_function_name = tegra_dpaux_get_function_name,
442         .get_function_groups = tegra_dpaux_get_function_groups,
443         .set_mux = tegra_dpaux_set_mux,
444 };
445 #endif
446
447 static int tegra_dpaux_probe(struct platform_device *pdev)
448 {
449         struct tegra_dpaux *dpaux;
450         struct resource *regs;
451         u32 value;
452         int err;
453
454         dpaux = devm_kzalloc(&pdev->dev, sizeof(*dpaux), GFP_KERNEL);
455         if (!dpaux)
456                 return -ENOMEM;
457
458         dpaux->soc = of_device_get_match_data(&pdev->dev);
459         INIT_WORK(&dpaux->work, tegra_dpaux_hotplug);
460         init_completion(&dpaux->complete);
461         INIT_LIST_HEAD(&dpaux->list);
462         dpaux->dev = &pdev->dev;
463
464         regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
465         dpaux->regs = devm_ioremap_resource(&pdev->dev, regs);
466         if (IS_ERR(dpaux->regs))
467                 return PTR_ERR(dpaux->regs);
468
469         dpaux->irq = platform_get_irq(pdev, 0);
470         if (dpaux->irq < 0) {
471                 dev_err(&pdev->dev, "failed to get IRQ\n");
472                 return -ENXIO;
473         }
474
475         if (!pdev->dev.pm_domain) {
476                 dpaux->rst = devm_reset_control_get(&pdev->dev, "dpaux");
477                 if (IS_ERR(dpaux->rst)) {
478                         dev_err(&pdev->dev,
479                                 "failed to get reset control: %ld\n",
480                                 PTR_ERR(dpaux->rst));
481                         return PTR_ERR(dpaux->rst);
482                 }
483         }
484
485         dpaux->clk = devm_clk_get(&pdev->dev, NULL);
486         if (IS_ERR(dpaux->clk)) {
487                 dev_err(&pdev->dev, "failed to get module clock: %ld\n",
488                         PTR_ERR(dpaux->clk));
489                 return PTR_ERR(dpaux->clk);
490         }
491
492         dpaux->clk_parent = devm_clk_get(&pdev->dev, "parent");
493         if (IS_ERR(dpaux->clk_parent)) {
494                 dev_err(&pdev->dev, "failed to get parent clock: %ld\n",
495                         PTR_ERR(dpaux->clk_parent));
496                 return PTR_ERR(dpaux->clk_parent);
497         }
498
499         err = clk_set_rate(dpaux->clk_parent, 270000000);
500         if (err < 0) {
501                 dev_err(&pdev->dev, "failed to set clock to 270 MHz: %d\n",
502                         err);
503                 return err;
504         }
505
506         dpaux->vdd = devm_regulator_get_optional(&pdev->dev, "vdd");
507         if (IS_ERR(dpaux->vdd)) {
508                 if (PTR_ERR(dpaux->vdd) != -ENODEV) {
509                         if (PTR_ERR(dpaux->vdd) != -EPROBE_DEFER)
510                                 dev_err(&pdev->dev,
511                                         "failed to get VDD supply: %ld\n",
512                                         PTR_ERR(dpaux->vdd));
513
514                         return PTR_ERR(dpaux->vdd);
515                 }
516
517                 dpaux->vdd = NULL;
518         }
519
520         platform_set_drvdata(pdev, dpaux);
521         pm_runtime_enable(&pdev->dev);
522         pm_runtime_get_sync(&pdev->dev);
523
524         err = devm_request_irq(dpaux->dev, dpaux->irq, tegra_dpaux_irq, 0,
525                                dev_name(dpaux->dev), dpaux);
526         if (err < 0) {
527                 dev_err(dpaux->dev, "failed to request IRQ#%u: %d\n",
528                         dpaux->irq, err);
529                 return err;
530         }
531
532         disable_irq(dpaux->irq);
533
534         dpaux->aux.transfer = tegra_dpaux_transfer;
535         dpaux->aux.dev = &pdev->dev;
536
537         drm_dp_aux_init(&dpaux->aux);
538
539         /*
540          * Assume that by default the DPAUX/I2C pads will be used for HDMI,
541          * so power them up and configure them in I2C mode.
542          *
543          * The DPAUX code paths reconfigure the pads in AUX mode, but there
544          * is no possibility to perform the I2C mode configuration in the
545          * HDMI path.
546          */
547         err = tegra_dpaux_pad_config(dpaux, DPAUX_PADCTL_FUNC_I2C);
548         if (err < 0)
549                 return err;
550
551 #ifdef CONFIG_GENERIC_PINCONF
552         dpaux->desc.name = dev_name(&pdev->dev);
553         dpaux->desc.pins = tegra_dpaux_pins;
554         dpaux->desc.npins = ARRAY_SIZE(tegra_dpaux_pins);
555         dpaux->desc.pctlops = &tegra_dpaux_pinctrl_ops;
556         dpaux->desc.pmxops = &tegra_dpaux_pinmux_ops;
557         dpaux->desc.owner = THIS_MODULE;
558
559         dpaux->pinctrl = devm_pinctrl_register(&pdev->dev, &dpaux->desc, dpaux);
560         if (IS_ERR(dpaux->pinctrl)) {
561                 dev_err(&pdev->dev, "failed to register pincontrol\n");
562                 return PTR_ERR(dpaux->pinctrl);
563         }
564 #endif
565         /* enable and clear all interrupts */
566         value = DPAUX_INTR_AUX_DONE | DPAUX_INTR_IRQ_EVENT |
567                 DPAUX_INTR_UNPLUG_EVENT | DPAUX_INTR_PLUG_EVENT;
568         tegra_dpaux_writel(dpaux, value, DPAUX_INTR_EN_AUX);
569         tegra_dpaux_writel(dpaux, value, DPAUX_INTR_AUX);
570
571         mutex_lock(&dpaux_lock);
572         list_add_tail(&dpaux->list, &dpaux_list);
573         mutex_unlock(&dpaux_lock);
574
575         return 0;
576 }
577
578 static int tegra_dpaux_remove(struct platform_device *pdev)
579 {
580         struct tegra_dpaux *dpaux = platform_get_drvdata(pdev);
581
582         cancel_work_sync(&dpaux->work);
583
584         /* make sure pads are powered down when not in use */
585         tegra_dpaux_pad_power_down(dpaux);
586
587         pm_runtime_put_sync(&pdev->dev);
588         pm_runtime_disable(&pdev->dev);
589
590         mutex_lock(&dpaux_lock);
591         list_del(&dpaux->list);
592         mutex_unlock(&dpaux_lock);
593
594         return 0;
595 }
596
597 #ifdef CONFIG_PM
598 static int tegra_dpaux_suspend(struct device *dev)
599 {
600         struct tegra_dpaux *dpaux = dev_get_drvdata(dev);
601         int err = 0;
602
603         if (dpaux->rst) {
604                 err = reset_control_assert(dpaux->rst);
605                 if (err < 0) {
606                         dev_err(dev, "failed to assert reset: %d\n", err);
607                         return err;
608                 }
609         }
610
611         usleep_range(1000, 2000);
612
613         clk_disable_unprepare(dpaux->clk_parent);
614         clk_disable_unprepare(dpaux->clk);
615
616         return err;
617 }
618
619 static int tegra_dpaux_resume(struct device *dev)
620 {
621         struct tegra_dpaux *dpaux = dev_get_drvdata(dev);
622         int err;
623
624         err = clk_prepare_enable(dpaux->clk);
625         if (err < 0) {
626                 dev_err(dev, "failed to enable clock: %d\n", err);
627                 return err;
628         }
629
630         err = clk_prepare_enable(dpaux->clk_parent);
631         if (err < 0) {
632                 dev_err(dev, "failed to enable parent clock: %d\n", err);
633                 goto disable_clk;
634         }
635
636         usleep_range(1000, 2000);
637
638         if (dpaux->rst) {
639                 err = reset_control_deassert(dpaux->rst);
640                 if (err < 0) {
641                         dev_err(dev, "failed to deassert reset: %d\n", err);
642                         goto disable_parent;
643                 }
644
645                 usleep_range(1000, 2000);
646         }
647
648         return 0;
649
650 disable_parent:
651         clk_disable_unprepare(dpaux->clk_parent);
652 disable_clk:
653         clk_disable_unprepare(dpaux->clk);
654         return err;
655 }
656 #endif
657
658 static const struct dev_pm_ops tegra_dpaux_pm_ops = {
659         SET_RUNTIME_PM_OPS(tegra_dpaux_suspend, tegra_dpaux_resume, NULL)
660 };
661
662 static const struct tegra_dpaux_soc tegra124_dpaux_soc = {
663         .cmh = 0x02,
664         .drvz = 0x04,
665         .drvi = 0x18,
666 };
667
668 static const struct tegra_dpaux_soc tegra210_dpaux_soc = {
669         .cmh = 0x02,
670         .drvz = 0x04,
671         .drvi = 0x30,
672 };
673
674 static const struct tegra_dpaux_soc tegra194_dpaux_soc = {
675         .cmh = 0x02,
676         .drvz = 0x04,
677         .drvi = 0x2c,
678 };
679
680 static const struct of_device_id tegra_dpaux_of_match[] = {
681         { .compatible = "nvidia,tegra194-dpaux", .data = &tegra194_dpaux_soc },
682         { .compatible = "nvidia,tegra186-dpaux", .data = &tegra210_dpaux_soc },
683         { .compatible = "nvidia,tegra210-dpaux", .data = &tegra210_dpaux_soc },
684         { .compatible = "nvidia,tegra124-dpaux", .data = &tegra124_dpaux_soc },
685         { },
686 };
687 MODULE_DEVICE_TABLE(of, tegra_dpaux_of_match);
688
689 struct platform_driver tegra_dpaux_driver = {
690         .driver = {
691                 .name = "tegra-dpaux",
692                 .of_match_table = tegra_dpaux_of_match,
693                 .pm = &tegra_dpaux_pm_ops,
694         },
695         .probe = tegra_dpaux_probe,
696         .remove = tegra_dpaux_remove,
697 };
698
699 struct drm_dp_aux *drm_dp_aux_find_by_of_node(struct device_node *np)
700 {
701         struct tegra_dpaux *dpaux;
702
703         mutex_lock(&dpaux_lock);
704
705         list_for_each_entry(dpaux, &dpaux_list, list)
706                 if (np == dpaux->dev->of_node) {
707                         mutex_unlock(&dpaux_lock);
708                         return &dpaux->aux;
709                 }
710
711         mutex_unlock(&dpaux_lock);
712
713         return NULL;
714 }
715
716 int drm_dp_aux_attach(struct drm_dp_aux *aux, struct tegra_output *output)
717 {
718         struct tegra_dpaux *dpaux = to_dpaux(aux);
719         unsigned long timeout;
720         int err;
721
722         err = drm_dp_aux_register(aux);
723         if (err < 0)
724                 return err;
725
726         output->connector.polled = DRM_CONNECTOR_POLL_HPD;
727         dpaux->output = output;
728
729         if (output->panel) {
730                 enum drm_connector_status status;
731
732                 if (dpaux->vdd) {
733                         err = regulator_enable(dpaux->vdd);
734                         if (err < 0)
735                                 return err;
736                 }
737
738                 timeout = jiffies + msecs_to_jiffies(250);
739
740                 while (time_before(jiffies, timeout)) {
741                         status = drm_dp_aux_detect(aux);
742
743                         if (status == connector_status_connected)
744                                 break;
745
746                         usleep_range(1000, 2000);
747                 }
748
749                 if (status != connector_status_connected)
750                         return -ETIMEDOUT;
751         }
752
753         enable_irq(dpaux->irq);
754         return 0;
755 }
756
757 int drm_dp_aux_detach(struct drm_dp_aux *aux)
758 {
759         struct tegra_dpaux *dpaux = to_dpaux(aux);
760         unsigned long timeout;
761         int err;
762
763         drm_dp_aux_unregister(aux);
764         disable_irq(dpaux->irq);
765
766         if (dpaux->output->panel) {
767                 enum drm_connector_status status;
768
769                 if (dpaux->vdd) {
770                         err = regulator_disable(dpaux->vdd);
771                         if (err < 0)
772                                 return err;
773                 }
774
775                 timeout = jiffies + msecs_to_jiffies(250);
776
777                 while (time_before(jiffies, timeout)) {
778                         status = drm_dp_aux_detect(aux);
779
780                         if (status == connector_status_disconnected)
781                                 break;
782
783                         usleep_range(1000, 2000);
784                 }
785
786                 if (status != connector_status_disconnected)
787                         return -ETIMEDOUT;
788
789                 dpaux->output = NULL;
790         }
791
792         return 0;
793 }
794
795 enum drm_connector_status drm_dp_aux_detect(struct drm_dp_aux *aux)
796 {
797         struct tegra_dpaux *dpaux = to_dpaux(aux);
798         u32 value;
799
800         value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXSTAT);
801
802         if (value & DPAUX_DP_AUXSTAT_HPD_STATUS)
803                 return connector_status_connected;
804
805         return connector_status_disconnected;
806 }
807
808 int drm_dp_aux_enable(struct drm_dp_aux *aux)
809 {
810         struct tegra_dpaux *dpaux = to_dpaux(aux);
811
812         return tegra_dpaux_pad_config(dpaux, DPAUX_PADCTL_FUNC_AUX);
813 }
814
815 int drm_dp_aux_disable(struct drm_dp_aux *aux)
816 {
817         struct tegra_dpaux *dpaux = to_dpaux(aux);
818
819         tegra_dpaux_pad_power_down(dpaux);
820
821         return 0;
822 }