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