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