1
2
3
4
5
6
7
8
9
10
11#include <linux/clk.h>
12#include <linux/component.h>
13#include <linux/delay.h>
14#include <linux/interrupt.h>
15#include <linux/module.h>
16#include <linux/of_address.h>
17#include <linux/of_graph.h>
18#include <linux/pinctrl/consumer.h>
19#include <linux/platform_device.h>
20#include <linux/pm_runtime.h>
21#include <linux/regmap.h>
22#include <linux/reset.h>
23
24#include <drm/drm_atomic.h>
25#include <drm/drm_atomic_helper.h>
26#include <drm/drm_bridge.h>
27#include <drm/drm_device.h>
28#include <drm/drm_fb_cma_helper.h>
29#include <drm/drm_fourcc.h>
30#include <drm/drm_gem_atomic_helper.h>
31#include <drm/drm_gem_cma_helper.h>
32#include <drm/drm_of.h>
33#include <drm/drm_plane_helper.h>
34#include <drm/drm_probe_helper.h>
35#include <drm/drm_simple_kms_helper.h>
36#include <drm/drm_vblank.h>
37
38#include <video/videomode.h>
39
40#include "ltdc.h"
41
42#define NB_CRTC 1
43#define CRTC_MASK GENMASK(NB_CRTC - 1, 0)
44
45#define MAX_IRQ 4
46
47#define HWVER_10200 0x010200
48#define HWVER_10300 0x010300
49#define HWVER_20101 0x020101
50#define HWVER_40100 0x040100
51
52
53
54
55
56#define LAY_OFS_0 0x80
57#define LAY_OFS_1 0x100
58#define LAY_OFS (ldev->caps.layer_ofs)
59
60
61#define LTDC_IDR 0x0000
62#define LTDC_LCR 0x0004
63#define LTDC_SSCR 0x0008
64#define LTDC_BPCR 0x000C
65#define LTDC_AWCR 0x0010
66#define LTDC_TWCR 0x0014
67#define LTDC_GCR 0x0018
68#define LTDC_GC1R 0x001C
69#define LTDC_GC2R 0x0020
70#define LTDC_SRCR 0x0024
71#define LTDC_GACR 0x0028
72#define LTDC_BCCR 0x002C
73#define LTDC_IER 0x0034
74#define LTDC_ISR 0x0038
75#define LTDC_ICR 0x003C
76#define LTDC_LIPCR 0x0040
77#define LTDC_CPSR 0x0044
78#define LTDC_CDSR 0x0048
79#define LTDC_EDCR 0x0060
80#define LTDC_CCRCR 0x007C
81#define LTDC_FUT 0x0090
82
83
84#define LTDC_L1C0R (ldev->caps.layer_regs[0])
85#define LTDC_L1C1R (ldev->caps.layer_regs[1])
86#define LTDC_L1RCR (ldev->caps.layer_regs[2])
87#define LTDC_L1CR (ldev->caps.layer_regs[3])
88#define LTDC_L1WHPCR (ldev->caps.layer_regs[4])
89#define LTDC_L1WVPCR (ldev->caps.layer_regs[5])
90#define LTDC_L1CKCR (ldev->caps.layer_regs[6])
91#define LTDC_L1PFCR (ldev->caps.layer_regs[7])
92#define LTDC_L1CACR (ldev->caps.layer_regs[8])
93#define LTDC_L1DCCR (ldev->caps.layer_regs[9])
94#define LTDC_L1BFCR (ldev->caps.layer_regs[10])
95#define LTDC_L1BLCR (ldev->caps.layer_regs[11])
96#define LTDC_L1PCR (ldev->caps.layer_regs[12])
97#define LTDC_L1CFBAR (ldev->caps.layer_regs[13])
98#define LTDC_L1CFBLR (ldev->caps.layer_regs[14])
99#define LTDC_L1CFBLNR (ldev->caps.layer_regs[15])
100#define LTDC_L1AFBA0R (ldev->caps.layer_regs[16])
101#define LTDC_L1AFBA1R (ldev->caps.layer_regs[17])
102#define LTDC_L1AFBLR (ldev->caps.layer_regs[18])
103#define LTDC_L1AFBLNR (ldev->caps.layer_regs[19])
104#define LTDC_L1CLUTWR (ldev->caps.layer_regs[20])
105#define LTDC_L1CYR0R (ldev->caps.layer_regs[21])
106#define LTDC_L1CYR1R (ldev->caps.layer_regs[22])
107#define LTDC_L1FPF0R (ldev->caps.layer_regs[23])
108#define LTDC_L1FPF1R (ldev->caps.layer_regs[24])
109
110
111#define SSCR_VSH GENMASK(10, 0)
112#define SSCR_HSW GENMASK(27, 16)
113
114#define BPCR_AVBP GENMASK(10, 0)
115#define BPCR_AHBP GENMASK(27, 16)
116
117#define AWCR_AAH GENMASK(10, 0)
118#define AWCR_AAW GENMASK(27, 16)
119
120#define TWCR_TOTALH GENMASK(10, 0)
121#define TWCR_TOTALW GENMASK(27, 16)
122
123#define GCR_LTDCEN BIT(0)
124#define GCR_DEN BIT(16)
125#define GCR_CRCEN BIT(19)
126#define GCR_PCPOL BIT(28)
127#define GCR_DEPOL BIT(29)
128#define GCR_VSPOL BIT(30)
129#define GCR_HSPOL BIT(31)
130
131#define GC1R_WBCH GENMASK(3, 0)
132#define GC1R_WGCH GENMASK(7, 4)
133#define GC1R_WRCH GENMASK(11, 8)
134#define GC1R_PBEN BIT(12)
135#define GC1R_DT GENMASK(15, 14)
136#define GC1R_GCT GENMASK(19, 17)
137#define GC1R_SHREN BIT(21)
138#define GC1R_BCP BIT(22)
139#define GC1R_BBEN BIT(23)
140#define GC1R_LNIP BIT(24)
141#define GC1R_TP BIT(25)
142#define GC1R_IPP BIT(26)
143#define GC1R_SPP BIT(27)
144#define GC1R_DWP BIT(28)
145#define GC1R_STREN BIT(29)
146#define GC1R_BMEN BIT(31)
147
148#define GC2R_EDCA BIT(0)
149#define GC2R_STSAEN BIT(1)
150#define GC2R_DVAEN BIT(2)
151#define GC2R_DPAEN BIT(3)
152#define GC2R_BW GENMASK(6, 4)
153#define GC2R_EDCEN BIT(7)
154
155#define SRCR_IMR BIT(0)
156#define SRCR_VBR BIT(1)
157
158#define BCCR_BCBLACK 0x00
159#define BCCR_BCBLUE GENMASK(7, 0)
160#define BCCR_BCGREEN GENMASK(15, 8)
161#define BCCR_BCRED GENMASK(23, 16)
162#define BCCR_BCWHITE GENMASK(23, 0)
163
164#define IER_LIE BIT(0)
165#define IER_FUIE BIT(1)
166#define IER_TERRIE BIT(2)
167#define IER_RRIE BIT(3)
168
169#define CPSR_CYPOS GENMASK(15, 0)
170
171#define ISR_LIF BIT(0)
172#define ISR_FUIF BIT(1)
173#define ISR_TERRIF BIT(2)
174#define ISR_RRIF BIT(3)
175
176#define EDCR_OCYEN BIT(25)
177#define EDCR_OCYSEL BIT(26)
178#define EDCR_OCYCO BIT(27)
179
180#define LXCR_LEN BIT(0)
181#define LXCR_COLKEN BIT(1)
182#define LXCR_CLUTEN BIT(4)
183
184#define LXWHPCR_WHSTPOS GENMASK(11, 0)
185#define LXWHPCR_WHSPPOS GENMASK(27, 16)
186
187#define LXWVPCR_WVSTPOS GENMASK(10, 0)
188#define LXWVPCR_WVSPPOS GENMASK(26, 16)
189
190#define LXPFCR_PF GENMASK(2, 0)
191#define PF_FLEXIBLE 0x7
192
193#define LXCACR_CONSTA GENMASK(7, 0)
194
195#define LXBFCR_BF2 GENMASK(2, 0)
196#define LXBFCR_BF1 GENMASK(10, 8)
197
198#define LXCFBLR_CFBLL GENMASK(12, 0)
199#define LXCFBLR_CFBP GENMASK(28, 16)
200
201#define LXCFBLNR_CFBLN GENMASK(10, 0)
202
203#define LXCR_C1R_YIA BIT(0)
204#define LXCR_C1R_YSPA BIT(1)
205#define LXCR_C1R_YFPA BIT(2)
206#define LXCR_C1R_SCA BIT(31)
207
208#define LxPCR_YREN BIT(9)
209#define LxPCR_OF BIT(8)
210#define LxPCR_CBF BIT(7)
211#define LxPCR_YF BIT(6)
212#define LxPCR_YCM GENMASK(5, 4)
213#define YCM_I 0x0
214#define YCM_SP 0x1
215#define YCM_FP 0x2
216#define LxPCR_YCEN BIT(3)
217
218#define LXRCR_IMR BIT(0)
219#define LXRCR_VBR BIT(1)
220#define LXRCR_GRMSK BIT(2)
221
222#define CLUT_SIZE 256
223
224#define CONSTA_MAX 0xFF
225#define BF1_PAXCA 0x600
226#define BF1_CA 0x400
227#define BF2_1PAXCA 0x007
228#define BF2_1CA 0x005
229
230#define NB_PF 8
231
232
233
234
235
236
237#define CRC_SKIP_FRAMES 2
238
239enum ltdc_pix_fmt {
240 PF_NONE,
241
242 PF_ARGB8888,
243 PF_RGBA8888,
244 PF_ABGR8888,
245 PF_BGRA8888,
246 PF_RGB888,
247 PF_BGR888,
248 PF_RGB565,
249 PF_BGR565,
250 PF_ARGB1555,
251 PF_ARGB4444,
252
253 PF_L8,
254 PF_AL44,
255 PF_AL88
256};
257
258
259static const enum ltdc_pix_fmt ltdc_pix_fmt_a0[NB_PF] = {
260 PF_ARGB8888,
261 PF_RGB888,
262 PF_RGB565,
263 PF_ARGB1555,
264 PF_ARGB4444,
265 PF_L8,
266 PF_AL44,
267 PF_AL88
268};
269
270static const enum ltdc_pix_fmt ltdc_pix_fmt_a1[NB_PF] = {
271 PF_ARGB8888,
272 PF_RGB888,
273 PF_RGB565,
274 PF_RGBA8888,
275 PF_AL44,
276 PF_L8,
277 PF_ARGB1555,
278 PF_ARGB4444
279};
280
281static const enum ltdc_pix_fmt ltdc_pix_fmt_a2[NB_PF] = {
282 PF_ARGB8888,
283 PF_ABGR8888,
284 PF_RGBA8888,
285 PF_BGRA8888,
286 PF_RGB565,
287 PF_BGR565,
288 PF_RGB888,
289 PF_NONE
290};
291
292static const u32 ltdc_drm_fmt_a0[] = {
293 DRM_FORMAT_ARGB8888,
294 DRM_FORMAT_XRGB8888,
295 DRM_FORMAT_RGB888,
296 DRM_FORMAT_RGB565,
297 DRM_FORMAT_ARGB1555,
298 DRM_FORMAT_XRGB1555,
299 DRM_FORMAT_ARGB4444,
300 DRM_FORMAT_XRGB4444,
301 DRM_FORMAT_C8
302};
303
304static const u32 ltdc_drm_fmt_a1[] = {
305 DRM_FORMAT_ARGB8888,
306 DRM_FORMAT_XRGB8888,
307 DRM_FORMAT_RGB888,
308 DRM_FORMAT_RGB565,
309 DRM_FORMAT_RGBA8888,
310 DRM_FORMAT_RGBX8888,
311 DRM_FORMAT_ARGB1555,
312 DRM_FORMAT_XRGB1555,
313 DRM_FORMAT_ARGB4444,
314 DRM_FORMAT_XRGB4444,
315 DRM_FORMAT_C8
316};
317
318static const u32 ltdc_drm_fmt_a2[] = {
319 DRM_FORMAT_ARGB8888,
320 DRM_FORMAT_XRGB8888,
321 DRM_FORMAT_ABGR8888,
322 DRM_FORMAT_XBGR8888,
323 DRM_FORMAT_RGBA8888,
324 DRM_FORMAT_RGBX8888,
325 DRM_FORMAT_BGRA8888,
326 DRM_FORMAT_BGRX8888,
327 DRM_FORMAT_RGB565,
328 DRM_FORMAT_BGR565,
329 DRM_FORMAT_RGB888,
330 DRM_FORMAT_BGR888,
331 DRM_FORMAT_ARGB1555,
332 DRM_FORMAT_XRGB1555,
333 DRM_FORMAT_ARGB4444,
334 DRM_FORMAT_XRGB4444,
335 DRM_FORMAT_C8
336};
337
338static const u32 ltdc_drm_fmt_ycbcr_cp[] = {
339 DRM_FORMAT_YUYV,
340 DRM_FORMAT_YVYU,
341 DRM_FORMAT_UYVY,
342 DRM_FORMAT_VYUY
343};
344
345static const u32 ltdc_drm_fmt_ycbcr_sp[] = {
346 DRM_FORMAT_NV12,
347 DRM_FORMAT_NV21
348};
349
350static const u32 ltdc_drm_fmt_ycbcr_fp[] = {
351 DRM_FORMAT_YUV420,
352 DRM_FORMAT_YVU420
353};
354
355
356static const u32 ltdc_layer_regs_a0[] = {
357 0x80,
358 0x00,
359 0x00,
360 0x84,
361 0x88,
362 0x8c,
363 0x90,
364 0x94,
365 0x98,
366 0x9c,
367 0xa0,
368 0x00,
369 0x00,
370 0xac,
371 0xb0,
372 0xb4,
373 0x00,
374 0x00,
375 0x00,
376 0x00,
377 0xc4,
378 0x00,
379 0x00,
380 0x00,
381 0x00
382};
383
384static const u32 ltdc_layer_regs_a1[] = {
385 0x80,
386 0x84,
387 0x00,
388 0x88,
389 0x8c,
390 0x90,
391 0x94,
392 0x98,
393 0x9c,
394 0xa0,
395 0xa4,
396 0xa8,
397 0x00,
398 0xac,
399 0xb0,
400 0xb4,
401 0xb8,
402 0xbc,
403 0xc0,
404 0xc4,
405 0xc8,
406 0x00,
407 0x00,
408 0x00,
409 0x00
410};
411
412static const u32 ltdc_layer_regs_a2[] = {
413 0x100,
414 0x104,
415 0x108,
416 0x10c,
417 0x110,
418 0x114,
419 0x118,
420 0x11c,
421 0x120,
422 0x124,
423 0x128,
424 0x12c,
425 0x130,
426 0x134,
427 0x138,
428 0x13c,
429 0x140,
430 0x144,
431 0x148,
432 0x14c,
433 0x150,
434 0x16c,
435 0x170,
436 0x174,
437 0x178
438};
439
440static const u64 ltdc_format_modifiers[] = {
441 DRM_FORMAT_MOD_LINEAR,
442 DRM_FORMAT_MOD_INVALID
443};
444
445static const struct regmap_config stm32_ltdc_regmap_cfg = {
446 .reg_bits = 32,
447 .val_bits = 32,
448 .reg_stride = sizeof(u32),
449 .max_register = 0x400,
450 .use_relaxed_mmio = true,
451 .cache_type = REGCACHE_NONE,
452};
453
454static const u32 ltdc_ycbcr2rgb_coeffs[DRM_COLOR_ENCODING_MAX][DRM_COLOR_RANGE_MAX][2] = {
455 [DRM_COLOR_YCBCR_BT601][DRM_COLOR_YCBCR_LIMITED_RANGE] = {
456 0x02040199,
457 0x006400D0
458 },
459 [DRM_COLOR_YCBCR_BT601][DRM_COLOR_YCBCR_FULL_RANGE] = {
460 0x01C60167,
461 0x005800B7
462 },
463 [DRM_COLOR_YCBCR_BT709][DRM_COLOR_YCBCR_LIMITED_RANGE] = {
464 0x021D01CB,
465 0x00370089
466 },
467 [DRM_COLOR_YCBCR_BT709][DRM_COLOR_YCBCR_FULL_RANGE] = {
468 0x01DB0193,
469 0x00300078
470 }
471
472};
473
474static inline struct ltdc_device *crtc_to_ltdc(struct drm_crtc *crtc)
475{
476 return (struct ltdc_device *)crtc->dev->dev_private;
477}
478
479static inline struct ltdc_device *plane_to_ltdc(struct drm_plane *plane)
480{
481 return (struct ltdc_device *)plane->dev->dev_private;
482}
483
484static inline struct ltdc_device *encoder_to_ltdc(struct drm_encoder *enc)
485{
486 return (struct ltdc_device *)enc->dev->dev_private;
487}
488
489static inline enum ltdc_pix_fmt to_ltdc_pixelformat(u32 drm_fmt)
490{
491 enum ltdc_pix_fmt pf;
492
493 switch (drm_fmt) {
494 case DRM_FORMAT_ARGB8888:
495 case DRM_FORMAT_XRGB8888:
496 pf = PF_ARGB8888;
497 break;
498 case DRM_FORMAT_ABGR8888:
499 case DRM_FORMAT_XBGR8888:
500 pf = PF_ABGR8888;
501 break;
502 case DRM_FORMAT_RGBA8888:
503 case DRM_FORMAT_RGBX8888:
504 pf = PF_RGBA8888;
505 break;
506 case DRM_FORMAT_BGRA8888:
507 case DRM_FORMAT_BGRX8888:
508 pf = PF_BGRA8888;
509 break;
510 case DRM_FORMAT_RGB888:
511 pf = PF_RGB888;
512 break;
513 case DRM_FORMAT_BGR888:
514 pf = PF_BGR888;
515 break;
516 case DRM_FORMAT_RGB565:
517 pf = PF_RGB565;
518 break;
519 case DRM_FORMAT_BGR565:
520 pf = PF_BGR565;
521 break;
522 case DRM_FORMAT_ARGB1555:
523 case DRM_FORMAT_XRGB1555:
524 pf = PF_ARGB1555;
525 break;
526 case DRM_FORMAT_ARGB4444:
527 case DRM_FORMAT_XRGB4444:
528 pf = PF_ARGB4444;
529 break;
530 case DRM_FORMAT_C8:
531 pf = PF_L8;
532 break;
533 default:
534 pf = PF_NONE;
535 break;
536
537 }
538
539 return pf;
540}
541
542static inline u32 ltdc_set_flexible_pixel_format(struct drm_plane *plane, enum ltdc_pix_fmt pix_fmt)
543{
544 struct ltdc_device *ldev = plane_to_ltdc(plane);
545 u32 lofs = plane->index * LAY_OFS, ret = PF_FLEXIBLE;
546 int psize, alen, apos, rlen, rpos, glen, gpos, blen, bpos;
547
548 switch (pix_fmt) {
549 case PF_BGR888:
550 psize = 3;
551 alen = 0; apos = 0; rlen = 8; rpos = 0;
552 glen = 8; gpos = 8; blen = 8; bpos = 16;
553 break;
554 case PF_ARGB1555:
555 psize = 2;
556 alen = 1; apos = 15; rlen = 5; rpos = 10;
557 glen = 5; gpos = 5; blen = 5; bpos = 0;
558 break;
559 case PF_ARGB4444:
560 psize = 2;
561 alen = 4; apos = 12; rlen = 4; rpos = 8;
562 glen = 4; gpos = 4; blen = 4; bpos = 0;
563 break;
564 case PF_L8:
565 psize = 1;
566 alen = 0; apos = 0; rlen = 8; rpos = 0;
567 glen = 8; gpos = 0; blen = 8; bpos = 0;
568 break;
569 case PF_AL44:
570 psize = 1;
571 alen = 4; apos = 4; rlen = 4; rpos = 0;
572 glen = 4; gpos = 0; blen = 4; bpos = 0;
573 break;
574 case PF_AL88:
575 psize = 2;
576 alen = 8; apos = 8; rlen = 8; rpos = 0;
577 glen = 8; gpos = 0; blen = 8; bpos = 0;
578 break;
579 default:
580 ret = NB_PF;
581 break;
582 }
583
584 if (ret == PF_FLEXIBLE) {
585 regmap_write(ldev->regmap, LTDC_L1FPF0R + lofs,
586 (rlen << 14) + (rpos << 9) + (alen << 5) + apos);
587
588 regmap_write(ldev->regmap, LTDC_L1FPF1R + lofs,
589 (psize << 18) + (blen << 14) + (bpos << 9) + (glen << 5) + gpos);
590 }
591
592 return ret;
593}
594
595
596
597
598
599static inline u32 is_xrgb(u32 drm)
600{
601 return ((drm & 0xFF) == 'X' || ((drm >> 8) & 0xFF) == 'X');
602}
603
604static inline void ltdc_set_ycbcr_config(struct drm_plane *plane, u32 drm_pix_fmt)
605{
606 struct ltdc_device *ldev = plane_to_ltdc(plane);
607 struct drm_plane_state *state = plane->state;
608 u32 lofs = plane->index * LAY_OFS;
609 u32 val;
610
611 switch (drm_pix_fmt) {
612 case DRM_FORMAT_YUYV:
613 val = (YCM_I << 4) | LxPCR_YF | LxPCR_CBF;
614 break;
615 case DRM_FORMAT_YVYU:
616 val = (YCM_I << 4) | LxPCR_YF;
617 break;
618 case DRM_FORMAT_UYVY:
619 val = (YCM_I << 4) | LxPCR_CBF;
620 break;
621 case DRM_FORMAT_VYUY:
622 val = (YCM_I << 4);
623 break;
624 case DRM_FORMAT_NV12:
625 val = (YCM_SP << 4) | LxPCR_CBF;
626 break;
627 case DRM_FORMAT_NV21:
628 val = (YCM_SP << 4);
629 break;
630 case DRM_FORMAT_YUV420:
631 case DRM_FORMAT_YVU420:
632 val = (YCM_FP << 4);
633 break;
634 default:
635
636 DRM_ERROR("Unsupported pixel format: %u\n", drm_pix_fmt);
637 return;
638 }
639
640
641 if (state->color_range == DRM_COLOR_YCBCR_LIMITED_RANGE)
642 val |= LxPCR_YREN;
643
644
645 val |= LxPCR_YCEN;
646
647 regmap_write(ldev->regmap, LTDC_L1PCR + lofs, val);
648}
649
650static inline void ltdc_set_ycbcr_coeffs(struct drm_plane *plane)
651{
652 struct ltdc_device *ldev = plane_to_ltdc(plane);
653 struct drm_plane_state *state = plane->state;
654 enum drm_color_encoding enc = state->color_encoding;
655 enum drm_color_range ran = state->color_range;
656 u32 lofs = plane->index * LAY_OFS;
657
658 if (enc != DRM_COLOR_YCBCR_BT601 && enc != DRM_COLOR_YCBCR_BT709) {
659 DRM_ERROR("color encoding %d not supported, use bt601 by default\n", enc);
660
661 enc = DRM_COLOR_YCBCR_BT601;
662 }
663
664 if (ran != DRM_COLOR_YCBCR_LIMITED_RANGE && ran != DRM_COLOR_YCBCR_FULL_RANGE) {
665 DRM_ERROR("color range %d not supported, use limited range by default\n", ran);
666
667 ran = DRM_COLOR_YCBCR_LIMITED_RANGE;
668 }
669
670 DRM_DEBUG_DRIVER("Color encoding=%d, range=%d\n", enc, ran);
671 regmap_write(ldev->regmap, LTDC_L1CYR0R + lofs,
672 ltdc_ycbcr2rgb_coeffs[enc][ran][0]);
673 regmap_write(ldev->regmap, LTDC_L1CYR1R + lofs,
674 ltdc_ycbcr2rgb_coeffs[enc][ran][1]);
675}
676
677static inline void ltdc_irq_crc_handle(struct ltdc_device *ldev,
678 struct drm_crtc *crtc)
679{
680 u32 crc;
681 int ret;
682
683 if (ldev->crc_skip_count < CRC_SKIP_FRAMES) {
684 ldev->crc_skip_count++;
685 return;
686 }
687
688
689 ret = regmap_read(ldev->regmap, LTDC_CCRCR, &crc);
690 if (ret)
691 return;
692
693
694 drm_crtc_add_crc_entry(crtc, true, drm_crtc_accurate_vblank_count(crtc), &crc);
695}
696
697static irqreturn_t ltdc_irq_thread(int irq, void *arg)
698{
699 struct drm_device *ddev = arg;
700 struct ltdc_device *ldev = ddev->dev_private;
701 struct drm_crtc *crtc = drm_crtc_from_index(ddev, 0);
702
703
704 if (ldev->irq_status & ISR_LIF) {
705 drm_crtc_handle_vblank(crtc);
706
707
708 if (ldev->crc_active)
709 ltdc_irq_crc_handle(ldev, crtc);
710 }
711
712
713 mutex_lock(&ldev->err_lock);
714 if (ldev->irq_status & ISR_FUIF)
715 ldev->error_status |= ISR_FUIF;
716 if (ldev->irq_status & ISR_TERRIF)
717 ldev->error_status |= ISR_TERRIF;
718 mutex_unlock(&ldev->err_lock);
719
720 return IRQ_HANDLED;
721}
722
723static irqreturn_t ltdc_irq(int irq, void *arg)
724{
725 struct drm_device *ddev = arg;
726 struct ltdc_device *ldev = ddev->dev_private;
727
728
729
730
731
732
733 ldev->irq_status = readl_relaxed(ldev->regs + LTDC_ISR);
734 writel_relaxed(ldev->irq_status, ldev->regs + LTDC_ICR);
735
736 return IRQ_WAKE_THREAD;
737}
738
739
740
741
742
743static void ltdc_crtc_update_clut(struct drm_crtc *crtc)
744{
745 struct ltdc_device *ldev = crtc_to_ltdc(crtc);
746 struct drm_color_lut *lut;
747 u32 val;
748 int i;
749
750 if (!crtc->state->color_mgmt_changed || !crtc->state->gamma_lut)
751 return;
752
753 lut = (struct drm_color_lut *)crtc->state->gamma_lut->data;
754
755 for (i = 0; i < CLUT_SIZE; i++, lut++) {
756 val = ((lut->red << 8) & 0xff0000) | (lut->green & 0xff00) |
757 (lut->blue >> 8) | (i << 24);
758 regmap_write(ldev->regmap, LTDC_L1CLUTWR, val);
759 }
760}
761
762static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc,
763 struct drm_atomic_state *state)
764{
765 struct ltdc_device *ldev = crtc_to_ltdc(crtc);
766 struct drm_device *ddev = crtc->dev;
767
768 DRM_DEBUG_DRIVER("\n");
769
770 pm_runtime_get_sync(ddev->dev);
771
772
773 regmap_write(ldev->regmap, LTDC_BCCR, BCCR_BCBLACK);
774
775
776 regmap_set_bits(ldev->regmap, LTDC_IER, IER_RRIE | IER_FUIE | IER_TERRIE);
777
778
779 if (!ldev->caps.plane_reg_shadow)
780 regmap_set_bits(ldev->regmap, LTDC_SRCR, SRCR_VBR);
781
782 drm_crtc_vblank_on(crtc);
783}
784
785static void ltdc_crtc_atomic_disable(struct drm_crtc *crtc,
786 struct drm_atomic_state *state)
787{
788 struct ltdc_device *ldev = crtc_to_ltdc(crtc);
789 struct drm_device *ddev = crtc->dev;
790
791 DRM_DEBUG_DRIVER("\n");
792
793 drm_crtc_vblank_off(crtc);
794
795
796 regmap_clear_bits(ldev->regmap, LTDC_IER, IER_RRIE | IER_FUIE | IER_TERRIE);
797
798
799 if (!ldev->caps.plane_reg_shadow)
800 regmap_set_bits(ldev->regmap, LTDC_SRCR, SRCR_IMR);
801
802 pm_runtime_put_sync(ddev->dev);
803}
804
805#define CLK_TOLERANCE_HZ 50
806
807static enum drm_mode_status
808ltdc_crtc_mode_valid(struct drm_crtc *crtc,
809 const struct drm_display_mode *mode)
810{
811 struct ltdc_device *ldev = crtc_to_ltdc(crtc);
812 int target = mode->clock * 1000;
813 int target_min = target - CLK_TOLERANCE_HZ;
814 int target_max = target + CLK_TOLERANCE_HZ;
815 int result;
816
817 result = clk_round_rate(ldev->pixel_clk, target);
818
819 DRM_DEBUG_DRIVER("clk rate target %d, available %d\n", target, result);
820
821
822 if (result > ldev->caps.pad_max_freq_hz)
823 return MODE_CLOCK_HIGH;
824
825
826
827
828
829
830
831
832
833 if (mode->type & DRM_MODE_TYPE_PREFERRED)
834 return MODE_OK;
835
836
837
838
839
840 if (result < target_min || result > target_max)
841 return MODE_CLOCK_RANGE;
842
843 return MODE_OK;
844}
845
846static bool ltdc_crtc_mode_fixup(struct drm_crtc *crtc,
847 const struct drm_display_mode *mode,
848 struct drm_display_mode *adjusted_mode)
849{
850 struct ltdc_device *ldev = crtc_to_ltdc(crtc);
851 int rate = mode->clock * 1000;
852
853 if (clk_set_rate(ldev->pixel_clk, rate) < 0) {
854 DRM_ERROR("Cannot set rate (%dHz) for pixel clk\n", rate);
855 return false;
856 }
857
858 adjusted_mode->clock = clk_get_rate(ldev->pixel_clk) / 1000;
859
860 DRM_DEBUG_DRIVER("requested clock %dkHz, adjusted clock %dkHz\n",
861 mode->clock, adjusted_mode->clock);
862
863 return true;
864}
865
866static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
867{
868 struct ltdc_device *ldev = crtc_to_ltdc(crtc);
869 struct drm_device *ddev = crtc->dev;
870 struct drm_connector_list_iter iter;
871 struct drm_connector *connector = NULL;
872 struct drm_encoder *encoder = NULL;
873 struct drm_bridge *bridge = NULL;
874 struct drm_display_mode *mode = &crtc->state->adjusted_mode;
875 u32 hsync, vsync, accum_hbp, accum_vbp, accum_act_w, accum_act_h;
876 u32 total_width, total_height;
877 u32 bus_formats = MEDIA_BUS_FMT_RGB888_1X24;
878 u32 bus_flags = 0;
879 u32 val;
880 int ret;
881
882
883 drm_for_each_encoder(encoder, ddev)
884 if (encoder->crtc == crtc)
885 break;
886
887 if (encoder) {
888
889 list_for_each_entry(bridge, &encoder->bridge_chain, chain_node)
890 if (bridge->encoder == encoder)
891 break;
892
893
894 drm_connector_list_iter_begin(ddev, &iter);
895 drm_for_each_connector_iter(connector, &iter)
896 if (connector->encoder == encoder)
897 break;
898 drm_connector_list_iter_end(&iter);
899 }
900
901 if (bridge && bridge->timings)
902 bus_flags = bridge->timings->input_bus_flags;
903 else if (connector) {
904 bus_flags = connector->display_info.bus_flags;
905 if (connector->display_info.num_bus_formats)
906 bus_formats = connector->display_info.bus_formats[0];
907 }
908
909 if (!pm_runtime_active(ddev->dev)) {
910 ret = pm_runtime_get_sync(ddev->dev);
911 if (ret) {
912 DRM_ERROR("Failed to set mode, cannot get sync\n");
913 return;
914 }
915 }
916
917 DRM_DEBUG_DRIVER("CRTC:%d mode:%s\n", crtc->base.id, mode->name);
918 DRM_DEBUG_DRIVER("Video mode: %dx%d", mode->hdisplay, mode->vdisplay);
919 DRM_DEBUG_DRIVER(" hfp %d hbp %d hsl %d vfp %d vbp %d vsl %d\n",
920 mode->hsync_start - mode->hdisplay,
921 mode->htotal - mode->hsync_end,
922 mode->hsync_end - mode->hsync_start,
923 mode->vsync_start - mode->vdisplay,
924 mode->vtotal - mode->vsync_end,
925 mode->vsync_end - mode->vsync_start);
926
927
928 hsync = mode->hsync_end - mode->hsync_start - 1;
929 vsync = mode->vsync_end - mode->vsync_start - 1;
930 accum_hbp = mode->htotal - mode->hsync_start - 1;
931 accum_vbp = mode->vtotal - mode->vsync_start - 1;
932 accum_act_w = accum_hbp + mode->hdisplay;
933 accum_act_h = accum_vbp + mode->vdisplay;
934 total_width = mode->htotal - 1;
935 total_height = mode->vtotal - 1;
936
937
938 val = 0;
939
940 if (mode->flags & DRM_MODE_FLAG_PHSYNC)
941 val |= GCR_HSPOL;
942
943 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
944 val |= GCR_VSPOL;
945
946 if (bus_flags & DRM_BUS_FLAG_DE_LOW)
947 val |= GCR_DEPOL;
948
949 if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
950 val |= GCR_PCPOL;
951
952 regmap_update_bits(ldev->regmap, LTDC_GCR,
953 GCR_HSPOL | GCR_VSPOL | GCR_DEPOL | GCR_PCPOL, val);
954
955
956 val = (hsync << 16) | vsync;
957 regmap_update_bits(ldev->regmap, LTDC_SSCR, SSCR_VSH | SSCR_HSW, val);
958
959
960 val = (accum_hbp << 16) | accum_vbp;
961 regmap_update_bits(ldev->regmap, LTDC_BPCR, BPCR_AVBP | BPCR_AHBP, val);
962
963
964 val = (accum_act_w << 16) | accum_act_h;
965 regmap_update_bits(ldev->regmap, LTDC_AWCR, AWCR_AAW | AWCR_AAH, val);
966
967
968 val = (total_width << 16) | total_height;
969 regmap_update_bits(ldev->regmap, LTDC_TWCR, TWCR_TOTALH | TWCR_TOTALW, val);
970
971 regmap_write(ldev->regmap, LTDC_LIPCR, (accum_act_h + 1));
972
973
974 if (ldev->caps.ycbcr_output) {
975
976 int vic = drm_match_cea_mode(mode);
977 u32 val;
978
979 if (vic == 6 || vic == 7 || vic == 21 || vic == 22 ||
980 vic == 2 || vic == 3 || vic == 17 || vic == 18)
981
982 val = 0;
983 else
984
985 val = EDCR_OCYSEL;
986
987 switch (bus_formats) {
988 case MEDIA_BUS_FMT_YUYV8_1X16:
989
990 regmap_write(ldev->regmap, LTDC_EDCR, EDCR_OCYEN | val);
991 break;
992 case MEDIA_BUS_FMT_YVYU8_1X16:
993
994 regmap_write(ldev->regmap, LTDC_EDCR, EDCR_OCYEN | EDCR_OCYCO | val);
995 break;
996 default:
997
998 regmap_write(ldev->regmap, LTDC_EDCR, 0);
999 break;
1000 }
1001 }
1002}
1003
1004static void ltdc_crtc_atomic_flush(struct drm_crtc *crtc,
1005 struct drm_atomic_state *state)
1006{
1007 struct ltdc_device *ldev = crtc_to_ltdc(crtc);
1008 struct drm_device *ddev = crtc->dev;
1009 struct drm_pending_vblank_event *event = crtc->state->event;
1010
1011 DRM_DEBUG_ATOMIC("\n");
1012
1013 ltdc_crtc_update_clut(crtc);
1014
1015
1016 if (!ldev->caps.plane_reg_shadow)
1017 regmap_set_bits(ldev->regmap, LTDC_SRCR, SRCR_VBR);
1018
1019 if (event) {
1020 crtc->state->event = NULL;
1021
1022 spin_lock_irq(&ddev->event_lock);
1023 if (drm_crtc_vblank_get(crtc) == 0)
1024 drm_crtc_arm_vblank_event(crtc, event);
1025 else
1026 drm_crtc_send_vblank_event(crtc, event);
1027 spin_unlock_irq(&ddev->event_lock);
1028 }
1029}
1030
1031static bool ltdc_crtc_get_scanout_position(struct drm_crtc *crtc,
1032 bool in_vblank_irq,
1033 int *vpos, int *hpos,
1034 ktime_t *stime, ktime_t *etime,
1035 const struct drm_display_mode *mode)
1036{
1037 struct drm_device *ddev = crtc->dev;
1038 struct ltdc_device *ldev = ddev->dev_private;
1039 int line, vactive_start, vactive_end, vtotal;
1040
1041 if (stime)
1042 *stime = ktime_get();
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058 if (pm_runtime_active(ddev->dev)) {
1059 regmap_read(ldev->regmap, LTDC_CPSR, &line);
1060 line &= CPSR_CYPOS;
1061 regmap_read(ldev->regmap, LTDC_BPCR, &vactive_start);
1062 vactive_start &= BPCR_AVBP;
1063 regmap_read(ldev->regmap, LTDC_AWCR, &vactive_end);
1064 vactive_end &= AWCR_AAH;
1065 regmap_read(ldev->regmap, LTDC_TWCR, &vtotal);
1066 vtotal &= TWCR_TOTALH;
1067
1068 if (line > vactive_end)
1069 *vpos = line - vtotal - vactive_start;
1070 else
1071 *vpos = line - vactive_start;
1072 } else {
1073 *vpos = 0;
1074 }
1075
1076 *hpos = 0;
1077
1078 if (etime)
1079 *etime = ktime_get();
1080
1081 return true;
1082}
1083
1084static const struct drm_crtc_helper_funcs ltdc_crtc_helper_funcs = {
1085 .mode_valid = ltdc_crtc_mode_valid,
1086 .mode_fixup = ltdc_crtc_mode_fixup,
1087 .mode_set_nofb = ltdc_crtc_mode_set_nofb,
1088 .atomic_flush = ltdc_crtc_atomic_flush,
1089 .atomic_enable = ltdc_crtc_atomic_enable,
1090 .atomic_disable = ltdc_crtc_atomic_disable,
1091 .get_scanout_position = ltdc_crtc_get_scanout_position,
1092};
1093
1094static int ltdc_crtc_enable_vblank(struct drm_crtc *crtc)
1095{
1096 struct ltdc_device *ldev = crtc_to_ltdc(crtc);
1097 struct drm_crtc_state *state = crtc->state;
1098
1099 DRM_DEBUG_DRIVER("\n");
1100
1101 if (state->enable)
1102 regmap_set_bits(ldev->regmap, LTDC_IER, IER_LIE);
1103 else
1104 return -EPERM;
1105
1106 return 0;
1107}
1108
1109static void ltdc_crtc_disable_vblank(struct drm_crtc *crtc)
1110{
1111 struct ltdc_device *ldev = crtc_to_ltdc(crtc);
1112
1113 DRM_DEBUG_DRIVER("\n");
1114 regmap_clear_bits(ldev->regmap, LTDC_IER, IER_LIE);
1115}
1116
1117static int ltdc_crtc_set_crc_source(struct drm_crtc *crtc, const char *source)
1118{
1119 struct ltdc_device *ldev = crtc_to_ltdc(crtc);
1120 int ret;
1121
1122 DRM_DEBUG_DRIVER("\n");
1123
1124 if (!crtc)
1125 return -ENODEV;
1126
1127 if (source && strcmp(source, "auto") == 0) {
1128 ldev->crc_active = true;
1129 ret = regmap_set_bits(ldev->regmap, LTDC_GCR, GCR_CRCEN);
1130 } else if (!source) {
1131 ldev->crc_active = false;
1132 ret = regmap_clear_bits(ldev->regmap, LTDC_GCR, GCR_CRCEN);
1133 } else {
1134 ret = -EINVAL;
1135 }
1136
1137 ldev->crc_skip_count = 0;
1138 return ret;
1139}
1140
1141static int ltdc_crtc_verify_crc_source(struct drm_crtc *crtc,
1142 const char *source, size_t *values_cnt)
1143{
1144 DRM_DEBUG_DRIVER("\n");
1145
1146 if (!crtc)
1147 return -ENODEV;
1148
1149 if (source && strcmp(source, "auto") != 0) {
1150 DRM_DEBUG_DRIVER("Unknown CRC source %s for %s\n",
1151 source, crtc->name);
1152 return -EINVAL;
1153 }
1154
1155 *values_cnt = 1;
1156 return 0;
1157}
1158
1159static const struct drm_crtc_funcs ltdc_crtc_funcs = {
1160 .destroy = drm_crtc_cleanup,
1161 .set_config = drm_atomic_helper_set_config,
1162 .page_flip = drm_atomic_helper_page_flip,
1163 .reset = drm_atomic_helper_crtc_reset,
1164 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
1165 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
1166 .enable_vblank = ltdc_crtc_enable_vblank,
1167 .disable_vblank = ltdc_crtc_disable_vblank,
1168 .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
1169};
1170
1171static const struct drm_crtc_funcs ltdc_crtc_with_crc_support_funcs = {
1172 .destroy = drm_crtc_cleanup,
1173 .set_config = drm_atomic_helper_set_config,
1174 .page_flip = drm_atomic_helper_page_flip,
1175 .reset = drm_atomic_helper_crtc_reset,
1176 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
1177 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
1178 .enable_vblank = ltdc_crtc_enable_vblank,
1179 .disable_vblank = ltdc_crtc_disable_vblank,
1180 .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
1181 .set_crc_source = ltdc_crtc_set_crc_source,
1182 .verify_crc_source = ltdc_crtc_verify_crc_source,
1183};
1184
1185
1186
1187
1188
1189static int ltdc_plane_atomic_check(struct drm_plane *plane,
1190 struct drm_atomic_state *state)
1191{
1192 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
1193 plane);
1194 struct drm_framebuffer *fb = new_plane_state->fb;
1195 u32 src_w, src_h;
1196
1197 DRM_DEBUG_DRIVER("\n");
1198
1199 if (!fb)
1200 return 0;
1201
1202
1203 src_w = new_plane_state->src_w >> 16;
1204 src_h = new_plane_state->src_h >> 16;
1205
1206
1207 if (src_w != new_plane_state->crtc_w || src_h != new_plane_state->crtc_h) {
1208 DRM_ERROR("Scaling is not supported");
1209 return -EINVAL;
1210 }
1211
1212 return 0;
1213}
1214
1215static void ltdc_plane_atomic_update(struct drm_plane *plane,
1216 struct drm_atomic_state *state)
1217{
1218 struct ltdc_device *ldev = plane_to_ltdc(plane);
1219 struct drm_plane_state *newstate = drm_atomic_get_new_plane_state(state,
1220 plane);
1221 struct drm_framebuffer *fb = newstate->fb;
1222 u32 lofs = plane->index * LAY_OFS;
1223 u32 x0 = newstate->crtc_x;
1224 u32 x1 = newstate->crtc_x + newstate->crtc_w - 1;
1225 u32 y0 = newstate->crtc_y;
1226 u32 y1 = newstate->crtc_y + newstate->crtc_h - 1;
1227 u32 src_x, src_y, src_w, src_h;
1228 u32 val, pitch_in_bytes, line_length, line_number, paddr, ahbp, avbp, bpcr;
1229 enum ltdc_pix_fmt pf;
1230
1231 if (!newstate->crtc || !fb) {
1232 DRM_DEBUG_DRIVER("fb or crtc NULL");
1233 return;
1234 }
1235
1236
1237 src_x = newstate->src_x >> 16;
1238 src_y = newstate->src_y >> 16;
1239 src_w = newstate->src_w >> 16;
1240 src_h = newstate->src_h >> 16;
1241
1242 DRM_DEBUG_DRIVER("plane:%d fb:%d (%dx%d)@(%d,%d) -> (%dx%d)@(%d,%d)\n",
1243 plane->base.id, fb->base.id,
1244 src_w, src_h, src_x, src_y,
1245 newstate->crtc_w, newstate->crtc_h,
1246 newstate->crtc_x, newstate->crtc_y);
1247
1248 regmap_read(ldev->regmap, LTDC_BPCR, &bpcr);
1249
1250 ahbp = (bpcr & BPCR_AHBP) >> 16;
1251 avbp = bpcr & BPCR_AVBP;
1252
1253
1254 val = ((x1 + 1 + ahbp) << 16) + (x0 + 1 + ahbp);
1255 regmap_write_bits(ldev->regmap, LTDC_L1WHPCR + lofs,
1256 LXWHPCR_WHSTPOS | LXWHPCR_WHSPPOS, val);
1257
1258
1259 val = ((y1 + 1 + avbp) << 16) + (y0 + 1 + avbp);
1260 regmap_write_bits(ldev->regmap, LTDC_L1WVPCR + lofs,
1261 LXWVPCR_WVSTPOS | LXWVPCR_WVSPPOS, val);
1262
1263
1264 pf = to_ltdc_pixelformat(fb->format->format);
1265 for (val = 0; val < NB_PF; val++)
1266 if (ldev->caps.pix_fmt_hw[val] == pf)
1267 break;
1268
1269
1270 if (ldev->caps.pix_fmt_flex && val == NB_PF)
1271 val = ltdc_set_flexible_pixel_format(plane, pf);
1272
1273 if (val == NB_PF) {
1274 DRM_ERROR("Pixel format %.4s not supported\n",
1275 (char *)&fb->format->format);
1276 val = 0;
1277 }
1278 regmap_write_bits(ldev->regmap, LTDC_L1PFCR + lofs, LXPFCR_PF, val);
1279
1280
1281 pitch_in_bytes = fb->pitches[0];
1282 line_length = fb->format->cpp[0] *
1283 (x1 - x0 + 1) + (ldev->caps.bus_width >> 3) - 1;
1284 val = ((pitch_in_bytes << 16) | line_length);
1285 regmap_write_bits(ldev->regmap, LTDC_L1CFBLR + lofs, LXCFBLR_CFBLL | LXCFBLR_CFBP, val);
1286
1287
1288 val = newstate->alpha >> 8;
1289 regmap_write_bits(ldev->regmap, LTDC_L1CACR + lofs, LXCACR_CONSTA, val);
1290
1291
1292 val = BF1_PAXCA | BF2_1PAXCA;
1293 if (!fb->format->has_alpha)
1294 val = BF1_CA | BF2_1CA;
1295
1296
1297 if (ldev->caps.non_alpha_only_l1 &&
1298 plane->type != DRM_PLANE_TYPE_PRIMARY)
1299 val = BF1_PAXCA | BF2_1PAXCA;
1300
1301 regmap_write_bits(ldev->regmap, LTDC_L1BFCR + lofs, LXBFCR_BF2 | LXBFCR_BF1, val);
1302
1303
1304 line_number = y1 - y0 + 1;
1305 regmap_write_bits(ldev->regmap, LTDC_L1CFBLNR + lofs, LXCFBLNR_CFBLN, line_number);
1306
1307
1308 paddr = (u32)drm_fb_cma_get_gem_addr(fb, newstate, 0);
1309
1310 DRM_DEBUG_DRIVER("fb: phys 0x%08x", paddr);
1311 regmap_write(ldev->regmap, LTDC_L1CFBAR + lofs, paddr);
1312
1313 if (ldev->caps.ycbcr_input) {
1314 if (fb->format->is_yuv) {
1315 switch (fb->format->format) {
1316 case DRM_FORMAT_NV12:
1317 case DRM_FORMAT_NV21:
1318
1319 paddr = (u32)drm_fb_cma_get_gem_addr(fb, newstate, 1);
1320 regmap_write(ldev->regmap, LTDC_L1AFBA0R + lofs, paddr);
1321 regmap_write(ldev->regmap, LTDC_L1AFBA1R + lofs, paddr + 1);
1322
1323
1324 val = ((pitch_in_bytes << 16) | line_length);
1325 regmap_write(ldev->regmap, LTDC_L1AFBLR + lofs, val);
1326
1327
1328 val = (line_number >> 1);
1329 regmap_write(ldev->regmap, LTDC_L1AFBLNR + lofs, val);
1330 break;
1331 case DRM_FORMAT_YUV420:
1332
1333 paddr = (u32)drm_fb_cma_get_gem_addr(fb, newstate, 1);
1334 regmap_write(ldev->regmap, LTDC_L1AFBA0R + lofs, paddr);
1335
1336
1337 paddr = (u32)drm_fb_cma_get_gem_addr(fb, newstate, 2);
1338 regmap_write(ldev->regmap, LTDC_L1AFBA1R + lofs, paddr);
1339
1340 line_length = ((fb->format->cpp[0] * (x1 - x0 + 1)) >> 1) +
1341 (ldev->caps.bus_width >> 3) - 1;
1342
1343
1344 val = (((pitch_in_bytes >> 1) << 16) | line_length);
1345 regmap_write(ldev->regmap, LTDC_L1AFBLR + lofs, val);
1346
1347
1348 val = (line_number >> 1);
1349 regmap_write(ldev->regmap, LTDC_L1AFBLNR + lofs, val);
1350 break;
1351 case DRM_FORMAT_YVU420:
1352
1353 paddr = (u32)drm_fb_cma_get_gem_addr(fb, newstate, 2);
1354 regmap_write(ldev->regmap, LTDC_L1AFBA0R + lofs, paddr);
1355
1356
1357 paddr = (u32)drm_fb_cma_get_gem_addr(fb, newstate, 1);
1358 regmap_write(ldev->regmap, LTDC_L1AFBA1R + lofs, paddr);
1359
1360 line_length = ((fb->format->cpp[0] * (x1 - x0 + 1)) >> 1) +
1361 (ldev->caps.bus_width >> 3) - 1;
1362
1363
1364 val = (((pitch_in_bytes >> 1) << 16) | line_length);
1365 regmap_write(ldev->regmap, LTDC_L1AFBLR + lofs, val);
1366
1367
1368 val = (line_number >> 1);
1369 regmap_write(ldev->regmap, LTDC_L1AFBLNR + lofs, val);
1370 break;
1371 }
1372
1373
1374 ltdc_set_ycbcr_coeffs(plane);
1375
1376
1377 ltdc_set_ycbcr_config(plane, fb->format->format);
1378 } else {
1379
1380 regmap_write(ldev->regmap, LTDC_L1PCR + lofs, 0);
1381 }
1382 }
1383
1384
1385 val = fb->format->format == DRM_FORMAT_C8 ? LXCR_CLUTEN : 0;
1386 val |= LXCR_LEN;
1387 regmap_write_bits(ldev->regmap, LTDC_L1CR + lofs, LXCR_LEN | LXCR_CLUTEN, val);
1388
1389
1390 if (ldev->caps.plane_reg_shadow)
1391 regmap_write_bits(ldev->regmap, LTDC_L1RCR + lofs,
1392 LXRCR_IMR | LXRCR_VBR | LXRCR_GRMSK, LXRCR_VBR);
1393
1394 ldev->plane_fpsi[plane->index].counter++;
1395
1396 mutex_lock(&ldev->err_lock);
1397 if (ldev->error_status & ISR_FUIF) {
1398 DRM_WARN("ltdc fifo underrun: please verify display mode\n");
1399 ldev->error_status &= ~ISR_FUIF;
1400 }
1401 if (ldev->error_status & ISR_TERRIF) {
1402 DRM_WARN("ltdc transfer error\n");
1403 ldev->error_status &= ~ISR_TERRIF;
1404 }
1405 mutex_unlock(&ldev->err_lock);
1406}
1407
1408static void ltdc_plane_atomic_disable(struct drm_plane *plane,
1409 struct drm_atomic_state *state)
1410{
1411 struct drm_plane_state *oldstate = drm_atomic_get_old_plane_state(state,
1412 plane);
1413 struct ltdc_device *ldev = plane_to_ltdc(plane);
1414 u32 lofs = plane->index * LAY_OFS;
1415
1416
1417 regmap_write_bits(ldev->regmap, LTDC_L1CR + lofs, LXCR_LEN, 0);
1418
1419
1420 if (ldev->caps.plane_reg_shadow)
1421 regmap_write_bits(ldev->regmap, LTDC_L1RCR + lofs,
1422 LXRCR_IMR | LXRCR_VBR | LXRCR_GRMSK, LXRCR_VBR);
1423
1424 DRM_DEBUG_DRIVER("CRTC:%d plane:%d\n",
1425 oldstate->crtc->base.id, plane->base.id);
1426}
1427
1428static void ltdc_plane_atomic_print_state(struct drm_printer *p,
1429 const struct drm_plane_state *state)
1430{
1431 struct drm_plane *plane = state->plane;
1432 struct ltdc_device *ldev = plane_to_ltdc(plane);
1433 struct fps_info *fpsi = &ldev->plane_fpsi[plane->index];
1434 int ms_since_last;
1435 ktime_t now;
1436
1437 now = ktime_get();
1438 ms_since_last = ktime_to_ms(ktime_sub(now, fpsi->last_timestamp));
1439
1440 drm_printf(p, "\tuser_updates=%dfps\n",
1441 DIV_ROUND_CLOSEST(fpsi->counter * 1000, ms_since_last));
1442
1443 fpsi->last_timestamp = now;
1444 fpsi->counter = 0;
1445}
1446
1447static const struct drm_plane_funcs ltdc_plane_funcs = {
1448 .update_plane = drm_atomic_helper_update_plane,
1449 .disable_plane = drm_atomic_helper_disable_plane,
1450 .destroy = drm_plane_cleanup,
1451 .reset = drm_atomic_helper_plane_reset,
1452 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
1453 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
1454 .atomic_print_state = ltdc_plane_atomic_print_state,
1455};
1456
1457static const struct drm_plane_helper_funcs ltdc_plane_helper_funcs = {
1458 .atomic_check = ltdc_plane_atomic_check,
1459 .atomic_update = ltdc_plane_atomic_update,
1460 .atomic_disable = ltdc_plane_atomic_disable,
1461};
1462
1463static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
1464 enum drm_plane_type type,
1465 int index)
1466{
1467 unsigned long possible_crtcs = CRTC_MASK;
1468 struct ltdc_device *ldev = ddev->dev_private;
1469 struct device *dev = ddev->dev;
1470 struct drm_plane *plane;
1471 unsigned int i, nb_fmt = 0;
1472 u32 *formats;
1473 u32 drm_fmt;
1474 const u64 *modifiers = ltdc_format_modifiers;
1475 u32 lofs = index * LAY_OFS;
1476 u32 val;
1477 int ret;
1478
1479
1480 formats = devm_kzalloc(dev, (ldev->caps.pix_fmt_nb +
1481 ARRAY_SIZE(ltdc_drm_fmt_ycbcr_cp) +
1482 ARRAY_SIZE(ltdc_drm_fmt_ycbcr_sp) +
1483 ARRAY_SIZE(ltdc_drm_fmt_ycbcr_fp)) *
1484 sizeof(*formats), GFP_KERNEL);
1485
1486 for (i = 0; i < ldev->caps.pix_fmt_nb; i++) {
1487 drm_fmt = ldev->caps.pix_fmt_drm[i];
1488
1489
1490 if (ldev->caps.non_alpha_only_l1)
1491
1492 if (type != DRM_PLANE_TYPE_PRIMARY && is_xrgb(drm_fmt))
1493 continue;
1494
1495 formats[nb_fmt++] = drm_fmt;
1496 }
1497
1498
1499 if (ldev->caps.ycbcr_input) {
1500 regmap_read(ldev->regmap, LTDC_L1C1R + lofs, &val);
1501 if (val & LXCR_C1R_YIA) {
1502 memcpy(&formats[nb_fmt], ltdc_drm_fmt_ycbcr_cp,
1503 ARRAY_SIZE(ltdc_drm_fmt_ycbcr_cp) * sizeof(*formats));
1504 nb_fmt += ARRAY_SIZE(ltdc_drm_fmt_ycbcr_cp);
1505 }
1506 if (val & LXCR_C1R_YSPA) {
1507 memcpy(&formats[nb_fmt], ltdc_drm_fmt_ycbcr_sp,
1508 ARRAY_SIZE(ltdc_drm_fmt_ycbcr_sp) * sizeof(*formats));
1509 nb_fmt += ARRAY_SIZE(ltdc_drm_fmt_ycbcr_sp);
1510 }
1511 if (val & LXCR_C1R_YFPA) {
1512 memcpy(&formats[nb_fmt], ltdc_drm_fmt_ycbcr_fp,
1513 ARRAY_SIZE(ltdc_drm_fmt_ycbcr_fp) * sizeof(*formats));
1514 nb_fmt += ARRAY_SIZE(ltdc_drm_fmt_ycbcr_fp);
1515 }
1516 }
1517
1518 plane = devm_kzalloc(dev, sizeof(*plane), GFP_KERNEL);
1519 if (!plane)
1520 return NULL;
1521
1522 ret = drm_universal_plane_init(ddev, plane, possible_crtcs,
1523 <dc_plane_funcs, formats, nb_fmt,
1524 modifiers, type, NULL);
1525 if (ret < 0)
1526 return NULL;
1527
1528 if (ldev->caps.ycbcr_input) {
1529 if (val & (LXCR_C1R_YIA | LXCR_C1R_YSPA | LXCR_C1R_YFPA))
1530 drm_plane_create_color_properties(plane,
1531 BIT(DRM_COLOR_YCBCR_BT601) |
1532 BIT(DRM_COLOR_YCBCR_BT709),
1533 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
1534 BIT(DRM_COLOR_YCBCR_FULL_RANGE),
1535 DRM_COLOR_YCBCR_BT601,
1536 DRM_COLOR_YCBCR_LIMITED_RANGE);
1537 }
1538
1539 drm_plane_helper_add(plane, <dc_plane_helper_funcs);
1540
1541 drm_plane_create_alpha_property(plane);
1542
1543 DRM_DEBUG_DRIVER("plane:%d created\n", plane->base.id);
1544
1545 return plane;
1546}
1547
1548static void ltdc_plane_destroy_all(struct drm_device *ddev)
1549{
1550 struct drm_plane *plane, *plane_temp;
1551
1552 list_for_each_entry_safe(plane, plane_temp,
1553 &ddev->mode_config.plane_list, head)
1554 drm_plane_cleanup(plane);
1555}
1556
1557static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
1558{
1559 struct ltdc_device *ldev = ddev->dev_private;
1560 struct drm_plane *primary, *overlay;
1561 unsigned int i;
1562 int ret;
1563
1564 primary = ltdc_plane_create(ddev, DRM_PLANE_TYPE_PRIMARY, 0);
1565 if (!primary) {
1566 DRM_ERROR("Can not create primary plane\n");
1567 return -EINVAL;
1568 }
1569
1570 drm_plane_create_zpos_immutable_property(primary, 0);
1571
1572
1573 if (ldev->caps.crc)
1574 ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL,
1575 <dc_crtc_with_crc_support_funcs, NULL);
1576 else
1577 ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL,
1578 <dc_crtc_funcs, NULL);
1579 if (ret) {
1580 DRM_ERROR("Can not initialize CRTC\n");
1581 goto cleanup;
1582 }
1583
1584 drm_crtc_helper_add(crtc, <dc_crtc_helper_funcs);
1585
1586 drm_mode_crtc_set_gamma_size(crtc, CLUT_SIZE);
1587 drm_crtc_enable_color_mgmt(crtc, 0, false, CLUT_SIZE);
1588
1589 DRM_DEBUG_DRIVER("CRTC:%d created\n", crtc->base.id);
1590
1591
1592 for (i = 1; i < ldev->caps.nb_layers; i++) {
1593 overlay = ltdc_plane_create(ddev, DRM_PLANE_TYPE_OVERLAY, i);
1594 if (!overlay) {
1595 ret = -ENOMEM;
1596 DRM_ERROR("Can not create overlay plane %d\n", i);
1597 goto cleanup;
1598 }
1599 drm_plane_create_zpos_immutable_property(overlay, i);
1600 }
1601
1602 return 0;
1603
1604cleanup:
1605 ltdc_plane_destroy_all(ddev);
1606 return ret;
1607}
1608
1609static void ltdc_encoder_disable(struct drm_encoder *encoder)
1610{
1611 struct drm_device *ddev = encoder->dev;
1612 struct ltdc_device *ldev = ddev->dev_private;
1613
1614 DRM_DEBUG_DRIVER("\n");
1615
1616
1617 regmap_clear_bits(ldev->regmap, LTDC_GCR, GCR_LTDCEN);
1618
1619
1620 pinctrl_pm_select_sleep_state(ddev->dev);
1621}
1622
1623static void ltdc_encoder_enable(struct drm_encoder *encoder)
1624{
1625 struct drm_device *ddev = encoder->dev;
1626 struct ltdc_device *ldev = ddev->dev_private;
1627
1628 DRM_DEBUG_DRIVER("\n");
1629
1630
1631 regmap_set_bits(ldev->regmap, LTDC_GCR, GCR_LTDCEN);
1632}
1633
1634static void ltdc_encoder_mode_set(struct drm_encoder *encoder,
1635 struct drm_display_mode *mode,
1636 struct drm_display_mode *adjusted_mode)
1637{
1638 struct drm_device *ddev = encoder->dev;
1639
1640 DRM_DEBUG_DRIVER("\n");
1641
1642
1643
1644
1645
1646
1647 if (encoder->encoder_type == DRM_MODE_ENCODER_DPI)
1648 pinctrl_pm_select_default_state(ddev->dev);
1649}
1650
1651static const struct drm_encoder_helper_funcs ltdc_encoder_helper_funcs = {
1652 .disable = ltdc_encoder_disable,
1653 .enable = ltdc_encoder_enable,
1654 .mode_set = ltdc_encoder_mode_set,
1655};
1656
1657static int ltdc_encoder_init(struct drm_device *ddev, struct drm_bridge *bridge)
1658{
1659 struct drm_encoder *encoder;
1660 int ret;
1661
1662 encoder = devm_kzalloc(ddev->dev, sizeof(*encoder), GFP_KERNEL);
1663 if (!encoder)
1664 return -ENOMEM;
1665
1666 encoder->possible_crtcs = CRTC_MASK;
1667 encoder->possible_clones = 0;
1668
1669 drm_simple_encoder_init(ddev, encoder, DRM_MODE_ENCODER_DPI);
1670
1671 drm_encoder_helper_add(encoder, <dc_encoder_helper_funcs);
1672
1673 ret = drm_bridge_attach(encoder, bridge, NULL, 0);
1674 if (ret) {
1675 if (ret != -EPROBE_DEFER)
1676 drm_encoder_cleanup(encoder);
1677 return ret;
1678 }
1679
1680 DRM_DEBUG_DRIVER("Bridge encoder:%d created\n", encoder->base.id);
1681
1682 return 0;
1683}
1684
1685static int ltdc_get_caps(struct drm_device *ddev)
1686{
1687 struct ltdc_device *ldev = ddev->dev_private;
1688 u32 bus_width_log2, lcr, gc2r;
1689
1690
1691
1692
1693
1694 regmap_read(ldev->regmap, LTDC_LCR, &lcr);
1695
1696 ldev->caps.nb_layers = clamp((int)lcr, 1, LTDC_MAX_LAYER);
1697
1698
1699 regmap_read(ldev->regmap, LTDC_GC2R, &gc2r);
1700 bus_width_log2 = (gc2r & GC2R_BW) >> 4;
1701 ldev->caps.bus_width = 8 << bus_width_log2;
1702 regmap_read(ldev->regmap, LTDC_IDR, &ldev->caps.hw_version);
1703
1704 switch (ldev->caps.hw_version) {
1705 case HWVER_10200:
1706 case HWVER_10300:
1707 ldev->caps.layer_ofs = LAY_OFS_0;
1708 ldev->caps.layer_regs = ltdc_layer_regs_a0;
1709 ldev->caps.pix_fmt_hw = ltdc_pix_fmt_a0;
1710 ldev->caps.pix_fmt_drm = ltdc_drm_fmt_a0;
1711 ldev->caps.pix_fmt_nb = ARRAY_SIZE(ltdc_drm_fmt_a0);
1712 ldev->caps.pix_fmt_flex = false;
1713
1714
1715
1716
1717
1718
1719
1720 ldev->caps.non_alpha_only_l1 = true;
1721 ldev->caps.pad_max_freq_hz = 90000000;
1722 if (ldev->caps.hw_version == HWVER_10200)
1723 ldev->caps.pad_max_freq_hz = 65000000;
1724 ldev->caps.nb_irq = 2;
1725 ldev->caps.ycbcr_input = false;
1726 ldev->caps.ycbcr_output = false;
1727 ldev->caps.plane_reg_shadow = false;
1728 ldev->caps.crc = false;
1729 break;
1730 case HWVER_20101:
1731 ldev->caps.layer_ofs = LAY_OFS_0;
1732 ldev->caps.layer_regs = ltdc_layer_regs_a1;
1733 ldev->caps.pix_fmt_hw = ltdc_pix_fmt_a1;
1734 ldev->caps.pix_fmt_drm = ltdc_drm_fmt_a1;
1735 ldev->caps.pix_fmt_nb = ARRAY_SIZE(ltdc_drm_fmt_a1);
1736 ldev->caps.pix_fmt_flex = false;
1737 ldev->caps.non_alpha_only_l1 = false;
1738 ldev->caps.pad_max_freq_hz = 150000000;
1739 ldev->caps.nb_irq = 4;
1740 ldev->caps.ycbcr_input = false;
1741 ldev->caps.ycbcr_output = false;
1742 ldev->caps.plane_reg_shadow = false;
1743 ldev->caps.crc = false;
1744 break;
1745 case HWVER_40100:
1746 ldev->caps.layer_ofs = LAY_OFS_1;
1747 ldev->caps.layer_regs = ltdc_layer_regs_a2;
1748 ldev->caps.pix_fmt_hw = ltdc_pix_fmt_a2;
1749 ldev->caps.pix_fmt_drm = ltdc_drm_fmt_a2;
1750 ldev->caps.pix_fmt_nb = ARRAY_SIZE(ltdc_drm_fmt_a2);
1751 ldev->caps.pix_fmt_flex = true;
1752 ldev->caps.non_alpha_only_l1 = false;
1753 ldev->caps.pad_max_freq_hz = 90000000;
1754 ldev->caps.nb_irq = 2;
1755 ldev->caps.ycbcr_input = true;
1756 ldev->caps.ycbcr_output = true;
1757 ldev->caps.plane_reg_shadow = true;
1758 ldev->caps.crc = true;
1759 break;
1760 default:
1761 return -ENODEV;
1762 }
1763
1764 return 0;
1765}
1766
1767void ltdc_suspend(struct drm_device *ddev)
1768{
1769 struct ltdc_device *ldev = ddev->dev_private;
1770
1771 DRM_DEBUG_DRIVER("\n");
1772 clk_disable_unprepare(ldev->pixel_clk);
1773}
1774
1775int ltdc_resume(struct drm_device *ddev)
1776{
1777 struct ltdc_device *ldev = ddev->dev_private;
1778 int ret;
1779
1780 DRM_DEBUG_DRIVER("\n");
1781
1782 ret = clk_prepare_enable(ldev->pixel_clk);
1783 if (ret) {
1784 DRM_ERROR("failed to enable pixel clock (%d)\n", ret);
1785 return ret;
1786 }
1787
1788 return 0;
1789}
1790
1791int ltdc_load(struct drm_device *ddev)
1792{
1793 struct platform_device *pdev = to_platform_device(ddev->dev);
1794 struct ltdc_device *ldev = ddev->dev_private;
1795 struct device *dev = ddev->dev;
1796 struct device_node *np = dev->of_node;
1797 struct drm_bridge *bridge;
1798 struct drm_panel *panel;
1799 struct drm_crtc *crtc;
1800 struct reset_control *rstc;
1801 struct resource *res;
1802 int irq, i, nb_endpoints;
1803 int ret = -ENODEV;
1804
1805 DRM_DEBUG_DRIVER("\n");
1806
1807
1808 nb_endpoints = of_graph_get_endpoint_count(np);
1809 if (!nb_endpoints)
1810 return -ENODEV;
1811
1812 ldev->pixel_clk = devm_clk_get(dev, "lcd");
1813 if (IS_ERR(ldev->pixel_clk)) {
1814 if (PTR_ERR(ldev->pixel_clk) != -EPROBE_DEFER)
1815 DRM_ERROR("Unable to get lcd clock\n");
1816 return PTR_ERR(ldev->pixel_clk);
1817 }
1818
1819 if (clk_prepare_enable(ldev->pixel_clk)) {
1820 DRM_ERROR("Unable to prepare pixel clock\n");
1821 return -ENODEV;
1822 }
1823
1824
1825 for (i = 0; i < nb_endpoints; i++) {
1826 ret = drm_of_find_panel_or_bridge(np, 0, i, &panel, &bridge);
1827
1828
1829
1830
1831
1832
1833 if (ret == -ENODEV)
1834 continue;
1835 else if (ret)
1836 goto err;
1837
1838 if (panel) {
1839 bridge = drm_panel_bridge_add_typed(panel,
1840 DRM_MODE_CONNECTOR_DPI);
1841 if (IS_ERR(bridge)) {
1842 DRM_ERROR("panel-bridge endpoint %d\n", i);
1843 ret = PTR_ERR(bridge);
1844 goto err;
1845 }
1846 }
1847
1848 if (bridge) {
1849 ret = ltdc_encoder_init(ddev, bridge);
1850 if (ret) {
1851 if (ret != -EPROBE_DEFER)
1852 DRM_ERROR("init encoder endpoint %d\n", i);
1853 goto err;
1854 }
1855 }
1856 }
1857
1858 rstc = devm_reset_control_get_exclusive(dev, NULL);
1859
1860 mutex_init(&ldev->err_lock);
1861
1862 if (!IS_ERR(rstc)) {
1863 reset_control_assert(rstc);
1864 usleep_range(10, 20);
1865 reset_control_deassert(rstc);
1866 }
1867
1868 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1869 ldev->regs = devm_ioremap_resource(dev, res);
1870 if (IS_ERR(ldev->regs)) {
1871 DRM_ERROR("Unable to get ltdc registers\n");
1872 ret = PTR_ERR(ldev->regs);
1873 goto err;
1874 }
1875
1876 ldev->regmap = devm_regmap_init_mmio(&pdev->dev, ldev->regs, &stm32_ltdc_regmap_cfg);
1877 if (IS_ERR(ldev->regmap)) {
1878 DRM_ERROR("Unable to regmap ltdc registers\n");
1879 ret = PTR_ERR(ldev->regmap);
1880 goto err;
1881 }
1882
1883
1884 regmap_clear_bits(ldev->regmap, LTDC_IER, IER_LIE | IER_RRIE | IER_FUIE | IER_TERRIE);
1885
1886 ret = ltdc_get_caps(ddev);
1887 if (ret) {
1888 DRM_ERROR("hardware identifier (0x%08x) not supported!\n",
1889 ldev->caps.hw_version);
1890 goto err;
1891 }
1892
1893 DRM_DEBUG_DRIVER("ltdc hw version 0x%08x\n", ldev->caps.hw_version);
1894
1895 for (i = 0; i < ldev->caps.nb_irq; i++) {
1896 irq = platform_get_irq(pdev, i);
1897 if (irq < 0) {
1898 ret = irq;
1899 goto err;
1900 }
1901
1902 ret = devm_request_threaded_irq(dev, irq, ltdc_irq,
1903 ltdc_irq_thread, IRQF_ONESHOT,
1904 dev_name(dev), ddev);
1905 if (ret) {
1906 DRM_ERROR("Failed to register LTDC interrupt\n");
1907 goto err;
1908 }
1909
1910 }
1911
1912 crtc = devm_kzalloc(dev, sizeof(*crtc), GFP_KERNEL);
1913 if (!crtc) {
1914 DRM_ERROR("Failed to allocate crtc\n");
1915 ret = -ENOMEM;
1916 goto err;
1917 }
1918
1919 ret = ltdc_crtc_init(ddev, crtc);
1920 if (ret) {
1921 DRM_ERROR("Failed to init crtc\n");
1922 goto err;
1923 }
1924
1925 ret = drm_vblank_init(ddev, NB_CRTC);
1926 if (ret) {
1927 DRM_ERROR("Failed calling drm_vblank_init()\n");
1928 goto err;
1929 }
1930
1931 clk_disable_unprepare(ldev->pixel_clk);
1932
1933 pinctrl_pm_select_sleep_state(ddev->dev);
1934
1935 pm_runtime_enable(ddev->dev);
1936
1937 return 0;
1938err:
1939 for (i = 0; i < nb_endpoints; i++)
1940 drm_of_panel_bridge_remove(ddev->dev->of_node, 0, i);
1941
1942 clk_disable_unprepare(ldev->pixel_clk);
1943
1944 return ret;
1945}
1946
1947void ltdc_unload(struct drm_device *ddev)
1948{
1949 struct device *dev = ddev->dev;
1950 int nb_endpoints, i;
1951
1952 DRM_DEBUG_DRIVER("\n");
1953
1954 nb_endpoints = of_graph_get_endpoint_count(dev->of_node);
1955
1956 for (i = 0; i < nb_endpoints; i++)
1957 drm_of_panel_bridge_remove(ddev->dev->of_node, 0, i);
1958
1959 pm_runtime_disable(ddev->dev);
1960}
1961
1962MODULE_AUTHOR("Philippe Cornu <philippe.cornu@st.com>");
1963MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>");
1964MODULE_AUTHOR("Fabien Dessenne <fabien.dessenne@st.com>");
1965MODULE_AUTHOR("Mickael Reulier <mickael.reulier@st.com>");
1966MODULE_DESCRIPTION("STMicroelectronics ST DRM LTDC driver");
1967MODULE_LICENSE("GPL v2");
1968