1
2
3
4
5
6
7
8
9
10#include <linux/clk.h>
11#include <linux/delay.h>
12#include <linux/io.h>
13#include <linux/module.h>
14#include <linux/of.h>
15#include <linux/of_device.h>
16#include <linux/of_graph.h>
17#include <linux/platform_device.h>
18#include <linux/slab.h>
19#include <linux/sys_soc.h>
20
21#include <drm/drm_atomic.h>
22#include <drm/drm_atomic_helper.h>
23#include <drm/drm_bridge.h>
24#include <drm/drm_of.h>
25#include <drm/drm_panel.h>
26#include <drm/drm_print.h>
27#include <drm/drm_probe_helper.h>
28
29#include "rcar_lvds.h"
30#include "rcar_lvds_regs.h"
31
32struct rcar_lvds;
33
34
35enum rcar_lvds_mode {
36 RCAR_LVDS_MODE_JEIDA = 0,
37 RCAR_LVDS_MODE_MIRROR = 1,
38 RCAR_LVDS_MODE_VESA = 4,
39};
40
41enum rcar_lvds_link_type {
42 RCAR_LVDS_SINGLE_LINK = 0,
43 RCAR_LVDS_DUAL_LINK_EVEN_ODD_PIXELS = 1,
44 RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS = 2,
45};
46
47#define RCAR_LVDS_QUIRK_LANES BIT(0)
48#define RCAR_LVDS_QUIRK_GEN3_LVEN BIT(1)
49#define RCAR_LVDS_QUIRK_PWD BIT(2)
50#define RCAR_LVDS_QUIRK_EXT_PLL BIT(3)
51#define RCAR_LVDS_QUIRK_DUAL_LINK BIT(4)
52
53struct rcar_lvds_device_info {
54 unsigned int gen;
55 unsigned int quirks;
56 void (*pll_setup)(struct rcar_lvds *lvds, unsigned int freq);
57};
58
59struct rcar_lvds {
60 struct device *dev;
61 const struct rcar_lvds_device_info *info;
62
63 struct drm_bridge bridge;
64
65 struct drm_bridge *next_bridge;
66 struct drm_connector connector;
67 struct drm_panel *panel;
68
69 void __iomem *mmio;
70 struct {
71 struct clk *mod;
72 struct clk *extal;
73 struct clk *dotclkin[2];
74 } clocks;
75
76 struct drm_bridge *companion;
77 enum rcar_lvds_link_type link_type;
78};
79
80#define bridge_to_rcar_lvds(b) \
81 container_of(b, struct rcar_lvds, bridge)
82
83#define connector_to_rcar_lvds(c) \
84 container_of(c, struct rcar_lvds, connector)
85
86static void rcar_lvds_write(struct rcar_lvds *lvds, u32 reg, u32 data)
87{
88 iowrite32(data, lvds->mmio + reg);
89}
90
91
92
93
94
95static int rcar_lvds_connector_get_modes(struct drm_connector *connector)
96{
97 struct rcar_lvds *lvds = connector_to_rcar_lvds(connector);
98
99 return drm_panel_get_modes(lvds->panel, connector);
100}
101
102static int rcar_lvds_connector_atomic_check(struct drm_connector *connector,
103 struct drm_atomic_state *state)
104{
105 struct rcar_lvds *lvds = connector_to_rcar_lvds(connector);
106 const struct drm_display_mode *panel_mode;
107 struct drm_connector_state *conn_state;
108 struct drm_crtc_state *crtc_state;
109
110 conn_state = drm_atomic_get_new_connector_state(state, connector);
111 if (!conn_state->crtc)
112 return 0;
113
114 if (list_empty(&connector->modes)) {
115 dev_dbg(lvds->dev, "connector: empty modes list\n");
116 return -EINVAL;
117 }
118
119 panel_mode = list_first_entry(&connector->modes,
120 struct drm_display_mode, head);
121
122
123 crtc_state = drm_atomic_get_crtc_state(state, conn_state->crtc);
124 if (IS_ERR(crtc_state))
125 return PTR_ERR(crtc_state);
126
127 if (crtc_state->mode.hdisplay != panel_mode->hdisplay ||
128 crtc_state->mode.vdisplay != panel_mode->vdisplay)
129 return -EINVAL;
130
131
132 drm_mode_copy(&crtc_state->adjusted_mode, panel_mode);
133
134 return 0;
135}
136
137static const struct drm_connector_helper_funcs rcar_lvds_conn_helper_funcs = {
138 .get_modes = rcar_lvds_connector_get_modes,
139 .atomic_check = rcar_lvds_connector_atomic_check,
140};
141
142static const struct drm_connector_funcs rcar_lvds_conn_funcs = {
143 .reset = drm_atomic_helper_connector_reset,
144 .fill_modes = drm_helper_probe_single_connector_modes,
145 .destroy = drm_connector_cleanup,
146 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
147 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
148};
149
150
151
152
153
154static void rcar_lvds_pll_setup_gen2(struct rcar_lvds *lvds, unsigned int freq)
155{
156 u32 val;
157
158 if (freq < 39000000)
159 val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M;
160 else if (freq < 61000000)
161 val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M;
162 else if (freq < 121000000)
163 val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M;
164 else
165 val = LVDPLLCR_PLLDLYCNT_150M;
166
167 rcar_lvds_write(lvds, LVDPLLCR, val);
168}
169
170static void rcar_lvds_pll_setup_gen3(struct rcar_lvds *lvds, unsigned int freq)
171{
172 u32 val;
173
174 if (freq < 42000000)
175 val = LVDPLLCR_PLLDIVCNT_42M;
176 else if (freq < 85000000)
177 val = LVDPLLCR_PLLDIVCNT_85M;
178 else if (freq < 128000000)
179 val = LVDPLLCR_PLLDIVCNT_128M;
180 else
181 val = LVDPLLCR_PLLDIVCNT_148M;
182
183 rcar_lvds_write(lvds, LVDPLLCR, val);
184}
185
186struct pll_info {
187 unsigned long diff;
188 unsigned int pll_m;
189 unsigned int pll_n;
190 unsigned int pll_e;
191 unsigned int div;
192 u32 clksel;
193};
194
195static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk,
196 unsigned long target, struct pll_info *pll,
197 u32 clksel, bool dot_clock_only)
198{
199 unsigned int div7 = dot_clock_only ? 1 : 7;
200 unsigned long output;
201 unsigned long fin;
202 unsigned int m_min;
203 unsigned int m_max;
204 unsigned int m;
205 int error;
206
207 if (!clk)
208 return;
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240 fin = clk_get_rate(clk);
241 if (fin < 12000000 || fin > 192000000)
242 return;
243
244
245
246
247
248
249
250 m_min = max_t(unsigned int, 1, DIV_ROUND_UP(fin, 24000000));
251 m_max = min_t(unsigned int, 8, fin / 12000000);
252
253 for (m = m_min; m <= m_max; ++m) {
254 unsigned long fpfd;
255 unsigned int n_min;
256 unsigned int n_max;
257 unsigned int n;
258
259
260
261
262
263
264
265
266 fpfd = fin / m;
267 n_min = max_t(unsigned int, 60, DIV_ROUND_UP(900000000, fpfd));
268 n_max = min_t(unsigned int, 120, 1800000000 / fpfd);
269
270 for (n = n_min; n < n_max; ++n) {
271 unsigned long fvco;
272 unsigned int e_min;
273 unsigned int e;
274
275
276
277
278
279
280
281
282 fvco = fpfd * n;
283 e_min = fvco > 1039500000 ? 1 : 0;
284
285 for (e = e_min; e < 3; ++e) {
286 unsigned long fout;
287 unsigned long diff;
288 unsigned int div;
289
290
291
292
293
294
295 fout = fvco / (1 << e) / div7;
296 div = max(1UL, DIV_ROUND_CLOSEST(fout, target));
297 diff = abs(fout / div - target);
298
299 if (diff < pll->diff) {
300 pll->diff = diff;
301 pll->pll_m = m;
302 pll->pll_n = n;
303 pll->pll_e = e;
304 pll->div = div;
305 pll->clksel = clksel;
306
307 if (diff == 0)
308 goto done;
309 }
310 }
311 }
312 }
313
314done:
315 output = fin * pll->pll_n / pll->pll_m / (1 << pll->pll_e)
316 / div7 / pll->div;
317 error = (long)(output - target) * 10000 / (long)target;
318
319 dev_dbg(lvds->dev,
320 "%pC %lu Hz -> Fout %lu Hz (target %lu Hz, error %d.%02u%%), PLL M/N/E/DIV %u/%u/%u/%u\n",
321 clk, fin, output, target, error / 100,
322 error < 0 ? -error % 100 : error % 100,
323 pll->pll_m, pll->pll_n, pll->pll_e, pll->div);
324}
325
326static void __rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds,
327 unsigned int freq, bool dot_clock_only)
328{
329 struct pll_info pll = { .diff = (unsigned long)-1 };
330 u32 lvdpllcr;
331
332 rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[0], freq, &pll,
333 LVDPLLCR_CKSEL_DU_DOTCLKIN(0), dot_clock_only);
334 rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[1], freq, &pll,
335 LVDPLLCR_CKSEL_DU_DOTCLKIN(1), dot_clock_only);
336 rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.extal, freq, &pll,
337 LVDPLLCR_CKSEL_EXTAL, dot_clock_only);
338
339 lvdpllcr = LVDPLLCR_PLLON | pll.clksel | LVDPLLCR_CLKOUT
340 | LVDPLLCR_PLLN(pll.pll_n - 1) | LVDPLLCR_PLLM(pll.pll_m - 1);
341
342 if (pll.pll_e > 0)
343 lvdpllcr |= LVDPLLCR_STP_CLKOUTE | LVDPLLCR_OUTCLKSEL
344 | LVDPLLCR_PLLE(pll.pll_e - 1);
345
346 if (dot_clock_only)
347 lvdpllcr |= LVDPLLCR_OCKSEL;
348
349 rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
350
351 if (pll.div > 1)
352
353
354
355
356 rcar_lvds_write(lvds, LVDDIV, LVDDIV_DIVSEL |
357 LVDDIV_DIVRESET | LVDDIV_DIV(pll.div - 1));
358 else
359 rcar_lvds_write(lvds, LVDDIV, 0);
360}
361
362static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned int freq)
363{
364 __rcar_lvds_pll_setup_d3_e3(lvds, freq, false);
365}
366
367
368
369
370
371int rcar_lvds_clk_enable(struct drm_bridge *bridge, unsigned long freq)
372{
373 struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
374 int ret;
375
376 if (WARN_ON(!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)))
377 return -ENODEV;
378
379 dev_dbg(lvds->dev, "enabling LVDS PLL, freq=%luHz\n", freq);
380
381 ret = clk_prepare_enable(lvds->clocks.mod);
382 if (ret < 0)
383 return ret;
384
385 __rcar_lvds_pll_setup_d3_e3(lvds, freq, true);
386
387 return 0;
388}
389EXPORT_SYMBOL_GPL(rcar_lvds_clk_enable);
390
391void rcar_lvds_clk_disable(struct drm_bridge *bridge)
392{
393 struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
394
395 if (WARN_ON(!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)))
396 return;
397
398 dev_dbg(lvds->dev, "disabling LVDS PLL\n");
399
400 rcar_lvds_write(lvds, LVDPLLCR, 0);
401
402 clk_disable_unprepare(lvds->clocks.mod);
403}
404EXPORT_SYMBOL_GPL(rcar_lvds_clk_disable);
405
406
407
408
409
410static enum rcar_lvds_mode rcar_lvds_get_lvds_mode(struct rcar_lvds *lvds,
411 const struct drm_connector *connector)
412{
413 const struct drm_display_info *info;
414 enum rcar_lvds_mode mode;
415
416
417
418
419
420 if (!lvds->panel)
421 return RCAR_LVDS_MODE_JEIDA;
422
423 info = &connector->display_info;
424 if (!info->num_bus_formats || !info->bus_formats) {
425 dev_warn(lvds->dev,
426 "no LVDS bus format reported, using JEIDA\n");
427 return RCAR_LVDS_MODE_JEIDA;
428 }
429
430 switch (info->bus_formats[0]) {
431 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
432 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
433 mode = RCAR_LVDS_MODE_JEIDA;
434 break;
435 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
436 mode = RCAR_LVDS_MODE_VESA;
437 break;
438 default:
439 dev_warn(lvds->dev,
440 "unsupported LVDS bus format 0x%04x, using JEIDA\n",
441 info->bus_formats[0]);
442 return RCAR_LVDS_MODE_JEIDA;
443 }
444
445 if (info->bus_flags & DRM_BUS_FLAG_DATA_LSB_TO_MSB)
446 mode |= RCAR_LVDS_MODE_MIRROR;
447
448 return mode;
449}
450
451static void __rcar_lvds_atomic_enable(struct drm_bridge *bridge,
452 struct drm_atomic_state *state,
453 struct drm_crtc *crtc,
454 struct drm_connector *connector)
455{
456 struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
457 u32 lvdhcr;
458 u32 lvdcr0;
459 int ret;
460
461 ret = clk_prepare_enable(lvds->clocks.mod);
462 if (ret < 0)
463 return;
464
465
466 if (lvds->link_type != RCAR_LVDS_SINGLE_LINK && lvds->companion)
467 __rcar_lvds_atomic_enable(lvds->companion, state, crtc,
468 connector);
469
470
471
472
473
474
475
476
477
478 rcar_lvds_write(lvds, LVDCTRCR, LVDCTRCR_CTR3SEL_ZERO |
479 LVDCTRCR_CTR2SEL_DISP | LVDCTRCR_CTR1SEL_VSYNC |
480 LVDCTRCR_CTR0SEL_HSYNC);
481
482 if (lvds->info->quirks & RCAR_LVDS_QUIRK_LANES)
483 lvdhcr = LVDCHCR_CHSEL_CH(0, 0) | LVDCHCR_CHSEL_CH(1, 3)
484 | LVDCHCR_CHSEL_CH(2, 2) | LVDCHCR_CHSEL_CH(3, 1);
485 else
486 lvdhcr = LVDCHCR_CHSEL_CH(0, 0) | LVDCHCR_CHSEL_CH(1, 1)
487 | LVDCHCR_CHSEL_CH(2, 2) | LVDCHCR_CHSEL_CH(3, 3);
488
489 rcar_lvds_write(lvds, LVDCHCR, lvdhcr);
490
491 if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK) {
492 u32 lvdstripe = 0;
493
494 if (lvds->link_type != RCAR_LVDS_SINGLE_LINK) {
495
496
497
498
499
500
501
502 bool swap_pixels = lvds->link_type ==
503 RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS;
504
505
506
507
508
509
510
511
512 lvdstripe = LVDSTRIPE_ST_ON
513 | (lvds->companion && swap_pixels ?
514 LVDSTRIPE_ST_SWAP : 0);
515 }
516 rcar_lvds_write(lvds, LVDSTRIPE, lvdstripe);
517 }
518
519
520
521
522
523 if (lvds->link_type == RCAR_LVDS_SINGLE_LINK || lvds->companion) {
524 const struct drm_crtc_state *crtc_state =
525 drm_atomic_get_new_crtc_state(state, crtc);
526 const struct drm_display_mode *mode =
527 &crtc_state->adjusted_mode;
528
529 lvds->info->pll_setup(lvds, mode->clock * 1000);
530 }
531
532
533 lvdcr0 = rcar_lvds_get_lvds_mode(lvds, connector) << LVDCR0_LVMD_SHIFT;
534
535 if (lvds->bridge.encoder) {
536 if (drm_crtc_index(crtc) == 2)
537 lvdcr0 |= LVDCR0_DUSEL;
538 }
539
540 rcar_lvds_write(lvds, LVDCR0, lvdcr0);
541
542
543 rcar_lvds_write(lvds, LVDCR1,
544 LVDCR1_CHSTBY(3) | LVDCR1_CHSTBY(2) |
545 LVDCR1_CHSTBY(1) | LVDCR1_CHSTBY(0) | LVDCR1_CLKSTBY);
546
547 if (lvds->info->gen < 3) {
548
549 lvdcr0 |= LVDCR0_BEN | LVDCR0_LVEN;
550 rcar_lvds_write(lvds, LVDCR0, lvdcr0);
551 }
552
553 if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
554
555
556
557
558 lvdcr0 |= LVDCR0_PLLON;
559 rcar_lvds_write(lvds, LVDCR0, lvdcr0);
560 }
561
562 if (lvds->info->quirks & RCAR_LVDS_QUIRK_PWD) {
563
564 lvdcr0 |= LVDCR0_PWD;
565 rcar_lvds_write(lvds, LVDCR0, lvdcr0);
566 }
567
568 if (lvds->info->quirks & RCAR_LVDS_QUIRK_GEN3_LVEN) {
569
570
571
572
573 lvdcr0 |= LVDCR0_LVEN;
574 if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_PWD))
575 rcar_lvds_write(lvds, LVDCR0, lvdcr0);
576 }
577
578 if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
579
580 usleep_range(100, 150);
581 }
582
583
584 lvdcr0 |= LVDCR0_LVRES;
585 rcar_lvds_write(lvds, LVDCR0, lvdcr0);
586
587 if (lvds->panel) {
588 drm_panel_prepare(lvds->panel);
589 drm_panel_enable(lvds->panel);
590 }
591}
592
593static void rcar_lvds_atomic_enable(struct drm_bridge *bridge,
594 struct drm_bridge_state *old_bridge_state)
595{
596 struct drm_atomic_state *state = old_bridge_state->base.state;
597 struct drm_connector *connector;
598 struct drm_crtc *crtc;
599
600 connector = drm_atomic_get_new_connector_for_encoder(state,
601 bridge->encoder);
602 crtc = drm_atomic_get_new_connector_state(state, connector)->crtc;
603
604 __rcar_lvds_atomic_enable(bridge, state, crtc, connector);
605}
606
607static void rcar_lvds_atomic_disable(struct drm_bridge *bridge,
608 struct drm_bridge_state *old_bridge_state)
609{
610 struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
611
612 if (lvds->panel) {
613 drm_panel_disable(lvds->panel);
614 drm_panel_unprepare(lvds->panel);
615 }
616
617 rcar_lvds_write(lvds, LVDCR0, 0);
618 rcar_lvds_write(lvds, LVDCR1, 0);
619 rcar_lvds_write(lvds, LVDPLLCR, 0);
620
621
622 if (lvds->link_type != RCAR_LVDS_SINGLE_LINK && lvds->companion)
623 lvds->companion->funcs->atomic_disable(lvds->companion,
624 old_bridge_state);
625
626 clk_disable_unprepare(lvds->clocks.mod);
627}
628
629static bool rcar_lvds_mode_fixup(struct drm_bridge *bridge,
630 const struct drm_display_mode *mode,
631 struct drm_display_mode *adjusted_mode)
632{
633 struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
634 int min_freq;
635
636
637
638
639
640
641 min_freq = lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL ? 5000 : 31000;
642 adjusted_mode->clock = clamp(adjusted_mode->clock, min_freq, 148500);
643
644 return true;
645}
646
647static int rcar_lvds_attach(struct drm_bridge *bridge,
648 enum drm_bridge_attach_flags flags)
649{
650 struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
651 struct drm_connector *connector = &lvds->connector;
652 struct drm_encoder *encoder = bridge->encoder;
653 int ret;
654
655
656 if (lvds->next_bridge)
657 return drm_bridge_attach(bridge->encoder, lvds->next_bridge,
658 bridge, flags);
659
660 if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
661 DRM_ERROR("Fix bridge driver to make connector optional!");
662 return -EINVAL;
663 }
664
665
666 if (!lvds->panel)
667 return 0;
668
669 ret = drm_connector_init(bridge->dev, connector, &rcar_lvds_conn_funcs,
670 DRM_MODE_CONNECTOR_LVDS);
671 if (ret < 0)
672 return ret;
673
674 drm_connector_helper_add(connector, &rcar_lvds_conn_helper_funcs);
675
676 ret = drm_connector_attach_encoder(connector, encoder);
677 if (ret < 0)
678 return ret;
679
680 return 0;
681}
682
683static void rcar_lvds_detach(struct drm_bridge *bridge)
684{
685}
686
687static const struct drm_bridge_funcs rcar_lvds_bridge_ops = {
688 .attach = rcar_lvds_attach,
689 .detach = rcar_lvds_detach,
690 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
691 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
692 .atomic_reset = drm_atomic_helper_bridge_reset,
693 .atomic_enable = rcar_lvds_atomic_enable,
694 .atomic_disable = rcar_lvds_atomic_disable,
695 .mode_fixup = rcar_lvds_mode_fixup,
696};
697
698bool rcar_lvds_dual_link(struct drm_bridge *bridge)
699{
700 struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
701
702 return lvds->link_type != RCAR_LVDS_SINGLE_LINK;
703}
704EXPORT_SYMBOL_GPL(rcar_lvds_dual_link);
705
706
707
708
709
710static int rcar_lvds_parse_dt_companion(struct rcar_lvds *lvds)
711{
712 const struct of_device_id *match;
713 struct device_node *companion;
714 struct device_node *port0, *port1;
715 struct rcar_lvds *companion_lvds;
716 struct device *dev = lvds->dev;
717 int dual_link;
718 int ret = 0;
719
720
721 companion = of_parse_phandle(dev->of_node, "renesas,companion", 0);
722 if (!companion)
723 return 0;
724
725
726
727
728
729 match = of_match_device(dev->driver->of_match_table, dev);
730 if (!of_device_is_compatible(companion, match->compatible)) {
731 dev_err(dev, "Companion LVDS encoder is invalid\n");
732 ret = -ENXIO;
733 goto done;
734 }
735
736
737
738
739
740
741
742 port0 = of_graph_get_port_by_id(dev->of_node, 1);
743 port1 = of_graph_get_port_by_id(companion, 1);
744 dual_link = drm_of_lvds_get_dual_link_pixel_order(port0, port1);
745 of_node_put(port0);
746 of_node_put(port1);
747
748 switch (dual_link) {
749 case DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS:
750 lvds->link_type = RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS;
751 break;
752 case DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS:
753 lvds->link_type = RCAR_LVDS_DUAL_LINK_EVEN_ODD_PIXELS;
754 break;
755 default:
756
757
758
759
760
761
762 if (lvds->next_bridge && lvds->next_bridge->timings &&
763 lvds->next_bridge->timings->dual_link)
764 lvds->link_type = RCAR_LVDS_DUAL_LINK_EVEN_ODD_PIXELS;
765 else
766 lvds->link_type = RCAR_LVDS_SINGLE_LINK;
767 }
768
769 if (lvds->link_type == RCAR_LVDS_SINGLE_LINK) {
770 dev_dbg(dev, "Single-link configuration detected\n");
771 goto done;
772 }
773
774 lvds->companion = of_drm_find_bridge(companion);
775 if (!lvds->companion) {
776 ret = -EPROBE_DEFER;
777 goto done;
778 }
779
780 dev_dbg(dev,
781 "Dual-link configuration detected (companion encoder %pOF)\n",
782 companion);
783
784 if (lvds->link_type == RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS)
785 dev_dbg(dev, "Data swapping required\n");
786
787
788
789
790
791
792
793
794
795
796 companion_lvds = bridge_to_rcar_lvds(lvds->companion);
797 companion_lvds->link_type = lvds->link_type;
798
799done:
800 of_node_put(companion);
801
802 return ret;
803}
804
805static int rcar_lvds_parse_dt(struct rcar_lvds *lvds)
806{
807 int ret;
808
809 ret = drm_of_find_panel_or_bridge(lvds->dev->of_node, 1, 0,
810 &lvds->panel, &lvds->next_bridge);
811 if (ret)
812 goto done;
813
814 if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK)
815 ret = rcar_lvds_parse_dt_companion(lvds);
816
817done:
818
819
820
821
822
823
824 if (lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)
825 return ret == -ENODEV ? 0 : ret;
826
827 return ret;
828}
829
830static struct clk *rcar_lvds_get_clock(struct rcar_lvds *lvds, const char *name,
831 bool optional)
832{
833 struct clk *clk;
834
835 clk = devm_clk_get(lvds->dev, name);
836 if (!IS_ERR(clk))
837 return clk;
838
839 if (PTR_ERR(clk) == -ENOENT && optional)
840 return NULL;
841
842 if (PTR_ERR(clk) != -EPROBE_DEFER)
843 dev_err(lvds->dev, "failed to get %s clock\n",
844 name ? name : "module");
845
846 return clk;
847}
848
849static int rcar_lvds_get_clocks(struct rcar_lvds *lvds)
850{
851 lvds->clocks.mod = rcar_lvds_get_clock(lvds, NULL, false);
852 if (IS_ERR(lvds->clocks.mod))
853 return PTR_ERR(lvds->clocks.mod);
854
855
856
857
858 if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL))
859 return 0;
860
861 lvds->clocks.extal = rcar_lvds_get_clock(lvds, "extal", true);
862 if (IS_ERR(lvds->clocks.extal))
863 return PTR_ERR(lvds->clocks.extal);
864
865 lvds->clocks.dotclkin[0] = rcar_lvds_get_clock(lvds, "dclkin.0", true);
866 if (IS_ERR(lvds->clocks.dotclkin[0]))
867 return PTR_ERR(lvds->clocks.dotclkin[0]);
868
869 lvds->clocks.dotclkin[1] = rcar_lvds_get_clock(lvds, "dclkin.1", true);
870 if (IS_ERR(lvds->clocks.dotclkin[1]))
871 return PTR_ERR(lvds->clocks.dotclkin[1]);
872
873
874 if (!lvds->clocks.extal && !lvds->clocks.dotclkin[0] &&
875 !lvds->clocks.dotclkin[1]) {
876 dev_err(lvds->dev,
877 "no input clock (extal, dclkin.0 or dclkin.1)\n");
878 return -EINVAL;
879 }
880
881 return 0;
882}
883
884static const struct rcar_lvds_device_info rcar_lvds_r8a7790es1_info = {
885 .gen = 2,
886 .quirks = RCAR_LVDS_QUIRK_LANES,
887 .pll_setup = rcar_lvds_pll_setup_gen2,
888};
889
890static const struct soc_device_attribute lvds_quirk_matches[] = {
891 {
892 .soc_id = "r8a7790", .revision = "ES1.*",
893 .data = &rcar_lvds_r8a7790es1_info,
894 },
895 { }
896};
897
898static int rcar_lvds_probe(struct platform_device *pdev)
899{
900 const struct soc_device_attribute *attr;
901 struct rcar_lvds *lvds;
902 struct resource *mem;
903 int ret;
904
905 lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL);
906 if (lvds == NULL)
907 return -ENOMEM;
908
909 platform_set_drvdata(pdev, lvds);
910
911 lvds->dev = &pdev->dev;
912 lvds->info = of_device_get_match_data(&pdev->dev);
913
914 attr = soc_device_match(lvds_quirk_matches);
915 if (attr)
916 lvds->info = attr->data;
917
918 ret = rcar_lvds_parse_dt(lvds);
919 if (ret < 0)
920 return ret;
921
922 lvds->bridge.driver_private = lvds;
923 lvds->bridge.funcs = &rcar_lvds_bridge_ops;
924 lvds->bridge.of_node = pdev->dev.of_node;
925
926 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
927 lvds->mmio = devm_ioremap_resource(&pdev->dev, mem);
928 if (IS_ERR(lvds->mmio))
929 return PTR_ERR(lvds->mmio);
930
931 ret = rcar_lvds_get_clocks(lvds);
932 if (ret < 0)
933 return ret;
934
935 drm_bridge_add(&lvds->bridge);
936
937 return 0;
938}
939
940static int rcar_lvds_remove(struct platform_device *pdev)
941{
942 struct rcar_lvds *lvds = platform_get_drvdata(pdev);
943
944 drm_bridge_remove(&lvds->bridge);
945
946 return 0;
947}
948
949static const struct rcar_lvds_device_info rcar_lvds_gen2_info = {
950 .gen = 2,
951 .pll_setup = rcar_lvds_pll_setup_gen2,
952};
953
954static const struct rcar_lvds_device_info rcar_lvds_gen3_info = {
955 .gen = 3,
956 .quirks = RCAR_LVDS_QUIRK_PWD,
957 .pll_setup = rcar_lvds_pll_setup_gen3,
958};
959
960static const struct rcar_lvds_device_info rcar_lvds_r8a77970_info = {
961 .gen = 3,
962 .quirks = RCAR_LVDS_QUIRK_PWD | RCAR_LVDS_QUIRK_GEN3_LVEN,
963 .pll_setup = rcar_lvds_pll_setup_gen2,
964};
965
966static const struct rcar_lvds_device_info rcar_lvds_r8a77990_info = {
967 .gen = 3,
968 .quirks = RCAR_LVDS_QUIRK_GEN3_LVEN | RCAR_LVDS_QUIRK_EXT_PLL
969 | RCAR_LVDS_QUIRK_DUAL_LINK,
970 .pll_setup = rcar_lvds_pll_setup_d3_e3,
971};
972
973static const struct rcar_lvds_device_info rcar_lvds_r8a77995_info = {
974 .gen = 3,
975 .quirks = RCAR_LVDS_QUIRK_GEN3_LVEN | RCAR_LVDS_QUIRK_PWD
976 | RCAR_LVDS_QUIRK_EXT_PLL | RCAR_LVDS_QUIRK_DUAL_LINK,
977 .pll_setup = rcar_lvds_pll_setup_d3_e3,
978};
979
980static const struct of_device_id rcar_lvds_of_table[] = {
981 { .compatible = "renesas,r8a7742-lvds", .data = &rcar_lvds_gen2_info },
982 { .compatible = "renesas,r8a7743-lvds", .data = &rcar_lvds_gen2_info },
983 { .compatible = "renesas,r8a7744-lvds", .data = &rcar_lvds_gen2_info },
984 { .compatible = "renesas,r8a774a1-lvds", .data = &rcar_lvds_gen3_info },
985 { .compatible = "renesas,r8a774b1-lvds", .data = &rcar_lvds_gen3_info },
986 { .compatible = "renesas,r8a774c0-lvds", .data = &rcar_lvds_r8a77990_info },
987 { .compatible = "renesas,r8a774e1-lvds", .data = &rcar_lvds_gen3_info },
988 { .compatible = "renesas,r8a7790-lvds", .data = &rcar_lvds_gen2_info },
989 { .compatible = "renesas,r8a7791-lvds", .data = &rcar_lvds_gen2_info },
990 { .compatible = "renesas,r8a7793-lvds", .data = &rcar_lvds_gen2_info },
991 { .compatible = "renesas,r8a7795-lvds", .data = &rcar_lvds_gen3_info },
992 { .compatible = "renesas,r8a7796-lvds", .data = &rcar_lvds_gen3_info },
993 { .compatible = "renesas,r8a77965-lvds", .data = &rcar_lvds_gen3_info },
994 { .compatible = "renesas,r8a77970-lvds", .data = &rcar_lvds_r8a77970_info },
995 { .compatible = "renesas,r8a77980-lvds", .data = &rcar_lvds_gen3_info },
996 { .compatible = "renesas,r8a77990-lvds", .data = &rcar_lvds_r8a77990_info },
997 { .compatible = "renesas,r8a77995-lvds", .data = &rcar_lvds_r8a77995_info },
998 { }
999};
1000
1001MODULE_DEVICE_TABLE(of, rcar_lvds_of_table);
1002
1003static struct platform_driver rcar_lvds_platform_driver = {
1004 .probe = rcar_lvds_probe,
1005 .remove = rcar_lvds_remove,
1006 .driver = {
1007 .name = "rcar-lvds",
1008 .of_match_table = rcar_lvds_of_table,
1009 },
1010};
1011
1012module_platform_driver(rcar_lvds_platform_driver);
1013
1014MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
1015MODULE_DESCRIPTION("Renesas R-Car LVDS Encoder Driver");
1016MODULE_LICENSE("GPL");
1017