blob: fd885ac8ccb69c5ea1d0ab62f535a6a4439a659b [file] [log] [blame]
Chris Morgan8895dd32023-03-24 13:53:07 -05001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Author(s): Chris Morgan <macromorgan@hotmail.com>
4 *
5 * This MIPI DSI controller driver is heavily based on the Linux Kernel
6 * driver from drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c and the
7 * U-Boot driver from drivers/video/stm32/stm32_dsi.c.
8 */
9
10#define LOG_CATEGORY UCLASS_VIDEO_BRIDGE
11
12#include <clk.h>
13#include <dm.h>
14#include <div64.h>
15#include <dsi_host.h>
16#include <generic-phy.h>
17#include <mipi_dsi.h>
18#include <panel.h>
19#include <phy-mipi-dphy.h>
20#include <reset.h>
21#include <video_bridge.h>
22#include <dm/device_compat.h>
23#include <dm/lists.h>
24#include <linux/iopoll.h>
25
26#include <common.h>
27#include <log.h>
28#include <video.h>
29#include <asm/io.h>
30#include <dm/device-internal.h>
31#include <linux/bitops.h>
32
33#define USEC_PER_SEC 1000000L
34
35/*
36 * DSI wrapper registers & bit definitions
37 * Note: registers are named as in the Reference Manual
38 */
39#define DSI_WCR 0x0404 /* Wrapper Control Reg */
40#define WCR_DSIEN BIT(3) /* DSI ENable */
41
42#define DSI_PHY_TST_CTRL0 0xb4
43#define PHY_TESTCLK BIT(1)
44#define PHY_UNTESTCLK 0
45#define PHY_TESTCLR BIT(0)
46#define PHY_UNTESTCLR 0
47
48#define DSI_PHY_TST_CTRL1 0xb8
49#define PHY_TESTEN BIT(16)
50#define PHY_UNTESTEN 0
51#define PHY_TESTDOUT(n) (((n) & 0xff) << 8)
52#define PHY_TESTDIN(n) (((n) & 0xff) << 0)
53
54#define BYPASS_VCO_RANGE BIT(7)
55#define VCO_RANGE_CON_SEL(val) (((val) & 0x7) << 3)
56#define VCO_IN_CAP_CON_DEFAULT (0x0 << 1)
57#define VCO_IN_CAP_CON_LOW (0x1 << 1)
58#define VCO_IN_CAP_CON_HIGH (0x2 << 1)
59#define REF_BIAS_CUR_SEL BIT(0)
60
61#define CP_CURRENT_3UA 0x1
62#define CP_CURRENT_4_5UA 0x2
63#define CP_CURRENT_7_5UA 0x6
64#define CP_CURRENT_6UA 0x9
65#define CP_CURRENT_12UA 0xb
66#define CP_CURRENT_SEL(val) ((val) & 0xf)
67#define CP_PROGRAM_EN BIT(7)
68
69#define LPF_RESISTORS_15_5KOHM 0x1
70#define LPF_RESISTORS_13KOHM 0x2
71#define LPF_RESISTORS_11_5KOHM 0x4
72#define LPF_RESISTORS_10_5KOHM 0x8
73#define LPF_RESISTORS_8KOHM 0x10
74#define LPF_PROGRAM_EN BIT(6)
75#define LPF_RESISTORS_SEL(val) ((val) & 0x3f)
76
77#define HSFREQRANGE_SEL(val) (((val) & 0x3f) << 1)
78
79#define INPUT_DIVIDER(val) (((val) - 1) & 0x7f)
80#define LOW_PROGRAM_EN 0
81#define HIGH_PROGRAM_EN BIT(7)
82#define LOOP_DIV_LOW_SEL(val) (((val) - 1) & 0x1f)
83#define LOOP_DIV_HIGH_SEL(val) ((((val) - 1) >> 5) & 0xf)
84#define PLL_LOOP_DIV_EN BIT(5)
85#define PLL_INPUT_DIV_EN BIT(4)
86
87#define POWER_CONTROL BIT(6)
88#define INTERNAL_REG_CURRENT BIT(3)
89#define BIAS_BLOCK_ON BIT(2)
90#define BANDGAP_ON BIT(0)
91
92#define TER_RESISTOR_HIGH BIT(7)
93#define TER_RESISTOR_LOW 0
94#define LEVEL_SHIFTERS_ON BIT(6)
95#define TER_CAL_DONE BIT(5)
96#define SETRD_MAX (0x7 << 2)
97#define POWER_MANAGE BIT(1)
98#define TER_RESISTORS_ON BIT(0)
99
100#define BIASEXTR_SEL(val) ((val) & 0x7)
101#define BANDGAP_SEL(val) ((val) & 0x7)
102#define TLP_PROGRAM_EN BIT(7)
103#define THS_PRE_PROGRAM_EN BIT(7)
104#define THS_ZERO_PROGRAM_EN BIT(6)
105
106#define PLL_BIAS_CUR_SEL_CAP_VCO_CONTROL 0x10
107#define PLL_CP_CONTROL_PLL_LOCK_BYPASS 0x11
108#define PLL_LPF_AND_CP_CONTROL 0x12
109#define PLL_INPUT_DIVIDER_RATIO 0x17
110#define PLL_LOOP_DIVIDER_RATIO 0x18
111#define PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL 0x19
112#define BANDGAP_AND_BIAS_CONTROL 0x20
113#define TERMINATION_RESISTER_CONTROL 0x21
114#define AFE_BIAS_BANDGAP_ANALOG_PROGRAMMABILITY 0x22
115#define HS_RX_CONTROL_OF_LANE_CLK 0x34
116#define HS_RX_CONTROL_OF_LANE_0 0x44
117#define HS_RX_CONTROL_OF_LANE_1 0x54
118#define HS_TX_CLOCK_LANE_REQUEST_STATE_TIME_CONTROL 0x60
119#define HS_TX_CLOCK_LANE_PREPARE_STATE_TIME_CONTROL 0x61
120#define HS_TX_CLOCK_LANE_HS_ZERO_STATE_TIME_CONTROL 0x62
121#define HS_TX_CLOCK_LANE_TRAIL_STATE_TIME_CONTROL 0x63
122#define HS_TX_CLOCK_LANE_EXIT_STATE_TIME_CONTROL 0x64
123#define HS_TX_CLOCK_LANE_POST_TIME_CONTROL 0x65
124#define HS_TX_DATA_LANE_REQUEST_STATE_TIME_CONTROL 0x70
125#define HS_TX_DATA_LANE_PREPARE_STATE_TIME_CONTROL 0x71
126#define HS_TX_DATA_LANE_HS_ZERO_STATE_TIME_CONTROL 0x72
127#define HS_TX_DATA_LANE_TRAIL_STATE_TIME_CONTROL 0x73
128#define HS_TX_DATA_LANE_EXIT_STATE_TIME_CONTROL 0x74
129#define HS_RX_DATA_LANE_THS_SETTLE_CONTROL 0x75
130#define HS_RX_CONTROL_OF_LANE_2 0x84
131#define HS_RX_CONTROL_OF_LANE_3 0x94
132
133#define RK3568_GRF_VO_CON2 0x0368
134#define RK3568_DSI0_SKEWCALHS (0x1f << 11)
135#define RK3568_DSI0_FORCETXSTOPMODE (0xf << 4)
136#define RK3568_DSI0_TURNDISABLE BIT(2)
137#define RK3568_DSI0_FORCERXMODE BIT(0)
138
139/*
140 * Note these registers do not appear in the datasheet, they are
141 * however present in the BSP driver which is where these values
142 * come from. Name GRF_VO_CON3 is assumed.
143 */
144#define RK3568_GRF_VO_CON3 0x36c
145#define RK3568_DSI1_SKEWCALHS (0x1f << 11)
146#define RK3568_DSI1_FORCETXSTOPMODE (0xf << 4)
147#define RK3568_DSI1_TURNDISABLE BIT(2)
148#define RK3568_DSI1_FORCERXMODE BIT(0)
149
150#define HIWORD_UPDATE(val, mask) (val | (mask) << 16)
151
152/* Timeout for regulator on/off, pll lock/unlock & fifo empty */
153#define TIMEOUT_US 200000
154
155enum {
156 BANDGAP_97_07,
157 BANDGAP_98_05,
158 BANDGAP_99_02,
159 BANDGAP_100_00,
160 BANDGAP_93_17,
161 BANDGAP_94_15,
162 BANDGAP_95_12,
163 BANDGAP_96_10,
164};
165
166enum {
167 BIASEXTR_87_1,
168 BIASEXTR_91_5,
169 BIASEXTR_95_9,
170 BIASEXTR_100,
171 BIASEXTR_105_94,
172 BIASEXTR_111_88,
173 BIASEXTR_118_8,
174 BIASEXTR_127_7,
175};
176
177struct rockchip_dw_dsi_chip_data {
178 u32 reg;
179
180 u32 lcdsel_grf_reg;
181 u32 lcdsel_big;
182 u32 lcdsel_lit;
183
184 u32 enable_grf_reg;
185 u32 enable;
186
187 u32 lanecfg1_grf_reg;
188 u32 lanecfg1;
189 u32 lanecfg2_grf_reg;
190 u32 lanecfg2;
191
192 unsigned int flags;
193 unsigned int max_data_lanes;
194};
195
196struct dw_rockchip_dsi_priv {
197 struct mipi_dsi_device device;
198 void __iomem *base;
199 struct udevice *panel;
200
201 /* Optional external dphy */
202 struct phy phy;
203 struct phy_configure_opts_mipi_dphy phy_opts;
204
205 struct clk *pclk;
206 struct clk *ref;
207 struct reset_ctl *rst;
208 unsigned int lane_mbps; /* per lane */
209 u16 input_div;
210 u16 feedback_div;
211 const struct rockchip_dw_dsi_chip_data *cdata;
212 struct udevice *dsi_host;
213};
214
215static inline void dsi_write(struct dw_rockchip_dsi_priv *dsi, u32 reg, u32 val)
216{
217 writel(val, dsi->base + reg);
218}
219
220static inline u32 dsi_read(struct dw_rockchip_dsi_priv *dsi, u32 reg)
221{
222 return readl(dsi->base + reg);
223}
224
225static inline void dsi_set(struct dw_rockchip_dsi_priv *dsi, u32 reg, u32 mask)
226{
227 dsi_write(dsi, reg, dsi_read(dsi, reg) | mask);
228}
229
230static inline void dsi_clear(struct dw_rockchip_dsi_priv *dsi, u32 reg, u32 mask)
231{
232 dsi_write(dsi, reg, dsi_read(dsi, reg) & ~mask);
233}
234
235static inline void dsi_update_bits(struct dw_rockchip_dsi_priv *dsi, u32 reg,
236 u32 mask, u32 val)
237{
238 dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val);
239}
240
241static void dw_mipi_dsi_phy_write(struct dw_rockchip_dsi_priv *dsi,
242 u8 test_code,
243 u8 test_data)
244{
245 /*
246 * With the falling edge on TESTCLK, the TESTDIN[7:0] signal content
247 * is latched internally as the current test code. Test data is
248 * programmed internally by rising edge on TESTCLK.
249 */
250 dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK | PHY_UNTESTCLR);
251
252 dsi_write(dsi, DSI_PHY_TST_CTRL1, PHY_TESTEN | PHY_TESTDOUT(0) |
253 PHY_TESTDIN(test_code));
254
255 dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLK | PHY_UNTESTCLR);
256
257 dsi_write(dsi, DSI_PHY_TST_CTRL1, PHY_UNTESTEN | PHY_TESTDOUT(0) |
258 PHY_TESTDIN(test_data));
259
260 dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK | PHY_UNTESTCLR);
261}
262
263struct dphy_pll_parameter_map {
264 unsigned int max_mbps;
265 u8 hsfreqrange;
266 u8 icpctrl;
267 u8 lpfctrl;
268};
269
270/* The table is based on 27MHz DPHY pll reference clock. */
271static const struct dphy_pll_parameter_map dppa_map[] = {
272 { 89, 0x00, CP_CURRENT_3UA, LPF_RESISTORS_13KOHM },
273 { 99, 0x10, CP_CURRENT_3UA, LPF_RESISTORS_13KOHM },
274 { 109, 0x20, CP_CURRENT_3UA, LPF_RESISTORS_13KOHM },
275 { 129, 0x01, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM },
276 { 139, 0x11, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM },
277 { 149, 0x21, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM },
278 { 169, 0x02, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM },
279 { 179, 0x12, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM },
280 { 199, 0x22, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM },
281 { 219, 0x03, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM },
282 { 239, 0x13, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM },
283 { 249, 0x23, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM },
284 { 269, 0x04, CP_CURRENT_6UA, LPF_RESISTORS_11_5KOHM },
285 { 299, 0x14, CP_CURRENT_6UA, LPF_RESISTORS_11_5KOHM },
286 { 329, 0x05, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM },
287 { 359, 0x15, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM },
288 { 399, 0x25, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM },
289 { 449, 0x06, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM },
290 { 499, 0x16, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM },
291 { 549, 0x07, CP_CURRENT_7_5UA, LPF_RESISTORS_10_5KOHM },
292 { 599, 0x17, CP_CURRENT_7_5UA, LPF_RESISTORS_10_5KOHM },
293 { 649, 0x08, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM },
294 { 699, 0x18, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM },
295 { 749, 0x09, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM },
296 { 799, 0x19, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM },
297 { 849, 0x29, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM },
298 { 899, 0x39, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM },
299 { 949, 0x0a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM },
300 { 999, 0x1a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM },
301 {1049, 0x2a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM },
302 {1099, 0x3a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM },
303 {1149, 0x0b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM },
304 {1199, 0x1b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM },
305 {1249, 0x2b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM },
306 {1299, 0x3b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM },
307 {1349, 0x0c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM },
308 {1399, 0x1c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM },
309 {1449, 0x2c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM },
310 {1500, 0x3c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM }
311};
312
313static int max_mbps_to_parameter(unsigned int max_mbps)
314{
315 int i;
316
317 for (i = 0; i < ARRAY_SIZE(dppa_map); i++)
318 if (dppa_map[i].max_mbps >= max_mbps)
319 return i;
320
321 return -EINVAL;
322}
323
324/*
325 * ns2bc - Nanoseconds to byte clock cycles
326 */
327static inline unsigned int ns2bc(struct dw_rockchip_dsi_priv *dsi, int ns)
328{
329 return DIV_ROUND_UP(ns * dsi->lane_mbps / 8, 1000);
330}
331
332/*
333 * ns2ui - Nanoseconds to UI time periods
334 */
335static inline unsigned int ns2ui(struct dw_rockchip_dsi_priv *dsi, int ns)
336{
337 return DIV_ROUND_UP(ns * dsi->lane_mbps, 1000);
338}
339
340static int dsi_phy_init(void *priv_data)
341{
342 struct mipi_dsi_device *device = priv_data;
343 struct udevice *dev = device->dev;
344 struct dw_rockchip_dsi_priv *dsi = dev_get_priv(dev);
345 int ret, i, vco;
346
Ondrej Jirman6518b732023-05-22 23:47:03 +0200347 if (dsi->phy.dev) {
Chris Morgan8895dd32023-03-24 13:53:07 -0500348 ret = generic_phy_configure(&dsi->phy, &dsi->phy_opts);
349 if (ret) {
350 dev_err(dsi->dsi_host,
351 "Configure external dphy fail %d\n",
352 ret);
353 return ret;
354 }
355
356 ret = generic_phy_power_on(&dsi->phy);
357 if (ret) {
358 dev_err(dsi->dsi_host,
359 "Generic phy power on fail %d\n", ret);
360 return ret;
361 }
362
363 return 0;
364 }
365
366 /*
367 * Get vco from frequency(lane_mbps)
368 * vco frequency table
369 * 000 - between 80 and 200 MHz
370 * 001 - between 200 and 300 MHz
371 * 010 - between 300 and 500 MHz
372 * 011 - between 500 and 700 MHz
373 * 100 - between 700 and 900 MHz
374 * 101 - between 900 and 1100 MHz
375 * 110 - between 1100 and 1300 MHz
376 * 111 - between 1300 and 1500 MHz
377 */
378 vco = (dsi->lane_mbps < 200) ? 0 : (dsi->lane_mbps + 100) / 200;
379
380 i = max_mbps_to_parameter(dsi->lane_mbps);
381 if (i < 0) {
382 dev_err(dsi->dsi_host,
383 "failed to get parameter for %dmbps clock\n",
384 dsi->lane_mbps);
385 return i;
386 }
387
388 dw_mipi_dsi_phy_write(dsi, PLL_BIAS_CUR_SEL_CAP_VCO_CONTROL,
389 BYPASS_VCO_RANGE |
390 VCO_RANGE_CON_SEL(vco) |
391 VCO_IN_CAP_CON_LOW |
392 REF_BIAS_CUR_SEL);
393
394 dw_mipi_dsi_phy_write(dsi, PLL_CP_CONTROL_PLL_LOCK_BYPASS,
395 CP_CURRENT_SEL(dppa_map[i].icpctrl));
396 dw_mipi_dsi_phy_write(dsi, PLL_LPF_AND_CP_CONTROL,
397 CP_PROGRAM_EN | LPF_PROGRAM_EN |
398 LPF_RESISTORS_SEL(dppa_map[i].lpfctrl));
399
400 dw_mipi_dsi_phy_write(dsi, HS_RX_CONTROL_OF_LANE_0,
401 HSFREQRANGE_SEL(dppa_map[i].hsfreqrange));
402
403 dw_mipi_dsi_phy_write(dsi, PLL_INPUT_DIVIDER_RATIO,
404 INPUT_DIVIDER(dsi->input_div));
405 dw_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO,
406 LOOP_DIV_LOW_SEL(dsi->feedback_div) |
407 LOW_PROGRAM_EN);
408 /*
409 * We need set PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL immediately
410 * to make the configured LSB effective according to IP simulation
411 * and lab test results.
412 * Only in this way can we get correct mipi phy pll frequency.
413 */
414 dw_mipi_dsi_phy_write(dsi, PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL,
415 PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);
416 dw_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO,
417 LOOP_DIV_HIGH_SEL(dsi->feedback_div) |
418 HIGH_PROGRAM_EN);
419 dw_mipi_dsi_phy_write(dsi, PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL,
420 PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);
421
422 dw_mipi_dsi_phy_write(dsi, AFE_BIAS_BANDGAP_ANALOG_PROGRAMMABILITY,
423 LOW_PROGRAM_EN | BIASEXTR_SEL(BIASEXTR_127_7));
424 dw_mipi_dsi_phy_write(dsi, AFE_BIAS_BANDGAP_ANALOG_PROGRAMMABILITY,
425 HIGH_PROGRAM_EN | BANDGAP_SEL(BANDGAP_96_10));
426
427 dw_mipi_dsi_phy_write(dsi, BANDGAP_AND_BIAS_CONTROL,
428 POWER_CONTROL | INTERNAL_REG_CURRENT |
429 BIAS_BLOCK_ON | BANDGAP_ON);
430
431 dw_mipi_dsi_phy_write(dsi, TERMINATION_RESISTER_CONTROL,
432 TER_RESISTOR_LOW | TER_CAL_DONE |
433 SETRD_MAX | TER_RESISTORS_ON);
434 dw_mipi_dsi_phy_write(dsi, TERMINATION_RESISTER_CONTROL,
435 TER_RESISTOR_HIGH | LEVEL_SHIFTERS_ON |
436 SETRD_MAX | POWER_MANAGE |
437 TER_RESISTORS_ON);
438
439 dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_REQUEST_STATE_TIME_CONTROL,
440 TLP_PROGRAM_EN | ns2bc(dsi, 500));
441 dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_PREPARE_STATE_TIME_CONTROL,
442 THS_PRE_PROGRAM_EN | ns2ui(dsi, 40));
443 dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_HS_ZERO_STATE_TIME_CONTROL,
444 THS_ZERO_PROGRAM_EN | ns2bc(dsi, 300));
445 dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_TRAIL_STATE_TIME_CONTROL,
446 THS_PRE_PROGRAM_EN | ns2ui(dsi, 100));
447 dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_EXIT_STATE_TIME_CONTROL,
448 BIT(5) | ns2bc(dsi, 100));
449 dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_POST_TIME_CONTROL,
450 BIT(5) | (ns2bc(dsi, 60) + 7));
451
452 dw_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_REQUEST_STATE_TIME_CONTROL,
453 TLP_PROGRAM_EN | ns2bc(dsi, 500));
454 dw_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_PREPARE_STATE_TIME_CONTROL,
455 THS_PRE_PROGRAM_EN | (ns2ui(dsi, 50) + 20));
456 dw_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_HS_ZERO_STATE_TIME_CONTROL,
457 THS_ZERO_PROGRAM_EN | (ns2bc(dsi, 140) + 2));
458 dw_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_TRAIL_STATE_TIME_CONTROL,
459 THS_PRE_PROGRAM_EN | (ns2ui(dsi, 60) + 8));
460 dw_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_EXIT_STATE_TIME_CONTROL,
461 BIT(5) | ns2bc(dsi, 100));
462
Ondrej Jirmanc6835442023-05-22 23:47:05 +0200463 return 0;
Chris Morgan8895dd32023-03-24 13:53:07 -0500464}
465
466static void dsi_phy_post_set_mode(void *priv_data, unsigned long mode_flags)
467{
468 struct mipi_dsi_device *device = priv_data;
469 struct udevice *dev = device->dev;
470 struct dw_rockchip_dsi_priv *dsi = dev_get_priv(dev);
471
472 dev_dbg(dev, "Set mode %p enable %ld\n", dsi,
473 mode_flags & MIPI_DSI_MODE_VIDEO);
474
475 if (!dsi)
476 return;
477
478 /*
479 * DSI wrapper must be enabled in video mode & disabled in command mode.
480 * If wrapper is enabled in command mode, the display controller
481 * register access will hang. Note that this was carried over from the
482 * stm32 dsi driver and is unknown if necessary for Rockchip.
483 */
484
485 if (mode_flags & MIPI_DSI_MODE_VIDEO)
486 dsi_set(dsi, DSI_WCR, WCR_DSIEN);
487 else
488 dsi_clear(dsi, DSI_WCR, WCR_DSIEN);
489}
490
491static int
492dw_mipi_dsi_get_lane_mbps(void *priv_data, struct display_timing *timings,
493 u32 lanes, u32 format, unsigned int *lane_mbps)
494{
495 struct mipi_dsi_device *device = priv_data;
496 struct udevice *dev = device->dev;
497 struct dw_rockchip_dsi_priv *dsi = dev_get_priv(dev);
498 int bpp;
499 unsigned long mpclk, tmp;
500 unsigned int target_mbps = 1000;
501 unsigned int max_mbps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps;
502 unsigned long best_freq = 0;
503 unsigned long fvco_min, fvco_max, fin, fout;
504 unsigned int min_prediv, max_prediv;
505 unsigned int _prediv, best_prediv;
506 unsigned long _fbdiv, best_fbdiv;
507 unsigned long min_delta = ULONG_MAX;
Chris Morgan8895dd32023-03-24 13:53:07 -0500508
509 bpp = mipi_dsi_pixel_format_to_bpp(format);
510 if (bpp < 0) {
511 dev_err(dsi->dsi_host,
512 "failed to get bpp for pixel format %d\n",
513 format);
514 return bpp;
515 }
516
517 mpclk = DIV_ROUND_UP(timings->pixelclock.typ, 1000);
518 if (mpclk) {
519 /* take 1 / 0.8, since mbps must big than bandwidth of RGB */
520 tmp = (mpclk * (bpp / lanes) * 10 / 8) / 1000;
521 if (tmp < max_mbps)
522 target_mbps = tmp;
523 else
524 dev_err(dsi->dsi_host,
525 "DPHY clock frequency is out of range\n");
526 }
527
528 /* for external phy only the mipi_dphy_config is necessary */
Ondrej Jirman6518b732023-05-22 23:47:03 +0200529 if (dsi->phy.dev) {
Chris Morgan8895dd32023-03-24 13:53:07 -0500530 phy_mipi_dphy_get_default_config(timings->pixelclock.typ * 10 / 8,
531 bpp, lanes,
532 &dsi->phy_opts);
533 dsi->lane_mbps = target_mbps;
534 *lane_mbps = dsi->lane_mbps;
535
536 return 0;
537 }
538
Ondrej Jirmanc27db342023-05-22 23:47:06 +0200539 fin = clk_get_rate(dsi->ref);
Chris Morgan8895dd32023-03-24 13:53:07 -0500540 fout = target_mbps * USEC_PER_SEC;
541
542 /* constraint: 5Mhz <= Fref / N <= 40MHz */
543 min_prediv = DIV_ROUND_UP(fin, 40 * USEC_PER_SEC);
544 max_prediv = fin / (5 * USEC_PER_SEC);
545
546 /* constraint: 80MHz <= Fvco <= 1500Mhz */
547 fvco_min = 80 * USEC_PER_SEC;
548 fvco_max = 1500 * USEC_PER_SEC;
549
550 for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) {
551 u64 tmp;
552 u32 delta;
553 /* Fvco = Fref * M / N */
554 tmp = (u64)fout * _prediv;
555 do_div(tmp, fin);
556 _fbdiv = tmp;
557 /*
558 * Due to the use of a "by 2 pre-scaler," the range of the
559 * feedback multiplication value M is limited to even division
560 * numbers, and m must be greater than 6, not bigger than 512.
561 */
562 if (_fbdiv < 6 || _fbdiv > 512)
563 continue;
564
565 _fbdiv += _fbdiv % 2;
566
567 tmp = (u64)_fbdiv * fin;
568 do_div(tmp, _prediv);
569 if (tmp < fvco_min || tmp > fvco_max)
570 continue;
571
572 delta = abs(fout - tmp);
573 if (delta < min_delta) {
574 best_prediv = _prediv;
575 best_fbdiv = _fbdiv;
576 min_delta = delta;
577 best_freq = tmp;
578 }
579 }
580
581 if (best_freq) {
582 dsi->lane_mbps = DIV_ROUND_UP(best_freq, USEC_PER_SEC);
583 *lane_mbps = dsi->lane_mbps;
584 dsi->input_div = best_prediv;
585 dsi->feedback_div = best_fbdiv;
586 } else {
587 dev_err(dsi->dsi_host, "Can not find best_freq for DPHY\n");
588 return -EINVAL;
589 }
590
591 return 0;
592}
593
594struct hstt {
595 unsigned int maxfreq;
596 struct mipi_dsi_phy_timing timing;
597};
598
599#define HSTT(_maxfreq, _c_lp2hs, _c_hs2lp, _d_lp2hs, _d_hs2lp) \
600{ \
601 .maxfreq = _maxfreq, \
602 .timing = { \
603 .clk_lp2hs = _c_lp2hs, \
604 .clk_hs2lp = _c_hs2lp, \
605 .data_lp2hs = _d_lp2hs, \
606 .data_hs2lp = _d_hs2lp, \
607 } \
608}
609
610/*
611 * Table A-3 High-Speed Transition Times
612 * (Note spacing is deliberate for readability).
613 */
614static struct hstt hstt_table[] = {
615 HSTT( 90, 32, 20, 26, 13),
616 HSTT( 100, 35, 23, 28, 14),
617 HSTT( 110, 32, 22, 26, 13),
618 HSTT( 130, 31, 20, 27, 13),
619 HSTT( 140, 33, 22, 26, 14),
620 HSTT( 150, 33, 21, 26, 14),
621 HSTT( 170, 32, 20, 27, 13),
622 HSTT( 180, 36, 23, 30, 15),
623 HSTT( 200, 40, 22, 33, 15),
624 HSTT( 220, 40, 22, 33, 15),
625 HSTT( 240, 44, 24, 36, 16),
626 HSTT( 250, 48, 24, 38, 17),
627 HSTT( 270, 48, 24, 38, 17),
628 HSTT( 300, 50, 27, 41, 18),
629 HSTT( 330, 56, 28, 45, 18),
630 HSTT( 360, 59, 28, 48, 19),
631 HSTT( 400, 61, 30, 50, 20),
632 HSTT( 450, 67, 31, 55, 21),
633 HSTT( 500, 73, 31, 59, 22),
634 HSTT( 550, 79, 36, 63, 24),
635 HSTT( 600, 83, 37, 68, 25),
636 HSTT( 650, 90, 38, 73, 27),
637 HSTT( 700, 95, 40, 77, 28),
638 HSTT( 750, 102, 40, 84, 28),
639 HSTT( 800, 106, 42, 87, 30),
640 HSTT( 850, 113, 44, 93, 31),
641 HSTT( 900, 118, 47, 98, 32),
642 HSTT( 950, 124, 47, 102, 34),
643 HSTT(1000, 130, 49, 107, 35),
644 HSTT(1050, 135, 51, 111, 37),
645 HSTT(1100, 139, 51, 114, 38),
646 HSTT(1150, 146, 54, 120, 40),
647 HSTT(1200, 153, 57, 125, 41),
648 HSTT(1250, 158, 58, 130, 42),
649 HSTT(1300, 163, 58, 135, 44),
650 HSTT(1350, 168, 60, 140, 45),
651 HSTT(1400, 172, 64, 144, 47),
652 HSTT(1450, 176, 65, 148, 48),
653 HSTT(1500, 181, 66, 153, 50)
654};
655
656static int dw_mipi_dsi_rockchip_get_timing(void *priv_data,
657 unsigned int lane_mbps,
658 struct mipi_dsi_phy_timing *timing)
659{
660 int i;
661
662 for (i = 0; i < ARRAY_SIZE(hstt_table); i++)
663 if (lane_mbps < hstt_table[i].maxfreq)
664 break;
665
666 if (i == ARRAY_SIZE(hstt_table))
667 i--;
668
669 *timing = hstt_table[i].timing;
670
671 return 0;
672}
673
674static const struct mipi_dsi_phy_ops dsi_rockchip_phy_ops = {
675 .init = dsi_phy_init,
676 .get_lane_mbps = dw_mipi_dsi_get_lane_mbps,
677 .get_timing = dw_mipi_dsi_rockchip_get_timing,
678 .post_set_mode = dsi_phy_post_set_mode,
679};
680
681static int dw_mipi_dsi_rockchip_attach(struct udevice *dev)
682{
683 struct dw_rockchip_dsi_priv *priv = dev_get_priv(dev);
684 struct mipi_dsi_device *device = &priv->device;
685 struct mipi_dsi_panel_plat *mplat;
686 struct display_timing timings;
687 int ret;
688
689 ret = uclass_first_device_err(UCLASS_PANEL, &priv->panel);
690 if (ret) {
691 dev_err(dev, "panel device error %d\n", ret);
692 return ret;
693 }
694
695 mplat = dev_get_plat(priv->panel);
696 mplat->device = &priv->device;
697 device->lanes = mplat->lanes;
698 device->format = mplat->format;
699 device->mode_flags = mplat->mode_flags;
700
701 ret = panel_get_display_timing(priv->panel, &timings);
702 if (ret) {
703 ret = ofnode_decode_display_timing(dev_ofnode(priv->panel),
704 0, &timings);
705 if (ret) {
706 dev_err(dev, "decode display timing error %d\n", ret);
707 return ret;
708 }
709 }
710
711 ret = uclass_get_device(UCLASS_DSI_HOST, 0, &priv->dsi_host);
712 if (ret) {
713 dev_err(dev, "No video dsi host detected %d\n", ret);
714 return ret;
715 }
716
717 ret = dsi_host_init(priv->dsi_host, device, &timings, 4,
718 &dsi_rockchip_phy_ops);
719 if (ret) {
720 dev_err(dev, "failed to initialize mipi dsi host\n");
721 return ret;
722 }
723
724 return 0;
725}
726
727static int dw_mipi_dsi_rockchip_set_bl(struct udevice *dev, int percent)
728{
729 struct dw_rockchip_dsi_priv *priv = dev_get_priv(dev);
730 int ret;
731
732 /*
733 * Allow backlight to be optional, since this driver may be
734 * used to simply detect a panel rather than bring one up.
735 */
736 ret = panel_enable_backlight(priv->panel);
737 if ((ret) && (ret != -ENOSYS)) {
738 dev_err(dev, "panel %s enable backlight error %d\n",
739 priv->panel->name, ret);
740 return ret;
741 }
742
743 ret = dsi_host_enable(priv->dsi_host);
744 if (ret) {
745 dev_err(dev, "failed to enable mipi dsi host\n");
746 return ret;
747 }
748
749 return 0;
750}
751
752static void dw_mipi_dsi_rockchip_config(struct dw_rockchip_dsi_priv *dsi)
753{
754 if (dsi->cdata->lanecfg1_grf_reg)
755 dsi_write(dsi, dsi->cdata->lanecfg1_grf_reg,
756 dsi->cdata->lanecfg1);
757
758 if (dsi->cdata->lanecfg2_grf_reg)
759 dsi_write(dsi, dsi->cdata->lanecfg2_grf_reg,
760 dsi->cdata->lanecfg2);
761
762 if (dsi->cdata->enable_grf_reg)
763 dsi_write(dsi, dsi->cdata->enable_grf_reg,
764 dsi->cdata->enable);
765}
766
767static int dw_mipi_dsi_rockchip_bind(struct udevice *dev)
768{
769 int ret;
770
771 ret = device_bind_driver_to_node(dev, "dw_mipi_dsi", "dsihost",
772 dev_ofnode(dev), NULL);
773 if (ret) {
774 dev_err(dev, "failed to bind driver to node\n");
775 return ret;
776 }
777
778 return dm_scan_fdt_dev(dev);
779}
780
781static int dw_mipi_dsi_rockchip_probe(struct udevice *dev)
782{
783 struct dw_rockchip_dsi_priv *priv = dev_get_priv(dev);
784 struct mipi_dsi_device *device = &priv->device;
785 int ret, i;
786 const struct rockchip_dw_dsi_chip_data *cdata =
787 (const struct rockchip_dw_dsi_chip_data *)dev_get_driver_data(dev);
788
789 device->dev = dev;
790
791 priv->base = (void *)dev_read_addr(dev);
792 if ((fdt_addr_t)priv->base == FDT_ADDR_T_NONE) {
793 dev_err(dev, "dsi dt register address error\n");
794 return -EINVAL;
795 }
796
797 i = 0;
798 while (cdata[i].reg) {
799 if (cdata[i].reg == (fdt_addr_t)priv->base) {
800 priv->cdata = &cdata[i];
801 break;
802 }
803
804 i++;
805 }
806
807 if (!priv->cdata) {
808 dev_err(dev, "no dsi-config for %s node\n", dev->name);
809 return -EINVAL;
810 }
811
812 /*
813 * Get an optional external dphy. The external dphy stays as
814 * NULL if it's not initialized.
815 */
816 ret = generic_phy_get_by_name(dev, "dphy", &priv->phy);
Ondrej Jirman81162942023-05-22 23:47:07 +0200817 if (ret && ret != -ENODATA) {
Chris Morgan8895dd32023-03-24 13:53:07 -0500818 dev_err(dev, "failed to get mipi dphy: %d\n", ret);
Ondrej Jirman81162942023-05-22 23:47:07 +0200819 return ret;
Chris Morgan8895dd32023-03-24 13:53:07 -0500820 }
821
822 priv->pclk = devm_clk_get(dev, "pclk");
823 if (IS_ERR(priv->pclk)) {
Ondrej Jirman139edfc2023-05-22 23:47:04 +0200824 ret = PTR_ERR(priv->pclk);
Chris Morgan8895dd32023-03-24 13:53:07 -0500825 dev_err(dev, "peripheral clock get error %d\n", ret);
826 return ret;
827 }
828
829 /* Get a ref clock only if not using an external phy. */
Ondrej Jirman6518b732023-05-22 23:47:03 +0200830 if (priv->phy.dev) {
Chris Morgan8895dd32023-03-24 13:53:07 -0500831 dev_dbg(dev, "setting priv->ref to NULL\n");
832 priv->ref = NULL;
833
834 } else {
835 priv->ref = devm_clk_get(dev, "ref");
Ondrej Jirman139edfc2023-05-22 23:47:04 +0200836 if (IS_ERR(priv->ref)) {
837 ret = PTR_ERR(priv->ref);
Chris Morgan8895dd32023-03-24 13:53:07 -0500838 dev_err(dev, "pll reference clock get error %d\n", ret);
839 return ret;
840 }
841 }
842
843 priv->rst = devm_reset_control_get_by_index(device->dev, 0);
844 if (IS_ERR(priv->rst)) {
Ondrej Jirman139edfc2023-05-22 23:47:04 +0200845 ret = PTR_ERR(priv->rst);
846 dev_err(dev, "missing dsi hardware reset %d\n", ret);
Chris Morgan8895dd32023-03-24 13:53:07 -0500847 return ret;
848 }
849
850 /* Reset */
851 reset_deassert(priv->rst);
852
853 dw_mipi_dsi_rockchip_config(priv);
854
855 return 0;
856}
857
858struct video_bridge_ops dw_mipi_dsi_rockchip_ops = {
859 .attach = dw_mipi_dsi_rockchip_attach,
860 .set_backlight = dw_mipi_dsi_rockchip_set_bl,
861};
862
863static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = {
864 {
865 .reg = 0xfe060000,
866 .lanecfg1_grf_reg = RK3568_GRF_VO_CON2,
867 .lanecfg1 = HIWORD_UPDATE(0, RK3568_DSI0_SKEWCALHS |
868 RK3568_DSI0_FORCETXSTOPMODE |
869 RK3568_DSI0_TURNDISABLE |
870 RK3568_DSI0_FORCERXMODE),
871 .max_data_lanes = 4,
872 },
873 {
874 .reg = 0xfe070000,
875 .lanecfg1_grf_reg = RK3568_GRF_VO_CON3,
876 .lanecfg1 = HIWORD_UPDATE(0, RK3568_DSI1_SKEWCALHS |
877 RK3568_DSI1_FORCETXSTOPMODE |
878 RK3568_DSI1_TURNDISABLE |
879 RK3568_DSI1_FORCERXMODE),
880 .max_data_lanes = 4,
881 },
882 { /* sentinel */ }
883};
884
885static const struct udevice_id dw_mipi_dsi_rockchip_dt_ids[] = {
886 { .compatible = "rockchip,rk3568-mipi-dsi",
887 .data = (long)&rk3568_chip_data,
888 },
889 { /* sentinel */ }
890};
891
892U_BOOT_DRIVER(dw_mipi_dsi_rockchip) = {
893 .name = "dw-mipi-dsi-rockchip",
894 .id = UCLASS_VIDEO_BRIDGE,
895 .of_match = dw_mipi_dsi_rockchip_dt_ids,
896 .bind = dw_mipi_dsi_rockchip_bind,
897 .probe = dw_mipi_dsi_rockchip_probe,
898 .ops = &dw_mipi_dsi_rockchip_ops,
899 .priv_auto = sizeof(struct dw_rockchip_dsi_priv),
900};