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