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 = ¶m_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