1 // SPDX-License-Identifier: GPL-2.0
3 * R-Car MIPI DSI Encoder
5 * Copyright (C) 2020 Renesas Electronics Corporation
9 #include <linux/delay.h>
11 #include <linux/iopoll.h>
12 #include <linux/math64.h>
13 #include <linux/module.h>
15 #include <linux/of_graph.h>
16 #include <linux/platform_device.h>
17 #include <linux/reset.h>
18 #include <linux/slab.h>
20 #include <drm/drm_atomic.h>
21 #include <drm/drm_atomic_helper.h>
22 #include <drm/drm_bridge.h>
23 #include <drm/drm_mipi_dsi.h>
24 #include <drm/drm_of.h>
25 #include <drm/drm_panel.h>
26 #include <drm/drm_probe_helper.h>
28 #include "rcar_mipi_dsi.h"
29 #include "rcar_mipi_dsi_regs.h"
31 #define MHZ(v) ((u32)((v) * 1000000U))
33 enum rcar_mipi_dsi_hw_model
{
38 struct rcar_mipi_dsi_device_info
{
39 enum rcar_mipi_dsi_hw_model model
;
41 const struct dsi_clk_config
*clk_cfg
;
43 u8 clockset2_m_offset
;
48 unsigned long fpfd_min
;
49 unsigned long fpfd_max
;
52 unsigned long fout_min
;
53 unsigned long fout_max
;
56 struct rcar_mipi_dsi
{
58 const struct rcar_mipi_dsi_device_info
*info
;
59 struct reset_control
*rstc
;
61 struct mipi_dsi_host host
;
62 struct drm_bridge bridge
;
63 struct drm_bridge
*next_bridge
;
64 struct drm_connector connector
;
73 enum mipi_dsi_pixel_format format
;
74 unsigned int num_data_lanes
;
78 struct dsi_setup_info
{
86 const struct dsi_clk_config
*clkset
;
89 static inline struct rcar_mipi_dsi
*
90 bridge_to_rcar_mipi_dsi(struct drm_bridge
*bridge
)
92 return container_of(bridge
, struct rcar_mipi_dsi
, bridge
);
95 static inline struct rcar_mipi_dsi
*
96 host_to_rcar_mipi_dsi(struct mipi_dsi_host
*host
)
98 return container_of(host
, struct rcar_mipi_dsi
, host
);
101 static const u32 hsfreqrange_table
[][2] = {
102 { MHZ(80), 0x00 }, { MHZ(90), 0x10 }, { MHZ(100), 0x20 },
103 { MHZ(110), 0x30 }, { MHZ(120), 0x01 }, { MHZ(130), 0x11 },
104 { MHZ(140), 0x21 }, { MHZ(150), 0x31 }, { MHZ(160), 0x02 },
105 { MHZ(170), 0x12 }, { MHZ(180), 0x22 }, { MHZ(190), 0x32 },
106 { MHZ(205), 0x03 }, { MHZ(220), 0x13 }, { MHZ(235), 0x23 },
107 { MHZ(250), 0x33 }, { MHZ(275), 0x04 }, { MHZ(300), 0x14 },
108 { MHZ(325), 0x25 }, { MHZ(350), 0x35 }, { MHZ(400), 0x05 },
109 { MHZ(450), 0x16 }, { MHZ(500), 0x26 }, { MHZ(550), 0x37 },
110 { MHZ(600), 0x07 }, { MHZ(650), 0x18 }, { MHZ(700), 0x28 },
111 { MHZ(750), 0x39 }, { MHZ(800), 0x09 }, { MHZ(850), 0x19 },
112 { MHZ(900), 0x29 }, { MHZ(950), 0x3a }, { MHZ(1000), 0x0a },
113 { MHZ(1050), 0x1a }, { MHZ(1100), 0x2a }, { MHZ(1150), 0x3b },
114 { MHZ(1200), 0x0b }, { MHZ(1250), 0x1b }, { MHZ(1300), 0x2b },
115 { MHZ(1350), 0x3c }, { MHZ(1400), 0x0c }, { MHZ(1450), 0x1c },
116 { MHZ(1500), 0x2c }, { MHZ(1550), 0x3d }, { MHZ(1600), 0x0d },
117 { MHZ(1650), 0x1d }, { MHZ(1700), 0x2e }, { MHZ(1750), 0x3e },
118 { MHZ(1800), 0x0e }, { MHZ(1850), 0x1e }, { MHZ(1900), 0x2f },
119 { MHZ(1950), 0x3f }, { MHZ(2000), 0x0f }, { MHZ(2050), 0x40 },
120 { MHZ(2100), 0x41 }, { MHZ(2150), 0x42 }, { MHZ(2200), 0x43 },
121 { MHZ(2250), 0x44 }, { MHZ(2300), 0x45 }, { MHZ(2350), 0x46 },
122 { MHZ(2400), 0x47 }, { MHZ(2450), 0x48 }, { MHZ(2500), 0x49 },
126 struct dsi_clk_config
{
136 static const struct dsi_clk_config dsi_clk_cfg_v3u
[] = {
137 { MHZ(40), MHZ(55), 0x3f, 0x10, 0x01, 0x00, 0x0b },
138 { MHZ(52.5), MHZ(80), 0x39, 0x10, 0x01, 0x00, 0x0b },
139 { MHZ(80), MHZ(110), 0x2f, 0x10, 0x01, 0x00, 0x0b },
140 { MHZ(105), MHZ(160), 0x29, 0x10, 0x01, 0x00, 0x0b },
141 { MHZ(160), MHZ(220), 0x1f, 0x10, 0x01, 0x00, 0x0b },
142 { MHZ(210), MHZ(320), 0x19, 0x10, 0x01, 0x00, 0x0b },
143 { MHZ(320), MHZ(440), 0x0f, 0x10, 0x01, 0x00, 0x0b },
144 { MHZ(420), MHZ(660), 0x09, 0x10, 0x01, 0x00, 0x0b },
145 { MHZ(630), MHZ(1149), 0x03, 0x10, 0x01, 0x00, 0x0b },
146 { MHZ(1100), MHZ(1152), 0x01, 0x10, 0x01, 0x00, 0x0b },
147 { MHZ(1150), MHZ(1250), 0x01, 0x10, 0x01, 0x00, 0x0c },
151 static const struct dsi_clk_config dsi_clk_cfg_v4h
[] = {
152 { MHZ(40), MHZ(45.31), 0x2b, 0x00, 0x00, 0x08, 0x0a },
153 { MHZ(45.31), MHZ(54.66), 0x28, 0x00, 0x00, 0x08, 0x0a },
154 { MHZ(54.66), MHZ(62.5), 0x28, 0x00, 0x00, 0x08, 0x0a },
155 { MHZ(62.5), MHZ(75), 0x27, 0x00, 0x00, 0x08, 0x0a },
156 { MHZ(75), MHZ(90.63), 0x23, 0x00, 0x00, 0x08, 0x0a },
157 { MHZ(90.63), MHZ(109.37), 0x20, 0x00, 0x00, 0x08, 0x0a },
158 { MHZ(109.37), MHZ(125), 0x20, 0x00, 0x00, 0x08, 0x0a },
159 { MHZ(125), MHZ(150), 0x1f, 0x00, 0x00, 0x08, 0x0a },
160 { MHZ(150), MHZ(181.25), 0x1b, 0x00, 0x00, 0x08, 0x0a },
161 { MHZ(181.25), MHZ(218.75), 0x18, 0x00, 0x00, 0x08, 0x0a },
162 { MHZ(218.75), MHZ(250), 0x18, 0x00, 0x00, 0x08, 0x0a },
163 { MHZ(250), MHZ(300), 0x17, 0x00, 0x00, 0x08, 0x0a },
164 { MHZ(300), MHZ(362.5), 0x13, 0x00, 0x00, 0x08, 0x0a },
165 { MHZ(362.5), MHZ(455.48), 0x10, 0x00, 0x00, 0x08, 0x0a },
166 { MHZ(455.48), MHZ(500), 0x10, 0x00, 0x00, 0x08, 0x0a },
167 { MHZ(500), MHZ(600), 0x0f, 0x00, 0x00, 0x08, 0x0a },
168 { MHZ(600), MHZ(725), 0x0b, 0x00, 0x00, 0x08, 0x0a },
169 { MHZ(725), MHZ(875), 0x08, 0x00, 0x00, 0x08, 0x0a },
170 { MHZ(875), MHZ(1000), 0x08, 0x00, 0x00, 0x08, 0x0a },
171 { MHZ(1000), MHZ(1200), 0x07, 0x00, 0x00, 0x08, 0x0a },
172 { MHZ(1200), MHZ(1250), 0x03, 0x00, 0x00, 0x08, 0x0a },
176 static void rcar_mipi_dsi_write(struct rcar_mipi_dsi
*dsi
, u32 reg
, u32 data
)
178 iowrite32(data
, dsi
->mmio
+ reg
);
181 static u32
rcar_mipi_dsi_read(struct rcar_mipi_dsi
*dsi
, u32 reg
)
183 return ioread32(dsi
->mmio
+ reg
);
186 static void rcar_mipi_dsi_clr(struct rcar_mipi_dsi
*dsi
, u32 reg
, u32 clr
)
188 rcar_mipi_dsi_write(dsi
, reg
, rcar_mipi_dsi_read(dsi
, reg
) & ~clr
);
191 static void rcar_mipi_dsi_set(struct rcar_mipi_dsi
*dsi
, u32 reg
, u32 set
)
193 rcar_mipi_dsi_write(dsi
, reg
, rcar_mipi_dsi_read(dsi
, reg
) | set
);
196 static int rcar_mipi_dsi_write_phtw(struct rcar_mipi_dsi
*dsi
, u32 phtw
)
201 rcar_mipi_dsi_write(dsi
, PHTW
, phtw
);
203 ret
= read_poll_timeout(rcar_mipi_dsi_read
, status
,
204 !(status
& (PHTW_DWEN
| PHTW_CWEN
)),
205 2000, 10000, false, dsi
, PHTW
);
207 dev_err(dsi
->dev
, "PHY test interface write timeout (0x%08x)\n",
215 static int rcar_mipi_dsi_write_phtw_arr(struct rcar_mipi_dsi
*dsi
,
216 const u32
*phtw
, unsigned int size
)
218 for (unsigned int i
= 0; i
< size
; i
++) {
219 int ret
= rcar_mipi_dsi_write_phtw(dsi
, phtw
[i
]);
228 #define WRITE_PHTW(...) \
230 static const u32 phtw[] = { __VA_ARGS__ }; \
232 ret = rcar_mipi_dsi_write_phtw_arr(dsi, phtw, \
237 static int rcar_mipi_dsi_init_phtw_v3u(struct rcar_mipi_dsi
*dsi
)
239 return WRITE_PHTW(0x01020114, 0x01600115, 0x01030116, 0x0102011d,
240 0x011101a4, 0x018601a4, 0x014201a0, 0x010001a3,
244 static int rcar_mipi_dsi_post_init_phtw_v3u(struct rcar_mipi_dsi
*dsi
)
246 return WRITE_PHTW(0x010c0130, 0x010c0140, 0x010c0150, 0x010c0180,
247 0x010c0190, 0x010a0160, 0x010a0170, 0x01800164,
251 static int rcar_mipi_dsi_init_phtw_v4h(struct rcar_mipi_dsi
*dsi
,
252 const struct dsi_setup_info
*setup_info
)
256 if (setup_info
->hsfreq
< MHZ(450)) {
257 ret
= WRITE_PHTW(0x01010100, 0x011b01ac);
262 ret
= WRITE_PHTW(0x01010100, 0x01030173, 0x01000174, 0x01500175,
263 0x01030176, 0x01040166, 0x010201ad);
267 if (setup_info
->hsfreq
<= MHZ(1000))
268 ret
= WRITE_PHTW(0x01020100, 0x01910170, 0x01020171,
270 else if (setup_info
->hsfreq
<= MHZ(1500))
271 ret
= WRITE_PHTW(0x01020100, 0x01980170, 0x01030171,
273 else if (setup_info
->hsfreq
<= MHZ(2500))
274 ret
= WRITE_PHTW(0x01020100, 0x0144016b, 0x01000172);
281 if (dsi
->lanes
<= 1) {
282 ret
= WRITE_PHTW(0x01070100, 0x010e010b);
287 if (dsi
->lanes
<= 2) {
288 ret
= WRITE_PHTW(0x01090100, 0x010e010b);
293 if (dsi
->lanes
<= 3) {
294 ret
= WRITE_PHTW(0x010b0100, 0x010e010b);
299 if (setup_info
->hsfreq
<= MHZ(1500)) {
300 ret
= WRITE_PHTW(0x01010100, 0x01c0016e);
309 rcar_mipi_dsi_post_init_phtw_v4h(struct rcar_mipi_dsi
*dsi
,
310 const struct dsi_setup_info
*setup_info
)
315 if (setup_info
->hsfreq
<= MHZ(1500)) {
316 WRITE_PHTW(0x01020100, 0x00000180);
318 ret
= read_poll_timeout(rcar_mipi_dsi_read
, status
,
319 status
& PHTR_TEST
, 2000, 10000, false,
322 dev_err(dsi
->dev
, "failed to test PHTR\n");
326 WRITE_PHTW(0x01010100, 0x0100016e);
332 /* -----------------------------------------------------------------------------
336 static void rcar_mipi_dsi_pll_calc(struct rcar_mipi_dsi
*dsi
,
337 unsigned long fin_rate
,
338 unsigned long fout_target
,
339 struct dsi_setup_info
*setup_info
)
341 unsigned int best_err
= -1;
342 const struct rcar_mipi_dsi_device_info
*info
= dsi
->info
;
344 for (unsigned int n
= info
->n_min
; n
<= info
->n_max
; n
++) {
349 if (fpfd
< info
->fpfd_min
|| fpfd
> info
->fpfd_max
)
352 for (unsigned int m
= info
->m_min
; m
<= info
->m_max
; m
++) {
356 fout
= div64_u64((u64
)fpfd
* m
, dsi
->info
->n_mul
);
358 if (fout
< info
->fout_min
|| fout
> info
->fout_max
)
361 fout
= div64_u64(fout
, setup_info
->vclk_divider
);
363 if (fout
< setup_info
->clkset
->min_freq
||
364 fout
> setup_info
->clkset
->max_freq
)
367 err
= abs((long)(fout
- fout_target
) * 10000 /
369 if (err
< best_err
) {
372 setup_info
->fout
= (unsigned long)fout
;
382 static void rcar_mipi_dsi_parameters_calc(struct rcar_mipi_dsi
*dsi
,
383 struct clk
*clk
, unsigned long target
,
384 struct dsi_setup_info
*setup_info
)
387 const struct dsi_clk_config
*clk_cfg
;
388 unsigned long fout_target
;
389 unsigned long fin_rate
;
394 * Calculate Fout = dot clock * ColorDepth / (2 * Lane Count)
395 * The range out Fout is [40 - 1250] Mhz
397 fout_target
= target
* mipi_dsi_pixel_format_to_bpp(dsi
->format
)
399 if (fout_target
< MHZ(40) || fout_target
> MHZ(1250))
402 /* Find PLL settings */
403 for (clk_cfg
= dsi
->info
->clk_cfg
; clk_cfg
->min_freq
!= 0; clk_cfg
++) {
404 if (fout_target
> clk_cfg
->min_freq
&&
405 fout_target
<= clk_cfg
->max_freq
) {
406 setup_info
->clkset
= clk_cfg
;
411 fin_rate
= clk_get_rate(clk
);
413 switch (dsi
->info
->model
) {
416 setup_info
->vclk_divider
= 1 << ((clk_cfg
->vco_cntrl
>> 4) & 0x3);
420 setup_info
->vclk_divider
= 1 << (((clk_cfg
->vco_cntrl
>> 3) & 0x7) + 1);
424 rcar_mipi_dsi_pll_calc(dsi
, fin_rate
, fout_target
, setup_info
);
426 /* Find hsfreqrange */
427 setup_info
->hsfreq
= setup_info
->fout
* 2;
428 for (i
= 0; i
< ARRAY_SIZE(hsfreqrange_table
); i
++) {
429 if (hsfreqrange_table
[i
][0] >= setup_info
->hsfreq
) {
430 setup_info
->hsfreqrange
= hsfreqrange_table
[i
][1];
435 err
= abs((long)(setup_info
->fout
- fout_target
) * 10000 / (long)fout_target
);
438 "Fout = %u * %lu / (%u * %u * %u) = %lu (target %lu Hz, error %d.%02u%%)\n",
439 setup_info
->m
, fin_rate
, dsi
->info
->n_mul
, setup_info
->n
,
440 setup_info
->vclk_divider
, setup_info
->fout
, fout_target
,
441 err
/ 100, err
% 100);
444 "vco_cntrl = 0x%x\tprop_cntrl = 0x%x\thsfreqrange = 0x%x\n",
445 clk_cfg
->vco_cntrl
, clk_cfg
->prop_cntrl
,
446 setup_info
->hsfreqrange
);
449 static void rcar_mipi_dsi_set_display_timing(struct rcar_mipi_dsi
*dsi
,
450 const struct drm_display_mode
*mode
)
459 /* Configuration for Pixel Stream and Packet Header */
460 if (mipi_dsi_pixel_format_to_bpp(dsi
->format
) == 24)
461 rcar_mipi_dsi_write(dsi
, TXVMPSPHSETR
, TXVMPSPHSETR_DT_RGB24
);
462 else if (mipi_dsi_pixel_format_to_bpp(dsi
->format
) == 18)
463 rcar_mipi_dsi_write(dsi
, TXVMPSPHSETR
, TXVMPSPHSETR_DT_RGB18
);
464 else if (mipi_dsi_pixel_format_to_bpp(dsi
->format
) == 16)
465 rcar_mipi_dsi_write(dsi
, TXVMPSPHSETR
, TXVMPSPHSETR_DT_RGB16
);
467 dev_warn(dsi
->dev
, "unsupported format");
471 /* Configuration for Blanking sequence and Input Pixel */
472 setr
= TXVMSETR_HSABPEN_EN
| TXVMSETR_HBPBPEN_EN
473 | TXVMSETR_HFPBPEN_EN
| TXVMSETR_SYNSEQ_PULSES
474 | TXVMSETR_PIXWDTH
| TXVMSETR_VSTPM
;
475 rcar_mipi_dsi_write(dsi
, TXVMSETR
, setr
);
477 /* Configuration for Video Parameters */
478 vprmset0r
= (mode
->flags
& DRM_MODE_FLAG_PVSYNC
?
479 TXVMVPRMSET0R_VSPOL_HIG
: TXVMVPRMSET0R_VSPOL_LOW
)
480 | (mode
->flags
& DRM_MODE_FLAG_PHSYNC
?
481 TXVMVPRMSET0R_HSPOL_HIG
: TXVMVPRMSET0R_HSPOL_LOW
)
482 | TXVMVPRMSET0R_CSPC_RGB
| TXVMVPRMSET0R_BPP_24
;
484 vprmset1r
= TXVMVPRMSET1R_VACTIVE(mode
->vdisplay
)
485 | TXVMVPRMSET1R_VSA(mode
->vsync_end
- mode
->vsync_start
);
487 vprmset2r
= TXVMVPRMSET2R_VFP(mode
->vsync_start
- mode
->vdisplay
)
488 | TXVMVPRMSET2R_VBP(mode
->vtotal
- mode
->vsync_end
);
490 vprmset3r
= TXVMVPRMSET3R_HACTIVE(mode
->hdisplay
)
491 | TXVMVPRMSET3R_HSA(mode
->hsync_end
- mode
->hsync_start
);
493 vprmset4r
= TXVMVPRMSET4R_HFP(mode
->hsync_start
- mode
->hdisplay
)
494 | TXVMVPRMSET4R_HBP(mode
->htotal
- mode
->hsync_end
);
496 rcar_mipi_dsi_write(dsi
, TXVMVPRMSET0R
, vprmset0r
);
497 rcar_mipi_dsi_write(dsi
, TXVMVPRMSET1R
, vprmset1r
);
498 rcar_mipi_dsi_write(dsi
, TXVMVPRMSET2R
, vprmset2r
);
499 rcar_mipi_dsi_write(dsi
, TXVMVPRMSET3R
, vprmset3r
);
500 rcar_mipi_dsi_write(dsi
, TXVMVPRMSET4R
, vprmset4r
);
503 static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi
*dsi
,
504 const struct drm_display_mode
*mode
)
506 struct dsi_setup_info setup_info
= {};
507 unsigned int timeout
;
511 u32 clockset2
, clockset3
;
515 /* Checking valid format */
516 dsi_format
= mipi_dsi_pixel_format_to_bpp(dsi
->format
);
517 if (dsi_format
< 0) {
518 dev_warn(dsi
->dev
, "invalid format");
522 /* Parameters Calculation */
523 rcar_mipi_dsi_parameters_calc(dsi
, dsi
->clocks
.pll
,
524 mode
->clock
* 1000, &setup_info
);
527 rcar_mipi_dsi_set(dsi
, LPCLKSET
, LPCLKSET_CKEN
);
530 rcar_mipi_dsi_set(dsi
, CFGCLKSET
, CFGCLKSET_CKEN
);
532 rcar_mipi_dsi_clr(dsi
, PHYSETUP
, PHYSETUP_RSTZ
);
533 rcar_mipi_dsi_clr(dsi
, PHYSETUP
, PHYSETUP_SHUTDOWNZ
);
535 rcar_mipi_dsi_set(dsi
, PHTC
, PHTC_TESTCLR
);
536 rcar_mipi_dsi_clr(dsi
, PHTC
, PHTC_TESTCLR
);
539 phy_setup
= rcar_mipi_dsi_read(dsi
, PHYSETUP
);
540 phy_setup
&= ~PHYSETUP_HSFREQRANGE_MASK
;
541 phy_setup
|= PHYSETUP_HSFREQRANGE(setup_info
.hsfreqrange
);
542 rcar_mipi_dsi_write(dsi
, PHYSETUP
, phy_setup
);
544 switch (dsi
->info
->model
) {
547 ret
= rcar_mipi_dsi_init_phtw_v3u(dsi
);
553 ret
= rcar_mipi_dsi_init_phtw_v4h(dsi
, &setup_info
);
559 /* PLL Clock Setting */
560 rcar_mipi_dsi_clr(dsi
, CLOCKSET1
, CLOCKSET1_SHADOW_CLEAR
);
561 rcar_mipi_dsi_set(dsi
, CLOCKSET1
, CLOCKSET1_SHADOW_CLEAR
);
562 rcar_mipi_dsi_clr(dsi
, CLOCKSET1
, CLOCKSET1_SHADOW_CLEAR
);
564 clockset2
= CLOCKSET2_M(setup_info
.m
- dsi
->info
->clockset2_m_offset
)
565 | CLOCKSET2_N(setup_info
.n
- 1)
566 | CLOCKSET2_VCO_CNTRL(setup_info
.clkset
->vco_cntrl
);
567 clockset3
= CLOCKSET3_PROP_CNTRL(setup_info
.clkset
->prop_cntrl
)
568 | CLOCKSET3_INT_CNTRL(setup_info
.clkset
->int_cntrl
)
569 | CLOCKSET3_CPBIAS_CNTRL(setup_info
.clkset
->cpbias_cntrl
)
570 | CLOCKSET3_GMP_CNTRL(setup_info
.clkset
->gmp_cntrl
);
571 rcar_mipi_dsi_write(dsi
, CLOCKSET2
, clockset2
);
572 rcar_mipi_dsi_write(dsi
, CLOCKSET3
, clockset3
);
574 rcar_mipi_dsi_clr(dsi
, CLOCKSET1
, CLOCKSET1_UPDATEPLL
);
575 rcar_mipi_dsi_set(dsi
, CLOCKSET1
, CLOCKSET1_UPDATEPLL
);
577 rcar_mipi_dsi_clr(dsi
, CLOCKSET1
, CLOCKSET1_UPDATEPLL
);
579 ppisetr
= PPISETR_DLEN_3
| PPISETR_CLEN
;
580 rcar_mipi_dsi_write(dsi
, PPISETR
, ppisetr
);
582 rcar_mipi_dsi_set(dsi
, PHYSETUP
, PHYSETUP_SHUTDOWNZ
);
583 rcar_mipi_dsi_set(dsi
, PHYSETUP
, PHYSETUP_RSTZ
);
584 usleep_range(400, 500);
586 /* Checking PPI clock status register */
587 for (timeout
= 10; timeout
> 0; --timeout
) {
588 if ((rcar_mipi_dsi_read(dsi
, PPICLSR
) & PPICLSR_STPST
) &&
589 (rcar_mipi_dsi_read(dsi
, PPIDLSR
) & PPIDLSR_STPST
) &&
590 (rcar_mipi_dsi_read(dsi
, CLOCKSET1
) & CLOCKSET1_LOCK
))
593 usleep_range(1000, 2000);
597 dev_err(dsi
->dev
, "failed to enable PPI clock\n");
601 switch (dsi
->info
->model
) {
604 ret
= rcar_mipi_dsi_post_init_phtw_v3u(dsi
);
610 ret
= rcar_mipi_dsi_post_init_phtw_v4h(dsi
, &setup_info
);
616 /* Enable DOT clock */
617 vclkset
= VCLKSET_CKEN
;
618 rcar_mipi_dsi_write(dsi
, VCLKSET
, vclkset
);
620 if (dsi_format
== 24)
621 vclkset
|= VCLKSET_BPP_24
;
622 else if (dsi_format
== 18)
623 vclkset
|= VCLKSET_BPP_18
;
624 else if (dsi_format
== 16)
625 vclkset
|= VCLKSET_BPP_16
;
627 dev_warn(dsi
->dev
, "unsupported format");
631 vclkset
|= VCLKSET_COLOR_RGB
| VCLKSET_LANE(dsi
->lanes
- 1);
633 switch (dsi
->info
->model
) {
636 vclkset
|= VCLKSET_DIV_V3U(__ffs(setup_info
.vclk_divider
));
640 vclkset
|= VCLKSET_DIV_V4H(__ffs(setup_info
.vclk_divider
) - 1);
644 rcar_mipi_dsi_write(dsi
, VCLKSET
, vclkset
);
646 /* After setting VCLKSET register, enable VCLKEN */
647 rcar_mipi_dsi_set(dsi
, VCLKEN
, VCLKEN_CKEN
);
649 dev_dbg(dsi
->dev
, "DSI device is started\n");
654 static void rcar_mipi_dsi_shutdown(struct rcar_mipi_dsi
*dsi
)
657 rcar_mipi_dsi_write(dsi
, VCLKSET
, 0);
659 /* Disable DOT clock */
660 rcar_mipi_dsi_write(dsi
, VCLKSET
, 0);
662 rcar_mipi_dsi_clr(dsi
, PHYSETUP
, PHYSETUP_RSTZ
);
663 rcar_mipi_dsi_clr(dsi
, PHYSETUP
, PHYSETUP_SHUTDOWNZ
);
666 rcar_mipi_dsi_clr(dsi
, CFGCLKSET
, CFGCLKSET_CKEN
);
669 rcar_mipi_dsi_clr(dsi
, LPCLKSET
, LPCLKSET_CKEN
);
671 dev_dbg(dsi
->dev
, "DSI device is shutdown\n");
674 static int rcar_mipi_dsi_clk_enable(struct rcar_mipi_dsi
*dsi
)
678 reset_control_deassert(dsi
->rstc
);
680 ret
= clk_prepare_enable(dsi
->clocks
.mod
);
684 ret
= clk_prepare_enable(dsi
->clocks
.dsi
);
691 clk_disable_unprepare(dsi
->clocks
.mod
);
693 reset_control_assert(dsi
->rstc
);
697 static void rcar_mipi_dsi_clk_disable(struct rcar_mipi_dsi
*dsi
)
699 clk_disable_unprepare(dsi
->clocks
.dsi
);
700 clk_disable_unprepare(dsi
->clocks
.mod
);
702 reset_control_assert(dsi
->rstc
);
705 static int rcar_mipi_dsi_start_hs_clock(struct rcar_mipi_dsi
*dsi
)
708 * In HW manual, we need to check TxDDRClkHS-Q Stable? but it dont
709 * write how to check. So we skip this check in this patch
714 /* Start HS clock. */
715 rcar_mipi_dsi_set(dsi
, PPICLCR
, PPICLCR_TXREQHS
);
717 ret
= read_poll_timeout(rcar_mipi_dsi_read
, status
,
718 status
& PPICLSR_TOHS
,
719 2000, 10000, false, dsi
, PPICLSR
);
721 dev_err(dsi
->dev
, "failed to enable HS clock\n");
725 rcar_mipi_dsi_set(dsi
, PPICLSCR
, PPICLSCR_TOHS
);
730 static int rcar_mipi_dsi_start_video(struct rcar_mipi_dsi
*dsi
)
735 /* Wait for the link to be ready. */
736 ret
= read_poll_timeout(rcar_mipi_dsi_read
, status
,
737 !(status
& (LINKSR_LPBUSY
| LINKSR_HSBUSY
)),
738 2000, 10000, false, dsi
, LINKSR
);
740 dev_err(dsi
->dev
, "Link failed to become ready\n");
744 /* De-assert video FIFO clear. */
745 rcar_mipi_dsi_clr(dsi
, TXVMCR
, TXVMCR_VFCLR
);
747 ret
= read_poll_timeout(rcar_mipi_dsi_read
, status
,
748 status
& TXVMSR_VFRDY
,
749 2000, 10000, false, dsi
, TXVMSR
);
751 dev_err(dsi
->dev
, "Failed to de-assert video FIFO clear\n");
755 /* Enable transmission in video mode. */
756 rcar_mipi_dsi_set(dsi
, TXVMCR
, TXVMCR_EN_VIDEO
);
758 ret
= read_poll_timeout(rcar_mipi_dsi_read
, status
,
760 2000, 10000, false, dsi
, TXVMSR
);
762 dev_err(dsi
->dev
, "Failed to enable video transmission\n");
769 static void rcar_mipi_dsi_stop_video(struct rcar_mipi_dsi
*dsi
)
774 /* Disable transmission in video mode. */
775 rcar_mipi_dsi_clr(dsi
, TXVMCR
, TXVMCR_EN_VIDEO
);
777 ret
= read_poll_timeout(rcar_mipi_dsi_read
, status
,
778 !(status
& TXVMSR_ACT
),
779 2000, 100000, false, dsi
, TXVMSR
);
781 dev_err(dsi
->dev
, "Failed to disable video transmission\n");
785 /* Assert video FIFO clear. */
786 rcar_mipi_dsi_set(dsi
, TXVMCR
, TXVMCR_VFCLR
);
788 ret
= read_poll_timeout(rcar_mipi_dsi_read
, status
,
789 !(status
& TXVMSR_VFRDY
),
790 2000, 100000, false, dsi
, TXVMSR
);
792 dev_err(dsi
->dev
, "Failed to assert video FIFO clear\n");
797 /* -----------------------------------------------------------------------------
801 static int rcar_mipi_dsi_attach(struct drm_bridge
*bridge
,
802 enum drm_bridge_attach_flags flags
)
804 struct rcar_mipi_dsi
*dsi
= bridge_to_rcar_mipi_dsi(bridge
);
806 return drm_bridge_attach(bridge
->encoder
, dsi
->next_bridge
, bridge
,
810 static void rcar_mipi_dsi_atomic_enable(struct drm_bridge
*bridge
,
811 struct drm_bridge_state
*old_bridge_state
)
813 struct rcar_mipi_dsi
*dsi
= bridge_to_rcar_mipi_dsi(bridge
);
815 rcar_mipi_dsi_start_video(dsi
);
818 static void rcar_mipi_dsi_atomic_disable(struct drm_bridge
*bridge
,
819 struct drm_bridge_state
*old_bridge_state
)
821 struct rcar_mipi_dsi
*dsi
= bridge_to_rcar_mipi_dsi(bridge
);
823 rcar_mipi_dsi_stop_video(dsi
);
826 void rcar_mipi_dsi_pclk_enable(struct drm_bridge
*bridge
,
827 struct drm_atomic_state
*state
)
829 struct rcar_mipi_dsi
*dsi
= bridge_to_rcar_mipi_dsi(bridge
);
830 const struct drm_display_mode
*mode
;
831 struct drm_connector
*connector
;
832 struct drm_crtc
*crtc
;
835 connector
= drm_atomic_get_new_connector_for_encoder(state
,
837 crtc
= drm_atomic_get_new_connector_state(state
, connector
)->crtc
;
838 mode
= &drm_atomic_get_new_crtc_state(state
, crtc
)->adjusted_mode
;
840 ret
= rcar_mipi_dsi_clk_enable(dsi
);
842 dev_err(dsi
->dev
, "failed to enable DSI clocks\n");
846 ret
= rcar_mipi_dsi_startup(dsi
, mode
);
848 goto err_dsi_startup
;
850 rcar_mipi_dsi_set_display_timing(dsi
, mode
);
852 ret
= rcar_mipi_dsi_start_hs_clock(dsi
);
854 goto err_dsi_start_hs
;
859 rcar_mipi_dsi_shutdown(dsi
);
861 rcar_mipi_dsi_clk_disable(dsi
);
863 EXPORT_SYMBOL_GPL(rcar_mipi_dsi_pclk_enable
);
865 void rcar_mipi_dsi_pclk_disable(struct drm_bridge
*bridge
)
867 struct rcar_mipi_dsi
*dsi
= bridge_to_rcar_mipi_dsi(bridge
);
869 rcar_mipi_dsi_shutdown(dsi
);
870 rcar_mipi_dsi_clk_disable(dsi
);
872 EXPORT_SYMBOL_GPL(rcar_mipi_dsi_pclk_disable
);
874 static enum drm_mode_status
875 rcar_mipi_dsi_bridge_mode_valid(struct drm_bridge
*bridge
,
876 const struct drm_display_info
*info
,
877 const struct drm_display_mode
*mode
)
879 if (mode
->clock
> 297000)
880 return MODE_CLOCK_HIGH
;
885 static const struct drm_bridge_funcs rcar_mipi_dsi_bridge_ops
= {
886 .attach
= rcar_mipi_dsi_attach
,
887 .atomic_duplicate_state
= drm_atomic_helper_bridge_duplicate_state
,
888 .atomic_destroy_state
= drm_atomic_helper_bridge_destroy_state
,
889 .atomic_reset
= drm_atomic_helper_bridge_reset
,
890 .atomic_enable
= rcar_mipi_dsi_atomic_enable
,
891 .atomic_disable
= rcar_mipi_dsi_atomic_disable
,
892 .mode_valid
= rcar_mipi_dsi_bridge_mode_valid
,
895 /* -----------------------------------------------------------------------------
899 static int rcar_mipi_dsi_host_attach(struct mipi_dsi_host
*host
,
900 struct mipi_dsi_device
*device
)
902 struct rcar_mipi_dsi
*dsi
= host_to_rcar_mipi_dsi(host
);
905 if (device
->lanes
> dsi
->num_data_lanes
)
908 dsi
->lanes
= device
->lanes
;
909 dsi
->format
= device
->format
;
911 dsi
->next_bridge
= devm_drm_of_get_bridge(dsi
->dev
, dsi
->dev
->of_node
,
913 if (IS_ERR(dsi
->next_bridge
)) {
914 ret
= PTR_ERR(dsi
->next_bridge
);
915 dev_err(dsi
->dev
, "failed to get next bridge: %d\n", ret
);
919 /* Initialize the DRM bridge. */
920 dsi
->bridge
.funcs
= &rcar_mipi_dsi_bridge_ops
;
921 dsi
->bridge
.of_node
= dsi
->dev
->of_node
;
922 drm_bridge_add(&dsi
->bridge
);
927 static int rcar_mipi_dsi_host_detach(struct mipi_dsi_host
*host
,
928 struct mipi_dsi_device
*device
)
930 struct rcar_mipi_dsi
*dsi
= host_to_rcar_mipi_dsi(host
);
932 drm_bridge_remove(&dsi
->bridge
);
937 static const struct mipi_dsi_host_ops rcar_mipi_dsi_host_ops
= {
938 .attach
= rcar_mipi_dsi_host_attach
,
939 .detach
= rcar_mipi_dsi_host_detach
,
942 /* -----------------------------------------------------------------------------
946 static int rcar_mipi_dsi_parse_dt(struct rcar_mipi_dsi
*dsi
)
950 ret
= drm_of_get_data_lanes_count_ep(dsi
->dev
->of_node
, 1, 0, 1, 4);
952 dev_err(dsi
->dev
, "missing or invalid data-lanes property\n");
956 dsi
->num_data_lanes
= ret
;
960 static struct clk
*rcar_mipi_dsi_get_clock(struct rcar_mipi_dsi
*dsi
,
966 clk
= devm_clk_get(dsi
->dev
, name
);
970 if (PTR_ERR(clk
) == -ENOENT
&& optional
)
973 dev_err_probe(dsi
->dev
, PTR_ERR(clk
), "failed to get %s clock\n",
974 name
? name
: "module");
979 static int rcar_mipi_dsi_get_clocks(struct rcar_mipi_dsi
*dsi
)
981 dsi
->clocks
.mod
= rcar_mipi_dsi_get_clock(dsi
, NULL
, false);
982 if (IS_ERR(dsi
->clocks
.mod
))
983 return PTR_ERR(dsi
->clocks
.mod
);
985 dsi
->clocks
.pll
= rcar_mipi_dsi_get_clock(dsi
, "pll", true);
986 if (IS_ERR(dsi
->clocks
.pll
))
987 return PTR_ERR(dsi
->clocks
.pll
);
989 dsi
->clocks
.dsi
= rcar_mipi_dsi_get_clock(dsi
, "dsi", true);
990 if (IS_ERR(dsi
->clocks
.dsi
))
991 return PTR_ERR(dsi
->clocks
.dsi
);
993 if (!dsi
->clocks
.pll
&& !dsi
->clocks
.dsi
) {
994 dev_err(dsi
->dev
, "no input clock (pll, dsi)\n");
1001 static int rcar_mipi_dsi_probe(struct platform_device
*pdev
)
1003 struct rcar_mipi_dsi
*dsi
;
1006 dsi
= devm_kzalloc(&pdev
->dev
, sizeof(*dsi
), GFP_KERNEL
);
1010 platform_set_drvdata(pdev
, dsi
);
1012 dsi
->dev
= &pdev
->dev
;
1013 dsi
->info
= of_device_get_match_data(&pdev
->dev
);
1015 ret
= rcar_mipi_dsi_parse_dt(dsi
);
1019 /* Acquire resources. */
1020 dsi
->mmio
= devm_platform_ioremap_resource(pdev
, 0);
1021 if (IS_ERR(dsi
->mmio
))
1022 return PTR_ERR(dsi
->mmio
);
1024 ret
= rcar_mipi_dsi_get_clocks(dsi
);
1028 dsi
->rstc
= devm_reset_control_get(dsi
->dev
, NULL
);
1029 if (IS_ERR(dsi
->rstc
)) {
1030 dev_err(dsi
->dev
, "failed to get cpg reset\n");
1031 return PTR_ERR(dsi
->rstc
);
1034 /* Initialize the DSI host. */
1035 dsi
->host
.dev
= dsi
->dev
;
1036 dsi
->host
.ops
= &rcar_mipi_dsi_host_ops
;
1037 ret
= mipi_dsi_host_register(&dsi
->host
);
1044 static void rcar_mipi_dsi_remove(struct platform_device
*pdev
)
1046 struct rcar_mipi_dsi
*dsi
= platform_get_drvdata(pdev
);
1048 mipi_dsi_host_unregister(&dsi
->host
);
1051 static const struct rcar_mipi_dsi_device_info v3u_data
= {
1052 .model
= RCAR_DSI_V3U
,
1053 .clk_cfg
= dsi_clk_cfg_v3u
,
1054 .clockset2_m_offset
= 2,
1062 .fout_min
= MHZ(320),
1063 .fout_max
= MHZ(1250),
1066 static const struct rcar_mipi_dsi_device_info v4h_data
= {
1067 .model
= RCAR_DSI_V4H
,
1068 .clk_cfg
= dsi_clk_cfg_v4h
,
1069 .clockset2_m_offset
= 0,
1074 .fpfd_max
= MHZ(24),
1077 .fout_min
= MHZ(2000),
1078 .fout_max
= MHZ(4000),
1081 static const struct of_device_id rcar_mipi_dsi_of_table
[] = {
1082 { .compatible
= "renesas,r8a779a0-dsi-csi2-tx", .data
= &v3u_data
},
1083 { .compatible
= "renesas,r8a779g0-dsi-csi2-tx", .data
= &v4h_data
},
1087 MODULE_DEVICE_TABLE(of
, rcar_mipi_dsi_of_table
);
1089 static struct platform_driver rcar_mipi_dsi_platform_driver
= {
1090 .probe
= rcar_mipi_dsi_probe
,
1091 .remove
= rcar_mipi_dsi_remove
,
1093 .name
= "rcar-mipi-dsi",
1094 .of_match_table
= rcar_mipi_dsi_of_table
,
1098 module_platform_driver(rcar_mipi_dsi_platform_driver
);
1100 MODULE_DESCRIPTION("Renesas R-Car MIPI DSI Encoder Driver");
1101 MODULE_LICENSE("GPL");