1 /*
2 * SPDX-License-Identifier: GPL-2.0+
3 * (C) Copyright 2008-2016 Fuzhou Rockchip Electronics Co., Ltd
4 */
5
6 #include <clk-uclass.h>
7 #include <config.h>
8 #include <common.h>
9 #include <errno.h>
10 #include <malloc.h>
11 #include <misc.h>
12 #include <fdtdec.h>
13 #include <fdt_support.h>
14 #include <asm/unaligned.h>
15 #include <asm/arch/clock.h>
16 #include <dm/device.h>
17 #include <dm/lists.h>
18 #include <dm/read.h>
19 #include <asm/io.h>
20 #include <linux/list.h>
21 #include <div64.h>
22 #include <linux/media-bus-format.h>
23
24 #include "rockchip_display.h"
25 #include "rockchip_crtc.h"
26 #include "rockchip_connector.h"
27 #include "rockchip_phy.h"
28
29 #define INNO_HDMI_PHY_TIMEOUT_LOOP_COUNT 1000
30 #define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l)))
31
32 /* REG: 0x00 */
33 #define PRE_PLL_REFCLK_SEL_MASK BIT(0)
34 #define PRE_PLL_REFCLK_SEL_PCLK BIT(0)
35 #define PRE_PLL_REFCLK_SEL_OSCCLK 0
36 /* REG: 0x01 */
37 #define BYPASS_RXSENSE_EN_MASK BIT(2)
38 #define BYPASS_RXSENSE_EN BIT(2)
39 #define BYPASS_PWRON_EN_MASK BIT(1)
40 #define BYPASS_PWRON_EN BIT(1)
41 #define BYPASS_PLLPD_EN_MASK BIT(0)
42 #define BYPASS_PLLPD_EN BIT(0)
43 /* REG: 0x02 */
44 #define BYPASS_PDATA_EN_MASK BIT(4)
45 #define BYPASS_PDATA_EN BIT(4)
46 #define PDATAEN_MASK BIT(0)
47 #define PDATAEN_DISABLE BIT(0)
48 #define PDATAEN_ENABLE 0
49 /* REG: 0x03 */
50 #define BYPASS_AUTO_TERM_RES_CAL BIT(7)
51 #define AUDO_TERM_RES_CAL_SPEED_14_8(x) UPDATE(x, 6, 0)
52 /* REG: 0x04 */
53 #define AUDO_TERM_RES_CAL_SPEED_7_0(x) UPDATE(x, 7, 0)
54 /* REG: 0xaa */
55 #define POST_PLL_CTRL_MASK BIT(0)
56 #define POST_PLL_CTRL_MANUAL BIT(0)
57 /* REG: 0xe0 */
58 #define POST_PLL_POWER_MASK BIT(5)
59 #define POST_PLL_POWER_DOWN BIT(5)
60 #define POST_PLL_POWER_UP 0
61 #define PRE_PLL_POWER_MASK BIT(4)
62 #define PRE_PLL_POWER_DOWN BIT(4)
63 #define PRE_PLL_POWER_UP 0
64 #define RXSENSE_CLK_CH_MASK BIT(3)
65 #define RXSENSE_CLK_CH_ENABLE BIT(3)
66 #define RXSENSE_DATA_CH2_MASK BIT(2)
67 #define RXSENSE_DATA_CH2_ENABLE BIT(2)
68 #define RXSENSE_DATA_CH1_MASK BIT(1)
69 #define RXSENSE_DATA_CH1_ENABLE BIT(1)
70 #define RXSENSE_DATA_CH0_MASK BIT(0)
71 #define RXSENSE_DATA_CH0_ENABLE BIT(0)
72 /* REG: 0xe1 */
73 #define BANDGAP_MASK BIT(4)
74 #define BANDGAP_ENABLE BIT(4)
75 #define BANDGAP_DISABLE 0
76 #define TMDS_DRIVER_MASK GENMASK(3, 0)
77 #define TMDS_DRIVER_ENABLE UPDATE(0xf, 3, 0)
78 #define TMDS_DRIVER_DISABLE 0
79 /* REG: 0xe2 */
80 #define PRE_PLL_FB_DIV_8_MASK BIT(7)
81 #define PRE_PLL_FB_DIV_8_SHIFT 7
82 #define PRE_PLL_FB_DIV_8(x) UPDATE(x, 7, 7)
83 #define PCLK_VCO_DIV_5_MASK BIT(5)
84 #define PCLK_VCO_DIV_5_SHIFT 5
85 #define PCLK_VCO_DIV_5(x) UPDATE(x, 5, 5)
86 #define PRE_PLL_PRE_DIV_MASK GENMASK(4, 0)
87 #define PRE_PLL_PRE_DIV(x) UPDATE(x, 4, 0)
88 /* REG: 0xe3 */
89 #define PRE_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0)
90 /* REG: 0xe4 */
91 #define PRE_PLL_PCLK_DIV_B_MASK GENMASK(6, 5)
92 #define PRE_PLL_PCLK_DIV_B_SHIFT 5
93 #define PRE_PLL_PCLK_DIV_B(x) UPDATE(x, 6, 5)
94 #define PRE_PLL_PCLK_DIV_A_MASK GENMASK(4, 0)
95 #define PRE_PLL_PCLK_DIV_A_SHIFT 0
96 #define PRE_PLL_PCLK_DIV_A(x) UPDATE(x, 4, 0)
97 /* REG: 0xe5 */
98 #define PRE_PLL_PCLK_DIV_C_MASK GENMASK(6, 5)
99 #define PRE_PLL_PCLK_DIV_C_SHIFT 5
100 #define PRE_PLL_PCLK_DIV_C(x) UPDATE(x, 6, 5)
101 #define PRE_PLL_PCLK_DIV_D_MASK GENMASK(4, 0)
102 #define PRE_PLL_PCLK_DIV_D_SHIFT 0
103 #define PRE_PLL_PCLK_DIV_D(x) UPDATE(x, 4, 0)
104 /* REG: 0xe6 */
105 #define PRE_PLL_TMDSCLK_DIV_C_MASK GENMASK(5, 4)
106 #define PRE_PLL_TMDSCLK_DIV_C(x) UPDATE(x, 5, 4)
107 #define PRE_PLL_TMDSCLK_DIV_A_MASK GENMASK(3, 2)
108 #define PRE_PLL_TMDSCLK_DIV_A(x) UPDATE(x, 3, 2)
109 #define PRE_PLL_TMDSCLK_DIV_B_MASK GENMASK(1, 0)
110 #define PRE_PLL_TMDSCLK_DIV_B(x) UPDATE(x, 1, 0)
111 /* REG: 0xe8 */
112 #define PRE_PLL_LOCK_STATUS BIT(0)
113 /* REG: 0xe9 */
114 #define POST_PLL_POST_DIV_EN_MASK GENMASK(7, 6)
115 #define POST_PLL_POST_DIV_ENABLE UPDATE(3, 7, 6)
116 #define POST_PLL_POST_DIV_DISABLE 0
117 #define POST_PLL_PRE_DIV_MASK GENMASK(4, 0)
118 #define POST_PLL_PRE_DIV(x) UPDATE(x, 4, 0)
119 /* REG: 0xea */
120 #define POST_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0)
121 /* REG: 0xeb */
122 #define POST_PLL_FB_DIV_8_MASK BIT(7)
123 #define POST_PLL_FB_DIV_8(x) UPDATE(x, 7, 7)
124 #define POST_PLL_POST_DIV_MASK GENMASK(5, 4)
125 #define POST_PLL_POST_DIV(x) UPDATE(x, 5, 4)
126 #define POST_PLL_LOCK_STATUS BIT(0)
127 /* REG: 0xee */
128 #define TMDS_CH_TA_MASK GENMASK(7, 4)
129 #define TMDS_CH_TA_ENABLE UPDATE(0xf, 7, 4)
130 #define TMDS_CH_TA_DISABLE 0
131 /* REG: 0xef */
132 #define TMDS_CLK_CH_TA(x) UPDATE(x, 7, 6)
133 #define TMDS_DATA_CH2_TA(x) UPDATE(x, 5, 4)
134 #define TMDS_DATA_CH1_TA(x) UPDATE(x, 3, 2)
135 #define TMDS_DATA_CH0_TA(x) UPDATE(x, 1, 0)
136 /* REG: 0xf0 */
137 #define TMDS_DATA_CH2_PRE_EMPHASIS_MASK GENMASK(5, 4)
138 #define TMDS_DATA_CH2_PRE_EMPHASIS(x) UPDATE(x, 5, 4)
139 #define TMDS_DATA_CH1_PRE_EMPHASIS_MASK GENMASK(3, 2)
140 #define TMDS_DATA_CH1_PRE_EMPHASIS(x) UPDATE(x, 3, 2)
141 #define TMDS_DATA_CH0_PRE_EMPHASIS_MASK GENMASK(1, 0)
142 #define TMDS_DATA_CH0_PRE_EMPHASIS(x) UPDATE(x, 1, 0)
143 /* REG: 0xf1 */
144 #define TMDS_CLK_CH_OUTPUT_SWING(x) UPDATE(x, 7, 4)
145 #define TMDS_DATA_CH2_OUTPUT_SWING(x) UPDATE(x, 3, 0)
146 /* REG: 0xf2 */
147 #define TMDS_DATA_CH1_OUTPUT_SWING(x) UPDATE(x, 7, 4)
148 #define TMDS_DATA_CH0_OUTPUT_SWING(x) UPDATE(x, 3, 0)
149
150 enum inno_hdmi_phy_type {
151 INNO_HDMI_PHY_RK3228,
152 INNO_HDMI_PHY_RK3328,
153 INNO_HDMI_PHY_RK3528
154 };
155
156 struct inno_hdmi_phy_drv_data;
157
158 struct phy_config {
159 unsigned long tmdsclock;
160 u8 regs[14];
161 };
162
163 struct inno_hdmi_phy {
164 struct udevice *dev;
165 ofnode node;
166 void *regs;
167
168 /* platform data */
169 const struct inno_hdmi_phy_drv_data *plat_data;
170 unsigned long pixclock;
171 u32 bus_width;
172 struct phy_config *phy_cfg;
173 };
174
175 struct pre_pll_config {
176 unsigned long pixclock;
177 unsigned long tmdsclock;
178 u8 prediv;
179 u16 fbdiv;
180 u8 tmds_div_a;
181 u8 tmds_div_b;
182 u8 tmds_div_c;
183 u8 pclk_div_a;
184 u8 pclk_div_b;
185 u8 pclk_div_c;
186 u8 pclk_div_d;
187 u8 vco_div_5_en;
188 u32 fracdiv;
189 };
190
191 struct post_pll_config {
192 unsigned long tmdsclock;
193 u8 prediv;
194 u16 fbdiv;
195 u8 postdiv;
196 u8 version;
197 };
198
199 struct inno_hdmi_phy_ops {
200 void (*init)(struct inno_hdmi_phy *inno);
201 int (*power_on)(struct inno_hdmi_phy *inno,
202 const struct post_pll_config *cfg,
203 const struct phy_config *phy_cfg);
204 void (*power_off)(struct inno_hdmi_phy *inno);
205 int (*pre_pll_update)(struct inno_hdmi_phy *inno,
206 const struct pre_pll_config *cfg);
207 unsigned long (*recalc_rate)(struct inno_hdmi_phy *inno,
208 unsigned long parent_rate);
209 };
210
211 struct inno_hdmi_phy_drv_data {
212 enum inno_hdmi_phy_type dev_type;
213 const struct inno_hdmi_phy_ops *ops;
214 const struct phy_config *phy_cfg_table;
215 };
216
217 struct rockchip_inno_data {
218 char compatible[30];
219 const void *data;
220 };
221
222 struct clk_inno_hdmi {
223 struct udevice *dev;
224 ulong rate;
225 };
226
227 /* global variables are used to pass reource from phy drivers to clk driver */
228 static struct inno_hdmi_phy *g_inno;
229
230 static const struct pre_pll_config pre_pll_cfg_table[] = {
231 { 27000000, 27000000, 1, 90, 3, 2, 2, 10, 3, 3, 4, 0, 0},
232 { 27000000, 33750000, 1, 90, 1, 3, 3, 10, 3, 3, 4, 0, 0},
233 { 40000000, 40000000, 1, 80, 2, 2, 2, 12, 2, 2, 2, 0, 0},
234 { 59341000, 59341000, 1, 98, 3, 1, 2, 1, 3, 3, 4, 0, 0xE6AE6B},
235 { 59400000, 59400000, 1, 99, 3, 1, 1, 1, 3, 3, 4, 0, 0},
236 { 59341000, 74176250, 1, 98, 0, 3, 3, 1, 3, 3, 4, 0, 0xE6AE6B},
237 { 59400000, 74250000, 1, 99, 1, 2, 2, 1, 3, 3, 4, 0, 0},
238 { 74176000, 74176000, 1, 98, 1, 2, 2, 1, 2, 3, 4, 0, 0xE6AE6B},
239 { 74250000, 74250000, 1, 99, 1, 2, 2, 1, 2, 3, 4, 0, 0},
240 { 74176000, 92720000, 4, 494, 1, 2, 2, 1, 3, 3, 4, 0, 0x816817},
241 { 74250000, 92812500, 4, 495, 1, 2, 2, 1, 3, 3, 4, 0, 0},
242 {148352000, 148352000, 1, 98, 1, 1, 1, 1, 2, 2, 2, 0, 0xE6AE6B},
243 {148500000, 148500000, 1, 99, 1, 1, 1, 1, 2, 2, 2, 0, 0},
244 {148352000, 185440000, 4, 494, 0, 2, 2, 1, 3, 2, 2, 0, 0x816817},
245 {148500000, 185625000, 4, 495, 0, 2, 2, 1, 3, 2, 2, 0, 0},
246 {296703000, 296703000, 1, 98, 0, 1, 1, 1, 0, 2, 2, 0, 0xE6AE6B},
247 {297000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 2, 0, 0},
248 {296703000, 370878750, 4, 494, 1, 2, 0, 1, 3, 1, 1, 0, 0x816817},
249 {297000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 0, 0},
250 {593407000, 296703500, 1, 98, 0, 1, 1, 1, 0, 2, 1, 0, 0xE6AE6B},
251 {594000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 1, 0, 0},
252 {593407000, 370879375, 4, 494, 1, 2, 0, 1, 3, 1, 1, 1, 0x816817},
253 {594000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 1, 0},
254 {593407000, 593407000, 1, 98, 0, 2, 0, 1, 0, 1, 1, 0, 0xE6AE6B},
255 {594000000, 594000000, 1, 99, 0, 2, 0, 1, 0, 1, 1, 0, 0},
256 { ~0UL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
257 };
258
259 static const struct post_pll_config post_pll_cfg_table[] = {
260 {33750000, 1, 40, 8, 1},
261 {33750000, 1, 80, 8, 2},
262 {33750000, 1, 10, 2, 4},
263 {74250000, 1, 40, 8, 1},
264 {74250000, 18, 80, 8, 2},
265 {74250000, 1, 20, 4, 8},
266 {148500000, 2, 40, 4, 3},
267 {148500000, 1, 10, 2, 8},
268 {297000000, 4, 40, 2, 3},
269 {297000000, 2, 20, 2, 8},
270 {594000000, 8, 40, 1, 3},
271 {594000000, 4, 20, 1, 8},
272 { ~0UL, 0, 0, 0, 0}
273 };
274
275 static const struct phy_config rk3228_phy_cfg[] = {
276 { 165000000, {
277 0xaa, 0x00, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
278 0x00, 0x00, 0x00, 0x00, 0x00,
279 },
280 }, {
281 340000000, {
282 0xaa, 0x15, 0x6a, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00,
283 0x00, 0x00, 0x00, 0x00, 0x00,
284 },
285 }, {
286 594000000, {
287 0xaa, 0x15, 0x7a, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00,
288 0x00, 0x00, 0x00, 0x00, 0x00,
289 },
290 }, {
291 ~0UL, {
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x00, 0x00, 0x00, 0x00, 0x00,
294 },
295 }
296 };
297
298 static const struct phy_config rk3328_phy_cfg[] = {
299 { 165000000, {
300 0x07, 0x08, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x08,
301 0x00, 0xac, 0xcc, 0xcc, 0xcc,
302 },
303 }, {
304 340000000, {
305 0x0b, 0x0d, 0x0d, 0x0d, 0x07, 0x15, 0x08, 0x08, 0x08,
306 0x3f, 0xac, 0xcc, 0xcd, 0xdd,
307 },
308 }, {
309 594000000, {
310 0x10, 0x1a, 0x1a, 0x1a, 0x07, 0x15, 0x08, 0x08, 0x08,
311 0x00, 0xac, 0xcc, 0xcc, 0xcc,
312 },
313 }, {
314 ~0UL, {
315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
316 0x00, 0x00, 0x00, 0x00, 0x00,
317 },
318 }
319 };
320
321 static const struct phy_config rk3528_phy_cfg[] = {
322 /* tmdsclk bias-clk bias-data voltage-clk voltage-data pre-emphasis-data */
323 { 165000000, {
324 0x02, 0x04, 0x0f, 0x0f, 0x00, 0x76, 0x83, 0x0a, 0x0a,
325 0x00, 0x00, 0x00, 0x00, 0x00,
326 },
327 }, {
328 185625000, {
329 0x02, 0x0b, 0x0f, 0x0f, 0x00, 0x76, 0x83, 0x0a, 0x33,
330 0x00, 0x00, 0x00, 0x00, 0x00,
331 },
332 }, {
333 340000000, {
334 0x03, 0x04, 0x0c, 0x12, 0x00, 0x76, 0x83, 0x00, 0x0f,
335 0x00, 0x00, 0x00, 0x00, 0x00,
336 },
337 }, {
338 371250000, {
339 0x02, 0x0b, 0x0d, 0x18, 0x00, 0x76, 0x83, 0x0a, 0x33,
340 0x00, 0x00, 0x00, 0x00, 0x00,
341 },
342 }, {
343 594000000, {
344 0x02, 0x0b, 0x0d, 0x18, 0x00, 0x76, 0x83, 0x0a, 0x33,
345 0x00, 0x00, 0x00, 0x00, 0x00,
346 },
347 }, {
348 ~0UL, {
349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
350 0x00, 0x00, 0x00, 0x00, 0x00,
351 },
352 }
353 };
354
inno_write(struct inno_hdmi_phy * inno,u32 reg,u8 val)355 static inline void inno_write(struct inno_hdmi_phy *inno, u32 reg, u8 val)
356 {
357 writel(val, inno->regs + (reg * 4));
358 }
359
inno_read(struct inno_hdmi_phy * inno,u32 reg)360 static inline u8 inno_read(struct inno_hdmi_phy *inno, u32 reg)
361 {
362 u32 val;
363
364 val = readl(inno->regs + (reg * 4));
365
366 return val;
367 }
368
inno_update_bits(struct inno_hdmi_phy * inno,u8 reg,u8 mask,u8 val)369 static inline void inno_update_bits(struct inno_hdmi_phy *inno, u8 reg,
370 u8 mask, u8 val)
371 {
372 u32 tmp, orig;
373
374 orig = inno_read(inno, reg);
375 tmp = orig & ~mask;
376 tmp |= val & mask;
377 inno_write(inno, reg, tmp);
378 }
379
inno_hdmi_phy_get_tmdsclk(struct inno_hdmi_phy * inno,unsigned long rate)380 static u32 inno_hdmi_phy_get_tmdsclk(struct inno_hdmi_phy *inno,
381 unsigned long rate)
382 {
383 u32 tmdsclk;
384
385 switch (inno->bus_width) {
386 case 4:
387 tmdsclk = (u32)rate / 2;
388 break;
389 case 5:
390 tmdsclk = (u32)rate * 5 / 8;
391 break;
392 case 6:
393 tmdsclk = (u32)rate * 3 / 4;
394 break;
395 case 10:
396 tmdsclk = (u32)rate * 5 / 4;
397 break;
398 case 12:
399 tmdsclk = (u32)rate * 3 / 2;
400 break;
401 case 16:
402 tmdsclk = (u32)rate * 2;
403 break;
404 default:
405 tmdsclk = rate;
406 }
407
408 return tmdsclk;
409 }
410
rk_get_cpu_version(void)411 static u8 rk_get_cpu_version(void)
412 {
413 u8 val = 0;
414 #ifdef CONFIG_ROCKCHIP_EFUSE
415 struct udevice *dev;
416 u32 regs[2] = {0};
417 u8 fuses[1];
418 ofnode node;
419 int ret;
420
421 ret = uclass_get_device_by_driver(UCLASS_MISC,
422 DM_GET_DRIVER(rockchip_efuse), &dev);
423 if (ret) {
424 printf("%s: no misc-device found\n", __func__);
425 return -EINVAL;
426 }
427
428 node = dev_read_subnode(dev, "cpu-version");
429 if (!ofnode_valid(node))
430 return -EINVAL;
431
432 ret = ofnode_read_u32_array(node, "reg", regs, 2);
433 if (ret) {
434 printf("Cannot get efuse reg\n");
435 return -EINVAL;
436 }
437
438 ret = misc_read(dev, regs[0], &fuses, regs[1]);
439 if (ret) {
440 printf("%s: misc_read failed\n", __func__);
441 return 0;
442 }
443
444 val = fuses[0];
445 val = (val >> 3) & 0x1;
446 #endif
447 return val;
448 }
449
inno_hdmi_phy_power_on(struct rockchip_phy * phy)450 static int inno_hdmi_phy_power_on(struct rockchip_phy *phy)
451 {
452 #ifdef CONFIG_SPL_BUILD
453 struct inno_hdmi_phy *inno = (struct inno_hdmi_phy *)phy->data;
454 #else
455 struct inno_hdmi_phy *inno = dev_get_priv(phy->dev);
456 #endif
457 const struct post_pll_config *cfg = post_pll_cfg_table;
458 const struct phy_config *phy_cfg = inno->plat_data->phy_cfg_table;
459 u32 tmdsclock = inno_hdmi_phy_get_tmdsclk(inno, inno->pixclock);
460 u32 chipversion = 1;
461
462 printf("start Inno HDMI PHY Power On\n");
463
464 if (inno->phy_cfg)
465 phy_cfg = inno->phy_cfg;
466
467 if (!tmdsclock) {
468 printf("TMDS clock is zero!\n");
469 return -EINVAL;
470 }
471
472 if (inno->plat_data->dev_type == INNO_HDMI_PHY_RK3328 &&
473 rk_get_cpu_version())
474 chipversion = 2;
475 else if (inno->plat_data->dev_type == INNO_HDMI_PHY_RK3228 &&
476 tmdsclock <= 33750000)
477 chipversion = 4;
478 else if (inno->plat_data->dev_type == INNO_HDMI_PHY_RK3528)
479 chipversion = 8;
480
481 printf("tmdsclock = %d; chipversion = %d\n", tmdsclock, chipversion);
482
483 for (; cfg->tmdsclock != ~0UL; cfg++)
484 if (tmdsclock <= cfg->tmdsclock &&
485 cfg->version & chipversion)
486 break;
487
488 for (; phy_cfg->tmdsclock != ~0UL; phy_cfg++)
489 if (tmdsclock <= phy_cfg->tmdsclock)
490 break;
491
492 if (cfg->tmdsclock == ~0UL || phy_cfg->tmdsclock == ~0UL)
493 return -EINVAL;
494
495 printf("Inno HDMI PHY Power On\n");
496 if (inno->plat_data->ops->power_on)
497 return inno->plat_data->ops->power_on(inno, cfg, phy_cfg);
498 else
499 return -EINVAL;
500 }
501
inno_hdmi_phy_power_off(struct rockchip_phy * phy)502 static int inno_hdmi_phy_power_off(struct rockchip_phy *phy)
503 {
504 #ifdef CONFIG_SPL_BUILD
505 struct inno_hdmi_phy *inno = (struct inno_hdmi_phy *)phy->data;
506 #else
507 struct inno_hdmi_phy *inno = dev_get_priv(phy->dev);
508 #endif
509
510 if (inno->plat_data->ops->power_off)
511 inno->plat_data->ops->power_off(inno);
512 printf("Inno HDMI PHY Power Off\n");
513
514 return 0;
515 }
516
inno_hdmi_phy_clk_is_prepared(struct inno_hdmi_phy * inno)517 static int inno_hdmi_phy_clk_is_prepared(struct inno_hdmi_phy *inno)
518 {
519 u8 status;
520
521 if (inno->plat_data->dev_type == INNO_HDMI_PHY_RK3228)
522 status = inno_read(inno, 0xe0) & PRE_PLL_POWER_MASK;
523 else
524 status = inno_read(inno, 0xa0) & 1;
525
526 return status ? 0 : 1;
527 }
528
inno_hdmi_phy_clk_prepare(struct inno_hdmi_phy * inno)529 static int inno_hdmi_phy_clk_prepare(struct inno_hdmi_phy *inno)
530 {
531 if (inno->plat_data->dev_type == INNO_HDMI_PHY_RK3228)
532 inno_update_bits(inno, 0xe0, PRE_PLL_POWER_MASK,
533 PRE_PLL_POWER_UP);
534 else
535 inno_update_bits(inno, 0xa0, 1, 0);
536
537 return 0;
538 }
539
inno_hdmi_phy_clk_set_rate(struct inno_hdmi_phy * inno,unsigned long rate)540 static int inno_hdmi_phy_clk_set_rate(struct inno_hdmi_phy *inno,
541 unsigned long rate)
542 {
543 const struct pre_pll_config *cfg = pre_pll_cfg_table;
544 u32 tmdsclock = inno_hdmi_phy_get_tmdsclk(inno, rate);
545
546 for (; cfg->pixclock != ~0UL; cfg++)
547 if (cfg->pixclock == rate && cfg->tmdsclock == tmdsclock)
548 break;
549
550 if (cfg->pixclock == ~0UL) {
551 printf("unsupported rate %lu\n", rate);
552 return -EINVAL;
553 }
554
555 if (inno->plat_data->ops->pre_pll_update)
556 inno->plat_data->ops->pre_pll_update(inno, cfg);
557
558 inno->pixclock = rate;
559
560 return 0;
561 }
562
inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy * inno)563 static void inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy *inno)
564 {
565 u32 m, v;
566
567 /*
568 * Use phy internal register control
569 * rxsense/poweron/pllpd/pdataen signal.
570 */
571 m = BYPASS_RXSENSE_EN_MASK | BYPASS_PWRON_EN_MASK |
572 BYPASS_PLLPD_EN_MASK;
573 v = BYPASS_RXSENSE_EN | BYPASS_PWRON_EN | BYPASS_PLLPD_EN;
574 inno_update_bits(inno, 0x01, m, v);
575 inno_update_bits(inno, 0x02, BYPASS_PDATA_EN_MASK, BYPASS_PDATA_EN);
576
577 /* manual power down post-PLL */
578 inno_update_bits(inno, 0xaa, POST_PLL_CTRL_MASK, POST_PLL_CTRL_MANUAL);
579 }
580
581 static int
inno_hdmi_phy_rk3228_power_on(struct inno_hdmi_phy * inno,const struct post_pll_config * cfg,const struct phy_config * phy_cfg)582 inno_hdmi_phy_rk3228_power_on(struct inno_hdmi_phy *inno,
583 const struct post_pll_config *cfg,
584 const struct phy_config *phy_cfg)
585 {
586 int pll_tries;
587 u32 m, v;
588
589 /* pdata_en disable */
590 inno_update_bits(inno, 0x02, PDATAEN_MASK, PDATAEN_DISABLE);
591
592 /* Power down Post-PLL */
593 inno_update_bits(inno, 0xe0, PRE_PLL_POWER_MASK, PRE_PLL_POWER_DOWN);
594 inno_update_bits(inno, 0xe0, POST_PLL_POWER_MASK, POST_PLL_POWER_DOWN);
595
596 /* Post-PLL update */
597 m = POST_PLL_PRE_DIV_MASK;
598 v = POST_PLL_PRE_DIV(cfg->prediv);
599 inno_update_bits(inno, 0xe9, m, v);
600
601 m = POST_PLL_FB_DIV_8_MASK;
602 v = POST_PLL_FB_DIV_8(cfg->fbdiv >> 8);
603 inno_update_bits(inno, 0xeb, m, v);
604 inno_write(inno, 0xea, POST_PLL_FB_DIV_7_0(cfg->fbdiv));
605
606 if (cfg->postdiv == 1) {
607 /* Disable Post-PLL post divider */
608 m = POST_PLL_POST_DIV_EN_MASK;
609 v = POST_PLL_POST_DIV_DISABLE;
610 inno_update_bits(inno, 0xe9, m, v);
611 } else {
612 /* Enable Post-PLL post divider */
613 m = POST_PLL_POST_DIV_EN_MASK;
614 v = POST_PLL_POST_DIV_ENABLE;
615 inno_update_bits(inno, 0xe9, m, v);
616
617 m = POST_PLL_POST_DIV_MASK;
618 v = POST_PLL_POST_DIV(cfg->postdiv / 2 - 1);
619 inno_update_bits(inno, 0xeb, m, v);
620 }
621
622 for (v = 0; v < 4; v++)
623 inno_write(inno, 0xef + v, phy_cfg->regs[v]);
624
625 /* Power up Post-PLL */
626 inno_update_bits(inno, 0xe0, POST_PLL_POWER_MASK, POST_PLL_POWER_UP);
627 inno_update_bits(inno, 0xe0, PRE_PLL_POWER_MASK, PRE_PLL_POWER_UP);
628
629 /* BandGap enable */
630 inno_update_bits(inno, 0xe1, BANDGAP_MASK, BANDGAP_ENABLE);
631
632 /* TMDS driver enable */
633 inno_update_bits(inno, 0xe1, TMDS_DRIVER_MASK, TMDS_DRIVER_ENABLE);
634
635 /* Wait for post PLL lock */
636 pll_tries = 0;
637 while (!(inno_read(inno, 0xeb) & POST_PLL_LOCK_STATUS)) {
638 if (pll_tries == INNO_HDMI_PHY_TIMEOUT_LOOP_COUNT) {
639 printf("Post-PLL unlock\n");
640 return -ETIMEDOUT;
641 }
642
643 pll_tries++;
644 udelay(100);
645 }
646
647 if (cfg->tmdsclock > 340000000)
648 mdelay(100);
649
650 /* pdata_en enable */
651 inno_update_bits(inno, 0x02, PDATAEN_MASK, PDATAEN_ENABLE);
652 return 0;
653 }
654
inno_hdmi_phy_rk3228_power_off(struct inno_hdmi_phy * inno)655 static void inno_hdmi_phy_rk3228_power_off(struct inno_hdmi_phy *inno)
656 {
657 /* TMDS driver Disable */
658 inno_update_bits(inno, 0xe1, TMDS_DRIVER_MASK, TMDS_DRIVER_DISABLE);
659
660 /* BandGap Disable */
661 inno_update_bits(inno, 0xe1, BANDGAP_MASK, BANDGAP_DISABLE);
662
663 /* Post-PLL power down */
664 inno_update_bits(inno, 0xe0, POST_PLL_POWER_MASK, POST_PLL_POWER_DOWN);
665 }
666
667 static int
inno_hdmi_phy_rk3228_pre_pll_update(struct inno_hdmi_phy * inno,const struct pre_pll_config * cfg)668 inno_hdmi_phy_rk3228_pre_pll_update(struct inno_hdmi_phy *inno,
669 const struct pre_pll_config *cfg)
670 {
671 int pll_tries;
672 u32 m, v;
673
674 /* Power down PRE-PLL */
675 inno_update_bits(inno, 0xe0, PRE_PLL_POWER_MASK, PRE_PLL_POWER_DOWN);
676
677 m = PRE_PLL_FB_DIV_8_MASK | PCLK_VCO_DIV_5_MASK | PRE_PLL_PRE_DIV_MASK;
678 v = PRE_PLL_FB_DIV_8(cfg->fbdiv >> 8) |
679 PCLK_VCO_DIV_5(cfg->vco_div_5_en) | PRE_PLL_PRE_DIV(cfg->prediv);
680 inno_update_bits(inno, 0xe2, m, v);
681
682 inno_write(inno, 0xe3, PRE_PLL_FB_DIV_7_0(cfg->fbdiv));
683
684 m = PRE_PLL_PCLK_DIV_B_MASK | PRE_PLL_PCLK_DIV_A_MASK;
685 v = PRE_PLL_PCLK_DIV_B(cfg->pclk_div_b) |
686 PRE_PLL_PCLK_DIV_A(cfg->pclk_div_a);
687 inno_update_bits(inno, 0xe4, m, v);
688
689 m = PRE_PLL_PCLK_DIV_C_MASK | PRE_PLL_PCLK_DIV_D_MASK;
690 v = PRE_PLL_PCLK_DIV_C(cfg->pclk_div_c) |
691 PRE_PLL_PCLK_DIV_D(cfg->pclk_div_d);
692 inno_update_bits(inno, 0xe5, m, v);
693
694 m = PRE_PLL_TMDSCLK_DIV_C_MASK | PRE_PLL_TMDSCLK_DIV_A_MASK |
695 PRE_PLL_TMDSCLK_DIV_B_MASK;
696 v = PRE_PLL_TMDSCLK_DIV_C(cfg->tmds_div_c) |
697 PRE_PLL_TMDSCLK_DIV_A(cfg->tmds_div_a) |
698 PRE_PLL_TMDSCLK_DIV_B(cfg->tmds_div_b);
699 inno_update_bits(inno, 0xe6, m, v);
700
701 /* Power up PRE-PLL */
702 inno_update_bits(inno, 0xe0, PRE_PLL_POWER_MASK, PRE_PLL_POWER_UP);
703
704 /* Wait for Pre-PLL lock */
705 pll_tries = 0;
706 while (!(inno_read(inno, 0xe8) & PRE_PLL_LOCK_STATUS)) {
707 if (pll_tries == INNO_HDMI_PHY_TIMEOUT_LOOP_COUNT) {
708 printf("Pre-PLL unlock\n");
709 return -ETIMEDOUT;
710 }
711
712 pll_tries++;
713 udelay(100);
714 }
715
716 return 0;
717 }
718
inno_hdmi_phy_rk3328_init(struct inno_hdmi_phy * inno)719 static void inno_hdmi_phy_rk3328_init(struct inno_hdmi_phy *inno)
720 {
721 /*
722 * Use phy internal register control
723 * rxsense/poweron/pllpd/pdataen signal.
724 */
725 inno_write(inno, 0x01, 0x07);
726 inno_write(inno, 0x02, 0x91);
727 }
728
729 static int
inno_hdmi_phy_rk3328_power_on(struct inno_hdmi_phy * inno,const struct post_pll_config * cfg,const struct phy_config * phy_cfg)730 inno_hdmi_phy_rk3328_power_on(struct inno_hdmi_phy *inno,
731 const struct post_pll_config *cfg,
732 const struct phy_config *phy_cfg)
733 {
734 u32 val;
735
736 /* set pdata_en to 0 */
737 inno_update_bits(inno, 0x02, 1, 0);
738 /* Power off post PLL */
739 inno_update_bits(inno, 0xaa, 1, 1);
740
741 val = cfg->fbdiv & 0xff;
742 inno_write(inno, 0xac, val);
743 if (cfg->postdiv == 1) {
744 inno_write(inno, 0xaa, 2);
745 val = (cfg->fbdiv >> 8) | cfg->prediv;
746 inno_write(inno, 0xab, val);
747 } else {
748 val = (cfg->postdiv / 2) - 1;
749 inno_write(inno, 0xad, val);
750 val = (cfg->fbdiv >> 8) | cfg->prediv;
751 inno_write(inno, 0xab, val);
752 inno_write(inno, 0xaa, 0x0e);
753 }
754
755 for (val = 0; val < 14; val++)
756 inno_write(inno, 0xb5 + val, phy_cfg->regs[val]);
757
758 /* bit[7:6] of reg c8/c9/ca/c8 is ESD detect threshold:
759 * 00 - 340mV
760 * 01 - 280mV
761 * 10 - 260mV
762 * 11 - 240mV
763 * default is 240mV, now we set it to 340mV
764 */
765 inno_write(inno, 0xc8, 0);
766 inno_write(inno, 0xc9, 0);
767 inno_write(inno, 0xca, 0);
768 inno_write(inno, 0xcb, 0);
769
770 if (phy_cfg->tmdsclock > 340000000) {
771 /* Set termination resistor to 100ohm */
772 val = 75000000 / 100000;
773 inno_write(inno, 0xc5, ((val >> 8) & 0xff) | 0x80);
774 inno_write(inno, 0xc6, val & 0xff);
775 inno_write(inno, 0xc7, 3 << 1);
776 inno_write(inno, 0xc5, ((val >> 8) & 0xff));
777 } else if (phy_cfg->tmdsclock > 165000000) {
778 inno_write(inno, 0xc5, 0x81);
779 /* clk termination resistor is 50ohm
780 * data termination resistor is 150ohm
781 */
782 inno_write(inno, 0xc8, 0x30);
783 inno_write(inno, 0xc9, 0x10);
784 inno_write(inno, 0xca, 0x10);
785 inno_write(inno, 0xcb, 0x10);
786 } else {
787 inno_write(inno, 0xc5, 0x81);
788 }
789
790 /* set TMDS sync detection counter length */
791 val = 47520000000UL / phy_cfg->tmdsclock;
792 inno_write(inno, 0xd8, (val >> 8) & 0xff);
793 inno_write(inno, 0xd9, val & 0xff);
794
795 /* Power up post PLL */
796 inno_update_bits(inno, 0xaa, 1, 0);
797 /* Power up tmds driver */
798 inno_update_bits(inno, 0xb0, 4, 4);
799 inno_write(inno, 0xb2, 0x0f);
800
801 /* Wait for post PLL lock */
802 for (val = 0; val < 5; val++) {
803 if (inno_read(inno, 0xaf) & 1)
804 break;
805 udelay(1000);
806 }
807 if (!(inno_read(inno, 0xaf) & 1)) {
808 printf("HDMI PHY Post PLL unlock\n");
809 return -ETIMEDOUT;
810 }
811 if (phy_cfg->tmdsclock > 340000000)
812 mdelay(100);
813 /* set pdata_en to 1 */
814 inno_update_bits(inno, 0x02, 1, 1);
815
816 return 0;
817 }
818
inno_hdmi_phy_rk3328_power_off(struct inno_hdmi_phy * inno)819 static void inno_hdmi_phy_rk3328_power_off(struct inno_hdmi_phy *inno)
820 {
821 /* Power off driver */
822 inno_write(inno, 0xb2, 0);
823 /* Power off band gap */
824 inno_update_bits(inno, 0xb0, 4, 0);
825 /* Power off post pll */
826 inno_update_bits(inno, 0xaa, 1, 1);
827 }
828
829 static int
inno_hdmi_phy_rk3328_pre_pll_update(struct inno_hdmi_phy * inno,const struct pre_pll_config * cfg)830 inno_hdmi_phy_rk3328_pre_pll_update(struct inno_hdmi_phy *inno,
831 const struct pre_pll_config *cfg)
832 {
833 u32 val;
834
835 /* Power off PLL */
836 inno_update_bits(inno, 0xa0, 1, 1);
837 /* Configure pre-pll */
838 inno_update_bits(inno, 0xa0, 2, (cfg->vco_div_5_en & 1) << 1);
839 inno_write(inno, 0xa1, cfg->prediv);
840 if (cfg->fracdiv)
841 val = ((cfg->fbdiv >> 8) & 0x0f) | 0xc0;
842 else
843 val = ((cfg->fbdiv >> 8) & 0x0f) | 0xf0;
844 inno_write(inno, 0xa2, val);
845 inno_write(inno, 0xa3, cfg->fbdiv & 0xff);
846 val = (cfg->pclk_div_a & 0x1f) |
847 ((cfg->pclk_div_b & 3) << 5);
848 inno_write(inno, 0xa5, val);
849 val = (cfg->pclk_div_d & 0x1f) |
850 ((cfg->pclk_div_c & 3) << 5);
851 inno_write(inno, 0xa6, val);
852 val = ((cfg->tmds_div_a & 3) << 4) |
853 ((cfg->tmds_div_b & 3) << 2) |
854 (cfg->tmds_div_c & 3);
855 inno_write(inno, 0xa4, val);
856
857 if (cfg->fracdiv) {
858 val = cfg->fracdiv & 0xff;
859 inno_write(inno, 0xd3, val);
860 val = (cfg->fracdiv >> 8) & 0xff;
861 inno_write(inno, 0xd2, val);
862 val = (cfg->fracdiv >> 16) & 0xff;
863 inno_write(inno, 0xd1, val);
864 } else {
865 inno_write(inno, 0xd3, 0);
866 inno_write(inno, 0xd2, 0);
867 inno_write(inno, 0xd1, 0);
868 }
869
870 /* Power up PLL */
871 inno_update_bits(inno, 0xa0, 1, 0);
872
873 /* Wait for PLL lock */
874 for (val = 0; val < 5; val++) {
875 if (inno_read(inno, 0xa9) & 1)
876 break;
877 udelay(1000);
878 }
879 if (val == 5) {
880 printf("Pre-PLL unlock\n");
881 return -ETIMEDOUT;
882 }
883
884 return 0;
885 }
886
887 static unsigned long
inno_hdmi_3328_phy_pll_recalc_rate(struct inno_hdmi_phy * inno,unsigned long parent_rate)888 inno_hdmi_3328_phy_pll_recalc_rate(struct inno_hdmi_phy *inno,
889 unsigned long parent_rate)
890 {
891 unsigned long rate, vco, frac;
892 u8 nd, no_a, no_b, no_d;
893 __maybe_unused u8 no_c;
894 u16 nf;
895
896 nd = inno_read(inno, 0xa1) & 0x3f;
897 nf = ((inno_read(inno, 0xa2) & 0x0f) << 8) | inno_read(inno, 0xa3);
898 vco = parent_rate * nf;
899 if ((inno_read(inno, 0xa2) & 0x30) == 0) {
900 frac = inno_read(inno, 0xd3) |
901 (inno_read(inno, 0xd2) << 8) |
902 (inno_read(inno, 0xd1) << 16);
903 vco += DIV_ROUND_CLOSEST(parent_rate * frac, (1 << 24));
904 }
905 if (inno_read(inno, 0xa0) & 2) {
906 rate = vco / (nd * 5);
907 } else {
908 no_a = inno_read(inno, 0xa5) & 0x1f;
909 no_b = ((inno_read(inno, 0xa5) >> 5) & 7) + 2;
910 no_c = (1 << ((inno_read(inno, 0xa6) >> 5) & 7));
911 no_d = inno_read(inno, 0xa6) & 0x1f;
912 if (no_a == 1)
913 rate = vco / (nd * no_b * no_d * 2);
914 else
915 rate = vco / (nd * no_a * no_d * 2);
916 }
917 inno->pixclock = rate;
918
919 return rate;
920 }
921
922 static int
inno_hdmi_phy_rk3528_power_on(struct inno_hdmi_phy * inno,const struct post_pll_config * cfg,const struct phy_config * phy_cfg)923 inno_hdmi_phy_rk3528_power_on(struct inno_hdmi_phy *inno,
924 const struct post_pll_config *cfg,
925 const struct phy_config *phy_cfg)
926 {
927 u32 val;
928 u64 temp;
929 u32 tmdsclock = inno_hdmi_phy_get_tmdsclk(inno, inno->pixclock);
930
931 /* Power off post PLL */
932 inno_update_bits(inno, 0xaa, 1, 0);
933
934 val = cfg->prediv;
935 inno_write(inno, 0xab, val);
936
937 if (cfg->postdiv == 1) {
938 inno_write(inno, 0xad, 0x8);
939 inno_write(inno, 0xaa, 2);
940 } else {
941 val = (cfg->postdiv / 2) - 1;
942 inno_write(inno, 0xad, val);
943 inno_write(inno, 0xaa, 0x0e);
944 }
945
946 val = cfg->fbdiv & 0xff;
947 inno_write(inno, 0xac, val);
948 val = (cfg->fbdiv >> 8) & BIT(0);
949 inno_update_bits(inno, 0xad, BIT(4), val);
950
951 /* current bias clk/data 2 */
952 val = phy_cfg->regs[0] << 4 | phy_cfg->regs[1];
953 inno_write(inno, 0xbf, val);
954
955 /* current bias data 1/0 */
956 val = phy_cfg->regs[1] << 4 | phy_cfg->regs[1];
957 inno_write(inno, 0xc0, val);
958
959 /* output voltage */
960 inno_write(inno, 0xb5, phy_cfg->regs[2]);
961 inno_write(inno, 0xb6, phy_cfg->regs[3]);
962 inno_write(inno, 0xb7, phy_cfg->regs[3]);
963 inno_write(inno, 0xb8, phy_cfg->regs[3]);
964
965 /* pre-emphasis */
966 inno_write(inno, 0xbb, phy_cfg->regs[4]);
967 inno_write(inno, 0xbc, phy_cfg->regs[4]);
968 inno_write(inno, 0xbd, phy_cfg->regs[4]);
969
970 /* enable LDO */
971 inno_write(inno, 0xb4, 0x7);
972
973 /* enable serializer */
974 inno_write(inno, 0xbe, 0x70);
975
976 inno_write(inno, 0xb2, 0x0f);
977
978 for (val = 0; val < 5; val++) {
979 if (inno_read(inno, 0xaf) & 1)
980 break;
981 udelay(1000);
982 }
983 if (!(inno_read(inno, 0xaf) & 1)) {
984 dev_err(inno->dev, "HDMI PHY Post PLL unlock\n");
985 return -ETIMEDOUT;
986 }
987
988 /* set termination resistance */
989 inno_write(inno, 0xc7, phy_cfg->regs[5]);
990 inno_write(inno, 0xc5, phy_cfg->regs[6]);
991 inno_write(inno, 0xc8, phy_cfg->regs[7]);
992 inno_write(inno, 0xc9, phy_cfg->regs[8]);
993 inno_write(inno, 0xca, phy_cfg->regs[8]);
994 inno_write(inno, 0xcb, phy_cfg->regs[8]);
995
996
997 /* set TMDS sync detection counter length */
998 temp = 47520000000UL / tmdsclock;
999 inno_write(inno, 0xd8, (temp >> 8) & 0xff);
1000 inno_write(inno, 0xd9, temp & 0xff);
1001
1002 if (phy_cfg->tmdsclock > 340000000)
1003 mdelay(100);
1004 /* set pdata_en to 0/1 */
1005 inno_update_bits(inno, 0x02, 1, 0);
1006 inno_update_bits(inno, 0x02, 1, 1);
1007
1008 /* Enable PHY IRQ */
1009 inno_write(inno, 0x05, 0x22);
1010 inno_write(inno, 0x07, 0x22);
1011 inno_write(inno, 0xcc, 0x0f);
1012
1013 return 0;
1014 }
1015
inno_hdmi_phy_rk3528_power_off(struct inno_hdmi_phy * inno)1016 static void inno_hdmi_phy_rk3528_power_off(struct inno_hdmi_phy *inno)
1017 {
1018 /* Power off driver */
1019 inno_write(inno, 0xb2, 0);
1020 /* Power off band gap */
1021 inno_update_bits(inno, 0xb0, 4, 0);
1022 /* Power off post pll */
1023 inno_update_bits(inno, 0xaa, 1, 1);
1024
1025 /* Disable PHY IRQ */
1026 inno_write(inno, 0x05, 0);
1027 inno_write(inno, 0x07, 0);
1028 }
1029
inno_hdmi_phy_rk3528_init(struct inno_hdmi_phy * inno)1030 static void inno_hdmi_phy_rk3528_init(struct inno_hdmi_phy *inno)
1031 {
1032 /*
1033 * Use phy internal register control
1034 * rxsense/poweron/pllpd/pdataen signal.
1035 */
1036 inno_write(inno, 0x02, 0x81);
1037 }
1038
1039 static int
inno_hdmi_phy_rk3528_pre_pll_update(struct inno_hdmi_phy * inno,const struct pre_pll_config * cfg)1040 inno_hdmi_phy_rk3528_pre_pll_update(struct inno_hdmi_phy *inno,
1041 const struct pre_pll_config *cfg)
1042 {
1043 u32 val;
1044
1045 inno_update_bits(inno, 0xb0, 4, 4);
1046 inno_write(inno, 0xcc, 0x0f);
1047
1048 /* Power on PLL */
1049 inno_update_bits(inno, 0xa0, 1, 0);
1050 /* Configure pre-pll */
1051 inno_update_bits(inno, 0xa0, 2, (cfg->vco_div_5_en & 1) << 1);
1052 inno_write(inno, 0xa1, cfg->prediv);
1053 if (cfg->fracdiv)
1054 val = ((cfg->fbdiv >> 8) & 0x0f) | 0xc0;
1055 else
1056 val = ((cfg->fbdiv >> 8) & 0x0f) | 0xf0;
1057 inno_write(inno, 0xa2, val);
1058 inno_write(inno, 0xa3, cfg->fbdiv & 0xff);
1059 val = (cfg->pclk_div_a & 0x1f) |
1060 ((cfg->pclk_div_b & 3) << 5);
1061 inno_write(inno, 0xa5, val);
1062 val = (cfg->pclk_div_d & 0x1f) |
1063 ((cfg->pclk_div_c & 3) << 5);
1064 inno_write(inno, 0xa6, val);
1065 val = ((cfg->tmds_div_a & 3) << 4) |
1066 ((cfg->tmds_div_b & 3) << 2) |
1067 (cfg->tmds_div_c & 3);
1068 inno_write(inno, 0xa4, val);
1069
1070 if (cfg->fracdiv) {
1071 val = cfg->fracdiv & 0xff;
1072 inno_write(inno, 0xd3, val);
1073 val = (cfg->fracdiv >> 8) & 0xff;
1074 inno_write(inno, 0xd2, val);
1075 val = (cfg->fracdiv >> 16) & 0xff;
1076 inno_write(inno, 0xd1, val);
1077 } else {
1078 inno_write(inno, 0xd3, 0);
1079 inno_write(inno, 0xd2, 0);
1080 inno_write(inno, 0xd1, 0);
1081 }
1082
1083 /* Wait for PLL lock */
1084 for (val = 0; val < 5; val++) {
1085 if (inno_read(inno, 0xa9) & 1)
1086 break;
1087 udelay(1000);
1088 }
1089 if (val == 5) {
1090 dev_err(inno->dev, "Pre-PLL unlock\n");
1091 return -ETIMEDOUT;
1092 }
1093
1094 return 0;
1095 }
1096
1097 static unsigned long
inno_hdmi_rk3528_phy_pll_recalc_rate(struct inno_hdmi_phy * inno,unsigned long parent_rate)1098 inno_hdmi_rk3528_phy_pll_recalc_rate(struct inno_hdmi_phy *inno,
1099 unsigned long parent_rate)
1100 {
1101 unsigned long frac;
1102 u8 nd, no_a, no_b, no_d;
1103 u16 nf;
1104 u64 vco = parent_rate;
1105
1106 nd = inno_read(inno, 0xa1) & 0x3f;
1107 nf = ((inno_read(inno, 0xa2) & 0x0f) << 8) | inno_read(inno, 0xa3);
1108 vco *= nf;
1109 if ((inno_read(inno, 0xa2) & 0x30) == 0) {
1110 frac = inno_read(inno, 0xd3) |
1111 (inno_read(inno, 0xd2) << 8) |
1112 (inno_read(inno, 0xd1) << 16);
1113 vco += DIV_ROUND_CLOSEST(parent_rate * frac, (1 << 24));
1114 }
1115 if (inno_read(inno, 0xa0) & 2) {
1116 do_div(vco, nd * 5);
1117 } else {
1118 no_a = inno_read(inno, 0xa5) & 0x1f;
1119 no_b = ((inno_read(inno, 0xa5) >> 5) & 7) + 2;
1120 no_d = inno_read(inno, 0xa6) & 0x1f;
1121 if (no_a == 1)
1122 do_div(vco, nd * no_b * no_d * 2);
1123 else
1124 do_div(vco, nd * no_a * no_d * 2);
1125 }
1126
1127 frac = vco;
1128 inno->pixclock = DIV_ROUND_CLOSEST(frac, 1000) * 1000;
1129
1130 dev_dbg(inno->dev, "%s rate %lu\n", __func__, inno->pixclock);
1131
1132 return frac;
1133 }
1134
1135 #ifndef CONFIG_SPL_BUILD
1136 #define PHY_TAB_LEN 60
1137
1138 static
inno_hdmi_update_phy_table(struct inno_hdmi_phy * inno,u32 * config,struct phy_config * phy_cfg,int phy_table_size)1139 int inno_hdmi_update_phy_table(struct inno_hdmi_phy *inno, u32 *config,
1140 struct phy_config *phy_cfg,
1141 int phy_table_size)
1142 {
1143 int i, j;
1144
1145 for (i = 0; i < phy_table_size; i++) {
1146 phy_cfg[i].tmdsclock =
1147 (unsigned long)config[i * 15];
1148
1149 debug("%ld ", phy_cfg[i].tmdsclock);
1150 for (j = 0; j < 14; j++) {
1151 phy_cfg[i].regs[j] = (u8)config[i * 15 + 1 + j];
1152 debug("0x%02x ", phy_cfg[i].regs[j]);
1153 }
1154 debug("\n");
1155 }
1156
1157 /*
1158 * The last set of phy cfg is used to indicate whether
1159 * there is no more phy cfg data.
1160 */
1161 phy_cfg[i].tmdsclock = ~0UL;
1162 for (j = 0; j < 14; j++)
1163 phy_cfg[i].regs[j] = 0;
1164
1165 return 0;
1166 }
1167 #endif
1168
1169 static const struct inno_hdmi_phy_ops rk3228_hdmi_phy_ops = {
1170 .init = inno_hdmi_phy_rk3228_init,
1171 .power_on = inno_hdmi_phy_rk3228_power_on,
1172 .power_off = inno_hdmi_phy_rk3228_power_off,
1173 .pre_pll_update = inno_hdmi_phy_rk3228_pre_pll_update,
1174 };
1175
1176 static const struct inno_hdmi_phy_ops rk3328_hdmi_phy_ops = {
1177 .init = inno_hdmi_phy_rk3328_init,
1178 .power_on = inno_hdmi_phy_rk3328_power_on,
1179 .power_off = inno_hdmi_phy_rk3328_power_off,
1180 .pre_pll_update = inno_hdmi_phy_rk3328_pre_pll_update,
1181 .recalc_rate = inno_hdmi_3328_phy_pll_recalc_rate,
1182 };
1183
1184 static const struct inno_hdmi_phy_ops rk3528_hdmi_phy_ops = {
1185 .init = inno_hdmi_phy_rk3528_init,
1186 .power_on = inno_hdmi_phy_rk3528_power_on,
1187 .power_off = inno_hdmi_phy_rk3528_power_off,
1188 .pre_pll_update = inno_hdmi_phy_rk3528_pre_pll_update,
1189 .recalc_rate = inno_hdmi_rk3528_phy_pll_recalc_rate,
1190 };
1191
1192 static const struct inno_hdmi_phy_drv_data rk3228_hdmi_phy_drv_data = {
1193 .dev_type = INNO_HDMI_PHY_RK3228,
1194 .ops = &rk3228_hdmi_phy_ops,
1195 .phy_cfg_table = rk3228_phy_cfg,
1196 };
1197
1198 static const struct inno_hdmi_phy_drv_data rk3328_hdmi_phy_drv_data = {
1199 .dev_type = INNO_HDMI_PHY_RK3328,
1200 .ops = &rk3328_hdmi_phy_ops,
1201 .phy_cfg_table = rk3328_phy_cfg,
1202 };
1203
1204 static const struct inno_hdmi_phy_drv_data rk3528_hdmi_phy_drv_data = {
1205 .dev_type = INNO_HDMI_PHY_RK3528,
1206 .ops = &rk3528_hdmi_phy_ops,
1207 .phy_cfg_table = rk3528_phy_cfg,
1208 };
1209
1210 static const struct rockchip_inno_data inno_hdmi_phy_of_match[] = {
1211 { .compatible = "rockchip,rk3228-hdmi-phy",
1212 .data = &rk3228_hdmi_phy_drv_data
1213 },
1214 { .compatible = "rockchip,rk3328-hdmi-phy",
1215 .data = &rk3328_hdmi_phy_drv_data
1216 },
1217 { .compatible = "rockchip,rk3528-hdmi-phy",
1218 .data = &rk3528_hdmi_phy_drv_data
1219 },
1220 {}
1221 };
1222
inno_hdmi_phy_init(struct rockchip_phy * phy)1223 static int inno_hdmi_phy_init(struct rockchip_phy *phy)
1224 {
1225 #ifdef CONFIG_SPL_BUILD
1226 struct inno_hdmi_phy *inno = (struct inno_hdmi_phy *)phy->data;
1227 #else
1228 struct udevice *dev = phy->dev;
1229 struct inno_hdmi_phy *inno = dev_get_priv(phy->dev);
1230 int val, phy_table_size, ret;
1231 u32 *phy_config;
1232 #endif
1233 int i;
1234 const char *name;
1235
1236 #ifdef CONFIG_SPL_BUILD
1237 inno->regs = (void *)RK3528_HDMIPHY_BASE;
1238 #else
1239 inno->regs = dev_read_addr_ptr(dev);
1240 inno->node = dev->node;
1241 #endif
1242 if (!inno->regs) {
1243 printf("%s: failed to get phy address\n", __func__);
1244 return -ENOMEM;
1245 }
1246
1247 #ifdef CONFIG_SPL_BUILD
1248 name = "rockchip,rk3528-hdmi-phy";
1249 #else
1250 name = dev_read_string(dev, "compatible");
1251 #endif
1252 for (i = 0; i < ARRAY_SIZE(inno_hdmi_phy_of_match); i++) {
1253 if (!strcmp(name, inno_hdmi_phy_of_match[i].compatible)) {
1254 inno->plat_data = inno_hdmi_phy_of_match[i].data;
1255 break;
1256 }
1257 }
1258
1259 #ifndef CONFIG_SPL_BUILD
1260 dev_read_prop(dev, "rockchip,phy-table", &val);
1261
1262 if (val >= 0) {
1263 if (val % PHY_TAB_LEN || !val) {
1264 printf("Invalid phy cfg table format!\n");
1265 return -EINVAL;
1266 }
1267
1268 phy_config = malloc(val);
1269 if (!phy_config) {
1270 printf("kmalloc phy table failed\n");
1271 return -ENOMEM;
1272 }
1273
1274 phy_table_size = val / PHY_TAB_LEN;
1275 /* Effective phy cfg data and the end of phy cfg table */
1276 inno->phy_cfg = malloc(val + PHY_TAB_LEN);
1277 if (!inno->phy_cfg) {
1278 free(phy_config);
1279 return -ENOMEM;
1280 }
1281
1282 dev_read_u32_array(dev, "rockchip,phy-table",
1283 phy_config, val / sizeof(u32));
1284 ret = inno_hdmi_update_phy_table(inno, phy_config,
1285 inno->phy_cfg,
1286 phy_table_size);
1287 if (ret) {
1288 free(phy_config);
1289 return ret;
1290 }
1291 free(phy_config);
1292 } else {
1293 printf("use default hdmi phy table\n");
1294 }
1295 #endif
1296
1297 if (i >= ARRAY_SIZE(inno_hdmi_phy_of_match))
1298 return 0;
1299
1300 if (!inno->plat_data || !inno->plat_data->ops)
1301 return -EINVAL;
1302
1303 if (inno->plat_data->ops->init)
1304 inno->plat_data->ops->init(inno);
1305
1306 return 0;
1307 }
1308
inno_hdmi_phy_set_pll(struct rockchip_phy * phy,unsigned long rate)1309 static unsigned long inno_hdmi_phy_set_pll(struct rockchip_phy *phy,
1310 unsigned long rate)
1311 {
1312 #ifdef CONFIG_SPL_BUILD
1313 struct inno_hdmi_phy *inno = (struct inno_hdmi_phy *)phy->data;
1314 #else
1315 struct inno_hdmi_phy *inno = dev_get_priv(phy->dev);
1316 #endif
1317
1318 #ifdef CONFIG_SPL_BUILD
1319 if (!inno)
1320 inno = g_inno;
1321 #endif
1322 inno_hdmi_phy_clk_prepare(inno);
1323 inno_hdmi_phy_clk_is_prepared(inno);
1324 inno_hdmi_phy_clk_set_rate(inno, rate);
1325 return 0;
1326 }
1327
1328 static int
inno_hdmi_phy_set_bus_width(struct rockchip_phy * phy,u32 bus_width)1329 inno_hdmi_phy_set_bus_width(struct rockchip_phy *phy, u32 bus_width)
1330 {
1331 #ifdef CONFIG_SPL_BUILD
1332 struct inno_hdmi_phy *inno = (struct inno_hdmi_phy *)phy->data;
1333 #else
1334 struct inno_hdmi_phy *inno = dev_get_priv(phy->dev);
1335 #endif
1336
1337 inno->bus_width = bus_width;
1338
1339 return 0;
1340 }
1341
1342 static long
inno_hdmi_phy_clk_round_rate(struct rockchip_phy * phy,unsigned long rate)1343 inno_hdmi_phy_clk_round_rate(struct rockchip_phy *phy, unsigned long rate)
1344 {
1345 #ifdef CONFIG_SPL_BUILD
1346 struct inno_hdmi_phy *inno = (struct inno_hdmi_phy *)phy->data;
1347 #else
1348 struct inno_hdmi_phy *inno = dev_get_priv(phy->dev);
1349 #endif
1350 int i;
1351 const struct pre_pll_config *cfg = pre_pll_cfg_table;
1352 u32 tmdsclock = inno_hdmi_phy_get_tmdsclk(inno, rate);
1353
1354 for (; cfg->pixclock != ~0UL; cfg++)
1355 if (cfg->pixclock == rate)
1356 break;
1357
1358 /*
1359 * XXX: Limit pixel clock under 600MHz
1360 * rk3228 does not support non-zero fracdiv
1361 */
1362 if ((inno->plat_data->dev_type == INNO_HDMI_PHY_RK3228 &&
1363 cfg->fracdiv) || cfg->pixclock > 600000000)
1364 return -EINVAL;
1365
1366 /*
1367 * If there is no dts phy cfg table, use default phy cfg table.
1368 * The tmds clock maximum is 594MHz. So there is no need to check
1369 * whether tmds clock is out of range.
1370 */
1371 if (!inno->phy_cfg)
1372 return cfg->pixclock;
1373
1374 /* Check if tmds clock is out of dts phy config's range. */
1375 for (i = 0; inno->phy_cfg[i].tmdsclock != ~0UL; i++) {
1376 if (inno->phy_cfg[i].tmdsclock >= tmdsclock)
1377 break;
1378 }
1379
1380 if (inno->phy_cfg[i].tmdsclock == ~0UL)
1381 return -EINVAL;
1382
1383 return cfg->pixclock;
1384 }
1385
1386 const struct rockchip_phy_funcs inno_hdmi_phy_funcs = {
1387 .init = inno_hdmi_phy_init,
1388 .power_on = inno_hdmi_phy_power_on,
1389 .power_off = inno_hdmi_phy_power_off,
1390 .set_pll = inno_hdmi_phy_set_pll,
1391 .set_bus_width = inno_hdmi_phy_set_bus_width,
1392 .round_rate = inno_hdmi_phy_clk_round_rate,
1393 };
1394
1395 static struct rockchip_phy inno_hdmi_phy_driver_data = {
1396 .funcs = &inno_hdmi_phy_funcs,
1397 };
1398
1399 static const struct udevice_id inno_hdmi_phy_ids[] = {
1400 {
1401 .compatible = "rockchip,rk3328-hdmi-phy",
1402 .data = (ulong)&inno_hdmi_phy_driver_data,
1403 },
1404 {
1405 .compatible = "rockchip,rk3228-hdmi-phy",
1406 .data = (ulong)&inno_hdmi_phy_driver_data,
1407 },
1408 {
1409 .compatible = "rockchip,rk3528-hdmi-phy",
1410 .data = (ulong)&inno_hdmi_phy_driver_data,
1411 },
1412 {}
1413 };
1414
1415 #ifdef CONFIG_SPL_BUILD
inno_spl_hdmi_phy_probe(struct display_state * state)1416 int inno_spl_hdmi_phy_probe(struct display_state *state)
1417 {
1418 struct inno_hdmi_phy *inno = malloc(sizeof(struct inno_hdmi_phy));
1419
1420 memset(inno, 0, sizeof(*inno));
1421 g_inno = inno;
1422
1423 state->conn_state.connector->phy = &inno_hdmi_phy_driver_data;
1424 state->conn_state.connector->phy->data = (void *)inno;
1425 return 0;
1426 }
1427 #else
inno_hdmi_phy_probe(struct udevice * dev)1428 static int inno_hdmi_phy_probe(struct udevice *dev)
1429 {
1430 struct inno_hdmi_phy *inno = dev_get_priv(dev);
1431 struct rockchip_phy *phy =
1432 (struct rockchip_phy *)dev_get_driver_data(dev);
1433
1434 inno->dev = dev;
1435 phy->dev = dev;
1436
1437 g_inno = inno;
1438 dev->driver_data = (ulong)&inno_hdmi_phy_driver_data;
1439 phy = &inno_hdmi_phy_driver_data;
1440
1441 return 0;
1442 }
1443 #endif
1444
rockchip_inno_phy_hdmi_bind(struct udevice * parent)1445 static int rockchip_inno_phy_hdmi_bind(struct udevice *parent)
1446 {
1447 struct udevice *child;
1448 ofnode subnode;
1449 int ret;
1450
1451 subnode = ofnode_find_subnode(parent->node, "clk-port");
1452 if (!ofnode_valid(subnode)) {
1453 printf("%s: no subnode for %s\n", __func__, parent->name);
1454 return -ENXIO;
1455 }
1456
1457 ret = device_bind_driver_to_node(parent, "clk_inno_hdmi", "inno_hdmi_pll_clk", subnode, &child);
1458 if (ret) {
1459 printf("%s: clk-port cannot bind its driver\n", __func__);
1460 return ret;
1461 }
1462
1463 return 0;
1464 }
1465
1466 U_BOOT_DRIVER(inno_hdmi_phy) = {
1467 .name = "inno_hdmi_phy",
1468 .id = UCLASS_PHY,
1469 .of_match = inno_hdmi_phy_ids,
1470 #ifndef CONFIG_SPL_BUILD
1471 .probe = inno_hdmi_phy_probe,
1472 #endif
1473 .bind = rockchip_inno_phy_hdmi_bind,
1474 .priv_auto_alloc_size = sizeof(struct inno_hdmi_phy),
1475 };
1476
1477
inno_hdmi_clk_get_rate(struct clk * clk)1478 static ulong inno_hdmi_clk_get_rate(struct clk *clk)
1479 {
1480 struct clk_inno_hdmi *priv = dev_get_priv(clk->dev);
1481
1482 return priv->rate;
1483 }
1484
inno_hdmi_clk_set_rate(struct clk * clk,ulong rate)1485 static ulong inno_hdmi_clk_set_rate(struct clk *clk, ulong rate)
1486 {
1487 struct clk_inno_hdmi *priv = dev_get_priv(clk->dev);
1488 int ret;
1489
1490 inno_hdmi_phy_clk_prepare(g_inno);
1491 inno_hdmi_phy_clk_is_prepared(g_inno);
1492 ret = inno_hdmi_phy_clk_set_rate(g_inno, rate);
1493 if (ret < 0) {
1494 printf("inno hdmi set rate failed ret:%d\n", ret);
1495 return ret;
1496 }
1497
1498 priv->rate = g_inno->pixclock;
1499
1500 return priv->rate;
1501 }
1502
1503 static const struct clk_ops inno_hdmi_clk_ops = {
1504 .get_rate = inno_hdmi_clk_get_rate,
1505 .set_rate = inno_hdmi_clk_set_rate,
1506 };
1507
inno_hdmi_clk_probe(struct udevice * dev)1508 static int inno_hdmi_clk_probe(struct udevice *dev)
1509 {
1510 return 0;
1511 }
1512
1513 /*
1514 * In order for other display interfaces to use hdmiphy as source
1515 * for dclk, hdmiphy must register a virtual clock driver
1516 */
1517 U_BOOT_DRIVER(clk_inno_hdmi) = {
1518 .name = "clk_inno_hdmi",
1519 .id = UCLASS_CLK,
1520 .priv_auto_alloc_size = sizeof(struct clk_inno_hdmi),
1521 .ops = &inno_hdmi_clk_ops,
1522 .probe = inno_hdmi_clk_probe,
1523 };
1524