1 /*
2  * Copyright (c) 2015 Google, Inc
3  * Copyright 2014 Rockchip Inc.
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #include <common.h>
9 #include <clk.h>
10 #include <display.h>
11 #include <dm.h>
12 #include <edid.h>
13 #include <regmap.h>
14 #include <syscon.h>
15 #include <asm/gpio.h>
16 #include <asm/io.h>
17 #include <asm/arch/clock.h>
18 #include <asm/arch/grf_rk3288.h>
19 #include <asm/arch/hdmi_rk3288.h>
20 #include <power/regulator.h>
21 
22 struct tmds_n_cts {
23 	u32 tmds;
24 	u32 cts;
25 	u32 n;
26 };
27 
28 struct rk_hdmi_priv {
29 	struct rk3288_hdmi *regs;
30 	struct rk3288_grf *grf;
31 };
32 
33 static const struct tmds_n_cts n_cts_table[] = {
34 	{
35 		.tmds = 25175000, .n = 6144, .cts = 25175,
36 	}, {
37 		.tmds = 25200000, .n = 6144, .cts = 25200,
38 	}, {
39 		.tmds = 27000000, .n = 6144, .cts = 27000,
40 	}, {
41 		.tmds = 27027000, .n = 6144, .cts = 27027,
42 	}, {
43 		.tmds = 40000000, .n = 6144, .cts = 40000,
44 	}, {
45 		.tmds = 54000000, .n = 6144, .cts = 54000,
46 	}, {
47 		.tmds = 54054000, .n = 6144, .cts = 54054,
48 	}, {
49 		.tmds = 65000000, .n = 6144, .cts = 65000,
50 	}, {
51 		.tmds = 74176000, .n = 11648, .cts = 140625,
52 	}, {
53 		.tmds = 74250000, .n = 6144, .cts = 74250,
54 	}, {
55 		.tmds = 83500000, .n = 6144, .cts = 83500,
56 	}, {
57 		.tmds = 106500000, .n = 6144, .cts = 106500,
58 	}, {
59 		.tmds = 108000000, .n = 6144, .cts = 108000,
60 	}, {
61 		.tmds = 148352000, .n = 5824, .cts = 140625,
62 	}, {
63 		.tmds = 148500000, .n = 6144, .cts = 148500,
64 	}, {
65 		.tmds = 297000000, .n = 5120, .cts = 247500,
66 	}
67 };
68 
69 struct hdmi_mpll_config {
70 	u64 mpixelclock;
71 	/* Mode of Operation and PLL Dividers Control Register */
72 	u32 cpce;
73 	/* PLL Gmp Control Register */
74 	u32 gmp;
75 	/* PLL Current COntrol Register */
76 	u32 curr;
77 };
78 
79 struct hdmi_phy_config {
80 	u64 mpixelclock;
81 	u32 sym_ctr;    /* clock symbol and transmitter control */
82 	u32 term;       /* transmission termination value */
83 	u32 vlev_ctr;   /* voltage level control */
84 };
85 
86 static const struct hdmi_phy_config rockchip_phy_config[] = {
87 	{
88 		.mpixelclock = 74250000,
89 		.sym_ctr = 0x8009, .term = 0x0004, .vlev_ctr = 0x0272,
90 	}, {
91 		.mpixelclock = 148500000,
92 		.sym_ctr = 0x802b, .term = 0x0004, .vlev_ctr = 0x028d,
93 	}, {
94 		.mpixelclock = 297000000,
95 		.sym_ctr = 0x8039, .term = 0x0005, .vlev_ctr = 0x028d,
96 	}, {
97 		.mpixelclock = ~0ul,
98 		.sym_ctr = 0x0000, .term = 0x0000, .vlev_ctr = 0x0000,
99 	}
100 };
101 
102 static const struct hdmi_mpll_config rockchip_mpll_cfg[] = {
103 	{
104 		.mpixelclock = 40000000,
105 		.cpce = 0x00b3, .gmp = 0x0000, .curr = 0x0018,
106 	}, {
107 		.mpixelclock = 65000000,
108 		.cpce = 0x0072, .gmp = 0x0001, .curr = 0x0028,
109 	}, {
110 		.mpixelclock = 66000000,
111 		.cpce = 0x013e, .gmp = 0x0003, .curr = 0x0038,
112 	}, {
113 		.mpixelclock = 83500000,
114 		.cpce = 0x0072, .gmp = 0x0001, .curr = 0x0028,
115 	}, {
116 		.mpixelclock = 146250000,
117 		.cpce = 0x0051, .gmp = 0x0002, .curr = 0x0038,
118 	}, {
119 		.mpixelclock = 148500000,
120 		.cpce = 0x0051, .gmp = 0x0003, .curr = 0x0000,
121 	}, {
122 		.mpixelclock = ~0ul,
123 		.cpce = 0x0051, .gmp = 0x0003, .curr = 0x0000,
124 	}
125 };
126 
127 static void hdmi_set_clock_regenerator(struct rk3288_hdmi *regs, u32 n, u32 cts)
128 {
129 	uint cts3;
130 	uint n3;
131 
132 	/* first set ncts_atomic_write (if present) */
133 	n3 = HDMI_AUD_N3_NCTS_ATOMIC_WRITE;
134 	writel(n3, &regs->aud_n3);
135 
136 	/* set cts_manual (if present) */
137 	cts3 = HDMI_AUD_CTS3_CTS_MANUAL;
138 
139 	cts3 |= HDMI_AUD_CTS3_N_SHIFT_1 << HDMI_AUD_CTS3_N_SHIFT_OFFSET;
140 	cts3 |= (cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK;
141 
142 	/* write cts values; cts3 must be written first */
143 	writel(cts3, &regs->aud_cts3);
144 	writel((cts >> 8) & 0xff, &regs->aud_cts2);
145 	writel(cts & 0xff, &regs->aud_cts1);
146 
147 	/* write n values; n1 must be written last */
148 	n3 |= (n >> 16) & HDMI_AUD_N3_AUDN19_16_MASK;
149 	writel(n3, &regs->aud_n3);
150 	writel((n >> 8) & 0xff, &regs->aud_n2);
151 	writel(n & 0xff, &regs->aud_n1);
152 
153 	writel(HDMI_AUD_INPUTCLKFS_128, &regs->aud_inputclkfs);
154 }
155 
156 static int hdmi_lookup_n_cts(u32 pixel_clk)
157 {
158 	int i;
159 
160 	for (i = 0; i < ARRAY_SIZE(n_cts_table); i++)
161 		if (pixel_clk <= n_cts_table[i].tmds)
162 			break;
163 
164 	if (i >= ARRAY_SIZE(n_cts_table))
165 		return -1;
166 
167 	return i;
168 }
169 
170 static void hdmi_audio_set_samplerate(struct rk3288_hdmi *regs, u32 pixel_clk)
171 {
172 	u32 clk_n, clk_cts;
173 	int index;
174 
175 	index = hdmi_lookup_n_cts(pixel_clk);
176 	if (index == -1) {
177 		debug("audio not supported for pixel clk %d\n", pixel_clk);
178 		return;
179 	}
180 
181 	clk_n = n_cts_table[index].n;
182 	clk_cts = n_cts_table[index].cts;
183 	hdmi_set_clock_regenerator(regs, clk_n, clk_cts);
184 }
185 
186 /*
187  * this submodule is responsible for the video data synchronization.
188  * for example, for rgb 4:4:4 input, the data map is defined as
189  *			pin{47~40} <==> r[7:0]
190  *			pin{31~24} <==> g[7:0]
191  *			pin{15~8}  <==> b[7:0]
192  */
193 static void hdmi_video_sample(struct rk3288_hdmi *regs)
194 {
195 	u32 color_format = 0x01;
196 	uint val;
197 
198 	val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE |
199 	      ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) &
200 	      HDMI_TX_INVID0_VIDEO_MAPPING_MASK);
201 
202 	writel(val, &regs->tx_invid0);
203 
204 	/* enable tx stuffing: when de is inactive, fix the output data to 0 */
205 	val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE |
206 	      HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE |
207 	      HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE;
208 	writel(val, &regs->tx_instuffing);
209 	writel(0x0, &regs->tx_gydata0);
210 	writel(0x0, &regs->tx_gydata1);
211 	writel(0x0, &regs->tx_rcrdata0);
212 	writel(0x0, &regs->tx_rcrdata1);
213 	writel(0x0, &regs->tx_bcbdata0);
214 	writel(0x0, &regs->tx_bcbdata1);
215 }
216 
217 static void hdmi_video_packetize(struct rk3288_hdmi *regs)
218 {
219 	u32 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
220 	u32 remap_size = HDMI_VP_REMAP_YCC422_16BIT;
221 	u32 color_depth = 0;
222 	uint val, vp_conf;
223 
224 	/* set the packetizer registers */
225 	val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
226 		HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
227 		((0 << HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
228 		HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
229 	writel(val, &regs->vp_pr_cd);
230 
231 	clrsetbits_le32(&regs->vp_stuff, HDMI_VP_STUFF_PR_STUFFING_MASK,
232 			HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE);
233 
234 	/* data from pixel repeater block */
235 	vp_conf = HDMI_VP_CONF_PR_EN_DISABLE |
236 		  HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
237 
238 	clrsetbits_le32(&regs->vp_conf, HDMI_VP_CONF_PR_EN_MASK |
239 			HDMI_VP_CONF_BYPASS_SELECT_MASK, vp_conf);
240 
241 	clrsetbits_le32(&regs->vp_stuff, HDMI_VP_STUFF_IDEFAULT_PHASE_MASK,
242 			1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET);
243 
244 	writel(remap_size, &regs->vp_remap);
245 
246 	vp_conf = HDMI_VP_CONF_BYPASS_EN_ENABLE |
247 		  HDMI_VP_CONF_PP_EN_DISABLE |
248 		  HDMI_VP_CONF_YCC422_EN_DISABLE;
249 
250 	clrsetbits_le32(&regs->vp_conf, HDMI_VP_CONF_BYPASS_EN_MASK |
251 			HDMI_VP_CONF_PP_EN_ENMASK | HDMI_VP_CONF_YCC422_EN_MASK,
252 			vp_conf);
253 
254 	clrsetbits_le32(&regs->vp_stuff, HDMI_VP_STUFF_PP_STUFFING_MASK |
255 			HDMI_VP_STUFF_YCC422_STUFFING_MASK,
256 			HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE |
257 			HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE);
258 
259 	clrsetbits_le32(&regs->vp_conf, HDMI_VP_CONF_OUTPUT_SELECTOR_MASK,
260 			output_select);
261 }
262 
263 static inline void hdmi_phy_test_clear(struct rk3288_hdmi *regs, uint bit)
264 {
265 	clrsetbits_le32(&regs->phy_tst0, HDMI_PHY_TST0_TSTCLR_MASK,
266 			bit << HDMI_PHY_TST0_TSTCLR_OFFSET);
267 }
268 
269 static int hdmi_phy_wait_i2c_done(struct rk3288_hdmi *regs, u32 msec)
270 {
271 	ulong start;
272 	u32 val;
273 
274 	start = get_timer(0);
275 	do {
276 		val = readl(&regs->ih_i2cmphy_stat0);
277 		if (val & 0x3) {
278 			writel(val, &regs->ih_i2cmphy_stat0);
279 			return 0;
280 		}
281 
282 		udelay(100);
283 	} while (get_timer(start) < msec);
284 
285 	return 1;
286 }
287 
288 static void hdmi_phy_i2c_write(struct rk3288_hdmi *regs, uint data, uint addr)
289 {
290 	writel(0xff, &regs->ih_i2cmphy_stat0);
291 	writel(addr, &regs->phy_i2cm_address_addr);
292 	writel((u8)(data >> 8), &regs->phy_i2cm_datao_1_addr);
293 	writel((u8)(data >> 0), &regs->phy_i2cm_datao_0_addr);
294 	writel(HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
295 	       &regs->phy_i2cm_operation_addr);
296 
297 	hdmi_phy_wait_i2c_done(regs, 1000);
298 }
299 
300 static void hdmi_phy_enable_power(struct rk3288_hdmi *regs, uint enable)
301 {
302 	clrsetbits_le32(&regs->phy_conf0, HDMI_PHY_CONF0_PDZ_MASK,
303 			enable << HDMI_PHY_CONF0_PDZ_OFFSET);
304 }
305 
306 static void hdmi_phy_enable_tmds(struct rk3288_hdmi *regs, uint enable)
307 {
308 	clrsetbits_le32(&regs->phy_conf0, HDMI_PHY_CONF0_ENTMDS_MASK,
309 			enable << HDMI_PHY_CONF0_ENTMDS_OFFSET);
310 }
311 
312 static void hdmi_phy_enable_spare(struct rk3288_hdmi *regs, uint enable)
313 {
314 	clrsetbits_le32(&regs->phy_conf0, HDMI_PHY_CONF0_SPARECTRL_MASK,
315 			enable << HDMI_PHY_CONF0_SPARECTRL_OFFSET);
316 }
317 
318 static void hdmi_phy_gen2_pddq(struct rk3288_hdmi *regs, uint enable)
319 {
320 	clrsetbits_le32(&regs->phy_conf0, HDMI_PHY_CONF0_GEN2_PDDQ_MASK,
321 			enable << HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET);
322 }
323 
324 static void hdmi_phy_gen2_txpwron(struct rk3288_hdmi *regs, uint enable)
325 {
326 	clrsetbits_le32(&regs->phy_conf0,
327 			HDMI_PHY_CONF0_GEN2_TXPWRON_MASK,
328 			enable << HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET);
329 }
330 
331 static void hdmi_phy_sel_data_en_pol(struct rk3288_hdmi *regs, uint enable)
332 {
333 	clrsetbits_le32(&regs->phy_conf0,
334 			HDMI_PHY_CONF0_SELDATAENPOL_MASK,
335 			enable << HDMI_PHY_CONF0_SELDATAENPOL_OFFSET);
336 }
337 
338 static void hdmi_phy_sel_interface_control(struct rk3288_hdmi *regs,
339 					   uint enable)
340 {
341 	clrsetbits_le32(&regs->phy_conf0, HDMI_PHY_CONF0_SELDIPIF_MASK,
342 			enable << HDMI_PHY_CONF0_SELDIPIF_OFFSET);
343 }
344 
345 static int hdmi_phy_configure(struct rk3288_hdmi *regs, u32 mpixelclock)
346 {
347 	ulong start;
348 	uint i, val;
349 
350 	writel(HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS,
351 	       &regs->mc_flowctrl);
352 
353 	/* gen2 tx power off */
354 	hdmi_phy_gen2_txpwron(regs, 0);
355 
356 	/* gen2 pddq */
357 	hdmi_phy_gen2_pddq(regs, 1);
358 
359 	/* phy reset */
360 	writel(HDMI_MC_PHYRSTZ_DEASSERT, &regs->mc_phyrstz);
361 	writel(HDMI_MC_PHYRSTZ_ASSERT, &regs->mc_phyrstz);
362 	writel(HDMI_MC_HEACPHY_RST_ASSERT, &regs->mc_heacphy_rst);
363 
364 	hdmi_phy_test_clear(regs, 1);
365 	writel(HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2, &regs->phy_i2cm_slave_addr);
366 	hdmi_phy_test_clear(regs, 0);
367 
368 	/* pll/mpll cfg - always match on final entry */
369 	for (i = 0; rockchip_mpll_cfg[i].mpixelclock != (~0ul); i++)
370 		if (mpixelclock <= rockchip_mpll_cfg[i].mpixelclock)
371 			break;
372 
373 	hdmi_phy_i2c_write(regs, rockchip_mpll_cfg[i].cpce, PHY_OPMODE_PLLCFG);
374 	hdmi_phy_i2c_write(regs, rockchip_mpll_cfg[i].gmp, PHY_PLLGMPCTRL);
375 	hdmi_phy_i2c_write(regs, rockchip_mpll_cfg[i].curr, PHY_PLLCURRCTRL);
376 
377 	hdmi_phy_i2c_write(regs, 0x0000, PHY_PLLPHBYCTRL);
378 	hdmi_phy_i2c_write(regs, 0x0006, PHY_PLLCLKBISTPHASE);
379 
380 	for (i = 0; rockchip_phy_config[i].mpixelclock != (~0ul); i++)
381 		if (mpixelclock <= rockchip_phy_config[i].mpixelclock)
382 			break;
383 
384 	/*
385 	 * resistance term 133ohm cfg
386 	 * preemp cgf 0.00
387 	 * tx/ck lvl 10
388 	 */
389 	hdmi_phy_i2c_write(regs, rockchip_phy_config[i].term, PHY_TXTERM);
390 	hdmi_phy_i2c_write(regs, rockchip_phy_config[i].sym_ctr,
391 			   PHY_CKSYMTXCTRL);
392 	hdmi_phy_i2c_write(regs, rockchip_phy_config[i].vlev_ctr, PHY_VLEVCTRL);
393 
394 	/* remove clk term */
395 	hdmi_phy_i2c_write(regs, 0x8000, PHY_CKCALCTRL);
396 
397 	hdmi_phy_enable_power(regs, 1);
398 
399 	/* toggle tmds enable */
400 	hdmi_phy_enable_tmds(regs, 0);
401 	hdmi_phy_enable_tmds(regs, 1);
402 
403 	/* gen2 tx power on */
404 	hdmi_phy_gen2_txpwron(regs, 1);
405 	hdmi_phy_gen2_pddq(regs, 0);
406 
407 	hdmi_phy_enable_spare(regs, 1);
408 
409 	/* wait for phy pll lock */
410 	start = get_timer(0);
411 	do {
412 		val = readl(&regs->phy_stat0);
413 		if (!(val & HDMI_PHY_TX_PHY_LOCK))
414 			return 0;
415 
416 		udelay(100);
417 	} while (get_timer(start) < 5);
418 
419 	return -1;
420 }
421 
422 static int hdmi_phy_init(struct rk3288_hdmi *regs, uint mpixelclock)
423 {
424 	int i, ret;
425 
426 	/* hdmi phy spec says to do the phy initialization sequence twice */
427 	for (i = 0; i < 2; i++) {
428 		hdmi_phy_sel_data_en_pol(regs, 1);
429 		hdmi_phy_sel_interface_control(regs, 0);
430 		hdmi_phy_enable_tmds(regs, 0);
431 		hdmi_phy_enable_power(regs, 0);
432 
433 		ret = hdmi_phy_configure(regs, mpixelclock);
434 		if (ret) {
435 			debug("hdmi phy config failure %d\n", ret);
436 			return ret;
437 		}
438 	}
439 
440 	return 0;
441 }
442 
443 static void hdmi_av_composer(struct rk3288_hdmi *regs,
444 			     const struct display_timing *edid)
445 {
446 	bool mdataenablepolarity = true;
447 	uint inv_val;
448 	uint hbl;
449 	uint vbl;
450 
451 	hbl = edid->hback_porch.typ + edid->hfront_porch.typ +
452 			edid->hsync_len.typ;
453 	vbl = edid->vback_porch.typ + edid->vfront_porch.typ +
454 			edid->vsync_len.typ;
455 
456 	/* set up hdmi_fc_invidconf */
457 	inv_val = HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE;
458 
459 	inv_val |= (edid->flags & DISPLAY_FLAGS_HSYNC_HIGH ?
460 		   HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
461 		   HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW);
462 
463 	inv_val |= (edid->flags & DISPLAY_FLAGS_VSYNC_HIGH ?
464 		   HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH :
465 		   HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW);
466 
467 	inv_val |= (mdataenablepolarity ?
468 		   HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
469 		   HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
470 
471 	/*
472 	 * TODO(sjg@chromium.org>: Need to check for HDMI / DVI
473 	 * inv_val |= (edid->hdmi_monitor_detected ?
474 	 *	   HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE :
475 	 *	   HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE);
476 	 */
477 	inv_val |= HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE;
478 
479 	inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW;
480 
481 	inv_val |= HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE;
482 
483 	writel(inv_val, &regs->fc_invidconf);
484 
485 	/* set up horizontal active pixel width */
486 	writel(edid->hactive.typ >> 8, &regs->fc_inhactv1);
487 	writel(edid->hactive.typ, &regs->fc_inhactv0);
488 
489 	/* set up vertical active lines */
490 	writel(edid->vactive.typ >> 8, &regs->fc_invactv1);
491 	writel(edid->vactive.typ, &regs->fc_invactv0);
492 
493 	/* set up horizontal blanking pixel region width */
494 	writel(hbl >> 8, &regs->fc_inhblank1);
495 	writel(hbl, &regs->fc_inhblank0);
496 
497 	/* set up vertical blanking pixel region width */
498 	writel(vbl, &regs->fc_invblank);
499 
500 	/* set up hsync active edge delay width (in pixel clks) */
501 	writel(edid->hfront_porch.typ >> 8, &regs->fc_hsyncindelay1);
502 	writel(edid->hfront_porch.typ, &regs->fc_hsyncindelay0);
503 
504 	/* set up vsync active edge delay (in lines) */
505 	writel(edid->vfront_porch.typ, &regs->fc_vsyncindelay);
506 
507 	/* set up hsync active pulse width (in pixel clks) */
508 	writel(edid->hsync_len.typ >> 8, &regs->fc_hsyncinwidth1);
509 	writel(edid->hsync_len.typ, &regs->fc_hsyncinwidth0);
510 
511 	/* set up vsync active edge delay (in lines) */
512 	writel(edid->vsync_len.typ, &regs->fc_vsyncinwidth);
513 }
514 
515 /* hdmi initialization step b.4 */
516 static void hdmi_enable_video_path(struct rk3288_hdmi *regs)
517 {
518 	uint clkdis;
519 
520 	/* control period minimum duration */
521 	writel(12, &regs->fc_ctrldur);
522 	writel(32, &regs->fc_exctrldur);
523 	writel(1, &regs->fc_exctrlspac);
524 
525 	/* set to fill tmds data channels */
526 	writel(0x0b, &regs->fc_ch0pream);
527 	writel(0x16, &regs->fc_ch1pream);
528 	writel(0x21, &regs->fc_ch2pream);
529 
530 	/* enable pixel clock and tmds data path */
531 	clkdis = 0x7f;
532 	clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
533 	writel(clkdis, &regs->mc_clkdis);
534 
535 	clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
536 	writel(clkdis, &regs->mc_clkdis);
537 
538 	clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
539 	writel(clkdis, &regs->mc_clkdis);
540 }
541 
542 /* workaround to clear the overflow condition */
543 static void hdmi_clear_overflow(struct rk3288_hdmi *regs)
544 {
545 	uint val, count;
546 
547 	/* tmds software reset */
548 	writel((u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, &regs->mc_swrstz);
549 
550 	val = readl(&regs->fc_invidconf);
551 
552 	for (count = 0; count < 4; count++)
553 		writel(val, &regs->fc_invidconf);
554 }
555 
556 static void hdmi_audio_set_format(struct rk3288_hdmi *regs)
557 {
558 	writel(HDMI_AUD_CONF0_I2S_SELECT | HDMI_AUD_CONF0_I2S_IN_EN_0,
559 	       &regs->aud_conf0);
560 
561 
562 	writel(HDMI_AUD_CONF1_I2S_MODE_STANDARD_MODE |
563 	       HDMI_AUD_CONF1_I2S_WIDTH_16BIT, &regs->aud_conf1);
564 
565 	writel(0x00, &regs->aud_conf2);
566 }
567 
568 static void hdmi_audio_fifo_reset(struct rk3288_hdmi *regs)
569 {
570 	writel((u8)~HDMI_MC_SWRSTZ_II2SSWRST_REQ, &regs->mc_swrstz);
571 	writel(HDMI_AUD_CONF0_SW_AUDIO_FIFO_RST, &regs->aud_conf0);
572 
573 	writel(0x00, &regs->aud_int);
574 	writel(0x00, &regs->aud_int1);
575 }
576 
577 static void hdmi_init_interrupt(struct rk3288_hdmi *regs)
578 {
579 	uint ih_mute;
580 
581 	/*
582 	 * boot up defaults are:
583 	 * hdmi_ih_mute   = 0x03 (disabled)
584 	 * hdmi_ih_mute_* = 0x00 (enabled)
585 	 *
586 	 * disable top level interrupt bits in hdmi block
587 	 */
588 	ih_mute = readl(&regs->ih_mute) |
589 		  HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
590 		  HDMI_IH_MUTE_MUTE_ALL_INTERRUPT;
591 
592 	writel(ih_mute, &regs->ih_mute);
593 
594 	/* enable i2c master done irq */
595 	writel(~0x04, &regs->i2cm_int);
596 
597 	/* enable i2c client nack % arbitration error irq */
598 	writel(~0x44, &regs->i2cm_ctlint);
599 
600 	/* enable phy i2cm done irq */
601 	writel(HDMI_PHY_I2CM_INT_ADDR_DONE_POL, &regs->phy_i2cm_int_addr);
602 
603 	/* enable phy i2cm nack & arbitration error irq */
604 	writel(HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
605 		HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
606 		&regs->phy_i2cm_ctlint_addr);
607 
608 	/* enable cable hot plug irq */
609 	writel((u8)~HDMI_PHY_HPD, &regs->phy_mask0);
610 
611 	/* clear hotplug interrupts */
612 	writel(HDMI_IH_PHY_STAT0_HPD, &regs->ih_phy_stat0);
613 }
614 
615 static int hdmi_get_plug_in_status(struct rk3288_hdmi *regs)
616 {
617 	uint val = readl(&regs->phy_stat0) & HDMI_PHY_HPD;
618 
619 	return !!val;
620 }
621 
622 static int hdmi_wait_for_hpd(struct rk3288_hdmi *regs)
623 {
624 	ulong start;
625 
626 	start = get_timer(0);
627 	do {
628 		if (hdmi_get_plug_in_status(regs))
629 			return 0;
630 		udelay(100);
631 	} while (get_timer(start) < 300);
632 
633 	return -1;
634 }
635 
636 static int hdmi_ddc_wait_i2c_done(struct rk3288_hdmi *regs, int msec)
637 {
638 	u32 val;
639 	ulong start;
640 
641 	start = get_timer(0);
642 	do {
643 		val = readl(&regs->ih_i2cm_stat0);
644 		if (val & 0x2) {
645 			writel(val, &regs->ih_i2cm_stat0);
646 			return 0;
647 		}
648 
649 		udelay(100);
650 	} while (get_timer(start) < msec);
651 
652 	return 1;
653 }
654 
655 static void hdmi_ddc_reset(struct rk3288_hdmi *regs)
656 {
657 	clrbits_le32(&regs->i2cm_softrstz, HDMI_I2CM_SOFTRSTZ);
658 }
659 
660 static int hdmi_read_edid(struct rk3288_hdmi *regs, int block, u8 *buff)
661 {
662 	int shift = (block % 2) * 0x80;
663 	int edid_read_err = 0;
664 	u32 trytime = 5;
665 	u32 n, j, val;
666 
667 	/* set ddc i2c clk which devided from ddc_clk to 100khz */
668 	writel(0x7a, &regs->i2cm_ss_scl_hcnt_0_addr);
669 	writel(0x8d, &regs->i2cm_ss_scl_lcnt_0_addr);
670 
671 	/*
672 	 * TODO(sjg@chromium.org): The above values don't work - these ones
673 	 * work better, but generate lots of errors in the data.
674 	 */
675 	writel(0x0d, &regs->i2cm_ss_scl_hcnt_0_addr);
676 	writel(0x0d, &regs->i2cm_ss_scl_lcnt_0_addr);
677 	clrsetbits_le32(&regs->i2cm_div, HDMI_I2CM_DIV_FAST_STD_MODE,
678 			HDMI_I2CM_DIV_STD_MODE);
679 
680 	writel(HDMI_I2CM_SLAVE_DDC_ADDR, &regs->i2cm_slave);
681 	writel(HDMI_I2CM_SEGADDR_DDC, &regs->i2cm_segaddr);
682 	writel(block >> 1, &regs->i2cm_segptr);
683 
684 	while (trytime--) {
685 		edid_read_err = 0;
686 
687 		for (n = 0; n < HDMI_EDID_BLOCK_SIZE / 8; n++) {
688 			writel(shift + 8 * n, &regs->i2c_address);
689 
690 			if (block == 0)
691 				clrsetbits_le32(&regs->i2cm_operation,
692 						HDMI_I2CM_OPT_RD8,
693 						HDMI_I2CM_OPT_RD8);
694 			else
695 				clrsetbits_le32(&regs->i2cm_operation,
696 						HDMI_I2CM_OPT_RD8_EXT,
697 						HDMI_I2CM_OPT_RD8_EXT);
698 
699 			if (hdmi_ddc_wait_i2c_done(regs, 10)) {
700 				hdmi_ddc_reset(regs);
701 				edid_read_err = 1;
702 				break;
703 			}
704 
705 			for (j = 0; j < 8; j++) {
706 				val = readl(&regs->i2cm_buf0 + j);
707 				buff[8 * n + j] = val;
708 			}
709 		}
710 
711 		if (!edid_read_err)
712 			break;
713 	}
714 
715 	return edid_read_err;
716 }
717 
718 static const u8 pre_buf[] = {
719 	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
720 	0x04, 0x69, 0xfa, 0x23, 0xc8, 0x28, 0x01, 0x00,
721 	0x10, 0x17, 0x01, 0x03, 0x80, 0x33, 0x1d, 0x78,
722 	0x2a, 0xd9, 0x45, 0xa2, 0x55, 0x4d, 0xa0, 0x27,
723 	0x12, 0x50, 0x54, 0xb7, 0xef, 0x00, 0x71, 0x4f,
724 	0x81, 0x40, 0x81, 0x80, 0x95, 0x00, 0xb3, 0x00,
725 	0xd1, 0xc0, 0x81, 0xc0, 0x81, 0x00, 0x02, 0x3a,
726 	0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
727 	0x45, 0x00, 0xfd, 0x1e, 0x11, 0x00, 0x00, 0x1e,
728 	0x00, 0x00, 0x00, 0xff, 0x00, 0x44, 0x34, 0x4c,
729 	0x4d, 0x54, 0x46, 0x30, 0x37, 0x35, 0x39, 0x37,
730 	0x36, 0x0a, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
731 	0x4b, 0x18, 0x53, 0x11, 0x00, 0x0a, 0x20, 0x20,
732 	0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc,
733 	0x00, 0x41, 0x53, 0x55, 0x53, 0x20, 0x56, 0x53,
734 	0x32, 0x33, 0x38, 0x0a, 0x20, 0x20, 0x01, 0xb0,
735 	0x02, 0x03, 0x22, 0x71, 0x4f, 0x01, 0x02, 0x03,
736 	0x11, 0x12, 0x13, 0x04, 0x14, 0x05, 0x0e, 0x0f,
737 	0x1d, 0x1e, 0x1f, 0x10, 0x23, 0x09, 0x17, 0x07,
738 	0x83, 0x01, 0x00, 0x00, 0x65, 0x03, 0x0c, 0x00,
739 	0x10, 0x00, 0x8c, 0x0a, 0xd0, 0x8a, 0x20, 0xe0,
740 	0x2d, 0x10, 0x10, 0x3e, 0x96, 0x00, 0xfd, 0x1e,
741 	0x11, 0x00, 0x00, 0x18, 0x01, 0x1d, 0x00, 0x72,
742 	0x51, 0xd0, 0x1e, 0x20, 0x6e, 0x28, 0x55, 0x00,
743 	0xfd, 0x1e, 0x11, 0x00, 0x00, 0x1e, 0x01, 0x1d,
744 	0x00, 0xbc, 0x52, 0xd0, 0x1e, 0x20, 0xb8, 0x28,
745 	0x55, 0x40, 0xfd, 0x1e, 0x11, 0x00, 0x00, 0x1e,
746 	0x8c, 0x0a, 0xd0, 0x90, 0x20, 0x40, 0x31, 0x20,
747 	0x0c, 0x40, 0x55, 0x00, 0xfd, 0x1e, 0x11, 0x00,
748 	0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
749 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
750 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe9,
751 };
752 
753 static int rk_hdmi_read_edid(struct udevice *dev, u8 *buf, int buf_size)
754 {
755 	struct rk_hdmi_priv *priv = dev_get_priv(dev);
756 	u32 edid_size = HDMI_EDID_BLOCK_SIZE;
757 	int ret;
758 
759 	if (0) {
760 		edid_size = sizeof(pre_buf);
761 		memcpy(buf, pre_buf, edid_size);
762 	} else {
763 		ret = hdmi_read_edid(priv->regs, 0, buf);
764 		if (ret) {
765 			debug("failed to read edid.\n");
766 			return -1;
767 		}
768 
769 		if (buf[0x7e] != 0) {
770 			hdmi_read_edid(priv->regs, 1,
771 				       buf + HDMI_EDID_BLOCK_SIZE);
772 			edid_size += HDMI_EDID_BLOCK_SIZE;
773 		}
774 	}
775 
776 	return edid_size;
777 }
778 
779 static int rk_hdmi_enable(struct udevice *dev, int panel_bpp,
780 			  const struct display_timing *edid)
781 {
782 	struct rk_hdmi_priv *priv = dev_get_priv(dev);
783 	struct rk3288_hdmi *regs = priv->regs;
784 	int ret;
785 
786 	debug("hdmi, mode info : clock %d hdis %d vdis %d\n",
787 	      edid->pixelclock.typ, edid->hactive.typ, edid->vactive.typ);
788 
789 	hdmi_av_composer(regs, edid);
790 
791 	ret = hdmi_phy_init(regs, edid->pixelclock.typ);
792 	if (ret)
793 		return ret;
794 
795 	hdmi_enable_video_path(regs);
796 
797 	hdmi_audio_fifo_reset(regs);
798 	hdmi_audio_set_format(regs);
799 	hdmi_audio_set_samplerate(regs, edid->pixelclock.typ);
800 
801 	hdmi_video_packetize(regs);
802 	hdmi_video_sample(regs);
803 
804 	hdmi_clear_overflow(regs);
805 
806 	return 0;
807 }
808 
809 static int rk_hdmi_ofdata_to_platdata(struct udevice *dev)
810 {
811 	struct rk_hdmi_priv *priv = dev_get_priv(dev);
812 
813 	priv->regs = (struct rk3288_hdmi *)dev_get_addr(dev);
814 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
815 
816 	return 0;
817 }
818 
819 static int rk_hdmi_probe(struct udevice *dev)
820 {
821 	struct display_plat *uc_plat = dev_get_uclass_platdata(dev);
822 	struct rk_hdmi_priv *priv = dev_get_priv(dev);
823 	struct udevice *reg;
824 	struct clk clk;
825 	int ret;
826 	int vop_id = uc_plat->source_id;
827 
828 	ret = clk_get_by_index(dev, 0, &clk);
829 	if (ret >= 0) {
830 		ret = clk_set_rate(&clk, 0);
831 		clk_free(&clk);
832 	}
833 	if (ret) {
834 		debug("%s: Failed to set hdmi clock: ret=%d\n", __func__, ret);
835 		return ret;
836 	}
837 
838 	/*
839 	 * Configure the maximum clock to permit whatever resolution the
840 	 * monitor wants
841 	 */
842 	ret = clk_get_by_index(uc_plat->src_dev, 0, &clk);
843 	if (ret >= 0) {
844 		ret = clk_set_rate(&clk, 384000000);
845 		clk_free(&clk);
846 	}
847 	if (ret < 0) {
848 		debug("%s: Failed to set clock in source device '%s': ret=%d\n",
849 		      __func__, uc_plat->src_dev->name, ret);
850 		return ret;
851 	}
852 
853 	ret = regulator_get_by_platname("vcc50_hdmi", &reg);
854 	if (!ret)
855 		ret = regulator_set_enable(reg, true);
856 	if (ret)
857 		debug("%s: Cannot set regulator vcc50_hdmi\n", __func__);
858 
859 	/* hdmi source select hdmi controller */
860 	rk_setreg(&priv->grf->soc_con6, 1 << 15);
861 
862 	/* hdmi data from vop id */
863 	rk_clrsetreg(&priv->grf->soc_con6, 1 << 4,
864 		     (vop_id == 1) ? (1 << 4) : 0);
865 
866 	ret = hdmi_wait_for_hpd(priv->regs);
867 	if (ret < 0) {
868 		debug("hdmi can not get hpd signal\n");
869 		return -1;
870 	}
871 
872 	hdmi_init_interrupt(priv->regs);
873 
874 	return 0;
875 }
876 
877 static const struct dm_display_ops rk_hdmi_ops = {
878 	.read_edid = rk_hdmi_read_edid,
879 	.enable = rk_hdmi_enable,
880 };
881 
882 static const struct udevice_id rk_hdmi_ids[] = {
883 	{ .compatible = "rockchip,rk3288-dw-hdmi" },
884 	{ }
885 };
886 
887 U_BOOT_DRIVER(hdmi_rockchip) = {
888 	.name	= "hdmi_rockchip",
889 	.id	= UCLASS_DISPLAY,
890 	.of_match = rk_hdmi_ids,
891 	.ops	= &rk_hdmi_ops,
892 	.ofdata_to_platdata	= rk_hdmi_ofdata_to_platdata,
893 	.probe	= rk_hdmi_probe,
894 	.priv_auto_alloc_size	 = sizeof(struct rk_hdmi_priv),
895 };
896