xref: /rk3399_rockchip-uboot/drivers/video/drm/dw_hdmi.c (revision 5ec685037a799ecdc53ecb1a12a9ed5a9cecb4f4)
1 /*
2  * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <fdtdec.h>
9 #include <fdt_support.h>
10 #include <malloc.h>
11 #include <syscon.h>
12 #include <asm/arch-rockchip/clock.h>
13 #include <edid.h>
14 #include <linux/hdmi.h>
15 #include <linux/media-bus-format.h>
16 #include <linux/dw_hdmi.h>
17 #include <asm/io.h>
18 #include "rockchip_display.h"
19 #include "rockchip_crtc.h"
20 #include "rockchip_connector.h"
21 #include "dw_hdmi.h"
22 
23 /*
24  * Unless otherwise noted, entries in this table are 100% optimization.
25  * Values can be obtained from hdmi_compute_n() but that function is
26  * slow so we pre-compute values we expect to see.
27  *
28  * All 32k and 48k values are expected to be the same (due to the way
29  * the math works) for any rate that's an exact kHz.
30  */
31 static const struct dw_hdmi_audio_tmds_n common_tmds_n_table[] = {
32 	{ .tmds = 25175000, .n_32k = 4096, .n_44k1 = 12854, .n_48k = 6144, },
33 	{ .tmds = 25200000, .n_32k = 4096, .n_44k1 = 5656, .n_48k = 6144, },
34 	{ .tmds = 27000000, .n_32k = 4096, .n_44k1 = 5488, .n_48k = 6144, },
35 	{ .tmds = 28320000, .n_32k = 4096, .n_44k1 = 5586, .n_48k = 6144, },
36 	{ .tmds = 30240000, .n_32k = 4096, .n_44k1 = 5642, .n_48k = 6144, },
37 	{ .tmds = 31500000, .n_32k = 4096, .n_44k1 = 5600, .n_48k = 6144, },
38 	{ .tmds = 32000000, .n_32k = 4096, .n_44k1 = 5733, .n_48k = 6144, },
39 	{ .tmds = 33750000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, },
40 	{ .tmds = 36000000, .n_32k = 4096, .n_44k1 = 5684, .n_48k = 6144, },
41 	{ .tmds = 40000000, .n_32k = 4096, .n_44k1 = 5733, .n_48k = 6144, },
42 	{ .tmds = 49500000, .n_32k = 4096, .n_44k1 = 5488, .n_48k = 6144, },
43 	{ .tmds = 50000000, .n_32k = 4096, .n_44k1 = 5292, .n_48k = 6144, },
44 	{ .tmds = 54000000, .n_32k = 4096, .n_44k1 = 5684, .n_48k = 6144, },
45 	{ .tmds = 65000000, .n_32k = 4096, .n_44k1 = 7056, .n_48k = 6144, },
46 	{ .tmds = 68250000, .n_32k = 4096, .n_44k1 = 5376, .n_48k = 6144, },
47 	{ .tmds = 71000000, .n_32k = 4096, .n_44k1 = 7056, .n_48k = 6144, },
48 	{ .tmds = 72000000, .n_32k = 4096, .n_44k1 = 5635, .n_48k = 6144, },
49 	{ .tmds = 73250000, .n_32k = 4096, .n_44k1 = 14112, .n_48k = 6144, },
50 	{ .tmds = 74250000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, },
51 	{ .tmds = 75000000, .n_32k = 4096, .n_44k1 = 5880, .n_48k = 6144, },
52 	{ .tmds = 78750000, .n_32k = 4096, .n_44k1 = 5600, .n_48k = 6144, },
53 	{ .tmds = 78800000, .n_32k = 4096, .n_44k1 = 5292, .n_48k = 6144, },
54 	{ .tmds = 79500000, .n_32k = 4096, .n_44k1 = 4704, .n_48k = 6144, },
55 	{ .tmds = 83500000, .n_32k = 4096, .n_44k1 = 7056, .n_48k = 6144, },
56 	{ .tmds = 85500000, .n_32k = 4096, .n_44k1 = 5488, .n_48k = 6144, },
57 	{ .tmds = 88750000, .n_32k = 4096, .n_44k1 = 14112, .n_48k = 6144, },
58 	{ .tmds = 97750000, .n_32k = 4096, .n_44k1 = 14112, .n_48k = 6144, },
59 	{ .tmds = 101000000, .n_32k = 4096, .n_44k1 = 7056, .n_48k = 6144, },
60 	{ .tmds = 106500000, .n_32k = 4096, .n_44k1 = 4704, .n_48k = 6144, },
61 	{ .tmds = 108000000, .n_32k = 4096, .n_44k1 = 5684, .n_48k = 6144, },
62 	{ .tmds = 115500000, .n_32k = 4096, .n_44k1 = 5712, .n_48k = 6144, },
63 	{ .tmds = 119000000, .n_32k = 4096, .n_44k1 = 5544, .n_48k = 6144, },
64 	{ .tmds = 135000000, .n_32k = 4096, .n_44k1 = 5488, .n_48k = 6144, },
65 	{ .tmds = 146250000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, },
66 	{ .tmds = 148500000, .n_32k = 4096, .n_44k1 = 5488, .n_48k = 6144, },
67 	{ .tmds = 154000000, .n_32k = 4096, .n_44k1 = 5544, .n_48k = 6144, },
68 	{ .tmds = 162000000, .n_32k = 4096, .n_44k1 = 5684, .n_48k = 6144, },
69 
70 	/* For 297 MHz+ HDMI spec have some other rule for setting N */
71 	{ .tmds = 297000000, .n_32k = 3073, .n_44k1 = 4704, .n_48k = 5120, },
72 	{ .tmds = 594000000, .n_32k = 3073, .n_44k1 = 9408, .n_48k = 10240, },
73 
74 	/* End of table */
75 	{ .tmds = 0,         .n_32k = 0,    .n_44k1 = 0,    .n_48k = 0, },
76 };
77 
78 static const u16 csc_coeff_default[3][4] = {
79 	{ 0x2000, 0x0000, 0x0000, 0x0000 },
80 	{ 0x0000, 0x2000, 0x0000, 0x0000 },
81 	{ 0x0000, 0x0000, 0x2000, 0x0000 }
82 };
83 
84 static const u16 csc_coeff_rgb_out_eitu601[3][4] = {
85 	{ 0x2000, 0x6926, 0x74fd, 0x010e },
86 	{ 0x2000, 0x2cdd, 0x0000, 0x7e9a },
87 	{ 0x2000, 0x0000, 0x38b4, 0x7e3b }
88 };
89 
90 static const u16 csc_coeff_rgb_out_eitu709[3][4] = {
91 	{ 0x2000, 0x7106, 0x7a02, 0x00a7 },
92 	{ 0x2000, 0x3264, 0x0000, 0x7e6d },
93 	{ 0x2000, 0x0000, 0x3b61, 0x7e25 }
94 };
95 
96 static const u16 csc_coeff_rgb_in_eitu601[3][4] = {
97 	{ 0x2591, 0x1322, 0x074b, 0x0000 },
98 	{ 0x6535, 0x2000, 0x7acc, 0x0200 },
99 	{ 0x6acd, 0x7534, 0x2000, 0x0200 }
100 };
101 
102 static const u16 csc_coeff_rgb_in_eitu709[3][4] = {
103 	{ 0x2dc5, 0x0d9b, 0x049e, 0x0000 },
104 	{ 0x62f0, 0x2000, 0x7d11, 0x0200 },
105 	{ 0x6756, 0x78ab, 0x2000, 0x0200 }
106 };
107 
108 struct hdmi_vmode {
109 	bool mdataenablepolarity;
110 
111 	unsigned int mpixelclock;
112 	unsigned int mpixelrepetitioninput;
113 	unsigned int mpixelrepetitionoutput;
114 };
115 
116 struct hdmi_data_info {
117 	unsigned int enc_in_bus_format;
118 	unsigned int enc_out_bus_format;
119 	unsigned int enc_in_encoding;
120 	unsigned int enc_out_encoding;
121 	unsigned int pix_repet_factor;
122 	struct hdmi_vmode video_mode;
123 };
124 
125 struct dw_hdmi_phy_data {
126 	enum dw_hdmi_phy_type type;
127 	const char *name;
128 	unsigned int gen;
129 	bool has_svsret;
130 	int (*configure)(struct dw_hdmi *hdmi,
131 			 const struct dw_hdmi_plat_data *pdata,
132 			 unsigned long mpixelclock);
133 };
134 
135 struct dw_hdmi {
136 	enum dw_hdmi_devtype dev_type;
137 	unsigned int version;
138 	struct hdmi_data_info hdmi_data;
139 	struct hdmi_edid_data edid_data;
140 	const struct dw_hdmi_plat_data *plat_data;
141 
142 	int vic;
143 	int io_width;
144 
145 	unsigned long bus_format;
146 	bool cable_plugin;
147 	bool sink_is_hdmi;
148 	bool sink_has_audio;
149 	void *regs;
150 	void *grf;
151 
152 	struct {
153 		const struct dw_hdmi_phy_ops *ops;
154 		const char *name;
155 		void *data;
156 		bool enabled;
157 	} phy;
158 
159 	struct drm_display_mode previous_mode;
160 
161 	unsigned int sample_rate;
162 	unsigned int audio_cts;
163 	unsigned int audio_n;
164 	bool audio_enable;
165 
166 	void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
167 	u8 (*read)(struct dw_hdmi *hdmi, int offset);
168 };
169 
170 static void dw_hdmi_writel(struct dw_hdmi *hdmi, u8 val, int offset)
171 {
172 	writel(val, hdmi->regs + (offset << 2));
173 }
174 
175 static u8 dw_hdmi_readl(struct dw_hdmi *hdmi, int offset)
176 {
177 	return readl(hdmi->regs + (offset << 2));
178 }
179 
180 static void dw_hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset)
181 {
182 	writeb(val, hdmi->regs + offset);
183 }
184 
185 static u8 dw_hdmi_readb(struct dw_hdmi *hdmi, int offset)
186 {
187 	return readb(hdmi->regs + offset);
188 }
189 
190 static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset)
191 {
192 	hdmi->write(hdmi, val, offset);
193 }
194 
195 static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset)
196 {
197 	return hdmi->read(hdmi, offset);
198 }
199 
200 static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
201 {
202 	u8 val = hdmi_readb(hdmi, reg) & ~mask;
203 
204 	val |= data & mask;
205 	hdmi_writeb(hdmi, val, reg);
206 }
207 
208 static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg,
209 			     u8 shift, u8 mask)
210 {
211 	hdmi_modb(hdmi, data << shift, mask, reg);
212 }
213 
214 static bool hdmi_bus_fmt_is_rgb(unsigned int bus_format)
215 {
216 	switch (bus_format) {
217 	case MEDIA_BUS_FMT_RGB888_1X24:
218 	case MEDIA_BUS_FMT_RGB101010_1X30:
219 	case MEDIA_BUS_FMT_RGB121212_1X36:
220 	case MEDIA_BUS_FMT_RGB161616_1X48:
221 		return true;
222 
223 	default:
224 		return false;
225 	}
226 }
227 
228 static bool hdmi_bus_fmt_is_yuv444(unsigned int bus_format)
229 {
230 	switch (bus_format) {
231 	case MEDIA_BUS_FMT_YUV8_1X24:
232 	case MEDIA_BUS_FMT_YUV10_1X30:
233 	case MEDIA_BUS_FMT_YUV12_1X36:
234 	case MEDIA_BUS_FMT_YUV16_1X48:
235 		return true;
236 
237 	default:
238 		return false;
239 	}
240 }
241 
242 static bool hdmi_bus_fmt_is_yuv422(unsigned int bus_format)
243 {
244 	switch (bus_format) {
245 	case MEDIA_BUS_FMT_UYVY8_1X16:
246 	case MEDIA_BUS_FMT_UYVY10_1X20:
247 	case MEDIA_BUS_FMT_UYVY12_1X24:
248 		return true;
249 
250 	default:
251 		return false;
252 	}
253 }
254 
255 static bool hdmi_bus_fmt_is_yuv420(unsigned int bus_format)
256 {
257 	switch (bus_format) {
258 	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
259 	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
260 	case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
261 	case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
262 		return true;
263 
264 	default:
265 		return false;
266 	}
267 }
268 
269 static int hdmi_bus_fmt_color_depth(unsigned int bus_format)
270 {
271 	switch (bus_format) {
272 	case MEDIA_BUS_FMT_RGB888_1X24:
273 	case MEDIA_BUS_FMT_YUV8_1X24:
274 	case MEDIA_BUS_FMT_UYVY8_1X16:
275 	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
276 		return 8;
277 
278 	case MEDIA_BUS_FMT_RGB101010_1X30:
279 	case MEDIA_BUS_FMT_YUV10_1X30:
280 	case MEDIA_BUS_FMT_UYVY10_1X20:
281 	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
282 		return 10;
283 
284 	case MEDIA_BUS_FMT_RGB121212_1X36:
285 	case MEDIA_BUS_FMT_YUV12_1X36:
286 	case MEDIA_BUS_FMT_UYVY12_1X24:
287 	case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
288 		return 12;
289 
290 	case MEDIA_BUS_FMT_RGB161616_1X48:
291 	case MEDIA_BUS_FMT_YUV16_1X48:
292 	case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
293 		return 16;
294 
295 	default:
296 		return 0;
297 	}
298 }
299 
300 static int is_color_space_conversion(struct dw_hdmi *hdmi)
301 {
302 	return hdmi->hdmi_data.enc_in_bus_format !=
303 	hdmi->hdmi_data.enc_out_bus_format;
304 }
305 
306 static int is_color_space_decimation(struct dw_hdmi *hdmi)
307 {
308 	if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format))
309 		return 0;
310 
311 	if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format) ||
312 	    hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_in_bus_format))
313 		return 1;
314 
315 	return 0;
316 }
317 
318 static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi,
319 				       unsigned char bit)
320 {
321 	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET,
322 		  HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
323 }
324 
325 static inline void hdmi_phy_test_enable(struct dw_hdmi *hdmi,
326 					unsigned char bit)
327 {
328 	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTEN_OFFSET,
329 		  HDMI_PHY_TST0_TSTEN_MASK, HDMI_PHY_TST0);
330 }
331 
332 static inline void hdmi_phy_test_clock(struct dw_hdmi *hdmi,
333 				       unsigned char bit)
334 {
335 	hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLK_OFFSET,
336 		  HDMI_PHY_TST0_TSTCLK_MASK, HDMI_PHY_TST0);
337 }
338 
339 static inline void hdmi_phy_test_din(struct dw_hdmi *hdmi,
340 				     unsigned char bit)
341 {
342 	hdmi_writeb(hdmi, bit, HDMI_PHY_TST1);
343 }
344 
345 static inline void hdmi_phy_test_dout(struct dw_hdmi *hdmi,
346 				      unsigned char bit)
347 {
348 	hdmi_writeb(hdmi, bit, HDMI_PHY_TST2);
349 }
350 
351 static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
352 {
353 	u32 val;
354 
355 	while ((val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) {
356 		if (msec-- == 0)
357 			return false;
358 		udelay(1000);
359 	}
360 	hdmi_writeb(hdmi, val, HDMI_IH_I2CMPHY_STAT0);
361 
362 	return true;
363 }
364 
365 static void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
366 				  unsigned char addr)
367 {
368 	hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0);
369 	hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
370 	hdmi_writeb(hdmi, (unsigned char)(data >> 8),
371 		    HDMI_PHY_I2CM_DATAO_1_ADDR);
372 	hdmi_writeb(hdmi, (unsigned char)(data >> 0),
373 		    HDMI_PHY_I2CM_DATAO_0_ADDR);
374 	hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
375 		    HDMI_PHY_I2CM_OPERATION_ADDR);
376 	hdmi_phy_wait_i2c_done(hdmi, 1000);
377 }
378 
379 static void dw_hdmi_phy_enable_powerdown(struct dw_hdmi *hdmi, bool enable)
380 {
381 	hdmi_mask_writeb(hdmi, !enable, HDMI_PHY_CONF0,
382 			 HDMI_PHY_CONF0_PDZ_OFFSET,
383 			 HDMI_PHY_CONF0_PDZ_MASK);
384 }
385 
386 static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable)
387 {
388 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
389 			 HDMI_PHY_CONF0_ENTMDS_OFFSET,
390 			 HDMI_PHY_CONF0_ENTMDS_MASK);
391 }
392 
393 static void dw_hdmi_phy_enable_svsret(struct dw_hdmi *hdmi, u8 enable)
394 {
395 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
396 			 HDMI_PHY_CONF0_SVSRET_OFFSET,
397 			 HDMI_PHY_CONF0_SVSRET_MASK);
398 }
399 
400 static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)
401 {
402 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
403 			 HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
404 			 HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
405 }
406 
407 static void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable)
408 {
409 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
410 			 HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
411 			 HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
412 }
413 
414 static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable)
415 {
416 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
417 			 HDMI_PHY_CONF0_SELDATAENPOL_OFFSET,
418 			 HDMI_PHY_CONF0_SELDATAENPOL_MASK);
419 }
420 
421 static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable)
422 {
423 	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
424 			 HDMI_PHY_CONF0_SELDIPIF_OFFSET,
425 			 HDMI_PHY_CONF0_SELDIPIF_MASK);
426 }
427 
428 static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
429 {
430 	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
431 	unsigned int i;
432 	u16 val;
433 
434 	if (phy->gen == 1) {
435 		dw_hdmi_phy_enable_tmds(hdmi, 0);
436 		dw_hdmi_phy_enable_powerdown(hdmi, true);
437 		return;
438 	}
439 
440 	dw_hdmi_phy_gen2_txpwron(hdmi, 0);
441 
442 	/*
443 	 * Wait for TX_PHY_LOCK to be deasserted to indicate that the PHY went
444 	 * to low power mode.
445 	 */
446 	for (i = 0; i < 5; ++i) {
447 		val = hdmi_readb(hdmi, HDMI_PHY_STAT0);
448 		if (!(val & HDMI_PHY_TX_PHY_LOCK))
449 			break;
450 
451 		udelay(2000);
452 	}
453 
454 	if (val & HDMI_PHY_TX_PHY_LOCK)
455 		printf("PHY failed to power down\n");
456 	else
457 		printf("PHY powered down in %u iterations\n", i);
458 
459 	dw_hdmi_phy_gen2_pddq(hdmi, 1);
460 }
461 
462 static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
463 {
464 	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
465 	unsigned int i;
466 	u8 val;
467 
468 	if (phy->gen == 1) {
469 		dw_hdmi_phy_enable_powerdown(hdmi, false);
470 
471 		/* Toggle TMDS enable. */
472 		dw_hdmi_phy_enable_tmds(hdmi, 0);
473 		dw_hdmi_phy_enable_tmds(hdmi, 1);
474 		return 0;
475 	}
476 
477 	dw_hdmi_phy_gen2_txpwron(hdmi, 1);
478 	dw_hdmi_phy_gen2_pddq(hdmi, 0);
479 
480 	/* Wait for PHY PLL lock */
481 	for (i = 0; i < 5; ++i) {
482 		val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
483 		if (val)
484 			break;
485 
486 		udelay(2000);
487 	}
488 
489 	if (!val) {
490 		printf("PHY PLL failed to lock\n");
491 		return -ETIMEDOUT;
492 	}
493 
494 	printf("PHY PLL locked %u iterations\n", i);
495 	return 0;
496 }
497 
498 /*
499  * PHY configuration function for the DWC HDMI 3D TX PHY. Based on the available
500  * information the DWC MHL PHY has the same register layout and is thus also
501  * supported by this function.
502  */
503 static
504 int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
505 				      const struct dw_hdmi_plat_data *pdata,
506 				      unsigned long mpixelclock)
507 {
508 	const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg;
509 	const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr;
510 	const struct dw_hdmi_phy_config *phy_config = pdata->phy_config;
511 
512 	/* PLL/MPLL Cfg - always match on final entry */
513 	for (; mpll_config->mpixelclock != ~0UL; mpll_config++)
514 		if (mpixelclock <= mpll_config->mpixelclock)
515 			break;
516 
517 	for (; curr_ctrl->mpixelclock != ~0UL; curr_ctrl++)
518 		if (mpixelclock <= curr_ctrl->mpixelclock)
519 			break;
520 
521 	for (; phy_config->mpixelclock != ~0UL; phy_config++)
522 		if (mpixelclock <= phy_config->mpixelclock)
523 			break;
524 
525 	if (mpll_config->mpixelclock == ~0UL ||
526 	    curr_ctrl->mpixelclock == ~0UL ||
527 	    phy_config->mpixelclock == ~0UL)
528 		return -EINVAL;
529 
530 	/*
531 	 * RK3399 mpll clock source is vpll, also is vop clock source.
532 	 * vpll rate is twice of mpixelclock in YCBCR420 mode, we need
533 	 * to enable mpll pre-divider.
534 	 */
535 	if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format) &&
536 	    (hdmi->dev_type == RK3399_HDMI || hdmi->dev_type == RK3368_HDMI))
537 		dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce | 4,
538 				      HDMI_3D_TX_PHY_CPCE_CTRL);
539 	else
540 		dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce,
541 				      HDMI_3D_TX_PHY_CPCE_CTRL);
542 	dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp,
543 			      HDMI_3D_TX_PHY_GMPCTRL);
544 	dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0],
545 			      HDMI_3D_TX_PHY_CURRCTRL);
546 
547 	dw_hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL);
548 	dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK,
549 			      HDMI_3D_TX_PHY_MSM_CTRL);
550 
551 	dw_hdmi_phy_i2c_write(hdmi, 0x0004, HDMI_3D_TX_PHY_TXTERM);
552 	dw_hdmi_phy_i2c_write(hdmi, 0x8009,
553 			      HDMI_3D_TX_PHY_CKSYMTXCTRL);
554 	dw_hdmi_phy_i2c_write(hdmi, 0x0272,
555 			      HDMI_3D_TX_PHY_VLEVCTRL);
556 
557 	/* Override and disable clock termination. */
558 	dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
559 			      HDMI_3D_TX_PHY_CKCALCTRL);
560 	return 0;
561 }
562 
563 static const struct dw_hdmi_phy_data dw_hdmi_phys[] = {
564 	{
565 		.type = DW_HDMI_PHY_DWC_HDMI_TX_PHY,
566 		.name = "DWC HDMI TX PHY",
567 		.gen = 1,
568 	}, {
569 		.type = DW_HDMI_PHY_DWC_MHL_PHY_HEAC,
570 		.name = "DWC MHL PHY + HEAC PHY",
571 		.gen = 2,
572 		.has_svsret = true,
573 		.configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
574 	}, {
575 		.type = DW_HDMI_PHY_DWC_MHL_PHY,
576 		.name = "DWC MHL PHY",
577 		.gen = 2,
578 		.has_svsret = true,
579 		.configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
580 	}, {
581 		.type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC,
582 		.name = "DWC HDMI 3D TX PHY + HEAC PHY",
583 		.gen = 2,
584 		.configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
585 	}, {
586 		.type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY,
587 		.name = "DWC HDMI 3D TX PHY",
588 		.gen = 2,
589 		.configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
590 	}, {
591 		.type = DW_HDMI_PHY_DWC_HDMI20_TX_PHY,
592 		.name = "DWC HDMI 2.0 TX PHY",
593 		.gen = 2,
594 		.has_svsret = true,
595 		.configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
596 	}, {
597 		.type = DW_HDMI_PHY_VENDOR_PHY,
598 		.name = "Vendor PHY",
599 	}
600 };
601 
602 /* ddc i2c master reset */
603 static void rockchip_dw_hdmi_i2cm_reset(struct dw_hdmi *hdmi)
604 {
605 	hdmi_writeb(hdmi, 0x00, HDMI_I2CM_SOFTRSTZ);
606 	udelay(100);
607 }
608 
609 static void rockchip_dw_hdmi_i2cm_mask_int(struct dw_hdmi *hdmi, int mask)
610 {
611 	if (!mask) {
612 		hdmi_writeb(hdmi, HDMI_I2CM_INT_DONE_POL, HDMI_I2CM_INT);
613 		hdmi_writeb(hdmi, HDMI_I2CM_CTLINT_NAC_POL |
614 			    HDMI_I2CM_CTLINT_ARB_POL, HDMI_I2CM_CTLINT);
615 		hdmi_writeb(hdmi, 0x00, HDMI_IH_MUTE_I2CM_STAT0);
616 	} else {
617 		hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
618 		hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
619 	}
620 }
621 
622 static u16 i2c_count(u16 sfrclock, u16 sclmintime)
623 {
624 	unsigned long tmp_scl_period = 0;
625 
626 	if (((sfrclock * sclmintime) % I2C_DIV_FACTOR) != 0)
627 		tmp_scl_period = (unsigned long)((sfrclock * sclmintime) +
628 				(I2C_DIV_FACTOR - ((sfrclock * sclmintime) %
629 				I2C_DIV_FACTOR))) / I2C_DIV_FACTOR;
630 	else
631 		tmp_scl_period = (unsigned long)(sfrclock * sclmintime) /
632 				I2C_DIV_FACTOR;
633 
634 	return (u16)(tmp_scl_period);
635 }
636 
637 static void rockchip_dw_hdmi_i2cm_clk_init(struct dw_hdmi *hdmi)
638 {
639 	int value;
640 
641 	/* Set DDC I2C CLK which divided from DDC_CLK. */
642 	value = i2c_count(24000, EDID_I2C_MIN_SS_SCL_HIGH_TIME);
643 	hdmi_writeb(hdmi, value & 0xff,
644 		    HDMI_I2CM_SS_SCL_HCNT_0_ADDR);
645 	hdmi_writeb(hdmi, (value >> 8) & 0xff,
646 		    HDMI_I2CM_SS_SCL_HCNT_1_ADDR);
647 	value = i2c_count(24000, EDID_I2C_MIN_SS_SCL_LOW_TIME);
648 	hdmi_writeb(hdmi, value & 0xff,
649 		    HDMI_I2CM_SS_SCL_LCNT_0_ADDR);
650 	hdmi_writeb(hdmi, (value >> 8) & 0xff,
651 		    HDMI_I2CM_SS_SCL_LCNT_1_ADDR);
652 	hdmi_modb(hdmi, HDMI_I2CM_DIV_STD_MODE,
653 		  HDMI_I2CM_DIV_FAST_STD_MODE, HDMI_I2CM_DIV);
654 }
655 
656 /*set read/write offset,set read/write mode*/
657 static void rockchip_dw_hdmi_i2cm_write_request(struct dw_hdmi *hdmi,
658 						u8 offset, u8 data)
659 {
660 	hdmi_writeb(hdmi, offset, HDMI_I2CM_ADDRESS);
661 	hdmi_writeb(hdmi, data, HDMI_I2CM_DATAO);
662 	hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_WRITE, HDMI_I2CM_OPERATION_READ);
663 }
664 
665 static void rockchip_dw_hdmi_i2cm_read_request(struct dw_hdmi *hdmi,
666 					       u8 offset)
667 {
668 	hdmi_writeb(hdmi, offset, HDMI_I2CM_ADDRESS);
669 	hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ, HDMI_I2CM_OPERATION);
670 }
671 
672 static void rockchip_dw_hdmi_i2cm_write_data(struct dw_hdmi *hdmi,
673 					     u8 data, u8 offset)
674 {
675 	u8 interrupt = 0;
676 	int trytime = 2;
677 	int i = 20;
678 
679 	while (trytime-- > 0) {
680 		rockchip_dw_hdmi_i2cm_write_request(hdmi, offset, data);
681 		while (i--) {
682 			udelay(1000);
683 			interrupt = hdmi_readb(hdmi, HDMI_IH_I2CM_STAT0);
684 			if (interrupt)
685 				hdmi_writeb(hdmi,
686 					    interrupt, HDMI_IH_I2CM_STAT0);
687 
688 			if (interrupt & (m_SCDC_READREQ |
689 					 m_I2CM_DONE | m_I2CM_ERROR))
690 				break;
691 		}
692 
693 		if (interrupt & m_I2CM_DONE) {
694 			printf("[%s] write offset %02x data %02x success\n",
695 			       __func__, offset, data);
696 			trytime = 0;
697 		} else if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
698 			printf("[%s] write data error\n", __func__);
699 			rockchip_dw_hdmi_i2cm_reset(hdmi);
700 		}
701 	}
702 }
703 
704 static int rockchip_dw_hdmi_i2cm_read_data(struct dw_hdmi *hdmi, u8 offset)
705 {
706 	u8 interrupt = 0, val = 0;
707 	int trytime = 2;
708 	int i = 20;
709 
710 	while (trytime-- > 0) {
711 		rockchip_dw_hdmi_i2cm_read_request(hdmi, offset);
712 		while (i--) {
713 			udelay(1000);
714 			interrupt = hdmi_readb(hdmi, HDMI_IH_I2CM_STAT0);
715 			if (interrupt)
716 				hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0,
717 					    interrupt);
718 
719 			if (interrupt & (m_SCDC_READREQ |
720 				m_I2CM_DONE | m_I2CM_ERROR))
721 				break;
722 		}
723 
724 		if (interrupt & m_I2CM_DONE) {
725 			val = hdmi_readb(hdmi, HDMI_I2CM_DATAI);
726 			trytime = 0;
727 		} else if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
728 			printf("[%s] read data error\n", __func__);
729 			rockchip_dw_hdmi_i2cm_reset(hdmi);
730 		}
731 	}
732 	return val;
733 }
734 
735 static int rockchip_dw_hdmi_scdc_get_sink_version(struct dw_hdmi *hdmi)
736 {
737 	return rockchip_dw_hdmi_i2cm_read_data(hdmi, SCDC_SINK_VERSION);
738 }
739 
740 static void rockchip_dw_hdmi_scdc_set_source_version(struct dw_hdmi *hdmi,
741 						     u8 version)
742 {
743 	rockchip_dw_hdmi_i2cm_write_data(hdmi, version, SCDC_SOURCE_VERSION);
744 }
745 
746 static void rockchip_dw_hdmi_scdc_init(struct dw_hdmi *hdmi)
747 {
748 	rockchip_dw_hdmi_i2cm_reset(hdmi);
749 	rockchip_dw_hdmi_i2cm_mask_int(hdmi, 1);
750 	rockchip_dw_hdmi_i2cm_clk_init(hdmi);
751 	/* set scdc i2c addr */
752 	hdmi_writeb(hdmi, DDC_I2C_SCDC_ADDR, HDMI_I2CM_SLAVE);
753 	rockchip_dw_hdmi_i2cm_mask_int(hdmi, 0);/*enable interrupt*/
754 }
755 
756 static int rockchip_dw_hdmi_scrambling_enable(struct dw_hdmi *hdmi,
757 					      int enable)
758 {
759 	int stat;
760 
761 	rockchip_dw_hdmi_scdc_init(hdmi);
762 	stat = rockchip_dw_hdmi_i2cm_read_data(hdmi,
763 					       SCDC_TMDS_CONFIG);
764 	if (stat < 0) {
765 		debug("Failed to read tmds config\n");
766 		return false;
767 	}
768 
769 	if (enable == 1) {
770 		/* Write on Rx the bit Scrambling_Enable, register 0x20 */
771 		stat |= SCDC_SCRAMBLING_ENABLE;
772 		rockchip_dw_hdmi_i2cm_write_data(hdmi, stat, SCDC_TMDS_CONFIG);
773 		/* TMDS software reset request */
774 		hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ,
775 			    HDMI_MC_SWRSTZ);
776 		/* Enable/Disable Scrambling */
777 		hdmi_writeb(hdmi, 1, HDMI_FC_SCRAMBLER_CTRL);
778 	} else {
779 		/* Enable/Disable Scrambling */
780 		hdmi_writeb(hdmi, 0, HDMI_FC_SCRAMBLER_CTRL);
781 		/* TMDS software reset request */
782 		hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ,
783 			    HDMI_MC_SWRSTZ);
784 		/* Write on Rx the bit Scrambling_Enable, register 0x20 */
785 		stat &= ~SCDC_SCRAMBLING_ENABLE;
786 		rockchip_dw_hdmi_i2cm_write_data(hdmi, stat, SCDC_TMDS_CONFIG);
787 	}
788 
789 	return 0;
790 }
791 
792 static void rockchip_dw_hdmi_scdc_set_tmds_rate(struct dw_hdmi *hdmi)
793 {
794 	int stat;
795 
796 	rockchip_dw_hdmi_scdc_init(hdmi);
797 	stat = rockchip_dw_hdmi_i2cm_read_data(hdmi,
798 					       SCDC_TMDS_CONFIG);
799 	if (hdmi->hdmi_data.video_mode.mpixelclock > 340000000)
800 		stat |= SCDC_TMDS_BIT_CLOCK_RATIO_BY_40;
801 	else
802 		stat &= ~SCDC_TMDS_BIT_CLOCK_RATIO_BY_40;
803 	rockchip_dw_hdmi_i2cm_write_data(hdmi, stat,
804 					 SCDC_TMDS_CONFIG);
805 }
806 
807 static int hdmi_phy_configure(struct dw_hdmi *hdmi)
808 {
809 	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
810 	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
811 	unsigned long mpixelclock = hdmi->hdmi_data.video_mode.mpixelclock;
812 	int ret, sink_version;
813 
814 	dw_hdmi_phy_power_off(hdmi);
815 
816 	/* Control for TMDS Bit Period/TMDS Clock-Period Ratio */
817 	if (hdmi->edid_data.display_info.hdmi.scdc.supported)
818 		rockchip_dw_hdmi_scdc_set_tmds_rate(hdmi);
819 
820 	/* Leave low power consumption mode by asserting SVSRET. */
821 	if (phy->has_svsret)
822 		dw_hdmi_phy_enable_svsret(hdmi, 1);
823 
824 	/* PHY reset. The reset signal is active high on Gen2 PHYs. */
825 	hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ);
826 	hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ);
827 
828 	hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
829 
830 	hdmi_phy_test_clear(hdmi, 1);
831 	hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
832 		    HDMI_PHY_I2CM_SLAVE_ADDR);
833 	hdmi_phy_test_clear(hdmi, 0);
834 
835 	/* Write to the PHY as configured by the platform */
836 	if (pdata->configure_phy)
837 		ret = pdata->configure_phy(hdmi, pdata, mpixelclock);
838 	else
839 		ret = phy->configure(hdmi, pdata, mpixelclock);
840 	if (ret) {
841 		printf("PHY configuration failed (clock %lu)\n",
842 		       mpixelclock);
843 		return ret;
844 	}
845 
846 	/* Wait for resuming transmission of TMDS clock and data */
847 	if (mpixelclock > 340000000)
848 		mdelay(100);
849 
850 	return dw_hdmi_phy_power_on(hdmi);
851 }
852 
853 static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
854 			    struct drm_display_mode *mode)
855 {
856 	int i, ret;
857 
858 	/* HDMI Phy spec says to do the phy initialization sequence twice */
859 	for (i = 0; i < 2; i++) {
860 		dw_hdmi_phy_sel_data_en_pol(hdmi, 1);
861 		dw_hdmi_phy_sel_interface_control(hdmi, 0);
862 		ret = hdmi_phy_configure(hdmi);
863 		if (ret)
864 			return ret;
865 	}
866 
867 	return 0;
868 }
869 
870 static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data)
871 {
872 	dw_hdmi_phy_power_off(hdmi);
873 }
874 
875 static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi,
876 						      void *data)
877 {
878 	return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
879 		connector_status_connected : connector_status_disconnected;
880 }
881 
882 static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = {
883 	.init = dw_hdmi_phy_init,
884 	.disable = dw_hdmi_phy_disable,
885 	.read_hpd = dw_hdmi_phy_read_hpd,
886 };
887 
888 static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
889 {
890 	unsigned int i;
891 	u8 phy_type;
892 
893 	phy_type = hdmi_readb(hdmi, HDMI_CONFIG2_ID);
894 
895 	/*
896 	 * RK3228 and RK3328 phy_type is DW_HDMI_PHY_DWC_HDMI20_TX_PHY,
897 	 * but it has a vedor phy.
898 	 */
899 	if (phy_type == DW_HDMI_PHY_VENDOR_PHY ||
900 	    hdmi->dev_type == RK3328_HDMI ||
901 	    hdmi->dev_type == RK3228_HDMI) {
902 		/* Vendor PHYs require support from the glue layer. */
903 		if (!hdmi->plat_data->phy_ops || !hdmi->plat_data->phy_name) {
904 			printf(
905 				"Vendor HDMI PHY not supported by glue layer\n");
906 			return -ENODEV;
907 		}
908 
909 		hdmi->phy.ops = hdmi->plat_data->phy_ops;
910 		hdmi->phy.data = hdmi->plat_data->phy_data;
911 		hdmi->phy.name = hdmi->plat_data->phy_name;
912 		return 0;
913 	}
914 
915 	/* Synopsys PHYs are handled internally. */
916 	for (i = 0; i < ARRAY_SIZE(dw_hdmi_phys); ++i) {
917 		if (dw_hdmi_phys[i].type == phy_type) {
918 			hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops;
919 			hdmi->phy.name = dw_hdmi_phys[i].name;
920 			hdmi->phy.data = (void *)&dw_hdmi_phys[i];
921 
922 			if (!dw_hdmi_phys[i].configure &&
923 			    !hdmi->plat_data->configure_phy) {
924 				printf("%s requires platform support\n",
925 				       hdmi->phy.name);
926 				return -ENODEV;
927 			}
928 
929 			return 0;
930 		}
931 	}
932 
933 	printf("Unsupported HDMI PHY type (%02x)\n", phy_type);
934 	return -ENODEV;
935 }
936 
937 static void hdmi_av_composer(struct dw_hdmi *hdmi,
938 			     const struct drm_display_mode *mode)
939 {
940 	u8 inv_val = 0;
941 	struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
942 	struct drm_hdmi_info *hdmi_info = &hdmi->edid_data.display_info.hdmi;
943 	int bytes, hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
944 	unsigned int hdisplay, vdisplay;
945 
946 	vmode->mpixelclock = mode->clock * 1000;
947 	if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
948 		vmode->mpixelclock /= 2;
949 	if ((mode->flags & DRM_MODE_FLAG_3D_MASK) ==
950 		DRM_MODE_FLAG_3D_FRAME_PACKING)
951 		vmode->mpixelclock *= 2;
952 	printf("final pixclk = %d\n", vmode->mpixelclock);
953 
954 	/* Set up HDMI_FC_INVIDCONF
955 	 * fc_invidconf.HDCP_keepout must be set (1'b1)
956 	 * when activate the scrambler feature.
957 	 */
958 	inv_val = (vmode->mpixelclock > 340000000 ||
959 		   hdmi_info->scdc.scrambling.low_rates ?
960 		   HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
961 		   HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE);
962 
963 	inv_val |= mode->flags & DRM_MODE_FLAG_PVSYNC ?
964 		HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
965 		HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW;
966 
967 	inv_val |= mode->flags & DRM_MODE_FLAG_PHSYNC ?
968 		HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH :
969 		HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW;
970 
971 	inv_val |= (vmode->mdataenablepolarity ?
972 		HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
973 		HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
974 
975 	if (hdmi->vic == 39)
976 		inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH;
977 	else
978 		inv_val |= mode->flags & DRM_MODE_FLAG_INTERLACE ?
979 			HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH :
980 			HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW;
981 
982 	inv_val |= mode->flags & DRM_MODE_FLAG_INTERLACE ?
983 		HDMI_FC_INVIDCONF_IN_I_P_INTERLACED :
984 		HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE;
985 
986 	inv_val |= hdmi->sink_is_hdmi ?
987 		HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE :
988 		HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE;
989 
990 	hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF);
991 
992 	hdisplay = mode->hdisplay;
993 	hblank = mode->htotal - mode->hdisplay;
994 	h_de_hs = mode->hsync_start - mode->hdisplay;
995 	hsync_len = mode->hsync_end - mode->hsync_start;
996 
997 	/*
998 	 * When we're setting a YCbCr420 mode, we need
999 	 * to adjust the horizontal timing to suit.
1000 	 */
1001 	/*
1002 	 * When we're setting a YCbCr420 mode, we need
1003 	 * to adjust the horizontal timing to suit.
1004 	 */
1005 	if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) {
1006 		hdisplay /= 2;
1007 		hblank /= 2;
1008 		h_de_hs /= 2;
1009 		hsync_len /= 2;
1010 	}
1011 
1012 	vdisplay = mode->vdisplay;
1013 	vblank = mode->vtotal - mode->vdisplay;
1014 	v_de_vs = mode->vsync_start - mode->vdisplay;
1015 	vsync_len = mode->vsync_end - mode->vsync_start;
1016 
1017 	/*
1018 	 * When we're setting an interlaced mode, we need
1019 	 * to adjust the vertical timing to suit.
1020 	 */
1021 	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1022 		vdisplay /= 2;
1023 		vblank /= 2;
1024 		v_de_vs /= 2;
1025 		vsync_len /= 2;
1026 	} else if ((mode->flags & DRM_MODE_FLAG_3D_MASK) ==
1027 		DRM_MODE_FLAG_3D_FRAME_PACKING) {
1028 		vdisplay += mode->vtotal;
1029 	}
1030 
1031 	/* Scrambling Control */
1032 	if (hdmi_info->scdc.supported) {
1033 		if (vmode->mpixelclock > 340000000 ||
1034 		    hdmi_info->scdc.scrambling.low_rates) {
1035 			bytes = rockchip_dw_hdmi_scdc_get_sink_version(hdmi);
1036 			rockchip_dw_hdmi_scdc_set_source_version(hdmi, bytes);
1037 			rockchip_dw_hdmi_scrambling_enable(hdmi, 1);
1038 		} else {
1039 			rockchip_dw_hdmi_scrambling_enable(hdmi, 0);
1040 		}
1041 	}
1042 
1043 	/* Set up horizontal active pixel width */
1044 	hdmi_writeb(hdmi, hdisplay >> 8, HDMI_FC_INHACTV1);
1045 	hdmi_writeb(hdmi, hdisplay, HDMI_FC_INHACTV0);
1046 
1047 	/* Set up vertical active lines */
1048 	hdmi_writeb(hdmi, vdisplay >> 8, HDMI_FC_INVACTV1);
1049 	hdmi_writeb(hdmi, vdisplay, HDMI_FC_INVACTV0);
1050 
1051 	/* Set up horizontal blanking pixel region width */
1052 	hdmi_writeb(hdmi, hblank >> 8, HDMI_FC_INHBLANK1);
1053 	hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0);
1054 
1055 	/* Set up vertical blanking pixel region width */
1056 	hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK);
1057 
1058 	/* Set up HSYNC active edge delay width (in pixel clks) */
1059 	hdmi_writeb(hdmi, h_de_hs >> 8, HDMI_FC_HSYNCINDELAY1);
1060 	hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0);
1061 
1062 	/* Set up VSYNC active edge delay (in lines) */
1063 	hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY);
1064 
1065 	/* Set up HSYNC active pulse width (in pixel clks) */
1066 	hdmi_writeb(hdmi, hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1);
1067 	hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0);
1068 
1069 	/* Set up VSYNC active edge delay (in lines) */
1070 	hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH);
1071 }
1072 
1073 static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi)
1074 {
1075 	const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
1076 	unsigned i;
1077 	u32 csc_scale = 1;
1078 
1079 	if (is_color_space_conversion(hdmi)) {
1080 		if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
1081 			if (hdmi->hdmi_data.enc_out_encoding ==
1082 						V4L2_YCBCR_ENC_601)
1083 				csc_coeff = &csc_coeff_rgb_out_eitu601;
1084 			else
1085 				csc_coeff = &csc_coeff_rgb_out_eitu709;
1086 		} else if (hdmi_bus_fmt_is_rgb(
1087 					hdmi->hdmi_data.enc_in_bus_format)) {
1088 			if (hdmi->hdmi_data.enc_out_encoding ==
1089 						V4L2_YCBCR_ENC_601)
1090 				csc_coeff = &csc_coeff_rgb_in_eitu601;
1091 			else
1092 				csc_coeff = &csc_coeff_rgb_in_eitu709;
1093 			csc_scale = 0;
1094 		}
1095 	}
1096 
1097 	/* The CSC registers are sequential, alternating MSB then LSB */
1098 	for (i = 0; i < ARRAY_SIZE(csc_coeff_default[0]); i++) {
1099 		u16 coeff_a = (*csc_coeff)[0][i];
1100 		u16 coeff_b = (*csc_coeff)[1][i];
1101 		u16 coeff_c = (*csc_coeff)[2][i];
1102 
1103 		hdmi_writeb(hdmi, coeff_a & 0xff, HDMI_CSC_COEF_A1_LSB + i * 2);
1104 		hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2);
1105 		hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2);
1106 		hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2);
1107 		hdmi_writeb(hdmi, coeff_c & 0xff, HDMI_CSC_COEF_C1_LSB + i * 2);
1108 		hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2);
1109 	}
1110 
1111 	hdmi_modb(hdmi, csc_scale, HDMI_CSC_SCALE_CSCSCALE_MASK,
1112 		  HDMI_CSC_SCALE);
1113 }
1114 
1115 static int is_color_space_interpolation(struct dw_hdmi *hdmi)
1116 {
1117 	if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_in_bus_format))
1118 		return 0;
1119 
1120 	if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) ||
1121 	    hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format))
1122 		return 1;
1123 
1124 	return 0;
1125 }
1126 
1127 static void hdmi_video_csc(struct dw_hdmi *hdmi)
1128 {
1129 	int color_depth = 0;
1130 	int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
1131 	int decimation = 0;
1132 
1133 	/* YCC422 interpolation to 444 mode */
1134 	if (is_color_space_interpolation(hdmi))
1135 		interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1;
1136 	else if (is_color_space_decimation(hdmi))
1137 		decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3;
1138 
1139 	switch (hdmi_bus_fmt_color_depth(hdmi->hdmi_data.enc_out_bus_format)) {
1140 	case 8:
1141 		color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP;
1142 		break;
1143 	case 10:
1144 		color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP;
1145 		break;
1146 	case 12:
1147 		color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP;
1148 		break;
1149 	case 16:
1150 		color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP;
1151 		break;
1152 
1153 	default:
1154 		return;
1155 	}
1156 
1157 	/* Configure the CSC registers */
1158 	hdmi_writeb(hdmi, interpolation | decimation, HDMI_CSC_CFG);
1159 	hdmi_modb(hdmi, color_depth, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK,
1160 		  HDMI_CSC_SCALE);
1161 
1162 	dw_hdmi_update_csc_coeffs(hdmi);
1163 }
1164 
1165 static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
1166 {
1167 	u8 clkdis;
1168 
1169 	/* control period minimum duration */
1170 	hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
1171 	hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
1172 	hdmi_writeb(hdmi, 1, HDMI_FC_EXCTRLSPAC);
1173 
1174 	/* Set to fill TMDS data channels */
1175 	hdmi_writeb(hdmi, 0x0B, HDMI_FC_CH0PREAM);
1176 	hdmi_writeb(hdmi, 0x16, HDMI_FC_CH1PREAM);
1177 	hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
1178 
1179 	/* Enable pixel clock and tmds data path */
1180 	clkdis = 0x7F;
1181 	clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
1182 	hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
1183 
1184 	clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
1185 	hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
1186 
1187 	/* Enable csc path */
1188 	if (is_color_space_conversion(hdmi)) {
1189 		clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
1190 		hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
1191 	}
1192 
1193 	/* Enable pixel repetition path */
1194 	if (hdmi->hdmi_data.video_mode.mpixelrepetitioninput) {
1195 		clkdis &= ~HDMI_MC_CLKDIS_PREPCLK_DISABLE;
1196 		hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
1197 	}
1198 
1199 	/* Enable color space conversion if needed */
1200 	if (is_color_space_conversion(hdmi))
1201 		hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH,
1202 			    HDMI_MC_FLOWCTRL);
1203 	else
1204 		hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS,
1205 			    HDMI_MC_FLOWCTRL);
1206 }
1207 
1208 static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
1209 {
1210 	unsigned int count;
1211 	unsigned int i;
1212 	u8 val;
1213 
1214 	/*
1215 	 * Under some circumstances the Frame Composer arithmetic unit can miss
1216 	 * an FC register write due to being busy processing the previous one.
1217 	 * The issue can be worked around by issuing a TMDS software reset and
1218 	 * then write one of the FC registers several times.
1219 	 *
1220 	 * The number of iterations matters and depends on the HDMI TX revision
1221 	 * (and possibly on the platform). So far only i.MX6Q (v1.30a) and
1222 	 * i.MX6DL (v1.31a) have been identified as needing the workaround, with
1223 	 * 4 and 1 iterations respectively.
1224 	 */
1225 
1226 	switch (hdmi->version) {
1227 	case 0x130a:
1228 		count = 4;
1229 		break;
1230 	case 0x131a:
1231 		count = 1;
1232 		break;
1233 	default:
1234 		return;
1235 	}
1236 
1237 	/* TMDS software reset */
1238 	hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
1239 
1240 	val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF);
1241 	for (i = 0; i < count; i++)
1242 		hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
1243 }
1244 
1245 static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
1246 {
1247 	hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
1248 		    HDMI_IH_MUTE_FC_STAT2);
1249 }
1250 
1251 static void hdmi_video_packetize(struct dw_hdmi *hdmi)
1252 {
1253 	unsigned int color_depth = 0;
1254 	unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit;
1255 	unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP;
1256 	struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
1257 	u8 val, vp_conf;
1258 
1259 	if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) ||
1260 	    hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format) ||
1261 	    hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) {
1262 		switch (hdmi_bus_fmt_color_depth(
1263 					hdmi->hdmi_data.enc_out_bus_format)) {
1264 		case 8:
1265 			color_depth = 0;
1266 			output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
1267 			break;
1268 		case 10:
1269 			color_depth = 5;
1270 			break;
1271 		case 12:
1272 			color_depth = 6;
1273 			break;
1274 		case 16:
1275 			color_depth = 7;
1276 			break;
1277 		default:
1278 			output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
1279 		}
1280 	} else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) {
1281 		switch (hdmi_bus_fmt_color_depth(
1282 					hdmi->hdmi_data.enc_out_bus_format)) {
1283 		case 0:
1284 		case 8:
1285 			remap_size = HDMI_VP_REMAP_YCC422_16bit;
1286 			break;
1287 		case 10:
1288 			remap_size = HDMI_VP_REMAP_YCC422_20bit;
1289 			break;
1290 		case 12:
1291 			remap_size = HDMI_VP_REMAP_YCC422_24bit;
1292 			break;
1293 
1294 		default:
1295 			return;
1296 		}
1297 		output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422;
1298 	} else {
1299 		return;
1300 	}
1301 
1302 	/* set the packetizer registers */
1303 	val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
1304 		HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
1305 		((hdmi_data->pix_repet_factor <<
1306 		HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
1307 		HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
1308 	hdmi_writeb(hdmi, val, HDMI_VP_PR_CD);
1309 
1310 	hdmi_modb(hdmi, HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE,
1311 		  HDMI_VP_STUFF_PR_STUFFING_MASK, HDMI_VP_STUFF);
1312 
1313 	/* Data from pixel repeater block */
1314 	if (hdmi_data->pix_repet_factor > 0) {
1315 		vp_conf = HDMI_VP_CONF_PR_EN_ENABLE |
1316 			  HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER;
1317 	} else { /* data from packetizer block */
1318 		vp_conf = HDMI_VP_CONF_PR_EN_DISABLE |
1319 			  HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
1320 	}
1321 
1322 	hdmi_modb(hdmi, vp_conf,
1323 		  HDMI_VP_CONF_PR_EN_MASK |
1324 		  HDMI_VP_CONF_BYPASS_SELECT_MASK, HDMI_VP_CONF);
1325 
1326 	hdmi_modb(hdmi, 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET,
1327 		  HDMI_VP_STUFF_IDEFAULT_PHASE_MASK, HDMI_VP_STUFF);
1328 
1329 	hdmi_writeb(hdmi, remap_size, HDMI_VP_REMAP);
1330 
1331 	if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) {
1332 		vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE |
1333 			  HDMI_VP_CONF_PP_EN_ENABLE |
1334 			  HDMI_VP_CONF_YCC422_EN_DISABLE;
1335 	} else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) {
1336 		vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE |
1337 			  HDMI_VP_CONF_PP_EN_DISABLE |
1338 			  HDMI_VP_CONF_YCC422_EN_ENABLE;
1339 	} else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) {
1340 		vp_conf = HDMI_VP_CONF_BYPASS_EN_ENABLE |
1341 			  HDMI_VP_CONF_PP_EN_DISABLE |
1342 			  HDMI_VP_CONF_YCC422_EN_DISABLE;
1343 	} else {
1344 		return;
1345 	}
1346 
1347 	hdmi_modb(hdmi, vp_conf,
1348 		  HDMI_VP_CONF_BYPASS_EN_MASK | HDMI_VP_CONF_PP_EN_ENMASK |
1349 		  HDMI_VP_CONF_YCC422_EN_MASK, HDMI_VP_CONF);
1350 
1351 	hdmi_modb(hdmi, HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE |
1352 			HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE,
1353 		  HDMI_VP_STUFF_PP_STUFFING_MASK |
1354 		  HDMI_VP_STUFF_YCC422_STUFFING_MASK, HDMI_VP_STUFF);
1355 
1356 	hdmi_modb(hdmi, output_select, HDMI_VP_CONF_OUTPUT_SELECTOR_MASK,
1357 		  HDMI_VP_CONF);
1358 }
1359 
1360 static void hdmi_video_sample(struct dw_hdmi *hdmi)
1361 {
1362 	int color_format = 0;
1363 	u8 val;
1364 
1365 	switch (hdmi->hdmi_data.enc_in_bus_format) {
1366 	case MEDIA_BUS_FMT_RGB888_1X24:
1367 		color_format = 0x01;
1368 		break;
1369 	case MEDIA_BUS_FMT_RGB101010_1X30:
1370 		color_format = 0x03;
1371 		break;
1372 	case MEDIA_BUS_FMT_RGB121212_1X36:
1373 		color_format = 0x05;
1374 		break;
1375 	case MEDIA_BUS_FMT_RGB161616_1X48:
1376 		color_format = 0x07;
1377 		break;
1378 
1379 	case MEDIA_BUS_FMT_YUV8_1X24:
1380 	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
1381 		color_format = 0x09;
1382 		break;
1383 	case MEDIA_BUS_FMT_YUV10_1X30:
1384 	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
1385 		color_format = 0x0B;
1386 		break;
1387 	case MEDIA_BUS_FMT_YUV12_1X36:
1388 	case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
1389 		color_format = 0x0D;
1390 		break;
1391 	case MEDIA_BUS_FMT_YUV16_1X48:
1392 	case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
1393 		color_format = 0x0F;
1394 		break;
1395 
1396 	case MEDIA_BUS_FMT_UYVY8_1X16:
1397 		color_format = 0x16;
1398 		break;
1399 	case MEDIA_BUS_FMT_UYVY10_1X20:
1400 		color_format = 0x14;
1401 		break;
1402 	case MEDIA_BUS_FMT_UYVY12_1X24:
1403 		color_format = 0x12;
1404 		break;
1405 
1406 	default:
1407 		return;
1408 	}
1409 
1410 	val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE |
1411 		((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) &
1412 		HDMI_TX_INVID0_VIDEO_MAPPING_MASK);
1413 	hdmi_writeb(hdmi, val, HDMI_TX_INVID0);
1414 
1415 	/* Enable TX stuffing: When DE is inactive, fix the output data to 0 */
1416 	val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE |
1417 		HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE |
1418 		HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE;
1419 	hdmi_writeb(hdmi, val, HDMI_TX_INSTUFFING);
1420 	hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA0);
1421 	hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA1);
1422 	hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA0);
1423 	hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA1);
1424 	hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA0);
1425 	hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1);
1426 }
1427 
1428 static void hdmi_enable_overflow_interrupts(struct dw_hdmi *hdmi)
1429 {
1430 	hdmi_writeb(hdmi, 0, HDMI_FC_MASK2);
1431 	hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2);
1432 }
1433 
1434 static void dw_hdmi_disable(struct dw_hdmi *hdmi)
1435 {
1436 	if (hdmi->phy.enabled) {
1437 		hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
1438 		hdmi->phy.enabled = false;
1439 	}
1440 }
1441 
1442 static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
1443 {
1444 	struct hdmi_avi_infoframe frame;
1445 	u8 val;
1446 	bool is_hdmi2 = false;
1447 
1448 	if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format) ||
1449 	    hdmi->edid_data.display_info.hdmi.scdc.supported)
1450 		is_hdmi2 = true;
1451 	/* Initialise info frame from DRM mode */
1452 	drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, is_hdmi2);
1453 
1454 	if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format))
1455 		frame.colorspace = HDMI_COLORSPACE_YUV444;
1456 	else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format))
1457 		frame.colorspace = HDMI_COLORSPACE_YUV422;
1458 	else if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
1459 		frame.colorspace = HDMI_COLORSPACE_YUV420;
1460 	else
1461 		frame.colorspace = HDMI_COLORSPACE_RGB;
1462 
1463 	/* Set up colorimetry */
1464 	switch (hdmi->hdmi_data.enc_out_encoding) {
1465 	case V4L2_YCBCR_ENC_601:
1466 		if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601)
1467 			frame.colorimetry = HDMI_COLORIMETRY_EXTENDED;
1468 		else
1469 			frame.colorimetry = HDMI_COLORIMETRY_ITU_601;
1470 		frame.extended_colorimetry =
1471 				HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
1472 		break;
1473 	case V4L2_YCBCR_ENC_709:
1474 		if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV709)
1475 			frame.colorimetry = HDMI_COLORIMETRY_EXTENDED;
1476 		else
1477 			frame.colorimetry = HDMI_COLORIMETRY_ITU_709;
1478 		frame.extended_colorimetry =
1479 				HDMI_EXTENDED_COLORIMETRY_XV_YCC_709;
1480 		break;
1481 	default: /* Carries no data */
1482 		frame.colorimetry = HDMI_COLORIMETRY_ITU_601;
1483 		frame.extended_colorimetry =
1484 				HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
1485 		break;
1486 	}
1487 
1488 	frame.scan_mode = HDMI_SCAN_MODE_NONE;
1489 
1490 	/*
1491 	 * The Designware IP uses a different byte format from standard
1492 	 * AVI info frames, though generally the bits are in the correct
1493 	 * bytes.
1494 	 */
1495 
1496 	/*
1497 	 * AVI data byte 1 differences: Colorspace in bits 0,1,7 rather than
1498 	 * 5,6,7, active aspect present in bit 6 rather than 4.
1499 	 */
1500 	val = (frame.scan_mode & 3) << 4 | (frame.colorspace & 0x3);
1501 	if (frame.active_aspect & 15)
1502 		val |= HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT;
1503 	if (frame.top_bar || frame.bottom_bar)
1504 		val |= HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR;
1505 	if (frame.left_bar || frame.right_bar)
1506 		val |= HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR;
1507 	hdmi_writeb(hdmi, val, HDMI_FC_AVICONF0);
1508 
1509 	/* AVI data byte 2 differences: none */
1510 	val = ((frame.colorimetry & 0x3) << 6) |
1511 	      ((frame.picture_aspect & 0x3) << 4) |
1512 	      (frame.active_aspect & 0xf);
1513 	hdmi_writeb(hdmi, val, HDMI_FC_AVICONF1);
1514 
1515 	/* AVI data byte 3 differences: none */
1516 	val = ((frame.extended_colorimetry & 0x7) << 4) |
1517 	      ((frame.quantization_range & 0x3) << 2) |
1518 	      (frame.nups & 0x3);
1519 	if (frame.itc)
1520 		val |= HDMI_FC_AVICONF2_IT_CONTENT_VALID;
1521 	hdmi_writeb(hdmi, val, HDMI_FC_AVICONF2);
1522 
1523 	/* AVI data byte 4 differences: none */
1524 	val = frame.video_code & 0x7f;
1525 	hdmi_writeb(hdmi, val, HDMI_FC_AVIVID);
1526 
1527 	/* AVI Data Byte 5- set up input and output pixel repetition */
1528 	val = (((hdmi->hdmi_data.video_mode.mpixelrepetitioninput + 1) <<
1529 		HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) &
1530 		HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) |
1531 		((hdmi->hdmi_data.video_mode.mpixelrepetitionoutput <<
1532 		HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) &
1533 		HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK);
1534 	hdmi_writeb(hdmi, val, HDMI_FC_PRCONF);
1535 
1536 	/*
1537 	 * AVI data byte 5 differences: content type in 0,1 rather than 4,5,
1538 	 * ycc range in bits 2,3 rather than 6,7
1539 	 */
1540 	val = ((frame.ycc_quantization_range & 0x3) << 2) |
1541 	      (frame.content_type & 0x3);
1542 	hdmi_writeb(hdmi, val, HDMI_FC_AVICONF3);
1543 
1544 	/* AVI Data Bytes 6-13 */
1545 	hdmi_writeb(hdmi, frame.top_bar & 0xff, HDMI_FC_AVIETB0);
1546 	hdmi_writeb(hdmi, (frame.top_bar >> 8) & 0xff, HDMI_FC_AVIETB1);
1547 	hdmi_writeb(hdmi, frame.bottom_bar & 0xff, HDMI_FC_AVISBB0);
1548 	hdmi_writeb(hdmi, (frame.bottom_bar >> 8) & 0xff, HDMI_FC_AVISBB1);
1549 	hdmi_writeb(hdmi, frame.left_bar & 0xff, HDMI_FC_AVIELB0);
1550 	hdmi_writeb(hdmi, (frame.left_bar >> 8) & 0xff, HDMI_FC_AVIELB1);
1551 	hdmi_writeb(hdmi, frame.right_bar & 0xff, HDMI_FC_AVISRB0);
1552 	hdmi_writeb(hdmi, (frame.right_bar >> 8) & 0xff, HDMI_FC_AVISRB1);
1553 }
1554 
1555 static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi,
1556 						  struct drm_display_mode *mode)
1557 {
1558 	struct hdmi_vendor_infoframe frame;
1559 	u8 buffer[10];
1560 	ssize_t err;
1561 
1562 	/* Disable HDMI vendor specific infoframe send */
1563 	hdmi_mask_writeb(hdmi, 0, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_VSD_OFFSET,
1564 			 HDMI_FC_DATAUTO0_VSD_MASK);
1565 
1566 	err = drm_hdmi_vendor_infoframe_from_display_mode(&frame, mode);
1567 	if (err < 0)
1568 		/*
1569 		 * Going into that statement does not means vendor infoframe
1570 		 * fails. It just informed us that vendor infoframe is not
1571 		 * needed for the selected mode. Only 4k or stereoscopic 3D
1572 		 * mode requires vendor infoframe. So just simply return.
1573 		 */
1574 		return;
1575 
1576 	err = hdmi_vendor_infoframe_pack(&frame, buffer, sizeof(buffer));
1577 	if (err < 0) {
1578 		printf("Failed to pack vendor infoframe: %zd\n", err);
1579 		return;
1580 	}
1581 
1582 	/* Set the length of HDMI vendor specific InfoFrame payload */
1583 	hdmi_writeb(hdmi, buffer[2], HDMI_FC_VSDSIZE);
1584 
1585 	/* Set 24bit IEEE Registration Identifier */
1586 	hdmi_writeb(hdmi, buffer[4], HDMI_FC_VSDIEEEID0);
1587 	hdmi_writeb(hdmi, buffer[5], HDMI_FC_VSDIEEEID1);
1588 	hdmi_writeb(hdmi, buffer[6], HDMI_FC_VSDIEEEID2);
1589 
1590 	/* Set HDMI_Video_Format and HDMI_VIC/3D_Structure */
1591 	hdmi_writeb(hdmi, buffer[7], HDMI_FC_VSDPAYLOAD0);
1592 	hdmi_writeb(hdmi, buffer[8], HDMI_FC_VSDPAYLOAD1);
1593 
1594 	if (frame.s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
1595 		hdmi_writeb(hdmi, buffer[9], HDMI_FC_VSDPAYLOAD2);
1596 
1597 	/* Packet frame interpolation */
1598 	hdmi_writeb(hdmi, 1, HDMI_FC_DATAUTO1);
1599 
1600 	/* Auto packets per frame and line spacing */
1601 	hdmi_writeb(hdmi, 0x11, HDMI_FC_DATAUTO2);
1602 
1603 	/* Configures the Frame Composer On RDRB mode */
1604 	hdmi_mask_writeb(hdmi, 1, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_VSD_OFFSET,
1605 			 HDMI_FC_DATAUTO0_VSD_MASK);
1606 }
1607 
1608 static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts,
1609 			   unsigned int n)
1610 {
1611 	/* Must be set/cleared first */
1612 	hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
1613 
1614 	/* nshift factor = 0 */
1615 	hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3);
1616 
1617 	hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
1618 		    HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
1619 	hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2);
1620 	hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1);
1621 
1622 	hdmi_writeb(hdmi, (n >> 16) & 0x0f, HDMI_AUD_N3);
1623 	hdmi_writeb(hdmi, (n >> 8) & 0xff, HDMI_AUD_N2);
1624 	hdmi_writeb(hdmi, n & 0xff, HDMI_AUD_N1);
1625 }
1626 
1627 static int hdmi_match_tmds_n_table(struct dw_hdmi *hdmi,
1628 				   unsigned long pixel_clk,
1629 				   unsigned long freq)
1630 {
1631 	const struct dw_hdmi_plat_data *plat_data = hdmi->plat_data;
1632 	const struct dw_hdmi_audio_tmds_n *tmds_n = NULL;
1633 	int i;
1634 
1635 	if (plat_data->tmds_n_table) {
1636 		for (i = 0; plat_data->tmds_n_table[i].tmds != 0; i++) {
1637 			if (pixel_clk == plat_data->tmds_n_table[i].tmds) {
1638 				tmds_n = &plat_data->tmds_n_table[i];
1639 				break;
1640 			}
1641 		}
1642 	}
1643 
1644 	if (!tmds_n) {
1645 		for (i = 0; common_tmds_n_table[i].tmds != 0; i++) {
1646 			if (pixel_clk == common_tmds_n_table[i].tmds) {
1647 				tmds_n = &common_tmds_n_table[i];
1648 				break;
1649 			}
1650 		}
1651 	}
1652 
1653 	if (!tmds_n)
1654 		return -ENOENT;
1655 
1656 	switch (freq) {
1657 	case 32000:
1658 		return tmds_n->n_32k;
1659 	case 44100:
1660 	case 88200:
1661 	case 176400:
1662 		return (freq / 44100) * tmds_n->n_44k1;
1663 	case 48000:
1664 	case 96000:
1665 	case 192000:
1666 		return (freq / 48000) * tmds_n->n_48k;
1667 	default:
1668 		return -ENOENT;
1669 	}
1670 }
1671 
1672 static u64 hdmi_audio_math_diff(unsigned int freq, unsigned int n,
1673 				unsigned int pixel_clk)
1674 {
1675 	u64 final, diff;
1676 	u64 cts;
1677 
1678 	final = (u64)pixel_clk * n;
1679 
1680 	cts = final;
1681 	do_div(cts, 128 * freq);
1682 
1683 	diff = final - (u64)cts * (128 * freq);
1684 
1685 	return diff;
1686 }
1687 
1688 static unsigned int hdmi_compute_n(struct dw_hdmi *hdmi,
1689 				   unsigned long pixel_clk,
1690 				   unsigned long freq)
1691 {
1692 	unsigned int min_n = DIV_ROUND_UP((128 * freq), 1500);
1693 	unsigned int max_n = (128 * freq) / 300;
1694 	unsigned int ideal_n = (128 * freq) / 1000;
1695 	unsigned int best_n_distance = ideal_n;
1696 	unsigned int best_n = 0;
1697 	u64 best_diff = U64_MAX;
1698 	int n;
1699 
1700 	/* If the ideal N could satisfy the audio math, then just take it */
1701 	if (hdmi_audio_math_diff(freq, ideal_n, pixel_clk) == 0)
1702 		return ideal_n;
1703 
1704 	for (n = min_n; n <= max_n; n++) {
1705 		u64 diff = hdmi_audio_math_diff(freq, n, pixel_clk);
1706 
1707 		if (diff < best_diff || (diff == best_diff &&
1708 					 abs(n - ideal_n) < best_n_distance)) {
1709 			best_n = n;
1710 			best_diff = diff;
1711 			best_n_distance = abs(best_n - ideal_n);
1712 		}
1713 
1714 		/*
1715 		 * The best N already satisfy the audio math, and also be
1716 		 * the closest value to ideal N, so just cut the loop.
1717 		 */
1718 		if ((best_diff == 0) && (abs(n - ideal_n) > best_n_distance))
1719 			break;
1720 	}
1721 
1722 	return best_n;
1723 }
1724 
1725 static unsigned int hdmi_find_n(struct dw_hdmi *hdmi, unsigned long pixel_clk,
1726 				unsigned long sample_rate)
1727 {
1728 	int n;
1729 
1730 	n = hdmi_match_tmds_n_table(hdmi, pixel_clk, sample_rate);
1731 	if (n > 0)
1732 		return n;
1733 
1734 	printf("Rate %lu missing; compute N dynamically\n",
1735 	       pixel_clk);
1736 
1737 	return hdmi_compute_n(hdmi, pixel_clk, sample_rate);
1738 }
1739 
1740 static
1741 void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi, unsigned long pixel_clk,
1742 			      unsigned int sample_rate)
1743 {
1744 	unsigned long ftdms = pixel_clk;
1745 	unsigned int n, cts;
1746 	u64 tmp;
1747 
1748 	n = hdmi_find_n(hdmi, pixel_clk, sample_rate);
1749 
1750 	/*
1751 	 * Compute the CTS value from the N value.  Note that CTS and N
1752 	 * can be up to 20 bits in total, so we need 64-bit math.  Also
1753 	 * note that our TDMS clock is not fully accurate; it is accurate
1754 	 * to kHz.  This can introduce an unnecessary remainder in the
1755 	 * calculation below, so we don't try to warn about that.
1756 	 */
1757 	tmp = (u64)ftdms * n;
1758 	do_div(tmp, 128 * sample_rate);
1759 	cts = tmp;
1760 
1761 	printf("%s: fs=%uHz ftdms=%lu.%03luMHz N=%d cts=%d\n", __func__,
1762 	       sample_rate, ftdms / 1000000, (ftdms / 1000) % 1000, n, cts);
1763 
1764 	hdmi->audio_n = n;
1765 	hdmi->audio_cts = cts;
1766 	hdmi_set_cts_n(hdmi, cts, hdmi->audio_enable ? n : 0);
1767 }
1768 
1769 static void hdmi_clk_regenerator_update_pixel_clock(struct dw_hdmi *hdmi)
1770 {
1771 	hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock,
1772 				 hdmi->sample_rate);
1773 }
1774 
1775 static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
1776 {
1777 	hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
1778 }
1779 
1780 void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate)
1781 {
1782 	hdmi->sample_rate = rate;
1783 	hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock,
1784 				 hdmi->sample_rate);
1785 }
1786 
1787 static int dw_hdmi_setup(struct dw_hdmi *hdmi,
1788 			 struct drm_display_mode *mode)
1789 {
1790 	int ret;
1791 	void *data = hdmi->plat_data->phy_data;
1792 
1793 	hdmi_disable_overflow_interrupts(hdmi);
1794 
1795 	if (!hdmi->vic)
1796 		printf("Non-CEA mode used in HDMI\n");
1797 	else
1798 		printf("CEA mode used vic=%d\n", hdmi->vic);
1799 
1800 	if (hdmi->plat_data->get_enc_out_encoding)
1801 		hdmi->hdmi_data.enc_out_encoding =
1802 			hdmi->plat_data->get_enc_out_encoding(data);
1803 	else if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
1804 		 (hdmi->vic == 21) || (hdmi->vic == 22) ||
1805 		 (hdmi->vic == 2) || (hdmi->vic == 3) ||
1806 		 (hdmi->vic == 17) || (hdmi->vic == 18))
1807 		hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_601;
1808 	else
1809 		hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_709;
1810 
1811 	if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
1812 		hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1;
1813 		hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 1;
1814 	} else {
1815 		hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
1816 		hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
1817 	}
1818 
1819 	/* TOFIX: Get input format from plat data or fallback to RGB888 */
1820 	if (hdmi->plat_data->get_input_bus_format)
1821 		hdmi->hdmi_data.enc_in_bus_format =
1822 			hdmi->plat_data->get_input_bus_format(data);
1823 	else if (hdmi->plat_data->input_bus_format)
1824 		hdmi->hdmi_data.enc_in_bus_format =
1825 			hdmi->plat_data->input_bus_format;
1826 	else
1827 		hdmi->hdmi_data.enc_in_bus_format =
1828 			MEDIA_BUS_FMT_RGB888_1X24;
1829 
1830 	/* TOFIX: Default to RGB888 output format */
1831 	if (hdmi->plat_data->get_output_bus_format)
1832 		hdmi->hdmi_data.enc_out_bus_format =
1833 			hdmi->plat_data->get_output_bus_format(data);
1834 	else
1835 		hdmi->hdmi_data.enc_out_bus_format =
1836 			MEDIA_BUS_FMT_RGB888_1X24;
1837 
1838 	/* TOFIX: Get input encoding from plat data or fallback to none */
1839 	if (hdmi->plat_data->get_enc_in_encoding)
1840 		hdmi->hdmi_data.enc_in_encoding =
1841 			hdmi->plat_data->get_enc_in_encoding(data);
1842 	else if (hdmi->plat_data->input_bus_encoding)
1843 		hdmi->hdmi_data.enc_in_encoding =
1844 			hdmi->plat_data->input_bus_encoding;
1845 	else
1846 		hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT;
1847 	/*
1848 	 * According to the dw-hdmi specification 6.4.2
1849 	 * vp_pr_cd[3:0]:
1850 	 * 0000b: No pixel repetition (pixel sent only once)
1851 	 * 0001b: Pixel sent two times (pixel repeated once)
1852 	 */
1853 	hdmi->hdmi_data.pix_repet_factor =
1854 		(mode->flags & DRM_MODE_FLAG_DBLCLK) ? 1 : 0;
1855 	hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
1856 
1857 	/* HDMI Initialization Step B.1 */
1858 	hdmi_av_composer(hdmi, mode);
1859 
1860 	/* HDMI Initialization Step B.2 */
1861 	ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, &hdmi->previous_mode);
1862 	if (ret)
1863 		return ret;
1864 	hdmi->phy.enabled = true;
1865 
1866 	/* HDMI Initializateion Step B.3 */
1867 	dw_hdmi_enable_video_path(hdmi);
1868 
1869 	/* HDMI Initialization Step E - Configure audio */
1870 	if (hdmi->sink_has_audio) {
1871 		printf("sink has audio support\n");
1872 		hdmi_clk_regenerator_update_pixel_clock(hdmi);
1873 		hdmi_enable_audio_clk(hdmi);
1874 	}
1875 
1876 	/* not for DVI mode */
1877 	if (hdmi->sink_is_hdmi) {
1878 		printf("%s HDMI mode\n", __func__);
1879 
1880 		/* HDMI Initialization Step F - Configure AVI InfoFrame */
1881 		hdmi_config_AVI(hdmi, mode);
1882 		hdmi_config_vendor_specific_infoframe(hdmi, mode);
1883 	} else {
1884 		printf("%s DVI mode\n", __func__);
1885 	}
1886 
1887 	hdmi_video_packetize(hdmi);
1888 	hdmi_video_csc(hdmi);
1889 	hdmi_video_sample(hdmi);
1890 	dw_hdmi_clear_overflow(hdmi);
1891 	if (hdmi->cable_plugin && hdmi->sink_is_hdmi)
1892 		hdmi_enable_overflow_interrupts(hdmi);
1893 
1894 	return 0;
1895 }
1896 
1897 int dw_hdmi_detect_hotplug(struct dw_hdmi *hdmi)
1898 {
1899 	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
1900 }
1901 
1902 static int dw_hdmi_set_reg_wr(struct dw_hdmi *hdmi)
1903 {
1904 	switch (hdmi->io_width) {
1905 	case 4:
1906 		hdmi->write = dw_hdmi_writel;
1907 		hdmi->read = dw_hdmi_readl;
1908 		break;
1909 	case 1:
1910 		hdmi->write = dw_hdmi_writeb;
1911 		hdmi->read = dw_hdmi_readb;
1912 		break;
1913 	default:
1914 		printf("reg-io-width must be 1 or 4\n");
1915 		return -EINVAL;
1916 	}
1917 
1918 	return 0;
1919 }
1920 
1921 static void initialize_hdmi_mutes(struct dw_hdmi *hdmi)
1922 {
1923 	/*mute unnecessary interrupt, only enable hpd */
1924 	hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT0);
1925 	hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT1);
1926 	hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT2);
1927 	hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AS_STAT0);
1928 	hdmi_writeb(hdmi, 0xfe, HDMI_IH_MUTE_PHY_STAT0);
1929 	hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CM_STAT0);
1930 	hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_CEC_STAT0);
1931 	hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_VP_STAT0);
1932 	hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CMPHY_STAT0);
1933 	hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
1934 	hdmi_writeb(hdmi, 0xf1, HDMI_PHY_MASK0);
1935 
1936 	/*Force output black*/
1937 	dw_hdmi_writel(hdmi, 0x00, HDMI_FC_DBGTMDS2);
1938 	dw_hdmi_writel(hdmi, 0x00, HDMI_FC_DBGTMDS1);
1939 	dw_hdmi_writel(hdmi, 0x00, HDMI_FC_DBGTMDS0);
1940 }
1941 
1942 static void dw_hdmi_dev_init(struct dw_hdmi *hdmi)
1943 {
1944 	hdmi->version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8)
1945 		      | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0);
1946 
1947 	dw_hdmi_phy_power_off(hdmi);
1948 	initialize_hdmi_mutes(hdmi);
1949 }
1950 
1951 static int dw_hdmi_read_edid(struct dw_hdmi *hdmi,
1952 			     int block, unsigned char *buff)
1953 {
1954 	int i = 0, n = 0, index = 0, ret = -1, trytime = 2;
1955 	int offset = (block % 2) * 0x80;
1956 	int interrupt = 0;
1957 
1958 	rockchip_dw_hdmi_i2cm_reset(hdmi);
1959 
1960 	/* Set DDC I2C CLK which divided from DDC_CLK to 100KHz. */
1961 	rockchip_dw_hdmi_i2cm_clk_init(hdmi);
1962 
1963 	/* Enable I2C interrupt for reading edid */
1964 	rockchip_dw_hdmi_i2cm_mask_int(hdmi, 0);
1965 
1966 	hdmi_writeb(hdmi, DDC_I2C_EDID_ADDR, HDMI_I2CM_SLAVE);
1967 	hdmi_writeb(hdmi, DDC_I2C_SEG_ADDR, HDMI_I2CM_SEGADDR);
1968 	hdmi_writeb(hdmi, block / 2, HDMI_I2CM_SEGPTR);
1969 
1970 	while (trytime--) {
1971 		for (n = 0; n < HDMI_EDID_BLOCK_SIZE / 8; n++) {
1972 			hdmi_writeb(hdmi, offset + 8 * n, HDMI_I2CM_ADDRESS);
1973 			/*enable extend sequential read operation*/
1974 			if (block == 0)
1975 				hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ8,
1976 					    HDMI_I2CM_OPERATION);
1977 			else
1978 				hdmi_writeb(hdmi,
1979 					    HDMI_I2CM_OPERATION_READ8_EXT,
1980 					    HDMI_I2CM_OPERATION);
1981 
1982 			i = 20;
1983 			while (i--) {
1984 				mdelay(1);
1985 				interrupt = hdmi_readb(hdmi,
1986 						       HDMI_IH_I2CM_STAT0);
1987 				if (interrupt) {
1988 					hdmi_writeb(hdmi,
1989 						    interrupt,
1990 						    HDMI_IH_I2CM_STAT0);
1991 				}
1992 
1993 				if (interrupt &
1994 				    (m_SCDC_READREQ |
1995 				     m_I2CM_DONE |
1996 				     m_I2CM_ERROR))
1997 					break;
1998 				mdelay(4);
1999 			}
2000 
2001 			if (interrupt & m_I2CM_DONE) {
2002 				for (index = 0; index < 8; index++)
2003 					buff[8 * n + index] =
2004 					hdmi_readb(hdmi, HDMI_I2CM_READ_BUFF0
2005 						   + index);
2006 
2007 				if (n == HDMI_EDID_BLOCK_SIZE / 8 - 1) {
2008 					ret = 0;
2009 					printf("[%s] edid read success\n",
2010 					       __func__);
2011 					goto exit;
2012 				}
2013 				continue;
2014 			} else if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
2015 				printf("[%s] edid read error\n", __func__);
2016 				rockchip_dw_hdmi_i2cm_reset(hdmi);
2017 				break;
2018 			}
2019 		}
2020 
2021 		printf("[%s] edid try times %d\n", __func__, trytime);
2022 		mdelay(100);
2023 	}
2024 
2025 exit:
2026 	/* Disable I2C interrupt */
2027 	rockchip_dw_hdmi_i2cm_mask_int(hdmi, 1);
2028 	return ret;
2029 }
2030 
2031 static int drm_do_get_edid(struct dw_hdmi *hdmi, u8 *edid)
2032 {
2033 	int i, j, block_num, ret;
2034 
2035 	/* base block fetch */
2036 	for (i = 0; i < 3; i++) {
2037 		ret = dw_hdmi_read_edid(hdmi, 0, edid);
2038 		if (!ret)
2039 			break;
2040 	}
2041 
2042 	if (ret) {
2043 		printf("get base block failed\n");
2044 		goto err;
2045 	}
2046 
2047 	/* get the number of extensions */
2048 	block_num = edid[0x7e];
2049 
2050 	for (j = 1; j <= block_num; j++) {
2051 		for (i = 0; i < 3; i++) {
2052 			ret = dw_hdmi_read_edid(hdmi, j, &edid[0x80 * j]);
2053 			if (!ret)
2054 				break;
2055 		}
2056 	}
2057 
2058 	if (ret) {
2059 		printf("get extensions failed\n");
2060 		goto err;
2061 	}
2062 
2063 	return 0;
2064 
2065 err:
2066 	memset(edid, 0, HDMI_EDID_BLOCK_SIZE);
2067 	return -EFAULT;
2068 }
2069 
2070 void dw_hdmi_audio_enable(struct dw_hdmi *hdmi)
2071 {
2072 	hdmi->audio_enable = true;
2073 	hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n);
2074 }
2075 
2076 void dw_hdmi_audio_disable(struct dw_hdmi *hdmi)
2077 {
2078 	hdmi->audio_enable = false;
2079 	hdmi_set_cts_n(hdmi, hdmi->audio_cts, 0);
2080 }
2081 
2082 int rockchip_dw_hdmi_init(struct display_state *state)
2083 {
2084 	struct connector_state *conn_state = &state->conn_state;
2085 	const struct rockchip_connector *connector = conn_state->connector;
2086 	const struct dw_hdmi_plat_data *pdata = connector->data;
2087 	struct crtc_state *crtc_state = &state->crtc_state;
2088 	struct dw_hdmi *hdmi;
2089 	struct drm_display_mode *mode_buf;
2090 	int hdmi_node = conn_state->node;
2091 	u32 val;
2092 
2093 	hdmi = malloc(sizeof(struct dw_hdmi));
2094 	if (!hdmi)
2095 		return -ENOMEM;
2096 
2097 	memset(hdmi, 0, sizeof(struct dw_hdmi));
2098 
2099 	mode_buf = malloc(MODE_LEN * sizeof(struct drm_display_mode));
2100 	if (!mode_buf)
2101 		return -ENOMEM;
2102 	memset(mode_buf, 0, MODE_LEN * sizeof(struct drm_display_mode));
2103 
2104 	hdmi->regs = (void *)fdtdec_get_addr_size_auto_noparent(state->blob,
2105 					hdmi_node, "reg", 0, NULL, false);
2106 	hdmi->io_width = fdtdec_get_int(state->blob, hdmi_node,
2107 					"reg-io-width", -1);
2108 	hdmi->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2109 	if (hdmi->grf <= 0) {
2110 		printf("%s: Get syscon grf failed (ret=%p)\n",
2111 		       __func__, hdmi->grf);
2112 		return -ENXIO;
2113 	}
2114 
2115 	dw_hdmi_set_reg_wr(hdmi);
2116 
2117 	if (crtc_state->crtc_id)
2118 		val = ((1 << pdata->vop_sel_bit) |
2119 		       (1 << (16 + pdata->vop_sel_bit)));
2120 	else
2121 		val = ((0 << pdata->vop_sel_bit) |
2122 		       (1 << (16 + pdata->vop_sel_bit)));
2123 	writel(val, hdmi->grf + pdata->grf_vop_sel_reg);
2124 
2125 	conn_state->type = DRM_MODE_CONNECTOR_HDMIA;
2126 	conn_state->output_mode = ROCKCHIP_OUT_MODE_AAAA;
2127 
2128 	hdmi->dev_type = pdata->dev_type;
2129 	hdmi->plat_data = pdata;
2130 	hdmi->edid_data.mode_buf = mode_buf;
2131 	hdmi->sample_rate = 48000;
2132 
2133 	conn_state->private = hdmi;
2134 	dw_hdmi_detect_phy(hdmi);
2135 	dw_hdmi_dev_init(hdmi);
2136 
2137 	return 0;
2138 }
2139 
2140 void rockchip_dw_hdmi_deinit(struct display_state *state)
2141 {
2142 	struct connector_state *conn_state = &state->conn_state;
2143 	struct dw_hdmi *hdmi = conn_state->private;
2144 
2145 	if (hdmi->edid_data.mode_buf)
2146 		free(hdmi->edid_data.mode_buf);
2147 	if (hdmi)
2148 		free(hdmi);
2149 }
2150 
2151 int rockchip_dw_hdmi_prepare(struct display_state *state)
2152 {
2153 	return 0;
2154 }
2155 
2156 int rockchip_dw_hdmi_enable(struct display_state *state)
2157 {
2158 	struct connector_state *conn_state = &state->conn_state;
2159 	struct drm_display_mode *mode = &conn_state->mode;
2160 	struct dw_hdmi *hdmi = conn_state->private;
2161 
2162 	if (!hdmi)
2163 		return -EFAULT;
2164 
2165 	dw_hdmi_setup(hdmi, mode);
2166 
2167 	return 0;
2168 }
2169 
2170 int rockchip_dw_hdmi_disable(struct display_state *state)
2171 {
2172 	struct connector_state *conn_state = &state->conn_state;
2173 	struct dw_hdmi *hdmi = conn_state->private;
2174 
2175 	dw_hdmi_disable(hdmi);
2176 	return 0;
2177 }
2178 
2179 int rockchip_dw_hdmi_get_timing(struct display_state *state)
2180 {
2181 	int ret;
2182 	struct connector_state *conn_state = &state->conn_state;
2183 	struct drm_display_mode *mode = &conn_state->mode;
2184 	struct dw_hdmi *hdmi = conn_state->private;
2185 
2186 	if (!hdmi)
2187 		return -EFAULT;
2188 	ret = drm_do_get_edid(hdmi, conn_state->edid);
2189 	if (!ret) {
2190 		ret = drm_add_edid_modes(&hdmi->edid_data, conn_state->edid);
2191 
2192 		if (ret > 0) {
2193 			hdmi->sink_is_hdmi =
2194 				drm_detect_hdmi_monitor(conn_state->edid);
2195 			hdmi->sink_has_audio = false;
2196 			*mode = *hdmi->edid_data.preferred_mode;
2197 			hdmi->vic = drm_match_cea_mode(mode);
2198 
2199 			return 0;
2200 		}
2201 	}
2202 
2203 	/* if can't get edid timing, use default resolution. */
2204 	printf("can't get edid timing\n");
2205 	hdmi->vic = HDMI_VIDEO_DEFAULT_MODE;
2206 	hdmi->sink_is_hdmi = true;
2207 	hdmi->sink_has_audio = false;
2208 	mode->hdisplay = 1280;
2209 	mode->hsync_start = 1390;
2210 	mode->hsync_end = 1430;
2211 	mode->htotal = 1650;
2212 	mode->vdisplay = 720;
2213 	mode->vsync_start = 725;
2214 	mode->vsync_end = 730;
2215 	mode->vtotal = 750;
2216 	mode->clock = 74250;
2217 	mode->flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC;
2218 
2219 	return 0;
2220 }
2221 
2222 int rockchip_dw_hdmi_detect(struct display_state *state)
2223 {
2224 	int ret;
2225 	struct connector_state *conn_state = &state->conn_state;
2226 	struct dw_hdmi *hdmi = conn_state->private;
2227 
2228 	if (!hdmi)
2229 		return -EFAULT;
2230 
2231 	ret = dw_hdmi_detect_hotplug(hdmi);
2232 
2233 	return ret;
2234 }
2235 
2236 int rockchip_dw_hdmi_get_edid(struct display_state *state)
2237 {
2238 	int ret;
2239 	struct connector_state *conn_state = &state->conn_state;
2240 	struct dw_hdmi *hdmi = conn_state->private;
2241 
2242 	ret = drm_do_get_edid(hdmi, conn_state->edid);
2243 
2244 	return ret;
2245 }
2246 
2247