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