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