xref: /rk3399_rockchip-uboot/drivers/video/drm/inno_mipi_phy.c (revision 6cef3c7b7cc45a9c882fc64e5496a416c99313b8)
1 /*
2  * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #include <config.h>
8 #include <common.h>
9 #include <errno.h>
10 #include <malloc.h>
11 #include <asm/unaligned.h>
12 #include <asm/io.h>
13 #include <linux/list.h>
14 #include <div64.h>
15 #include <dm/device.h>
16 #include <dm/read.h>
17 #include <dm/uclass.h>
18 #include <dm/uclass-id.h>
19 
20 #include "rockchip_phy.h"
21 
22 #define NSEC_PER_USEC		1000L
23 #define USEC_PER_SEC		1000000L
24 #define NSEC_PER_SEC		1000000000L
25 
26 #define UPDATE(v, h, l)		(((v) << (l)) & GENMASK((h), (l)))
27 
28 /* Innosilicon MIPI D-PHY registers */
29 #define INNO_PHY_LANE_CTRL		0x0000
30 #define MIPI_BGPD			BIT(7)
31 #define CLK_LANE_EN_MASK		BIT(6)
32 #define DATA_LANE_3_EN_MASK		BIT(5)
33 #define DATA_LANE_2_EN_MASK		BIT(4)
34 #define DATA_LANE_1_EN_MASK		BIT(3)
35 #define DATA_LANE_0_EN_MASK		BIT(2)
36 #define CLK_LANE_EN			BIT(6)
37 #define DATA_LANE_3_EN			BIT(5)
38 #define DATA_LANE_2_EN			BIT(4)
39 #define DATA_LANE_1_EN			BIT(3)
40 #define DATA_LANE_0_EN			BIT(2)
41 #define PWROK_BP			BIT(1)
42 #define PWROK				BIT(0)
43 #define INNO_PHY_POWER_CTRL		0x0004
44 #define ANALOG_RESET_MASK		BIT(2)
45 #define ANALOG_RESET			BIT(2)
46 #define ANALOG_NORMAL			0
47 #define LDO_POWER_MASK			BIT(1)
48 #define LDO_POWER_DOWN			BIT(1)
49 #define LDO_POWER_ON			0
50 #define PLL_POWER_MASK			BIT(0)
51 #define PLL_POWER_DOWN			BIT(0)
52 #define PLL_POWER_ON			0
53 #define INNO_PHY_PLL_CTRL_0		0x000c
54 #define FBDIV_HI_MASK			BIT(5)
55 #define FBDIV_HI(x)			UPDATE(x, 5, 5)
56 #define PREDIV_MASK			GENMASK(4, 0)
57 #define PREDIV(x)			UPDATE(x, 4, 0)
58 #define INNO_PHY_PLL_CTRL_1		0x0010
59 #define FBDIV_LO_MASK			GENMASK(7, 0)
60 #define FBDIV_LO(x)			UPDATE(x, 7, 0)
61 #define ANALOG_REG_08			0x0020
62 #define PRE_EMPHASIS_ENABLE_MASK	BIT(7)
63 #define PRE_EMPHASIS_ENABLE		BIT(7)
64 #define PRE_EMPHASIS_DISABLE		0
65 #define PLL_POST_DIV_ENABLE_MASK	BIT(5)
66 #define PLL_POST_DIV_ENABLE		BIT(5)
67 #define PLL_POST_DIV_DISABLE		0
68 #define DATA_LANE_VOD_RANGE_SET_MASK	GENMASK(3, 0)
69 #define DATA_LANE_VOD_RANGE_SET(x)	UPDATE(x, 3, 0)
70 #define ANALOG_REG_0B			0x002c
71 #define CLOCK_LANE_VOD_RANGE_SET_MASK	GENMASK(3, 0)
72 #define CLOCK_LANE_VOD_RANGE_SET(x)	UPDATE(x, 3, 0)
73 #define VOD_MIN_RANGE			0x1
74 #define VOD_MID_RANGE			0x3
75 #define VOD_BIG_RANGE			0x7
76 #define VOD_MAX_RANGE			0xf
77 #define RK3506_VOD_MIN_RANGE		0x8
78 #define RK3506_VOD_MID_RANGE		0xc
79 #define RK3506_VOD_BIG_RANGE		0xe
80 #define RK3506_VOD_MAX_RANGE		0xf
81 #define RK3506_PRE_EMPHASIS			0x0060
82 #define LANE0_PRE_EMPHASIS_ENABLE_MASK          BIT(6)
83 #define LANE0_PRE_EMPHASIS_ENABLE               BIT(6)
84 #define LANE0_PRE_EMPHASIS_DISABLE              0
85 #define LANE1_PRE_EMPHASIS_ENABLE_MASK          BIT(5)
86 #define LANE1_PRE_EMPHASIS_ENABLE               BIT(5)
87 #define LANE1_PRE_EMPHASIS_DISABLE              0
88 #define PRE_EMPHASIS_RANGE                      0x0064
89 #define PRE_EMPHASIS_RANGE_SET_MASK             GENMASK(7, 6)
90 #define PRE_EMPHASIS_RANGE_SET(x)               UPDATE(x, 7, 6)
91 #define LANE0_PRE_EMPHASIS_RANGE                0x0068
92 #define LANE0_PRE_EMPHASIS_RANGE_SET_MASK       GENMASK(7, 6)
93 #define LANE0_PRE_EMPHASIS_RANGE_SET(x)         UPDATE(x, 7, 6)
94 #define LANE1_PRE_EMPHASIS_RANGE                0x006c
95 #define LANE1_PRE_EMPHASIS_RANGE_SET_MASK       GENMASK(7, 6)
96 #define LANE1_PRE_EMPHASIS_RANGE_SET(x)         UPDATE(x, 7, 6)
97 #define PRE_EMPHASIS_MIN_RANGE			0x0
98 #define PRE_EMPHASIS_MID_RANGE			0x1
99 #define PRE_EMPHASIS_MAX_RANGE			0x2
100 #define PRE_EMPHASIS_RESERVED_RANGE		0x3
101 #define INNO_PHY_DIG_CTRL		0x0080
102 #define DIGITAL_RESET_MASK		BIT(0)
103 #define DIGITAL_NORMAL			BIT(0)
104 #define DIGITAL_RESET			0
105 #define INNO_PHY_LVDS_CTRL		0x03ac
106 #define LVDS_BGPD			BIT(0)
107 
108 #define INNO_CLOCK_LANE_REG_BASE	0x0100
109 #define INNO_DATA_LANE_0_REG_BASE	0x0180
110 #define INNO_DATA_LANE_1_REG_BASE	0x0200
111 #define INNO_DATA_LANE_2_REG_BASE	0x0280
112 #define INNO_DATA_LANE_3_REG_BASE	0x0300
113 
114 #define T_LPX_OFFSET		0x0014
115 #define T_HS_PREPARE_OFFSET	0x0018
116 #define T_HS_ZERO_OFFSET	0x001c
117 #define T_HS_TRAIL_OFFSET	0x0020
118 #define T_HS_EXIT_OFFSET	0x0024
119 #define T_CLK_POST_OFFSET	0x0028
120 #define T_CLK_POST_OFFSET_H	0x0040
121 #define T_WAKUP_H_OFFSET	0x0030
122 #define T_WAKUP_L_OFFSET	0x0034
123 #define T_CLK_PRE_OFFSET	0x0038
124 #define T_TA_GO_OFFSET		0x0040
125 #define T_TA_SURE_OFFSET	0x0044
126 #define T_TA_WAIT_OFFSET	0x0048
127 
128 #define T_LPX_MASK		GENMASK(5, 0)
129 #define T_LPX(x)		UPDATE(x, 5, 0)
130 #define T_HS_PREPARE_MASK	GENMASK(6, 0)
131 #define T_HS_PREPARE(x)		UPDATE(x, 6, 0)
132 #define T_HS_ZERO_MASK		GENMASK(5, 0)
133 #define T_HS_ZERO(x)		UPDATE(x, 5, 0)
134 #define T_HS_TRAIL_MASK		GENMASK(6, 0)
135 #define T_HS_TRAIL(x)		UPDATE(x, 6, 0)
136 #define T_HS_EXIT_MASK		GENMASK(4, 0)
137 #define T_HS_EXIT(x)		UPDATE(x, 4, 0)
138 #define T_CLK_POST_MASK		GENMASK(3, 0)
139 #define T_CLK_POST(x)		UPDATE(x, 3, 0)
140 #define T_CLK_POST_HI_MASK	GENMASK(7, 6)
141 #define T_CLK_POST_HI(x)	UPDATE(x, 7, 6)
142 #define T_WAKUP_H_MASK		GENMASK(1, 0)
143 #define T_WAKUP_H(x)		UPDATE(x, 1, 0)
144 #define T_WAKUP_L_MASK		GENMASK(7, 0)
145 #define T_WAKUP_L(x)		UPDATE(x, 7, 0)
146 #define T_CLK_PRE_MASK		GENMASK(3, 0)
147 #define T_CLK_PRE(x)		UPDATE(x, 3, 0)
148 #define T_TA_GO_MASK		GENMASK(5, 0)
149 #define T_TA_GO(x)		UPDATE(x, 5, 0)
150 #define T_TA_SURE_MASK		GENMASK(5, 0)
151 #define T_TA_SURE(x)		UPDATE(x, 5, 0)
152 #define T_TA_WAIT_MASK		GENMASK(5, 0)
153 #define T_TA_WAIT(x)		UPDATE(x, 5, 0)
154 
155 enum soc_type {
156 	RV1108_MIPI_DPHY,
157 	RK1808_MIPI_DPHY,
158 	RK3506_MIPI_DPHY,
159 };
160 
161 enum lane_type {
162 	CLOCK_LANE,
163 	DATA_LANE_0,
164 	DATA_LANE_1,
165 	DATA_LANE_2,
166 	DATA_LANE_3,
167 };
168 
169 struct mipi_dphy_timing {
170 	unsigned int clkmiss;
171 	unsigned int clkpost;
172 	unsigned int clkpre;
173 	unsigned int clkprepare;
174 	unsigned int clksettle;
175 	unsigned int clktermen;
176 	unsigned int clktrail;
177 	unsigned int clkzero;
178 	unsigned int dtermen;
179 	unsigned int eot;
180 	unsigned int hsexit;
181 	unsigned int hsprepare;
182 	unsigned int hszero;
183 	unsigned int hssettle;
184 	unsigned int hsskip;
185 	unsigned int hstrail;
186 	unsigned int init;
187 	unsigned int lpx;
188 	unsigned int taget;
189 	unsigned int tago;
190 	unsigned int tasure;
191 	unsigned int wakeup;
192 };
193 
194 struct inno_mipi_dphy_timing {
195 	u8 lpx;
196 	u8 hs_prepare;
197 	u8 hs_zero;
198 	u8 hs_trail;
199 	u8 hs_exit;
200 	u8 clk_post;
201 	u8 wakup_h;
202 	u8 wakup_l;
203 	u8 clk_pre;
204 	u8 ta_go;
205 	u8 ta_sure;
206 	u8 ta_wait;
207 };
208 
209 struct inno_mipi_dphy {
210 	struct udevice *dev;
211 	void __iomem *regs;
212 	unsigned int lane_mbps;
213 	int lanes;
214 };
215 
216 static const u32 lane_reg_offset[] = {
217 	[CLOCK_LANE] = INNO_CLOCK_LANE_REG_BASE,
218 	[DATA_LANE_0] = INNO_DATA_LANE_0_REG_BASE,
219 	[DATA_LANE_1] = INNO_DATA_LANE_1_REG_BASE,
220 	[DATA_LANE_2] = INNO_DATA_LANE_2_REG_BASE,
221 	[DATA_LANE_3] = INNO_DATA_LANE_3_REG_BASE,
222 };
223 
224 #define FIXED_PARAM(_freq, _lpx, _prepare, _clk_zero, _data_zero, _trail)	\
225 {	\
226 	.max_freq = _freq,	\
227 	.lpx = _lpx,	\
228 	.hs_prepare = _prepare,	\
229 	.clk_lane = {	\
230 		.hs_zero = _clk_zero,	\
231 	},	\
232 	.data_lane = {	\
233 		.hs_zero = _data_zero,	\
234 	},	\
235 	.hs_trail = _trail,	\
236 }
237 
238 struct fixed_param {
239 	unsigned int max_freq;
240 	u8 lpx;
241 	u8 hs_prepare;
242 	struct {
243 		u8 hs_zero;
244 	} clk_lane;
245 	struct {
246 		u8 hs_zero;
247 	} data_lane;
248 	u8 hs_trail;
249 };
250 
251 static const struct fixed_param fixed_param_table[] = {
252 	FIXED_PARAM(110, 0x0, 0x20, 0x16, 0x02, 0x22),
253 	FIXED_PARAM(150, 0x0, 0x06, 0x16, 0x03, 0x45),
254 	FIXED_PARAM(200, 0x0, 0x18, 0x17, 0x04, 0x0b),
255 	FIXED_PARAM(250, 0x0, 0x05, 0x17, 0x05, 0x16),
256 	FIXED_PARAM(300, 0x0, 0x51, 0x18, 0x06, 0x2c),
257 	FIXED_PARAM(400, 0x0, 0x64, 0x19, 0x07, 0x33),
258 	FIXED_PARAM(500, 0x0, 0x20, 0x1b, 0x07, 0x4e),
259 	FIXED_PARAM(600, 0x0, 0x6a, 0x1d, 0x08, 0x3a),
260 	FIXED_PARAM(700, 0x0, 0x3e, 0x1e, 0x08, 0x6a),
261 	FIXED_PARAM(800, 0x0, 0x21, 0x1f, 0x09, 0x29),
262 	FIXED_PARAM(1000, 0x0, 0x09, 0x20, 0x09, 0x27)
263 };
264 
265 static const struct fixed_param rk1808_fixed_param_table[] = {
266 	FIXED_PARAM(110, 0x02, 0x7f, 0x16, 0x02, 0x02),
267 	FIXED_PARAM(150, 0x02, 0x7f, 0x16, 0x03, 0x02),
268 	FIXED_PARAM(200, 0x02, 0x7f, 0x17, 0x04, 0x02),
269 	FIXED_PARAM(250, 0x02, 0x7f, 0x17, 0x05, 0x04),
270 	FIXED_PARAM(300, 0x02, 0x7f, 0x18, 0x06, 0x04),
271 	FIXED_PARAM(400, 0x03, 0x7e, 0x19, 0x07, 0x04),
272 	FIXED_PARAM(500, 0x03, 0x7c, 0x1b, 0x07, 0x08),
273 	FIXED_PARAM(600, 0x03, 0x70, 0x1d, 0x08, 0x10),
274 	FIXED_PARAM(700, 0x05, 0x40, 0x1e, 0x08, 0x30),
275 	FIXED_PARAM(800, 0x05, 0x02, 0x1f, 0x09, 0x30),
276 	FIXED_PARAM(1000, 0x05, 0x08, 0x20, 0x09, 0x30),
277 	FIXED_PARAM(1400, 0x09, 0x03, 0x32, 0x14, 0x0f),
278 	FIXED_PARAM(1600, 0x0d, 0x42, 0x36, 0x0e, 0x0f),
279 	FIXED_PARAM(1800, 0x0e, 0x47, 0x7a, 0x0e, 0x0f),
280 	FIXED_PARAM(2000, 0x11, 0x64, 0x7a, 0x0e, 0x0b),
281 };
282 
283 static inline void inno_write(struct inno_mipi_dphy *inno, u32 reg, u32 val)
284 {
285 	writel(val, inno->regs + reg);
286 }
287 
288 static inline u32 inno_read(struct inno_mipi_dphy *inno, u32 reg)
289 {
290 	return readl(inno->regs + reg);
291 }
292 
293 static inline void inno_update_bits(struct inno_mipi_dphy *inno, u32 reg,
294 				    u32 mask, u32 val)
295 {
296 	u32 tmp, orig;
297 
298 	orig = inno_read(inno, reg);
299 	tmp = orig & ~mask;
300 	tmp |= val & mask;
301 	inno_write(inno, reg, tmp);
302 }
303 
304 static void mipi_dphy_timing_get_default(struct mipi_dphy_timing *timing,
305 					 unsigned long period)
306 {
307 	/* Global Operation Timing Parameters */
308 	timing->clkmiss = 0;
309 	timing->clkpost = 70 + 52 * period;
310 	timing->clkpre = 8 * period;
311 	timing->clkprepare = 65;
312 	timing->clksettle = 95;
313 	timing->clktermen = 0;
314 	timing->clktrail = 80;
315 	timing->clkzero = 260;
316 	timing->dtermen = 0;
317 	timing->eot = 0;
318 	timing->hsexit = 120;
319 	timing->hsprepare = 65 + 4 * period;
320 	timing->hszero = 145 + 6 * period;
321 	timing->hssettle = 85 + 6 * period;
322 	timing->hsskip = 40;
323 	timing->hstrail = max(8 * period, 60 + 4 * period);
324 	timing->init = 100000;
325 	timing->lpx = 60;
326 	timing->taget = 5 * timing->lpx;
327 	timing->tago = 4 * timing->lpx;
328 	timing->tasure = 2 * timing->lpx;
329 	timing->wakeup = 1000000;
330 }
331 
332 static void inno_mipi_dphy_timing_update(struct inno_mipi_dphy *inno,
333 					 enum lane_type lane_type,
334 					 struct inno_mipi_dphy_timing *t)
335 {
336 	u32 base = lane_reg_offset[lane_type];
337 	u32 m, v;
338 
339 	m = T_HS_PREPARE_MASK;
340 	v = T_HS_PREPARE(t->hs_prepare);
341 	inno_update_bits(inno, base + T_HS_PREPARE_OFFSET, m, v);
342 
343 	m = T_HS_ZERO_MASK;
344 	v = T_HS_ZERO(t->hs_zero);
345 	inno_update_bits(inno, base + T_HS_ZERO_OFFSET, m, v);
346 
347 	m = T_HS_TRAIL_MASK;
348 	v = T_HS_TRAIL(t->hs_trail);
349 	inno_update_bits(inno, base + T_HS_TRAIL_OFFSET, m, v);
350 
351 	m = T_HS_EXIT_MASK;
352 	v = T_HS_EXIT(t->hs_exit);
353 	inno_update_bits(inno, base + T_HS_EXIT_OFFSET, m, v);
354 
355 	if (lane_type == CLOCK_LANE) {
356 		m = T_CLK_POST_MASK;
357 		v = T_CLK_POST(t->clk_post);
358 		inno_update_bits(inno, base + T_CLK_POST_OFFSET, m, v);
359 		m = T_CLK_POST_HI_MASK;
360 		v = T_CLK_POST_HI(t->clk_post >> 4);
361 		inno_update_bits(inno, base + T_CLK_POST_OFFSET_H, m, v);
362 		m = T_CLK_PRE_MASK;
363 		v = T_CLK_PRE(t->clk_pre);
364 		inno_update_bits(inno, base + T_CLK_PRE_OFFSET, m, v);
365 	}
366 
367 	m = T_WAKUP_H_MASK;
368 	v = T_WAKUP_H(t->wakup_h);
369 	inno_update_bits(inno, base + T_WAKUP_H_OFFSET, m, v);
370 
371 	m = T_WAKUP_L_MASK;
372 	v = T_WAKUP_L(t->wakup_l);
373 	inno_update_bits(inno, base + T_WAKUP_L_OFFSET, m, v);
374 
375 	m = T_LPX_MASK;
376 	v = T_LPX(t->lpx);
377 	inno_update_bits(inno, base + T_LPX_OFFSET, m, v);
378 
379 	m = T_TA_GO_MASK;
380 	v = T_TA_GO(t->ta_go);
381 	inno_update_bits(inno, base + T_TA_GO_OFFSET, m, v);
382 
383 	m = T_TA_SURE_MASK;
384 	v = T_TA_SURE(t->ta_sure);
385 	inno_update_bits(inno, base + T_TA_SURE_OFFSET, m, v);
386 
387 	m = T_TA_WAIT_MASK;
388 	v = T_TA_WAIT(t->ta_wait);
389 	inno_update_bits(inno, base + T_TA_WAIT_OFFSET, m, v);
390 }
391 
392 static void inno_mipi_dphy_get_fixed_param(struct inno_mipi_dphy_timing *t,
393 					   unsigned int freq,
394 					   enum soc_type soc_type,
395 					   enum lane_type lane_type)
396 {
397 	const struct fixed_param *param, *param_table;
398 	int i, param_num;
399 
400 	if (soc_type == RK1808_MIPI_DPHY || soc_type == RK3506_MIPI_DPHY) {
401 		param_table = rk1808_fixed_param_table;
402 		param_num = ARRAY_SIZE(rk1808_fixed_param_table);
403 	} else {
404 		param_table = fixed_param_table;
405 		param_num = ARRAY_SIZE(fixed_param_table);
406 	}
407 
408 	for (i = 0; i < param_num; i++)
409 		if (freq <= param_table[i].max_freq)
410 			break;
411 
412 	if (i == param_num)
413 		--i;
414 
415 	param = &param_table[i];
416 
417 	if (lane_type == CLOCK_LANE)
418 		t->hs_zero = param->clk_lane.hs_zero;
419 	else
420 		t->hs_zero = param->data_lane.hs_zero;
421 
422 	t->hs_prepare = param->hs_prepare;
423 	t->hs_trail = param->hs_trail;
424 
425 	if (soc_type == RK1808_MIPI_DPHY || soc_type == RK3506_MIPI_DPHY)
426 		t->lpx = param->lpx;
427 }
428 
429 static void inno_mipi_dphy_lane_timing_init(struct inno_mipi_dphy *inno,
430 					    enum lane_type lane_type)
431 {
432 	struct rockchip_phy *phy =
433 		(struct rockchip_phy *)dev_get_driver_data(inno->dev);
434 	struct mipi_dphy_timing timing;
435 	struct inno_mipi_dphy_timing data;
436 	unsigned long txbyteclk, txclkesc, UI;
437 	unsigned int esc_clk_div;
438 
439 	memset(&timing, 0, sizeof(timing));
440 	memset(&data, 0, sizeof(data));
441 
442 	txbyteclk = inno->lane_mbps * USEC_PER_SEC / 8;
443 	esc_clk_div = DIV_ROUND_UP(txbyteclk, 20000000);
444 	txclkesc = txbyteclk / esc_clk_div;
445 	UI = DIV_ROUND_CLOSEST(NSEC_PER_USEC, inno->lane_mbps);
446 
447 	debug("txbyteclk=%lu, txclkesc=%lu, esc_clk_div=%u, UI=%lu\n",
448 	      txbyteclk, txclkesc, esc_clk_div, UI);
449 
450 	mipi_dphy_timing_get_default(&timing, UI);
451 	inno_mipi_dphy_get_fixed_param(&data, inno->lane_mbps,
452 				       phy->soc_type, lane_type);
453 
454 	/*
455 	 * Ttxbyteclk * val >= Ths-exit
456 	 * Ttxbyteclk * val >= Tclk-post
457 	 * Ttxbyteclk * val >= Tclk-pre
458 	 * Ttxbyteclk * (2 + val) >= Tlpx
459 	 */
460 	data.hs_exit = DIV_ROUND_UP(timing.hsexit * txbyteclk, NSEC_PER_SEC);
461 	data.clk_post = DIV_ROUND_UP(timing.clkpost * txbyteclk, NSEC_PER_SEC);
462 	data.clk_pre = DIV_ROUND_UP(timing.clkpre * txbyteclk, NSEC_PER_SEC);
463 	data.wakup_h = 0x3;
464 	data.wakup_l = 0xff;
465 
466 	if (phy->soc_type == RV1108_MIPI_DPHY) {
467 		data.lpx = DIV_ROUND_UP(txbyteclk * timing.lpx, NSEC_PER_SEC);
468 		if (data.lpx > 2)
469 			data.lpx -= 2;
470 	}
471 
472 	/*
473 	 * Ttxclkesc * val >= Tta-go
474 	 * Ttxclkesc * val >= Tta-sure
475 	 * Ttxclkesc * val >= Tta-wait
476 	 */
477 	data.ta_go = DIV_ROUND_UP(timing.tago * txclkesc, NSEC_PER_SEC);
478 	data.ta_sure = DIV_ROUND_UP(timing.tasure * txclkesc, NSEC_PER_SEC);
479 	data.ta_wait = DIV_ROUND_UP(timing.taget * txclkesc, NSEC_PER_SEC);
480 
481 	inno_mipi_dphy_timing_update(inno, lane_type, &data);
482 
483 #define TIMING_NS(x, freq) (((x) * (DIV_ROUND_CLOSEST(NSEC_PER_SEC, freq))))
484 	debug("hs-exit=%lu, clk-post=%lu, clk-pre=%lu, lpx=%lu\n",
485 	      TIMING_NS(data.hs_exit, txbyteclk),
486 	      TIMING_NS(data.clk_post, txbyteclk),
487 	      TIMING_NS(data.clk_pre, txbyteclk),
488 	      TIMING_NS(data.lpx + 2, txbyteclk));
489 	debug("ta-go=%lu, ta-sure=%lu, ta-wait=%lu\n",
490 	      TIMING_NS(data.ta_go, txclkesc),
491 	      TIMING_NS(data.ta_sure, txclkesc),
492 	      TIMING_NS(data.ta_wait, txclkesc));
493 }
494 
495 static unsigned long inno_mipi_dphy_pll_round_rate(unsigned long fin,
496 						   unsigned long fout,
497 						   u8 *prediv, u16 *fbdiv)
498 {
499 	unsigned long best_freq = 0;
500 	u8 min_prediv, max_prediv;
501 	u8 _prediv, best_prediv = 0;
502 	u16 _fbdiv, best_fbdiv = 0;
503 	u32 min_delta = 0xffffffff;
504 
505 	fout *= 2;
506 
507 	min_prediv = DIV_ROUND_UP(fin, 40000000);
508 	max_prediv = fin / 5000000;
509 
510 	for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) {
511 		u64 tmp;
512 		u32 delta;
513 		tmp = (u64)fout * _prediv;
514 		do_div(tmp, fin);
515 		_fbdiv = tmp;
516 		if ((_fbdiv == 15) || (_fbdiv < 12) || (_fbdiv > 511))
517 			continue;
518 		tmp = (u64)_fbdiv * fin;
519 		do_div(tmp, _prediv);
520 
521 		delta = abs(fout - tmp);
522 		if (delta < min_delta) {
523 			best_prediv = _prediv;
524 			best_fbdiv = _fbdiv;
525 			min_delta = delta;
526 			best_freq = tmp;
527 		}
528 	}
529 
530 	if (best_freq) {
531 		*prediv = best_prediv;
532 		*fbdiv = best_fbdiv;
533 	}
534 
535 	return best_freq / 2;
536 }
537 
538 static inline void inno_mipi_dphy_reset(struct inno_mipi_dphy *inno)
539 {
540 	/* Reset analog */
541 	inno_update_bits(inno, INNO_PHY_POWER_CTRL,
542 			 ANALOG_RESET_MASK, ANALOG_RESET);
543 	udelay(1);
544 	inno_update_bits(inno, INNO_PHY_POWER_CTRL,
545 			 ANALOG_RESET_MASK, ANALOG_NORMAL);
546 	/* Reset digital */
547 	inno_update_bits(inno, INNO_PHY_DIG_CTRL,
548 			 DIGITAL_RESET_MASK, DIGITAL_RESET);
549 	udelay(1);
550 	inno_update_bits(inno, INNO_PHY_DIG_CTRL,
551 			 DIGITAL_RESET_MASK, DIGITAL_NORMAL);
552 }
553 
554 static void inno_mipi_dphy_timing_init(struct inno_mipi_dphy *inno)
555 {
556 	switch (inno->lanes) {
557 	case 4:
558 		inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_3);
559 		/* Fall through */
560 	case 3:
561 		inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_2);
562 		/* Fall through */
563 	case 2:
564 		inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_1);
565 		/* Fall through */
566 	case 1:
567 	default:
568 		inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_0);
569 		inno_mipi_dphy_lane_timing_init(inno, CLOCK_LANE);
570 		break;
571 	}
572 }
573 
574 static inline void inno_mipi_dphy_lane_enable(struct inno_mipi_dphy *inno)
575 {
576 	u32 m = 0, v = 0;
577 
578 	switch (inno->lanes) {
579 	case 4:
580 		m |= DATA_LANE_3_EN_MASK;
581 		v |= DATA_LANE_3_EN;
582 		/* Fall through */
583 	case 3:
584 		m |= DATA_LANE_2_EN_MASK;
585 		v |= DATA_LANE_2_EN;
586 		/* Fall through */
587 	case 2:
588 		m |= DATA_LANE_1_EN_MASK;
589 		v |= DATA_LANE_1_EN;
590 		/* Fall through */
591 	default:
592 	case 1:
593 		m |= DATA_LANE_0_EN_MASK | CLK_LANE_EN_MASK;
594 		v |= DATA_LANE_0_EN | CLK_LANE_EN;
595 		break;
596 	}
597 
598 	inno_update_bits(inno, INNO_PHY_LANE_CTRL, m, v);
599 }
600 
601 static inline void inno_mipi_dphy_pll_ldo_disable(struct inno_mipi_dphy *inno)
602 {
603 	inno_update_bits(inno, INNO_PHY_POWER_CTRL,
604 			 PLL_POWER_MASK | LDO_POWER_MASK,
605 			 PLL_POWER_DOWN | LDO_POWER_DOWN);
606 }
607 
608 static inline void inno_mipi_dphy_pll_ldo_enable(struct inno_mipi_dphy *inno)
609 {
610 	inno_update_bits(inno, INNO_PHY_POWER_CTRL,
611 			 PLL_POWER_MASK | LDO_POWER_MASK,
612 			 PLL_POWER_ON | LDO_POWER_ON);
613 }
614 
615 static inline void inno_mipi_dphy_da_pwrok_enable(struct inno_mipi_dphy *inno)
616 {
617 	inno_update_bits(inno, INNO_PHY_LANE_CTRL, PWROK_BP | PWROK, PWROK);
618 }
619 
620 static inline void inno_mipi_dphy_da_pwrok_disable(struct inno_mipi_dphy *inno)
621 {
622 	inno_update_bits(inno, INNO_PHY_LANE_CTRL, PWROK_BP | PWROK, PWROK_BP);
623 }
624 
625 static inline void inno_mipi_dphy_bgpd_enable(struct inno_mipi_dphy *inno)
626 {
627 	inno_update_bits(inno, INNO_PHY_LANE_CTRL, MIPI_BGPD, 0);
628 }
629 
630 static inline void inno_mipi_dphy_bgpd_disable(struct inno_mipi_dphy *inno)
631 {
632 	inno_update_bits(inno, INNO_PHY_LANE_CTRL, MIPI_BGPD, MIPI_BGPD);
633 	inno_update_bits(inno, INNO_PHY_LVDS_CTRL, LVDS_BGPD, LVDS_BGPD);
634 }
635 
636 static int inno_mipi_dphy_power_on(struct rockchip_phy *phy)
637 {
638 	struct inno_mipi_dphy *inno = dev_get_priv(phy->dev);
639 
640 	inno_mipi_dphy_bgpd_enable(inno);
641 	inno_mipi_dphy_da_pwrok_enable(inno);
642 	inno_mipi_dphy_pll_ldo_enable(inno);
643 	inno_mipi_dphy_lane_enable(inno);
644 	inno_mipi_dphy_reset(inno);
645 	inno_mipi_dphy_timing_init(inno);
646 	udelay(1);
647 
648 	return 0;
649 }
650 
651 static inline void inno_mipi_dphy_lane_disable(struct inno_mipi_dphy *inno)
652 {
653 	inno_update_bits(inno, INNO_PHY_LANE_CTRL, 0x7c, 0x00);
654 }
655 
656 static int inno_mipi_dphy_power_off(struct rockchip_phy *phy)
657 {
658 	struct inno_mipi_dphy *inno = dev_get_priv(phy->dev);
659 
660 	inno_mipi_dphy_lane_disable(inno);
661 	inno_mipi_dphy_pll_ldo_disable(inno);
662 	inno_mipi_dphy_da_pwrok_disable(inno);
663 	inno_mipi_dphy_bgpd_disable(inno);
664 
665 	return 0;
666 }
667 
668 static unsigned long inno_mipi_dphy_set_pll(struct rockchip_phy *phy,
669 					    unsigned long rate)
670 {
671 	struct inno_mipi_dphy *inno = dev_get_priv(phy->dev);
672 	unsigned long fin, fout;
673 	u16 fbdiv = 0;
674 	u8 prediv = 0;
675 	u32 m, v;
676 
677 	fin = 24000000;
678 	fout = inno_mipi_dphy_pll_round_rate(fin, rate, &prediv, &fbdiv);
679 
680 	debug("%s: fin=%lu, fout=%lu, prediv=%u, fbdiv=%u\n",
681 	       __func__, fin, fout, prediv, fbdiv);
682 
683 	m = FBDIV_HI_MASK | PREDIV_MASK;
684 	v = FBDIV_HI(fbdiv >> 8) | PREDIV(prediv);
685 	inno_update_bits(inno, INNO_PHY_PLL_CTRL_0, m, v);
686 
687 	m = FBDIV_LO_MASK;
688 	v = FBDIV_LO(fbdiv);
689 	inno_update_bits(inno, INNO_PHY_PLL_CTRL_1, m, v);
690 
691 	if (phy->soc_type == RK1808_MIPI_DPHY) {
692 		inno_update_bits(inno, ANALOG_REG_08,
693 				 PLL_POST_DIV_ENABLE_MASK, PLL_POST_DIV_ENABLE);
694 		inno_update_bits(inno, ANALOG_REG_0B,
695 				 CLOCK_LANE_VOD_RANGE_SET_MASK,
696 				 CLOCK_LANE_VOD_RANGE_SET(VOD_MAX_RANGE));
697 	}
698 
699 	if (phy->soc_type == RK3506_MIPI_DPHY) {
700 		inno_update_bits(inno, RK3506_PRE_EMPHASIS,
701 				LANE0_PRE_EMPHASIS_ENABLE_MASK, LANE0_PRE_EMPHASIS_ENABLE);
702 		inno_update_bits(inno, RK3506_PRE_EMPHASIS,
703 				LANE1_PRE_EMPHASIS_ENABLE_MASK, LANE1_PRE_EMPHASIS_ENABLE);
704 		inno_update_bits(inno, PRE_EMPHASIS_RANGE,
705 				PRE_EMPHASIS_RANGE_SET_MASK,
706 				PRE_EMPHASIS_RANGE_SET(PRE_EMPHASIS_MID_RANGE));
707 		inno_update_bits(inno, LANE0_PRE_EMPHASIS_RANGE,
708 				LANE0_PRE_EMPHASIS_RANGE_SET_MASK,
709 				LANE0_PRE_EMPHASIS_RANGE_SET(PRE_EMPHASIS_MID_RANGE));
710 		inno_update_bits(inno, LANE1_PRE_EMPHASIS_RANGE,
711 				LANE1_PRE_EMPHASIS_RANGE_SET_MASK,
712 				LANE1_PRE_EMPHASIS_RANGE_SET(PRE_EMPHASIS_MID_RANGE));
713 		inno_update_bits(inno, ANALOG_REG_0B,
714 				CLOCK_LANE_VOD_RANGE_SET_MASK,
715 				CLOCK_LANE_VOD_RANGE_SET(RK3506_VOD_MAX_RANGE));
716 	}
717 
718 	inno->lane_mbps = fout / USEC_PER_SEC;
719 
720 	return fout;
721 }
722 
723 static int inno_mipi_dphy_parse_dt(struct inno_mipi_dphy *inno)
724 {
725 	struct udevice *dev = inno->dev;
726 
727 #if defined(CONFIG_ROCKCHIP_RK3506)
728 	inno->lanes = ofnode_read_u32_default(dev->node, "inno,lanes", 2);
729 #else
730 	inno->lanes = ofnode_read_u32_default(dev->node, "inno,lanes", 4);
731 #endif
732 
733 	return 0;
734 }
735 
736 static int inno_mipi_dphy_init(struct rockchip_phy *phy)
737 {
738 	struct inno_mipi_dphy *inno = dev_get_priv(phy->dev);
739 	int ret;
740 
741 	ret = inno_mipi_dphy_parse_dt(inno);
742 	if (ret) {
743 		printf("%s: failed to parse DT\n", __func__);
744 		return ret;
745 	}
746 
747 	inno->regs = dev_read_addr_ptr(inno->dev);
748 
749 	return 0;
750 }
751 
752 static const struct rockchip_phy_funcs inno_mipi_dphy_funcs = {
753 	.init = inno_mipi_dphy_init,
754 	.power_on = inno_mipi_dphy_power_on,
755 	.power_off = inno_mipi_dphy_power_off,
756 	.set_pll = inno_mipi_dphy_set_pll,
757 };
758 
759 static const struct udevice_id inno_mipi_dphy_ids[] = {
760 	{
761 		.compatible = "rockchip,rv1108-mipi-dphy",
762 	},
763 	{
764 		.compatible = "rockchip,rk1808-mipi-dphy",
765 	},
766 	{
767 		.compatible = "rockchip,rv1126-mipi-dphy",
768 	},
769 	{
770 		.compatible = "rockchip,rk3506-dsi-dphy",
771 	},
772 	{}
773 };
774 
775 static int inno_mipi_dphy_probe(struct udevice *dev)
776 {
777 	struct inno_mipi_dphy *inno = dev_get_priv(dev);
778 	struct rockchip_phy *phy;
779 
780 	phy = calloc(1, sizeof(*phy));
781 	if (!phy)
782 		return -ENOMEM;
783 
784 	dev->driver_data = (ulong)phy;
785 	inno->dev = dev;
786 	phy->dev = dev;
787 	phy->funcs = &inno_mipi_dphy_funcs;
788 
789 #if defined(CONFIG_ROCKCHIP_RV1108)
790 	phy->soc_type = RV1108_MIPI_DPHY;
791 #elif defined(CONFIG_ROCKCHIP_RK3506)
792 	phy->soc_type = RK3506_MIPI_DPHY;
793 #else
794 	phy->soc_type = RK1808_MIPI_DPHY;
795 #endif
796 
797 	return 0;
798 }
799 
800 U_BOOT_DRIVER(inno_mipi_dphy) = {
801 	.name = "inno_mipi_dphy",
802 	.id = UCLASS_PHY,
803 	.of_match = inno_mipi_dphy_ids,
804 	.probe = inno_mipi_dphy_probe,
805 	.priv_auto_alloc_size = sizeof(struct inno_mipi_dphy),
806 };
807