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