xref: /linux/drivers/gpu/drm/exynos/exynos_hdmi.c (revision 08ec212c0f92cbf30e3ecc7349f18151714041d6)
1 /*
2  * Copyright (C) 2011 Samsung Electronics Co.Ltd
3  * Authors:
4  * Seung-Woo Kim <sw0312.kim@samsung.com>
5  *	Inki Dae <inki.dae@samsung.com>
6  *	Joonyoung Shim <jy0922.shim@samsung.com>
7  *
8  * Based on drivers/media/video/s5p-tv/hdmi_drv.c
9  *
10  * This program is free software; you can redistribute  it and/or modify it
11  * under  the terms of  the GNU General  Public License as published by the
12  * Free Software Foundation;  either version 2 of the  License, or (at your
13  * option) any later version.
14  *
15  */
16 
17 #include <drm/drmP.h>
18 #include <drm/drm_edid.h>
19 #include <drm/drm_crtc_helper.h>
20 
21 #include "regs-hdmi.h"
22 
23 #include <linux/kernel.h>
24 #include <linux/spinlock.h>
25 #include <linux/wait.h>
26 #include <linux/i2c.h>
27 #include <linux/module.h>
28 #include <linux/platform_device.h>
29 #include <linux/interrupt.h>
30 #include <linux/irq.h>
31 #include <linux/delay.h>
32 #include <linux/pm_runtime.h>
33 #include <linux/clk.h>
34 #include <linux/regulator/consumer.h>
35 #include <linux/io.h>
36 #include <linux/of_gpio.h>
37 #include <plat/gpio-cfg.h>
38 
39 #include <drm/exynos_drm.h>
40 
41 #include "exynos_drm_drv.h"
42 #include "exynos_drm_hdmi.h"
43 
44 #include "exynos_hdmi.h"
45 
46 #include <linux/gpio.h>
47 #include <media/s5p_hdmi.h>
48 
49 #define MAX_WIDTH		1920
50 #define MAX_HEIGHT		1080
51 #define get_hdmi_context(dev)	platform_get_drvdata(to_platform_device(dev))
52 
53 enum hdmi_type {
54 	HDMI_TYPE13,
55 	HDMI_TYPE14,
56 };
57 
58 struct hdmi_resources {
59 	struct clk			*hdmi;
60 	struct clk			*sclk_hdmi;
61 	struct clk			*sclk_pixel;
62 	struct clk			*sclk_hdmiphy;
63 	struct clk			*hdmiphy;
64 	struct regulator_bulk_data	*regul_bulk;
65 	int				regul_count;
66 };
67 
68 struct hdmi_context {
69 	struct device			*dev;
70 	struct drm_device		*drm_dev;
71 	bool				hpd;
72 	bool				powered;
73 	bool				dvi_mode;
74 	struct mutex			hdmi_mutex;
75 
76 	void __iomem			*regs;
77 	int				external_irq;
78 	int				internal_irq;
79 
80 	struct i2c_client		*ddc_port;
81 	struct i2c_client		*hdmiphy_port;
82 
83 	/* current hdmiphy conf index */
84 	int cur_conf;
85 
86 	struct hdmi_resources		res;
87 	void				*parent_ctx;
88 
89 	int				hpd_gpio;
90 
91 	enum hdmi_type			type;
92 };
93 
94 /* HDMI Version 1.3 */
95 static const u8 hdmiphy_v13_conf27[32] = {
96 	0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
97 	0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
98 	0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
99 	0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
100 };
101 
102 static const u8 hdmiphy_v13_conf27_027[32] = {
103 	0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
104 	0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
105 	0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
106 	0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
107 };
108 
109 static const u8 hdmiphy_v13_conf74_175[32] = {
110 	0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
111 	0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
112 	0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
113 	0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
114 };
115 
116 static const u8 hdmiphy_v13_conf74_25[32] = {
117 	0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
118 	0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
119 	0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
120 	0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
121 };
122 
123 static const u8 hdmiphy_v13_conf148_5[32] = {
124 	0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
125 	0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
126 	0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
127 	0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
128 };
129 
130 struct hdmi_v13_tg_regs {
131 	u8 cmd;
132 	u8 h_fsz_l;
133 	u8 h_fsz_h;
134 	u8 hact_st_l;
135 	u8 hact_st_h;
136 	u8 hact_sz_l;
137 	u8 hact_sz_h;
138 	u8 v_fsz_l;
139 	u8 v_fsz_h;
140 	u8 vsync_l;
141 	u8 vsync_h;
142 	u8 vsync2_l;
143 	u8 vsync2_h;
144 	u8 vact_st_l;
145 	u8 vact_st_h;
146 	u8 vact_sz_l;
147 	u8 vact_sz_h;
148 	u8 field_chg_l;
149 	u8 field_chg_h;
150 	u8 vact_st2_l;
151 	u8 vact_st2_h;
152 	u8 vsync_top_hdmi_l;
153 	u8 vsync_top_hdmi_h;
154 	u8 vsync_bot_hdmi_l;
155 	u8 vsync_bot_hdmi_h;
156 	u8 field_top_hdmi_l;
157 	u8 field_top_hdmi_h;
158 	u8 field_bot_hdmi_l;
159 	u8 field_bot_hdmi_h;
160 };
161 
162 struct hdmi_v13_core_regs {
163 	u8 h_blank[2];
164 	u8 v_blank[3];
165 	u8 h_v_line[3];
166 	u8 vsync_pol[1];
167 	u8 int_pro_mode[1];
168 	u8 v_blank_f[3];
169 	u8 h_sync_gen[3];
170 	u8 v_sync_gen1[3];
171 	u8 v_sync_gen2[3];
172 	u8 v_sync_gen3[3];
173 };
174 
175 struct hdmi_v13_preset_conf {
176 	struct hdmi_v13_core_regs core;
177 	struct hdmi_v13_tg_regs tg;
178 };
179 
180 struct hdmi_v13_conf {
181 	int width;
182 	int height;
183 	int vrefresh;
184 	bool interlace;
185 	const u8 *hdmiphy_data;
186 	const struct hdmi_v13_preset_conf *conf;
187 };
188 
189 static const struct hdmi_v13_preset_conf hdmi_v13_conf_480p = {
190 	.core = {
191 		.h_blank = {0x8a, 0x00},
192 		.v_blank = {0x0d, 0x6a, 0x01},
193 		.h_v_line = {0x0d, 0xa2, 0x35},
194 		.vsync_pol = {0x01},
195 		.int_pro_mode = {0x00},
196 		.v_blank_f = {0x00, 0x00, 0x00},
197 		.h_sync_gen = {0x0e, 0x30, 0x11},
198 		.v_sync_gen1 = {0x0f, 0x90, 0x00},
199 		/* other don't care */
200 	},
201 	.tg = {
202 		0x00, /* cmd */
203 		0x5a, 0x03, /* h_fsz */
204 		0x8a, 0x00, 0xd0, 0x02, /* hact */
205 		0x0d, 0x02, /* v_fsz */
206 		0x01, 0x00, 0x33, 0x02, /* vsync */
207 		0x2d, 0x00, 0xe0, 0x01, /* vact */
208 		0x33, 0x02, /* field_chg */
209 		0x49, 0x02, /* vact_st2 */
210 		0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
211 		0x01, 0x00, 0x33, 0x02, /* field top/bot */
212 	},
213 };
214 
215 static const struct hdmi_v13_preset_conf hdmi_v13_conf_720p60 = {
216 	.core = {
217 		.h_blank = {0x72, 0x01},
218 		.v_blank = {0xee, 0xf2, 0x00},
219 		.h_v_line = {0xee, 0x22, 0x67},
220 		.vsync_pol = {0x00},
221 		.int_pro_mode = {0x00},
222 		.v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
223 		.h_sync_gen = {0x6c, 0x50, 0x02},
224 		.v_sync_gen1 = {0x0a, 0x50, 0x00},
225 		.v_sync_gen2 = {0x01, 0x10, 0x00},
226 		.v_sync_gen3 = {0x01, 0x10, 0x00},
227 		/* other don't care */
228 	},
229 	.tg = {
230 		0x00, /* cmd */
231 		0x72, 0x06, /* h_fsz */
232 		0x71, 0x01, 0x01, 0x05, /* hact */
233 		0xee, 0x02, /* v_fsz */
234 		0x01, 0x00, 0x33, 0x02, /* vsync */
235 		0x1e, 0x00, 0xd0, 0x02, /* vact */
236 		0x33, 0x02, /* field_chg */
237 		0x49, 0x02, /* vact_st2 */
238 		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
239 		0x01, 0x00, 0x33, 0x02, /* field top/bot */
240 	},
241 };
242 
243 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i50 = {
244 	.core = {
245 		.h_blank = {0xd0, 0x02},
246 		.v_blank = {0x32, 0xB2, 0x00},
247 		.h_v_line = {0x65, 0x04, 0xa5},
248 		.vsync_pol = {0x00},
249 		.int_pro_mode = {0x01},
250 		.v_blank_f = {0x49, 0x2A, 0x23},
251 		.h_sync_gen = {0x0E, 0xEA, 0x08},
252 		.v_sync_gen1 = {0x07, 0x20, 0x00},
253 		.v_sync_gen2 = {0x39, 0x42, 0x23},
254 		.v_sync_gen3 = {0x38, 0x87, 0x73},
255 		/* other don't care */
256 	},
257 	.tg = {
258 		0x00, /* cmd */
259 		0x50, 0x0A, /* h_fsz */
260 		0xCF, 0x02, 0x81, 0x07, /* hact */
261 		0x65, 0x04, /* v_fsz */
262 		0x01, 0x00, 0x33, 0x02, /* vsync */
263 		0x16, 0x00, 0x1c, 0x02, /* vact */
264 		0x33, 0x02, /* field_chg */
265 		0x49, 0x02, /* vact_st2 */
266 		0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
267 		0x01, 0x00, 0x33, 0x02, /* field top/bot */
268 	},
269 };
270 
271 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p50 = {
272 	.core = {
273 		.h_blank = {0xd0, 0x02},
274 		.v_blank = {0x65, 0x6c, 0x01},
275 		.h_v_line = {0x65, 0x04, 0xa5},
276 		.vsync_pol = {0x00},
277 		.int_pro_mode = {0x00},
278 		.v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
279 		.h_sync_gen = {0x0e, 0xea, 0x08},
280 		.v_sync_gen1 = {0x09, 0x40, 0x00},
281 		.v_sync_gen2 = {0x01, 0x10, 0x00},
282 		.v_sync_gen3 = {0x01, 0x10, 0x00},
283 		/* other don't care */
284 	},
285 	.tg = {
286 		0x00, /* cmd */
287 		0x50, 0x0A, /* h_fsz */
288 		0xCF, 0x02, 0x81, 0x07, /* hact */
289 		0x65, 0x04, /* v_fsz */
290 		0x01, 0x00, 0x33, 0x02, /* vsync */
291 		0x2d, 0x00, 0x38, 0x04, /* vact */
292 		0x33, 0x02, /* field_chg */
293 		0x48, 0x02, /* vact_st2 */
294 		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
295 		0x01, 0x00, 0x33, 0x02, /* field top/bot */
296 	},
297 };
298 
299 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i60 = {
300 	.core = {
301 		.h_blank = {0x18, 0x01},
302 		.v_blank = {0x32, 0xB2, 0x00},
303 		.h_v_line = {0x65, 0x84, 0x89},
304 		.vsync_pol = {0x00},
305 		.int_pro_mode = {0x01},
306 		.v_blank_f = {0x49, 0x2A, 0x23},
307 		.h_sync_gen = {0x56, 0x08, 0x02},
308 		.v_sync_gen1 = {0x07, 0x20, 0x00},
309 		.v_sync_gen2 = {0x39, 0x42, 0x23},
310 		.v_sync_gen3 = {0xa4, 0x44, 0x4a},
311 		/* other don't care */
312 	},
313 	.tg = {
314 		0x00, /* cmd */
315 		0x98, 0x08, /* h_fsz */
316 		0x17, 0x01, 0x81, 0x07, /* hact */
317 		0x65, 0x04, /* v_fsz */
318 		0x01, 0x00, 0x33, 0x02, /* vsync */
319 		0x16, 0x00, 0x1c, 0x02, /* vact */
320 		0x33, 0x02, /* field_chg */
321 		0x49, 0x02, /* vact_st2 */
322 		0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
323 		0x01, 0x00, 0x33, 0x02, /* field top/bot */
324 	},
325 };
326 
327 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60 = {
328 	.core = {
329 		.h_blank = {0x18, 0x01},
330 		.v_blank = {0x65, 0x6c, 0x01},
331 		.h_v_line = {0x65, 0x84, 0x89},
332 		.vsync_pol = {0x00},
333 		.int_pro_mode = {0x00},
334 		.v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
335 		.h_sync_gen = {0x56, 0x08, 0x02},
336 		.v_sync_gen1 = {0x09, 0x40, 0x00},
337 		.v_sync_gen2 = {0x01, 0x10, 0x00},
338 		.v_sync_gen3 = {0x01, 0x10, 0x00},
339 		/* other don't care */
340 	},
341 	.tg = {
342 		0x00, /* cmd */
343 		0x98, 0x08, /* h_fsz */
344 		0x17, 0x01, 0x81, 0x07, /* hact */
345 		0x65, 0x04, /* v_fsz */
346 		0x01, 0x00, 0x33, 0x02, /* vsync */
347 		0x2d, 0x00, 0x38, 0x04, /* vact */
348 		0x33, 0x02, /* field_chg */
349 		0x48, 0x02, /* vact_st2 */
350 		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
351 		0x01, 0x00, 0x33, 0x02, /* field top/bot */
352 	},
353 };
354 
355 static const struct hdmi_v13_conf hdmi_v13_confs[] = {
356 	{ 1280, 720, 60, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 },
357 	{ 1280, 720, 50, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 },
358 	{ 720, 480, 60, false, hdmiphy_v13_conf27_027, &hdmi_v13_conf_480p },
359 	{ 1920, 1080, 50, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i50 },
360 	{ 1920, 1080, 50, false, hdmiphy_v13_conf148_5,
361 				 &hdmi_v13_conf_1080p50 },
362 	{ 1920, 1080, 60, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i60 },
363 	{ 1920, 1080, 60, false, hdmiphy_v13_conf148_5,
364 				 &hdmi_v13_conf_1080p60 },
365 };
366 
367 /* HDMI Version 1.4 */
368 static const u8 hdmiphy_conf27_027[32] = {
369 	0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
370 	0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
371 	0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
372 	0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
373 };
374 
375 static const u8 hdmiphy_conf74_176[32] = {
376 	0x01, 0xd1, 0x1f, 0x10, 0x40, 0x5b, 0xef, 0x08,
377 	0x81, 0xa0, 0xb9, 0xd8, 0x45, 0xa0, 0xac, 0x80,
378 	0x5a, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
379 	0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
380 };
381 
382 static const u8 hdmiphy_conf74_25[32] = {
383 	0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
384 	0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
385 	0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
386 	0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
387 };
388 
389 static const u8 hdmiphy_conf148_5[32] = {
390 	0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
391 	0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
392 	0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
393 	0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
394 };
395 
396 struct hdmi_tg_regs {
397 	u8 cmd;
398 	u8 h_fsz_l;
399 	u8 h_fsz_h;
400 	u8 hact_st_l;
401 	u8 hact_st_h;
402 	u8 hact_sz_l;
403 	u8 hact_sz_h;
404 	u8 v_fsz_l;
405 	u8 v_fsz_h;
406 	u8 vsync_l;
407 	u8 vsync_h;
408 	u8 vsync2_l;
409 	u8 vsync2_h;
410 	u8 vact_st_l;
411 	u8 vact_st_h;
412 	u8 vact_sz_l;
413 	u8 vact_sz_h;
414 	u8 field_chg_l;
415 	u8 field_chg_h;
416 	u8 vact_st2_l;
417 	u8 vact_st2_h;
418 	u8 vact_st3_l;
419 	u8 vact_st3_h;
420 	u8 vact_st4_l;
421 	u8 vact_st4_h;
422 	u8 vsync_top_hdmi_l;
423 	u8 vsync_top_hdmi_h;
424 	u8 vsync_bot_hdmi_l;
425 	u8 vsync_bot_hdmi_h;
426 	u8 field_top_hdmi_l;
427 	u8 field_top_hdmi_h;
428 	u8 field_bot_hdmi_l;
429 	u8 field_bot_hdmi_h;
430 	u8 tg_3d;
431 };
432 
433 struct hdmi_core_regs {
434 	u8 h_blank[2];
435 	u8 v2_blank[2];
436 	u8 v1_blank[2];
437 	u8 v_line[2];
438 	u8 h_line[2];
439 	u8 hsync_pol[1];
440 	u8 vsync_pol[1];
441 	u8 int_pro_mode[1];
442 	u8 v_blank_f0[2];
443 	u8 v_blank_f1[2];
444 	u8 h_sync_start[2];
445 	u8 h_sync_end[2];
446 	u8 v_sync_line_bef_2[2];
447 	u8 v_sync_line_bef_1[2];
448 	u8 v_sync_line_aft_2[2];
449 	u8 v_sync_line_aft_1[2];
450 	u8 v_sync_line_aft_pxl_2[2];
451 	u8 v_sync_line_aft_pxl_1[2];
452 	u8 v_blank_f2[2]; /* for 3D mode */
453 	u8 v_blank_f3[2]; /* for 3D mode */
454 	u8 v_blank_f4[2]; /* for 3D mode */
455 	u8 v_blank_f5[2]; /* for 3D mode */
456 	u8 v_sync_line_aft_3[2];
457 	u8 v_sync_line_aft_4[2];
458 	u8 v_sync_line_aft_5[2];
459 	u8 v_sync_line_aft_6[2];
460 	u8 v_sync_line_aft_pxl_3[2];
461 	u8 v_sync_line_aft_pxl_4[2];
462 	u8 v_sync_line_aft_pxl_5[2];
463 	u8 v_sync_line_aft_pxl_6[2];
464 	u8 vact_space_1[2];
465 	u8 vact_space_2[2];
466 	u8 vact_space_3[2];
467 	u8 vact_space_4[2];
468 	u8 vact_space_5[2];
469 	u8 vact_space_6[2];
470 };
471 
472 struct hdmi_preset_conf {
473 	struct hdmi_core_regs core;
474 	struct hdmi_tg_regs tg;
475 };
476 
477 struct hdmi_conf {
478 	int width;
479 	int height;
480 	int vrefresh;
481 	bool interlace;
482 	const u8 *hdmiphy_data;
483 	const struct hdmi_preset_conf *conf;
484 };
485 
486 static const struct hdmi_preset_conf hdmi_conf_480p60 = {
487 	.core = {
488 		.h_blank = {0x8a, 0x00},
489 		.v2_blank = {0x0d, 0x02},
490 		.v1_blank = {0x2d, 0x00},
491 		.v_line = {0x0d, 0x02},
492 		.h_line = {0x5a, 0x03},
493 		.hsync_pol = {0x01},
494 		.vsync_pol = {0x01},
495 		.int_pro_mode = {0x00},
496 		.v_blank_f0 = {0xff, 0xff},
497 		.v_blank_f1 = {0xff, 0xff},
498 		.h_sync_start = {0x0e, 0x00},
499 		.h_sync_end = {0x4c, 0x00},
500 		.v_sync_line_bef_2 = {0x0f, 0x00},
501 		.v_sync_line_bef_1 = {0x09, 0x00},
502 		.v_sync_line_aft_2 = {0xff, 0xff},
503 		.v_sync_line_aft_1 = {0xff, 0xff},
504 		.v_sync_line_aft_pxl_2 = {0xff, 0xff},
505 		.v_sync_line_aft_pxl_1 = {0xff, 0xff},
506 		.v_blank_f2 = {0xff, 0xff},
507 		.v_blank_f3 = {0xff, 0xff},
508 		.v_blank_f4 = {0xff, 0xff},
509 		.v_blank_f5 = {0xff, 0xff},
510 		.v_sync_line_aft_3 = {0xff, 0xff},
511 		.v_sync_line_aft_4 = {0xff, 0xff},
512 		.v_sync_line_aft_5 = {0xff, 0xff},
513 		.v_sync_line_aft_6 = {0xff, 0xff},
514 		.v_sync_line_aft_pxl_3 = {0xff, 0xff},
515 		.v_sync_line_aft_pxl_4 = {0xff, 0xff},
516 		.v_sync_line_aft_pxl_5 = {0xff, 0xff},
517 		.v_sync_line_aft_pxl_6 = {0xff, 0xff},
518 		.vact_space_1 = {0xff, 0xff},
519 		.vact_space_2 = {0xff, 0xff},
520 		.vact_space_3 = {0xff, 0xff},
521 		.vact_space_4 = {0xff, 0xff},
522 		.vact_space_5 = {0xff, 0xff},
523 		.vact_space_6 = {0xff, 0xff},
524 		/* other don't care */
525 	},
526 	.tg = {
527 		0x00, /* cmd */
528 		0x5a, 0x03, /* h_fsz */
529 		0x8a, 0x00, 0xd0, 0x02, /* hact */
530 		0x0d, 0x02, /* v_fsz */
531 		0x01, 0x00, 0x33, 0x02, /* vsync */
532 		0x2d, 0x00, 0xe0, 0x01, /* vact */
533 		0x33, 0x02, /* field_chg */
534 		0x48, 0x02, /* vact_st2 */
535 		0x00, 0x00, /* vact_st3 */
536 		0x00, 0x00, /* vact_st4 */
537 		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
538 		0x01, 0x00, 0x33, 0x02, /* field top/bot */
539 		0x00, /* 3d FP */
540 	},
541 };
542 
543 static const struct hdmi_preset_conf hdmi_conf_720p50 = {
544 	.core = {
545 		.h_blank = {0xbc, 0x02},
546 		.v2_blank = {0xee, 0x02},
547 		.v1_blank = {0x1e, 0x00},
548 		.v_line = {0xee, 0x02},
549 		.h_line = {0xbc, 0x07},
550 		.hsync_pol = {0x00},
551 		.vsync_pol = {0x00},
552 		.int_pro_mode = {0x00},
553 		.v_blank_f0 = {0xff, 0xff},
554 		.v_blank_f1 = {0xff, 0xff},
555 		.h_sync_start = {0xb6, 0x01},
556 		.h_sync_end = {0xde, 0x01},
557 		.v_sync_line_bef_2 = {0x0a, 0x00},
558 		.v_sync_line_bef_1 = {0x05, 0x00},
559 		.v_sync_line_aft_2 = {0xff, 0xff},
560 		.v_sync_line_aft_1 = {0xff, 0xff},
561 		.v_sync_line_aft_pxl_2 = {0xff, 0xff},
562 		.v_sync_line_aft_pxl_1 = {0xff, 0xff},
563 		.v_blank_f2 = {0xff, 0xff},
564 		.v_blank_f3 = {0xff, 0xff},
565 		.v_blank_f4 = {0xff, 0xff},
566 		.v_blank_f5 = {0xff, 0xff},
567 		.v_sync_line_aft_3 = {0xff, 0xff},
568 		.v_sync_line_aft_4 = {0xff, 0xff},
569 		.v_sync_line_aft_5 = {0xff, 0xff},
570 		.v_sync_line_aft_6 = {0xff, 0xff},
571 		.v_sync_line_aft_pxl_3 = {0xff, 0xff},
572 		.v_sync_line_aft_pxl_4 = {0xff, 0xff},
573 		.v_sync_line_aft_pxl_5 = {0xff, 0xff},
574 		.v_sync_line_aft_pxl_6 = {0xff, 0xff},
575 		.vact_space_1 = {0xff, 0xff},
576 		.vact_space_2 = {0xff, 0xff},
577 		.vact_space_3 = {0xff, 0xff},
578 		.vact_space_4 = {0xff, 0xff},
579 		.vact_space_5 = {0xff, 0xff},
580 		.vact_space_6 = {0xff, 0xff},
581 		/* other don't care */
582 	},
583 	.tg = {
584 		0x00, /* cmd */
585 		0xbc, 0x07, /* h_fsz */
586 		0xbc, 0x02, 0x00, 0x05, /* hact */
587 		0xee, 0x02, /* v_fsz */
588 		0x01, 0x00, 0x33, 0x02, /* vsync */
589 		0x1e, 0x00, 0xd0, 0x02, /* vact */
590 		0x33, 0x02, /* field_chg */
591 		0x48, 0x02, /* vact_st2 */
592 		0x00, 0x00, /* vact_st3 */
593 		0x00, 0x00, /* vact_st4 */
594 		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
595 		0x01, 0x00, 0x33, 0x02, /* field top/bot */
596 		0x00, /* 3d FP */
597 	},
598 };
599 
600 static const struct hdmi_preset_conf hdmi_conf_720p60 = {
601 	.core = {
602 		.h_blank = {0x72, 0x01},
603 		.v2_blank = {0xee, 0x02},
604 		.v1_blank = {0x1e, 0x00},
605 		.v_line = {0xee, 0x02},
606 		.h_line = {0x72, 0x06},
607 		.hsync_pol = {0x00},
608 		.vsync_pol = {0x00},
609 		.int_pro_mode = {0x00},
610 		.v_blank_f0 = {0xff, 0xff},
611 		.v_blank_f1 = {0xff, 0xff},
612 		.h_sync_start = {0x6c, 0x00},
613 		.h_sync_end = {0x94, 0x00},
614 		.v_sync_line_bef_2 = {0x0a, 0x00},
615 		.v_sync_line_bef_1 = {0x05, 0x00},
616 		.v_sync_line_aft_2 = {0xff, 0xff},
617 		.v_sync_line_aft_1 = {0xff, 0xff},
618 		.v_sync_line_aft_pxl_2 = {0xff, 0xff},
619 		.v_sync_line_aft_pxl_1 = {0xff, 0xff},
620 		.v_blank_f2 = {0xff, 0xff},
621 		.v_blank_f3 = {0xff, 0xff},
622 		.v_blank_f4 = {0xff, 0xff},
623 		.v_blank_f5 = {0xff, 0xff},
624 		.v_sync_line_aft_3 = {0xff, 0xff},
625 		.v_sync_line_aft_4 = {0xff, 0xff},
626 		.v_sync_line_aft_5 = {0xff, 0xff},
627 		.v_sync_line_aft_6 = {0xff, 0xff},
628 		.v_sync_line_aft_pxl_3 = {0xff, 0xff},
629 		.v_sync_line_aft_pxl_4 = {0xff, 0xff},
630 		.v_sync_line_aft_pxl_5 = {0xff, 0xff},
631 		.v_sync_line_aft_pxl_6 = {0xff, 0xff},
632 		.vact_space_1 = {0xff, 0xff},
633 		.vact_space_2 = {0xff, 0xff},
634 		.vact_space_3 = {0xff, 0xff},
635 		.vact_space_4 = {0xff, 0xff},
636 		.vact_space_5 = {0xff, 0xff},
637 		.vact_space_6 = {0xff, 0xff},
638 		/* other don't care */
639 	},
640 	.tg = {
641 		0x00, /* cmd */
642 		0x72, 0x06, /* h_fsz */
643 		0x72, 0x01, 0x00, 0x05, /* hact */
644 		0xee, 0x02, /* v_fsz */
645 		0x01, 0x00, 0x33, 0x02, /* vsync */
646 		0x1e, 0x00, 0xd0, 0x02, /* vact */
647 		0x33, 0x02, /* field_chg */
648 		0x48, 0x02, /* vact_st2 */
649 		0x00, 0x00, /* vact_st3 */
650 		0x00, 0x00, /* vact_st4 */
651 		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
652 		0x01, 0x00, 0x33, 0x02, /* field top/bot */
653 		0x00, /* 3d FP */
654 	},
655 };
656 
657 static const struct hdmi_preset_conf hdmi_conf_1080i50 = {
658 	.core = {
659 		.h_blank = {0xd0, 0x02},
660 		.v2_blank = {0x32, 0x02},
661 		.v1_blank = {0x16, 0x00},
662 		.v_line = {0x65, 0x04},
663 		.h_line = {0x50, 0x0a},
664 		.hsync_pol = {0x00},
665 		.vsync_pol = {0x00},
666 		.int_pro_mode = {0x01},
667 		.v_blank_f0 = {0x49, 0x02},
668 		.v_blank_f1 = {0x65, 0x04},
669 		.h_sync_start = {0x0e, 0x02},
670 		.h_sync_end = {0x3a, 0x02},
671 		.v_sync_line_bef_2 = {0x07, 0x00},
672 		.v_sync_line_bef_1 = {0x02, 0x00},
673 		.v_sync_line_aft_2 = {0x39, 0x02},
674 		.v_sync_line_aft_1 = {0x34, 0x02},
675 		.v_sync_line_aft_pxl_2 = {0x38, 0x07},
676 		.v_sync_line_aft_pxl_1 = {0x38, 0x07},
677 		.v_blank_f2 = {0xff, 0xff},
678 		.v_blank_f3 = {0xff, 0xff},
679 		.v_blank_f4 = {0xff, 0xff},
680 		.v_blank_f5 = {0xff, 0xff},
681 		.v_sync_line_aft_3 = {0xff, 0xff},
682 		.v_sync_line_aft_4 = {0xff, 0xff},
683 		.v_sync_line_aft_5 = {0xff, 0xff},
684 		.v_sync_line_aft_6 = {0xff, 0xff},
685 		.v_sync_line_aft_pxl_3 = {0xff, 0xff},
686 		.v_sync_line_aft_pxl_4 = {0xff, 0xff},
687 		.v_sync_line_aft_pxl_5 = {0xff, 0xff},
688 		.v_sync_line_aft_pxl_6 = {0xff, 0xff},
689 		.vact_space_1 = {0xff, 0xff},
690 		.vact_space_2 = {0xff, 0xff},
691 		.vact_space_3 = {0xff, 0xff},
692 		.vact_space_4 = {0xff, 0xff},
693 		.vact_space_5 = {0xff, 0xff},
694 		.vact_space_6 = {0xff, 0xff},
695 		/* other don't care */
696 	},
697 	.tg = {
698 		0x00, /* cmd */
699 		0x50, 0x0a, /* h_fsz */
700 		0xd0, 0x02, 0x80, 0x07, /* hact */
701 		0x65, 0x04, /* v_fsz */
702 		0x01, 0x00, 0x33, 0x02, /* vsync */
703 		0x16, 0x00, 0x1c, 0x02, /* vact */
704 		0x33, 0x02, /* field_chg */
705 		0x49, 0x02, /* vact_st2 */
706 		0x00, 0x00, /* vact_st3 */
707 		0x00, 0x00, /* vact_st4 */
708 		0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
709 		0x01, 0x00, 0x33, 0x02, /* field top/bot */
710 		0x00, /* 3d FP */
711 	},
712 };
713 
714 static const struct hdmi_preset_conf hdmi_conf_1080i60 = {
715 	.core = {
716 		.h_blank = {0x18, 0x01},
717 		.v2_blank = {0x32, 0x02},
718 		.v1_blank = {0x16, 0x00},
719 		.v_line = {0x65, 0x04},
720 		.h_line = {0x98, 0x08},
721 		.hsync_pol = {0x00},
722 		.vsync_pol = {0x00},
723 		.int_pro_mode = {0x01},
724 		.v_blank_f0 = {0x49, 0x02},
725 		.v_blank_f1 = {0x65, 0x04},
726 		.h_sync_start = {0x56, 0x00},
727 		.h_sync_end = {0x82, 0x00},
728 		.v_sync_line_bef_2 = {0x07, 0x00},
729 		.v_sync_line_bef_1 = {0x02, 0x00},
730 		.v_sync_line_aft_2 = {0x39, 0x02},
731 		.v_sync_line_aft_1 = {0x34, 0x02},
732 		.v_sync_line_aft_pxl_2 = {0xa4, 0x04},
733 		.v_sync_line_aft_pxl_1 = {0xa4, 0x04},
734 		.v_blank_f2 = {0xff, 0xff},
735 		.v_blank_f3 = {0xff, 0xff},
736 		.v_blank_f4 = {0xff, 0xff},
737 		.v_blank_f5 = {0xff, 0xff},
738 		.v_sync_line_aft_3 = {0xff, 0xff},
739 		.v_sync_line_aft_4 = {0xff, 0xff},
740 		.v_sync_line_aft_5 = {0xff, 0xff},
741 		.v_sync_line_aft_6 = {0xff, 0xff},
742 		.v_sync_line_aft_pxl_3 = {0xff, 0xff},
743 		.v_sync_line_aft_pxl_4 = {0xff, 0xff},
744 		.v_sync_line_aft_pxl_5 = {0xff, 0xff},
745 		.v_sync_line_aft_pxl_6 = {0xff, 0xff},
746 		.vact_space_1 = {0xff, 0xff},
747 		.vact_space_2 = {0xff, 0xff},
748 		.vact_space_3 = {0xff, 0xff},
749 		.vact_space_4 = {0xff, 0xff},
750 		.vact_space_5 = {0xff, 0xff},
751 		.vact_space_6 = {0xff, 0xff},
752 		/* other don't care */
753 	},
754 	.tg = {
755 		0x00, /* cmd */
756 		0x98, 0x08, /* h_fsz */
757 		0x18, 0x01, 0x80, 0x07, /* hact */
758 		0x65, 0x04, /* v_fsz */
759 		0x01, 0x00, 0x33, 0x02, /* vsync */
760 		0x16, 0x00, 0x1c, 0x02, /* vact */
761 		0x33, 0x02, /* field_chg */
762 		0x49, 0x02, /* vact_st2 */
763 		0x00, 0x00, /* vact_st3 */
764 		0x00, 0x00, /* vact_st4 */
765 		0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
766 		0x01, 0x00, 0x33, 0x02, /* field top/bot */
767 		0x00, /* 3d FP */
768 	},
769 };
770 
771 static const struct hdmi_preset_conf hdmi_conf_1080p30 = {
772 	.core = {
773 		.h_blank = {0x18, 0x01},
774 		.v2_blank = {0x65, 0x04},
775 		.v1_blank = {0x2d, 0x00},
776 		.v_line = {0x65, 0x04},
777 		.h_line = {0x98, 0x08},
778 		.hsync_pol = {0x00},
779 		.vsync_pol = {0x00},
780 		.int_pro_mode = {0x00},
781 		.v_blank_f0 = {0xff, 0xff},
782 		.v_blank_f1 = {0xff, 0xff},
783 		.h_sync_start = {0x56, 0x00},
784 		.h_sync_end = {0x82, 0x00},
785 		.v_sync_line_bef_2 = {0x09, 0x00},
786 		.v_sync_line_bef_1 = {0x04, 0x00},
787 		.v_sync_line_aft_2 = {0xff, 0xff},
788 		.v_sync_line_aft_1 = {0xff, 0xff},
789 		.v_sync_line_aft_pxl_2 = {0xff, 0xff},
790 		.v_sync_line_aft_pxl_1 = {0xff, 0xff},
791 		.v_blank_f2 = {0xff, 0xff},
792 		.v_blank_f3 = {0xff, 0xff},
793 		.v_blank_f4 = {0xff, 0xff},
794 		.v_blank_f5 = {0xff, 0xff},
795 		.v_sync_line_aft_3 = {0xff, 0xff},
796 		.v_sync_line_aft_4 = {0xff, 0xff},
797 		.v_sync_line_aft_5 = {0xff, 0xff},
798 		.v_sync_line_aft_6 = {0xff, 0xff},
799 		.v_sync_line_aft_pxl_3 = {0xff, 0xff},
800 		.v_sync_line_aft_pxl_4 = {0xff, 0xff},
801 		.v_sync_line_aft_pxl_5 = {0xff, 0xff},
802 		.v_sync_line_aft_pxl_6 = {0xff, 0xff},
803 		.vact_space_1 = {0xff, 0xff},
804 		.vact_space_2 = {0xff, 0xff},
805 		.vact_space_3 = {0xff, 0xff},
806 		.vact_space_4 = {0xff, 0xff},
807 		.vact_space_5 = {0xff, 0xff},
808 		.vact_space_6 = {0xff, 0xff},
809 		/* other don't care */
810 	},
811 	.tg = {
812 		0x00, /* cmd */
813 		0x98, 0x08, /* h_fsz */
814 		0x18, 0x01, 0x80, 0x07, /* hact */
815 		0x65, 0x04, /* v_fsz */
816 		0x01, 0x00, 0x33, 0x02, /* vsync */
817 		0x2d, 0x00, 0x38, 0x04, /* vact */
818 		0x33, 0x02, /* field_chg */
819 		0x48, 0x02, /* vact_st2 */
820 		0x00, 0x00, /* vact_st3 */
821 		0x00, 0x00, /* vact_st4 */
822 		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
823 		0x01, 0x00, 0x33, 0x02, /* field top/bot */
824 		0x00, /* 3d FP */
825 	},
826 };
827 
828 static const struct hdmi_preset_conf hdmi_conf_1080p50 = {
829 	.core = {
830 		.h_blank = {0xd0, 0x02},
831 		.v2_blank = {0x65, 0x04},
832 		.v1_blank = {0x2d, 0x00},
833 		.v_line = {0x65, 0x04},
834 		.h_line = {0x50, 0x0a},
835 		.hsync_pol = {0x00},
836 		.vsync_pol = {0x00},
837 		.int_pro_mode = {0x00},
838 		.v_blank_f0 = {0xff, 0xff},
839 		.v_blank_f1 = {0xff, 0xff},
840 		.h_sync_start = {0x0e, 0x02},
841 		.h_sync_end = {0x3a, 0x02},
842 		.v_sync_line_bef_2 = {0x09, 0x00},
843 		.v_sync_line_bef_1 = {0x04, 0x00},
844 		.v_sync_line_aft_2 = {0xff, 0xff},
845 		.v_sync_line_aft_1 = {0xff, 0xff},
846 		.v_sync_line_aft_pxl_2 = {0xff, 0xff},
847 		.v_sync_line_aft_pxl_1 = {0xff, 0xff},
848 		.v_blank_f2 = {0xff, 0xff},
849 		.v_blank_f3 = {0xff, 0xff},
850 		.v_blank_f4 = {0xff, 0xff},
851 		.v_blank_f5 = {0xff, 0xff},
852 		.v_sync_line_aft_3 = {0xff, 0xff},
853 		.v_sync_line_aft_4 = {0xff, 0xff},
854 		.v_sync_line_aft_5 = {0xff, 0xff},
855 		.v_sync_line_aft_6 = {0xff, 0xff},
856 		.v_sync_line_aft_pxl_3 = {0xff, 0xff},
857 		.v_sync_line_aft_pxl_4 = {0xff, 0xff},
858 		.v_sync_line_aft_pxl_5 = {0xff, 0xff},
859 		.v_sync_line_aft_pxl_6 = {0xff, 0xff},
860 		.vact_space_1 = {0xff, 0xff},
861 		.vact_space_2 = {0xff, 0xff},
862 		.vact_space_3 = {0xff, 0xff},
863 		.vact_space_4 = {0xff, 0xff},
864 		.vact_space_5 = {0xff, 0xff},
865 		.vact_space_6 = {0xff, 0xff},
866 		/* other don't care */
867 	},
868 	.tg = {
869 		0x00, /* cmd */
870 		0x50, 0x0a, /* h_fsz */
871 		0xd0, 0x02, 0x80, 0x07, /* hact */
872 		0x65, 0x04, /* v_fsz */
873 		0x01, 0x00, 0x33, 0x02, /* vsync */
874 		0x2d, 0x00, 0x38, 0x04, /* vact */
875 		0x33, 0x02, /* field_chg */
876 		0x48, 0x02, /* vact_st2 */
877 		0x00, 0x00, /* vact_st3 */
878 		0x00, 0x00, /* vact_st4 */
879 		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
880 		0x01, 0x00, 0x33, 0x02, /* field top/bot */
881 		0x00, /* 3d FP */
882 	},
883 };
884 
885 static const struct hdmi_preset_conf hdmi_conf_1080p60 = {
886 	.core = {
887 		.h_blank = {0x18, 0x01},
888 		.v2_blank = {0x65, 0x04},
889 		.v1_blank = {0x2d, 0x00},
890 		.v_line = {0x65, 0x04},
891 		.h_line = {0x98, 0x08},
892 		.hsync_pol = {0x00},
893 		.vsync_pol = {0x00},
894 		.int_pro_mode = {0x00},
895 		.v_blank_f0 = {0xff, 0xff},
896 		.v_blank_f1 = {0xff, 0xff},
897 		.h_sync_start = {0x56, 0x00},
898 		.h_sync_end = {0x82, 0x00},
899 		.v_sync_line_bef_2 = {0x09, 0x00},
900 		.v_sync_line_bef_1 = {0x04, 0x00},
901 		.v_sync_line_aft_2 = {0xff, 0xff},
902 		.v_sync_line_aft_1 = {0xff, 0xff},
903 		.v_sync_line_aft_pxl_2 = {0xff, 0xff},
904 		.v_sync_line_aft_pxl_1 = {0xff, 0xff},
905 		.v_blank_f2 = {0xff, 0xff},
906 		.v_blank_f3 = {0xff, 0xff},
907 		.v_blank_f4 = {0xff, 0xff},
908 		.v_blank_f5 = {0xff, 0xff},
909 		.v_sync_line_aft_3 = {0xff, 0xff},
910 		.v_sync_line_aft_4 = {0xff, 0xff},
911 		.v_sync_line_aft_5 = {0xff, 0xff},
912 		.v_sync_line_aft_6 = {0xff, 0xff},
913 		.v_sync_line_aft_pxl_3 = {0xff, 0xff},
914 		.v_sync_line_aft_pxl_4 = {0xff, 0xff},
915 		.v_sync_line_aft_pxl_5 = {0xff, 0xff},
916 		.v_sync_line_aft_pxl_6 = {0xff, 0xff},
917 		/* other don't care */
918 	},
919 	.tg = {
920 		0x00, /* cmd */
921 		0x98, 0x08, /* h_fsz */
922 		0x18, 0x01, 0x80, 0x07, /* hact */
923 		0x65, 0x04, /* v_fsz */
924 		0x01, 0x00, 0x33, 0x02, /* vsync */
925 		0x2d, 0x00, 0x38, 0x04, /* vact */
926 		0x33, 0x02, /* field_chg */
927 		0x48, 0x02, /* vact_st2 */
928 		0x00, 0x00, /* vact_st3 */
929 		0x00, 0x00, /* vact_st4 */
930 		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
931 		0x01, 0x00, 0x33, 0x02, /* field top/bot */
932 		0x00, /* 3d FP */
933 	},
934 };
935 
936 static const struct hdmi_conf hdmi_confs[] = {
937 	{ 720, 480, 60, false, hdmiphy_conf27_027, &hdmi_conf_480p60 },
938 	{ 1280, 720, 50, false, hdmiphy_conf74_25, &hdmi_conf_720p50 },
939 	{ 1280, 720, 60, false, hdmiphy_conf74_25, &hdmi_conf_720p60 },
940 	{ 1920, 1080, 50, true, hdmiphy_conf74_25, &hdmi_conf_1080i50 },
941 	{ 1920, 1080, 60, true, hdmiphy_conf74_25, &hdmi_conf_1080i60 },
942 	{ 1920, 1080, 30, false, hdmiphy_conf74_176, &hdmi_conf_1080p30 },
943 	{ 1920, 1080, 50, false, hdmiphy_conf148_5, &hdmi_conf_1080p50 },
944 	{ 1920, 1080, 60, false, hdmiphy_conf148_5, &hdmi_conf_1080p60 },
945 };
946 
947 
948 static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
949 {
950 	return readl(hdata->regs + reg_id);
951 }
952 
953 static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
954 				 u32 reg_id, u8 value)
955 {
956 	writeb(value, hdata->regs + reg_id);
957 }
958 
959 static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
960 				 u32 reg_id, u32 value, u32 mask)
961 {
962 	u32 old = readl(hdata->regs + reg_id);
963 	value = (value & mask) | (old & ~mask);
964 	writel(value, hdata->regs + reg_id);
965 }
966 
967 static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix)
968 {
969 #define DUMPREG(reg_id) \
970 	DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
971 	readl(hdata->regs + reg_id))
972 	DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
973 	DUMPREG(HDMI_INTC_FLAG);
974 	DUMPREG(HDMI_INTC_CON);
975 	DUMPREG(HDMI_HPD_STATUS);
976 	DUMPREG(HDMI_V13_PHY_RSTOUT);
977 	DUMPREG(HDMI_V13_PHY_VPLL);
978 	DUMPREG(HDMI_V13_PHY_CMU);
979 	DUMPREG(HDMI_V13_CORE_RSTOUT);
980 
981 	DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
982 	DUMPREG(HDMI_CON_0);
983 	DUMPREG(HDMI_CON_1);
984 	DUMPREG(HDMI_CON_2);
985 	DUMPREG(HDMI_SYS_STATUS);
986 	DUMPREG(HDMI_V13_PHY_STATUS);
987 	DUMPREG(HDMI_STATUS_EN);
988 	DUMPREG(HDMI_HPD);
989 	DUMPREG(HDMI_MODE_SEL);
990 	DUMPREG(HDMI_V13_HPD_GEN);
991 	DUMPREG(HDMI_V13_DC_CONTROL);
992 	DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN);
993 
994 	DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
995 	DUMPREG(HDMI_H_BLANK_0);
996 	DUMPREG(HDMI_H_BLANK_1);
997 	DUMPREG(HDMI_V13_V_BLANK_0);
998 	DUMPREG(HDMI_V13_V_BLANK_1);
999 	DUMPREG(HDMI_V13_V_BLANK_2);
1000 	DUMPREG(HDMI_V13_H_V_LINE_0);
1001 	DUMPREG(HDMI_V13_H_V_LINE_1);
1002 	DUMPREG(HDMI_V13_H_V_LINE_2);
1003 	DUMPREG(HDMI_VSYNC_POL);
1004 	DUMPREG(HDMI_INT_PRO_MODE);
1005 	DUMPREG(HDMI_V13_V_BLANK_F_0);
1006 	DUMPREG(HDMI_V13_V_BLANK_F_1);
1007 	DUMPREG(HDMI_V13_V_BLANK_F_2);
1008 	DUMPREG(HDMI_V13_H_SYNC_GEN_0);
1009 	DUMPREG(HDMI_V13_H_SYNC_GEN_1);
1010 	DUMPREG(HDMI_V13_H_SYNC_GEN_2);
1011 	DUMPREG(HDMI_V13_V_SYNC_GEN_1_0);
1012 	DUMPREG(HDMI_V13_V_SYNC_GEN_1_1);
1013 	DUMPREG(HDMI_V13_V_SYNC_GEN_1_2);
1014 	DUMPREG(HDMI_V13_V_SYNC_GEN_2_0);
1015 	DUMPREG(HDMI_V13_V_SYNC_GEN_2_1);
1016 	DUMPREG(HDMI_V13_V_SYNC_GEN_2_2);
1017 	DUMPREG(HDMI_V13_V_SYNC_GEN_3_0);
1018 	DUMPREG(HDMI_V13_V_SYNC_GEN_3_1);
1019 	DUMPREG(HDMI_V13_V_SYNC_GEN_3_2);
1020 
1021 	DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
1022 	DUMPREG(HDMI_TG_CMD);
1023 	DUMPREG(HDMI_TG_H_FSZ_L);
1024 	DUMPREG(HDMI_TG_H_FSZ_H);
1025 	DUMPREG(HDMI_TG_HACT_ST_L);
1026 	DUMPREG(HDMI_TG_HACT_ST_H);
1027 	DUMPREG(HDMI_TG_HACT_SZ_L);
1028 	DUMPREG(HDMI_TG_HACT_SZ_H);
1029 	DUMPREG(HDMI_TG_V_FSZ_L);
1030 	DUMPREG(HDMI_TG_V_FSZ_H);
1031 	DUMPREG(HDMI_TG_VSYNC_L);
1032 	DUMPREG(HDMI_TG_VSYNC_H);
1033 	DUMPREG(HDMI_TG_VSYNC2_L);
1034 	DUMPREG(HDMI_TG_VSYNC2_H);
1035 	DUMPREG(HDMI_TG_VACT_ST_L);
1036 	DUMPREG(HDMI_TG_VACT_ST_H);
1037 	DUMPREG(HDMI_TG_VACT_SZ_L);
1038 	DUMPREG(HDMI_TG_VACT_SZ_H);
1039 	DUMPREG(HDMI_TG_FIELD_CHG_L);
1040 	DUMPREG(HDMI_TG_FIELD_CHG_H);
1041 	DUMPREG(HDMI_TG_VACT_ST2_L);
1042 	DUMPREG(HDMI_TG_VACT_ST2_H);
1043 	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
1044 	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
1045 	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
1046 	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
1047 	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
1048 	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
1049 	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
1050 	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
1051 #undef DUMPREG
1052 }
1053 
1054 static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix)
1055 {
1056 	int i;
1057 
1058 #define DUMPREG(reg_id) \
1059 	DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
1060 	readl(hdata->regs + reg_id))
1061 
1062 	DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
1063 	DUMPREG(HDMI_INTC_CON);
1064 	DUMPREG(HDMI_INTC_FLAG);
1065 	DUMPREG(HDMI_HPD_STATUS);
1066 	DUMPREG(HDMI_INTC_CON_1);
1067 	DUMPREG(HDMI_INTC_FLAG_1);
1068 	DUMPREG(HDMI_PHY_STATUS_0);
1069 	DUMPREG(HDMI_PHY_STATUS_PLL);
1070 	DUMPREG(HDMI_PHY_CON_0);
1071 	DUMPREG(HDMI_PHY_RSTOUT);
1072 	DUMPREG(HDMI_PHY_VPLL);
1073 	DUMPREG(HDMI_PHY_CMU);
1074 	DUMPREG(HDMI_CORE_RSTOUT);
1075 
1076 	DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
1077 	DUMPREG(HDMI_CON_0);
1078 	DUMPREG(HDMI_CON_1);
1079 	DUMPREG(HDMI_CON_2);
1080 	DUMPREG(HDMI_SYS_STATUS);
1081 	DUMPREG(HDMI_PHY_STATUS_0);
1082 	DUMPREG(HDMI_STATUS_EN);
1083 	DUMPREG(HDMI_HPD);
1084 	DUMPREG(HDMI_MODE_SEL);
1085 	DUMPREG(HDMI_ENC_EN);
1086 	DUMPREG(HDMI_DC_CONTROL);
1087 	DUMPREG(HDMI_VIDEO_PATTERN_GEN);
1088 
1089 	DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
1090 	DUMPREG(HDMI_H_BLANK_0);
1091 	DUMPREG(HDMI_H_BLANK_1);
1092 	DUMPREG(HDMI_V2_BLANK_0);
1093 	DUMPREG(HDMI_V2_BLANK_1);
1094 	DUMPREG(HDMI_V1_BLANK_0);
1095 	DUMPREG(HDMI_V1_BLANK_1);
1096 	DUMPREG(HDMI_V_LINE_0);
1097 	DUMPREG(HDMI_V_LINE_1);
1098 	DUMPREG(HDMI_H_LINE_0);
1099 	DUMPREG(HDMI_H_LINE_1);
1100 	DUMPREG(HDMI_HSYNC_POL);
1101 
1102 	DUMPREG(HDMI_VSYNC_POL);
1103 	DUMPREG(HDMI_INT_PRO_MODE);
1104 	DUMPREG(HDMI_V_BLANK_F0_0);
1105 	DUMPREG(HDMI_V_BLANK_F0_1);
1106 	DUMPREG(HDMI_V_BLANK_F1_0);
1107 	DUMPREG(HDMI_V_BLANK_F1_1);
1108 
1109 	DUMPREG(HDMI_H_SYNC_START_0);
1110 	DUMPREG(HDMI_H_SYNC_START_1);
1111 	DUMPREG(HDMI_H_SYNC_END_0);
1112 	DUMPREG(HDMI_H_SYNC_END_1);
1113 
1114 	DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0);
1115 	DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1);
1116 	DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0);
1117 	DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1);
1118 
1119 	DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0);
1120 	DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1);
1121 	DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0);
1122 	DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1);
1123 
1124 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0);
1125 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1);
1126 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0);
1127 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1);
1128 
1129 	DUMPREG(HDMI_V_BLANK_F2_0);
1130 	DUMPREG(HDMI_V_BLANK_F2_1);
1131 	DUMPREG(HDMI_V_BLANK_F3_0);
1132 	DUMPREG(HDMI_V_BLANK_F3_1);
1133 	DUMPREG(HDMI_V_BLANK_F4_0);
1134 	DUMPREG(HDMI_V_BLANK_F4_1);
1135 	DUMPREG(HDMI_V_BLANK_F5_0);
1136 	DUMPREG(HDMI_V_BLANK_F5_1);
1137 
1138 	DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0);
1139 	DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1);
1140 	DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0);
1141 	DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1);
1142 	DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0);
1143 	DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1);
1144 	DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0);
1145 	DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1);
1146 
1147 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0);
1148 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1);
1149 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0);
1150 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1);
1151 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0);
1152 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1);
1153 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0);
1154 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1);
1155 
1156 	DUMPREG(HDMI_VACT_SPACE_1_0);
1157 	DUMPREG(HDMI_VACT_SPACE_1_1);
1158 	DUMPREG(HDMI_VACT_SPACE_2_0);
1159 	DUMPREG(HDMI_VACT_SPACE_2_1);
1160 	DUMPREG(HDMI_VACT_SPACE_3_0);
1161 	DUMPREG(HDMI_VACT_SPACE_3_1);
1162 	DUMPREG(HDMI_VACT_SPACE_4_0);
1163 	DUMPREG(HDMI_VACT_SPACE_4_1);
1164 	DUMPREG(HDMI_VACT_SPACE_5_0);
1165 	DUMPREG(HDMI_VACT_SPACE_5_1);
1166 	DUMPREG(HDMI_VACT_SPACE_6_0);
1167 	DUMPREG(HDMI_VACT_SPACE_6_1);
1168 
1169 	DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
1170 	DUMPREG(HDMI_TG_CMD);
1171 	DUMPREG(HDMI_TG_H_FSZ_L);
1172 	DUMPREG(HDMI_TG_H_FSZ_H);
1173 	DUMPREG(HDMI_TG_HACT_ST_L);
1174 	DUMPREG(HDMI_TG_HACT_ST_H);
1175 	DUMPREG(HDMI_TG_HACT_SZ_L);
1176 	DUMPREG(HDMI_TG_HACT_SZ_H);
1177 	DUMPREG(HDMI_TG_V_FSZ_L);
1178 	DUMPREG(HDMI_TG_V_FSZ_H);
1179 	DUMPREG(HDMI_TG_VSYNC_L);
1180 	DUMPREG(HDMI_TG_VSYNC_H);
1181 	DUMPREG(HDMI_TG_VSYNC2_L);
1182 	DUMPREG(HDMI_TG_VSYNC2_H);
1183 	DUMPREG(HDMI_TG_VACT_ST_L);
1184 	DUMPREG(HDMI_TG_VACT_ST_H);
1185 	DUMPREG(HDMI_TG_VACT_SZ_L);
1186 	DUMPREG(HDMI_TG_VACT_SZ_H);
1187 	DUMPREG(HDMI_TG_FIELD_CHG_L);
1188 	DUMPREG(HDMI_TG_FIELD_CHG_H);
1189 	DUMPREG(HDMI_TG_VACT_ST2_L);
1190 	DUMPREG(HDMI_TG_VACT_ST2_H);
1191 	DUMPREG(HDMI_TG_VACT_ST3_L);
1192 	DUMPREG(HDMI_TG_VACT_ST3_H);
1193 	DUMPREG(HDMI_TG_VACT_ST4_L);
1194 	DUMPREG(HDMI_TG_VACT_ST4_H);
1195 	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
1196 	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
1197 	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
1198 	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
1199 	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
1200 	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
1201 	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
1202 	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
1203 	DUMPREG(HDMI_TG_3D);
1204 
1205 	DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix);
1206 	DUMPREG(HDMI_AVI_CON);
1207 	DUMPREG(HDMI_AVI_HEADER0);
1208 	DUMPREG(HDMI_AVI_HEADER1);
1209 	DUMPREG(HDMI_AVI_HEADER2);
1210 	DUMPREG(HDMI_AVI_CHECK_SUM);
1211 	DUMPREG(HDMI_VSI_CON);
1212 	DUMPREG(HDMI_VSI_HEADER0);
1213 	DUMPREG(HDMI_VSI_HEADER1);
1214 	DUMPREG(HDMI_VSI_HEADER2);
1215 	for (i = 0; i < 7; ++i)
1216 		DUMPREG(HDMI_VSI_DATA(i));
1217 
1218 #undef DUMPREG
1219 }
1220 
1221 static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
1222 {
1223 	if (hdata->type == HDMI_TYPE13)
1224 		hdmi_v13_regs_dump(hdata, prefix);
1225 	else
1226 		hdmi_v14_regs_dump(hdata, prefix);
1227 }
1228 
1229 static int hdmi_v13_conf_index(struct drm_display_mode *mode)
1230 {
1231 	int i;
1232 
1233 	for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1234 		if (hdmi_v13_confs[i].width == mode->hdisplay &&
1235 				hdmi_v13_confs[i].height == mode->vdisplay &&
1236 				hdmi_v13_confs[i].vrefresh == mode->vrefresh &&
1237 				hdmi_v13_confs[i].interlace ==
1238 				((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1239 				 true : false))
1240 			return i;
1241 
1242 	return -EINVAL;
1243 }
1244 
1245 static int hdmi_v14_conf_index(struct drm_display_mode *mode)
1246 {
1247 	int i;
1248 
1249 	for (i = 0; i < ARRAY_SIZE(hdmi_confs); ++i)
1250 		if (hdmi_confs[i].width == mode->hdisplay &&
1251 				hdmi_confs[i].height == mode->vdisplay &&
1252 				hdmi_confs[i].vrefresh == mode->vrefresh &&
1253 				hdmi_confs[i].interlace ==
1254 				((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1255 				 true : false))
1256 			return i;
1257 
1258 	return -EINVAL;
1259 }
1260 
1261 static int hdmi_conf_index(struct hdmi_context *hdata,
1262 			   struct drm_display_mode *mode)
1263 {
1264 	if (hdata->type == HDMI_TYPE13)
1265 		return hdmi_v13_conf_index(mode);
1266 
1267 	return hdmi_v14_conf_index(mode);
1268 }
1269 
1270 static bool hdmi_is_connected(void *ctx)
1271 {
1272 	struct hdmi_context *hdata = ctx;
1273 
1274 	return hdata->hpd;
1275 }
1276 
1277 static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
1278 				u8 *edid, int len)
1279 {
1280 	struct edid *raw_edid;
1281 	struct hdmi_context *hdata = ctx;
1282 
1283 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1284 
1285 	if (!hdata->ddc_port)
1286 		return -ENODEV;
1287 
1288 	raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter);
1289 	if (raw_edid) {
1290 		hdata->dvi_mode = !drm_detect_hdmi_monitor(raw_edid);
1291 		memcpy(edid, raw_edid, min((1 + raw_edid->extensions)
1292 					* EDID_LENGTH, len));
1293 		DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
1294 			(hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
1295 			raw_edid->width_cm, raw_edid->height_cm);
1296 	} else {
1297 		return -ENODEV;
1298 	}
1299 
1300 	return 0;
1301 }
1302 
1303 static int hdmi_v13_check_timing(struct fb_videomode *check_timing)
1304 {
1305 	int i;
1306 
1307 	DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1308 			check_timing->xres, check_timing->yres,
1309 			check_timing->refresh, (check_timing->vmode &
1310 			FB_VMODE_INTERLACED) ? true : false);
1311 
1312 	for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1313 		if (hdmi_v13_confs[i].width == check_timing->xres &&
1314 			hdmi_v13_confs[i].height == check_timing->yres &&
1315 			hdmi_v13_confs[i].vrefresh == check_timing->refresh &&
1316 			hdmi_v13_confs[i].interlace ==
1317 			((check_timing->vmode & FB_VMODE_INTERLACED) ?
1318 			 true : false))
1319 				return 0;
1320 
1321 	/* TODO */
1322 
1323 	return -EINVAL;
1324 }
1325 
1326 static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
1327 {
1328 	int i;
1329 
1330 	DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1331 			check_timing->xres, check_timing->yres,
1332 			check_timing->refresh, (check_timing->vmode &
1333 			FB_VMODE_INTERLACED) ? true : false);
1334 
1335 	for (i = 0; i < ARRAY_SIZE(hdmi_confs); i++)
1336 		if (hdmi_confs[i].width == check_timing->xres &&
1337 			hdmi_confs[i].height == check_timing->yres &&
1338 			hdmi_confs[i].vrefresh == check_timing->refresh &&
1339 			hdmi_confs[i].interlace ==
1340 			((check_timing->vmode & FB_VMODE_INTERLACED) ?
1341 			 true : false))
1342 				return 0;
1343 
1344 	/* TODO */
1345 
1346 	return -EINVAL;
1347 }
1348 
1349 static int hdmi_check_timing(void *ctx, void *timing)
1350 {
1351 	struct hdmi_context *hdata = ctx;
1352 	struct fb_videomode *check_timing = timing;
1353 
1354 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1355 
1356 	DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres,
1357 			check_timing->yres, check_timing->refresh,
1358 			check_timing->vmode);
1359 
1360 	if (hdata->type == HDMI_TYPE13)
1361 		return hdmi_v13_check_timing(check_timing);
1362 	else
1363 		return hdmi_v14_check_timing(check_timing);
1364 }
1365 
1366 static void hdmi_set_acr(u32 freq, u8 *acr)
1367 {
1368 	u32 n, cts;
1369 
1370 	switch (freq) {
1371 	case 32000:
1372 		n = 4096;
1373 		cts = 27000;
1374 		break;
1375 	case 44100:
1376 		n = 6272;
1377 		cts = 30000;
1378 		break;
1379 	case 88200:
1380 		n = 12544;
1381 		cts = 30000;
1382 		break;
1383 	case 176400:
1384 		n = 25088;
1385 		cts = 30000;
1386 		break;
1387 	case 48000:
1388 		n = 6144;
1389 		cts = 27000;
1390 		break;
1391 	case 96000:
1392 		n = 12288;
1393 		cts = 27000;
1394 		break;
1395 	case 192000:
1396 		n = 24576;
1397 		cts = 27000;
1398 		break;
1399 	default:
1400 		n = 0;
1401 		cts = 0;
1402 		break;
1403 	}
1404 
1405 	acr[1] = cts >> 16;
1406 	acr[2] = cts >> 8 & 0xff;
1407 	acr[3] = cts & 0xff;
1408 
1409 	acr[4] = n >> 16;
1410 	acr[5] = n >> 8 & 0xff;
1411 	acr[6] = n & 0xff;
1412 }
1413 
1414 static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr)
1415 {
1416 	hdmi_reg_writeb(hdata, HDMI_ACR_N0, acr[6]);
1417 	hdmi_reg_writeb(hdata, HDMI_ACR_N1, acr[5]);
1418 	hdmi_reg_writeb(hdata, HDMI_ACR_N2, acr[4]);
1419 	hdmi_reg_writeb(hdata, HDMI_ACR_MCTS0, acr[3]);
1420 	hdmi_reg_writeb(hdata, HDMI_ACR_MCTS1, acr[2]);
1421 	hdmi_reg_writeb(hdata, HDMI_ACR_MCTS2, acr[1]);
1422 	hdmi_reg_writeb(hdata, HDMI_ACR_CTS0, acr[3]);
1423 	hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]);
1424 	hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]);
1425 
1426 	if (hdata->type == HDMI_TYPE13)
1427 		hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4);
1428 	else
1429 		hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1430 }
1431 
1432 static void hdmi_audio_init(struct hdmi_context *hdata)
1433 {
1434 	u32 sample_rate, bits_per_sample, frame_size_code;
1435 	u32 data_num, bit_ch, sample_frq;
1436 	u32 val;
1437 	u8 acr[7];
1438 
1439 	sample_rate = 44100;
1440 	bits_per_sample = 16;
1441 	frame_size_code = 0;
1442 
1443 	switch (bits_per_sample) {
1444 	case 20:
1445 		data_num = 2;
1446 		bit_ch  = 1;
1447 		break;
1448 	case 24:
1449 		data_num = 3;
1450 		bit_ch  = 1;
1451 		break;
1452 	default:
1453 		data_num = 1;
1454 		bit_ch  = 0;
1455 		break;
1456 	}
1457 
1458 	hdmi_set_acr(sample_rate, acr);
1459 	hdmi_reg_acr(hdata, acr);
1460 
1461 	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1462 				| HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1463 				| HDMI_I2S_MUX_ENABLE);
1464 
1465 	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1466 			| HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1467 
1468 	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1469 
1470 	sample_frq = (sample_rate == 44100) ? 0 :
1471 			(sample_rate == 48000) ? 2 :
1472 			(sample_rate == 32000) ? 3 :
1473 			(sample_rate == 96000) ? 0xa : 0x0;
1474 
1475 	hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1476 	hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1477 
1478 	val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1479 	hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1480 
1481 	/* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1482 	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1483 			| HDMI_I2S_SEL_LRCK(6));
1484 	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1485 			| HDMI_I2S_SEL_SDATA2(4));
1486 	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1487 			| HDMI_I2S_SEL_SDATA2(2));
1488 	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1489 
1490 	/* I2S_CON_1 & 2 */
1491 	hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1492 			| HDMI_I2S_L_CH_LOW_POL);
1493 	hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1494 			| HDMI_I2S_SET_BIT_CH(bit_ch)
1495 			| HDMI_I2S_SET_SDATA_BIT(data_num)
1496 			| HDMI_I2S_BASIC_FORMAT);
1497 
1498 	/* Configure register related to CUV information */
1499 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
1500 			| HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1501 			| HDMI_I2S_COPYRIGHT
1502 			| HDMI_I2S_LINEAR_PCM
1503 			| HDMI_I2S_CONSUMER_FORMAT);
1504 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1505 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1506 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1507 			| HDMI_I2S_SET_SMP_FREQ(sample_frq));
1508 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1509 			HDMI_I2S_ORG_SMP_FREQ_44_1
1510 			| HDMI_I2S_WORD_LEN_MAX24_24BITS
1511 			| HDMI_I2S_WORD_LEN_MAX_24BITS);
1512 
1513 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1514 }
1515 
1516 static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1517 {
1518 	if (hdata->dvi_mode)
1519 		return;
1520 
1521 	hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
1522 	hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ?
1523 			HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1524 }
1525 
1526 static void hdmi_conf_reset(struct hdmi_context *hdata)
1527 {
1528 	u32 reg;
1529 
1530 	if (hdata->type == HDMI_TYPE13)
1531 		reg = HDMI_V13_CORE_RSTOUT;
1532 	else
1533 		reg = HDMI_CORE_RSTOUT;
1534 
1535 	/* resetting HDMI core */
1536 	hdmi_reg_writemask(hdata, reg,  0, HDMI_CORE_SW_RSTOUT);
1537 	mdelay(10);
1538 	hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT);
1539 	mdelay(10);
1540 }
1541 
1542 static void hdmi_conf_init(struct hdmi_context *hdata)
1543 {
1544 	/* disable HPD interrupts */
1545 	hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1546 		HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1547 
1548 	/* choose HDMI mode */
1549 	hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1550 		HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1551 	/* disable bluescreen */
1552 	hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1553 
1554 	if (hdata->dvi_mode) {
1555 		/* choose DVI mode */
1556 		hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1557 				HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1558 		hdmi_reg_writeb(hdata, HDMI_CON_2,
1559 				HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1560 	}
1561 
1562 	if (hdata->type == HDMI_TYPE13) {
1563 		/* choose bluescreen (fecal) color */
1564 		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1565 		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1566 		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1567 
1568 		/* enable AVI packet every vsync, fixes purple line problem */
1569 		hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1570 		/* force RGB, look to CEA-861-D, table 7 for more detail */
1571 		hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1572 		hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1573 
1574 		hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1575 		hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1576 		hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1577 	} else {
1578 		/* enable AVI packet every vsync, fixes purple line problem */
1579 		hdmi_reg_writeb(hdata, HDMI_AVI_CON, 0x02);
1580 		hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 2 << 5);
1581 		hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1582 	}
1583 }
1584 
1585 static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
1586 {
1587 	const struct hdmi_v13_preset_conf *conf =
1588 		hdmi_v13_confs[hdata->cur_conf].conf;
1589 	const struct hdmi_v13_core_regs *core = &conf->core;
1590 	const struct hdmi_v13_tg_regs *tg = &conf->tg;
1591 	int tries;
1592 
1593 	/* setting core registers */
1594 	hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1595 	hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1596 	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_0, core->v_blank[0]);
1597 	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_1, core->v_blank[1]);
1598 	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_2, core->v_blank[2]);
1599 	hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_0, core->h_v_line[0]);
1600 	hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_1, core->h_v_line[1]);
1601 	hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_2, core->h_v_line[2]);
1602 	hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1603 	hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1604 	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_0, core->v_blank_f[0]);
1605 	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_1, core->v_blank_f[1]);
1606 	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_2, core->v_blank_f[2]);
1607 	hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_0, core->h_sync_gen[0]);
1608 	hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_1, core->h_sync_gen[1]);
1609 	hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_2, core->h_sync_gen[2]);
1610 	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_0, core->v_sync_gen1[0]);
1611 	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_1, core->v_sync_gen1[1]);
1612 	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_2, core->v_sync_gen1[2]);
1613 	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_0, core->v_sync_gen2[0]);
1614 	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_1, core->v_sync_gen2[1]);
1615 	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_2, core->v_sync_gen2[2]);
1616 	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_0, core->v_sync_gen3[0]);
1617 	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]);
1618 	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]);
1619 	/* Timing generator registers */
1620 	hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1621 	hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1622 	hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1623 	hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1624 	hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1625 	hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1626 	hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1627 	hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1628 	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1629 	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1630 	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1631 	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1632 	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1633 	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1634 	hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1635 	hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1636 	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1637 	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1638 	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1639 	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1640 	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1641 	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1642 	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1643 	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1644 	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1645 	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1646 	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1647 	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1648 
1649 	/* waiting for HDMIPHY's PLL to get to steady state */
1650 	for (tries = 100; tries; --tries) {
1651 		u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS);
1652 		if (val & HDMI_PHY_STATUS_READY)
1653 			break;
1654 		mdelay(1);
1655 	}
1656 	/* steady state not achieved */
1657 	if (tries == 0) {
1658 		DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1659 		hdmi_regs_dump(hdata, "timing apply");
1660 	}
1661 
1662 	clk_disable(hdata->res.sclk_hdmi);
1663 	clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1664 	clk_enable(hdata->res.sclk_hdmi);
1665 
1666 	/* enable HDMI and timing generator */
1667 	hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1668 	if (core->int_pro_mode[0])
1669 		hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1670 				HDMI_FIELD_EN);
1671 	else
1672 		hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1673 }
1674 
1675 static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
1676 {
1677 	const struct hdmi_preset_conf *conf = hdmi_confs[hdata->cur_conf].conf;
1678 	const struct hdmi_core_regs *core = &conf->core;
1679 	const struct hdmi_tg_regs *tg = &conf->tg;
1680 	int tries;
1681 
1682 	/* setting core registers */
1683 	hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1684 	hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1685 	hdmi_reg_writeb(hdata, HDMI_V2_BLANK_0, core->v2_blank[0]);
1686 	hdmi_reg_writeb(hdata, HDMI_V2_BLANK_1, core->v2_blank[1]);
1687 	hdmi_reg_writeb(hdata, HDMI_V1_BLANK_0, core->v1_blank[0]);
1688 	hdmi_reg_writeb(hdata, HDMI_V1_BLANK_1, core->v1_blank[1]);
1689 	hdmi_reg_writeb(hdata, HDMI_V_LINE_0, core->v_line[0]);
1690 	hdmi_reg_writeb(hdata, HDMI_V_LINE_1, core->v_line[1]);
1691 	hdmi_reg_writeb(hdata, HDMI_H_LINE_0, core->h_line[0]);
1692 	hdmi_reg_writeb(hdata, HDMI_H_LINE_1, core->h_line[1]);
1693 	hdmi_reg_writeb(hdata, HDMI_HSYNC_POL, core->hsync_pol[0]);
1694 	hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1695 	hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1696 	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_0, core->v_blank_f0[0]);
1697 	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_1, core->v_blank_f0[1]);
1698 	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_0, core->v_blank_f1[0]);
1699 	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_1, core->v_blank_f1[1]);
1700 	hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_0, core->h_sync_start[0]);
1701 	hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_1, core->h_sync_start[1]);
1702 	hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_0, core->h_sync_end[0]);
1703 	hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_1, core->h_sync_end[1]);
1704 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_0,
1705 			core->v_sync_line_bef_2[0]);
1706 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_1,
1707 			core->v_sync_line_bef_2[1]);
1708 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_0,
1709 			core->v_sync_line_bef_1[0]);
1710 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_1,
1711 			core->v_sync_line_bef_1[1]);
1712 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_0,
1713 			core->v_sync_line_aft_2[0]);
1714 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_1,
1715 			core->v_sync_line_aft_2[1]);
1716 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_0,
1717 			core->v_sync_line_aft_1[0]);
1718 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_1,
1719 			core->v_sync_line_aft_1[1]);
1720 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0,
1721 			core->v_sync_line_aft_pxl_2[0]);
1722 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_1,
1723 			core->v_sync_line_aft_pxl_2[1]);
1724 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0,
1725 			core->v_sync_line_aft_pxl_1[0]);
1726 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_1,
1727 			core->v_sync_line_aft_pxl_1[1]);
1728 	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_0, core->v_blank_f2[0]);
1729 	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_1, core->v_blank_f2[1]);
1730 	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_0, core->v_blank_f3[0]);
1731 	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_1, core->v_blank_f3[1]);
1732 	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_0, core->v_blank_f4[0]);
1733 	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_1, core->v_blank_f4[1]);
1734 	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_0, core->v_blank_f5[0]);
1735 	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_1, core->v_blank_f5[1]);
1736 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_0,
1737 			core->v_sync_line_aft_3[0]);
1738 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_1,
1739 			core->v_sync_line_aft_3[1]);
1740 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_0,
1741 			core->v_sync_line_aft_4[0]);
1742 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_1,
1743 			core->v_sync_line_aft_4[1]);
1744 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_0,
1745 			core->v_sync_line_aft_5[0]);
1746 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_1,
1747 			core->v_sync_line_aft_5[1]);
1748 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_0,
1749 			core->v_sync_line_aft_6[0]);
1750 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_1,
1751 			core->v_sync_line_aft_6[1]);
1752 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0,
1753 			core->v_sync_line_aft_pxl_3[0]);
1754 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_1,
1755 			core->v_sync_line_aft_pxl_3[1]);
1756 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0,
1757 			core->v_sync_line_aft_pxl_4[0]);
1758 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_1,
1759 			core->v_sync_line_aft_pxl_4[1]);
1760 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0,
1761 			core->v_sync_line_aft_pxl_5[0]);
1762 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_1,
1763 			core->v_sync_line_aft_pxl_5[1]);
1764 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0,
1765 			core->v_sync_line_aft_pxl_6[0]);
1766 	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_1,
1767 			core->v_sync_line_aft_pxl_6[1]);
1768 	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_0, core->vact_space_1[0]);
1769 	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_1, core->vact_space_1[1]);
1770 	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_0, core->vact_space_2[0]);
1771 	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_1, core->vact_space_2[1]);
1772 	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_0, core->vact_space_3[0]);
1773 	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_1, core->vact_space_3[1]);
1774 	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_0, core->vact_space_4[0]);
1775 	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_1, core->vact_space_4[1]);
1776 	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_0, core->vact_space_5[0]);
1777 	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_1, core->vact_space_5[1]);
1778 	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_0, core->vact_space_6[0]);
1779 	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]);
1780 
1781 	/* Timing generator registers */
1782 	hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1783 	hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1784 	hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1785 	hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1786 	hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1787 	hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1788 	hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1789 	hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1790 	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1791 	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1792 	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1793 	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1794 	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1795 	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1796 	hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1797 	hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1798 	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1799 	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1800 	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1801 	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1802 	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3_l);
1803 	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3_h);
1804 	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4_l);
1805 	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4_h);
1806 	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1807 	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1808 	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1809 	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1810 	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1811 	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1812 	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1813 	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1814 	hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d);
1815 
1816 	/* waiting for HDMIPHY's PLL to get to steady state */
1817 	for (tries = 100; tries; --tries) {
1818 		u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0);
1819 		if (val & HDMI_PHY_STATUS_READY)
1820 			break;
1821 		mdelay(1);
1822 	}
1823 	/* steady state not achieved */
1824 	if (tries == 0) {
1825 		DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1826 		hdmi_regs_dump(hdata, "timing apply");
1827 	}
1828 
1829 	clk_disable(hdata->res.sclk_hdmi);
1830 	clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1831 	clk_enable(hdata->res.sclk_hdmi);
1832 
1833 	/* enable HDMI and timing generator */
1834 	hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1835 	if (core->int_pro_mode[0])
1836 		hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1837 				HDMI_FIELD_EN);
1838 	else
1839 		hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1840 }
1841 
1842 static void hdmi_timing_apply(struct hdmi_context *hdata)
1843 {
1844 	if (hdata->type == HDMI_TYPE13)
1845 		hdmi_v13_timing_apply(hdata);
1846 	else
1847 		hdmi_v14_timing_apply(hdata);
1848 }
1849 
1850 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1851 {
1852 	u8 buffer[2];
1853 	u32 reg;
1854 
1855 	clk_disable(hdata->res.sclk_hdmi);
1856 	clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel);
1857 	clk_enable(hdata->res.sclk_hdmi);
1858 
1859 	/* operation mode */
1860 	buffer[0] = 0x1f;
1861 	buffer[1] = 0x00;
1862 
1863 	if (hdata->hdmiphy_port)
1864 		i2c_master_send(hdata->hdmiphy_port, buffer, 2);
1865 
1866 	if (hdata->type == HDMI_TYPE13)
1867 		reg = HDMI_V13_PHY_RSTOUT;
1868 	else
1869 		reg = HDMI_PHY_RSTOUT;
1870 
1871 	/* reset hdmiphy */
1872 	hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT);
1873 	mdelay(10);
1874 	hdmi_reg_writemask(hdata, reg,  0, HDMI_PHY_SW_RSTOUT);
1875 	mdelay(10);
1876 }
1877 
1878 static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1879 {
1880 	const u8 *hdmiphy_data;
1881 	u8 buffer[32];
1882 	u8 operation[2];
1883 	u8 read_buffer[32] = {0, };
1884 	int ret;
1885 	int i;
1886 
1887 	if (!hdata->hdmiphy_port) {
1888 		DRM_ERROR("hdmiphy is not attached\n");
1889 		return;
1890 	}
1891 
1892 	/* pixel clock */
1893 	if (hdata->type == HDMI_TYPE13)
1894 		hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data;
1895 	else
1896 		hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data;
1897 
1898 	memcpy(buffer, hdmiphy_data, 32);
1899 	ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
1900 	if (ret != 32) {
1901 		DRM_ERROR("failed to configure HDMIPHY via I2C\n");
1902 		return;
1903 	}
1904 
1905 	mdelay(10);
1906 
1907 	/* operation mode */
1908 	operation[0] = 0x1f;
1909 	operation[1] = 0x80;
1910 
1911 	ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
1912 	if (ret != 2) {
1913 		DRM_ERROR("failed to enable hdmiphy\n");
1914 		return;
1915 	}
1916 
1917 	ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
1918 	if (ret < 0) {
1919 		DRM_ERROR("failed to read hdmiphy config\n");
1920 		return;
1921 	}
1922 
1923 	for (i = 0; i < ret; i++)
1924 		DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
1925 			"recv [0x%02x]\n", i, buffer[i], read_buffer[i]);
1926 }
1927 
1928 static void hdmi_conf_apply(struct hdmi_context *hdata)
1929 {
1930 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1931 
1932 	hdmiphy_conf_reset(hdata);
1933 	hdmiphy_conf_apply(hdata);
1934 
1935 	mutex_lock(&hdata->hdmi_mutex);
1936 	hdmi_conf_reset(hdata);
1937 	hdmi_conf_init(hdata);
1938 	mutex_unlock(&hdata->hdmi_mutex);
1939 
1940 	hdmi_audio_init(hdata);
1941 
1942 	/* setting core registers */
1943 	hdmi_timing_apply(hdata);
1944 	hdmi_audio_control(hdata, true);
1945 
1946 	hdmi_regs_dump(hdata, "start");
1947 }
1948 
1949 static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
1950 				const struct drm_display_mode *mode,
1951 				struct drm_display_mode *adjusted_mode)
1952 {
1953 	struct drm_display_mode *m;
1954 	struct hdmi_context *hdata = ctx;
1955 	int index;
1956 
1957 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1958 
1959 	drm_mode_set_crtcinfo(adjusted_mode, 0);
1960 
1961 	if (hdata->type == HDMI_TYPE13)
1962 		index = hdmi_v13_conf_index(adjusted_mode);
1963 	else
1964 		index = hdmi_v14_conf_index(adjusted_mode);
1965 
1966 	/* just return if user desired mode exists. */
1967 	if (index >= 0)
1968 		return;
1969 
1970 	/*
1971 	 * otherwise, find the most suitable mode among modes and change it
1972 	 * to adjusted_mode.
1973 	 */
1974 	list_for_each_entry(m, &connector->modes, head) {
1975 		if (hdata->type == HDMI_TYPE13)
1976 			index = hdmi_v13_conf_index(m);
1977 		else
1978 			index = hdmi_v14_conf_index(m);
1979 
1980 		if (index >= 0) {
1981 			DRM_INFO("desired mode doesn't exist so\n");
1982 			DRM_INFO("use the most suitable mode among modes.\n");
1983 			memcpy(adjusted_mode, m, sizeof(*m));
1984 			break;
1985 		}
1986 	}
1987 }
1988 
1989 static void hdmi_mode_set(void *ctx, void *mode)
1990 {
1991 	struct hdmi_context *hdata = ctx;
1992 	int conf_idx;
1993 
1994 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1995 
1996 	conf_idx = hdmi_conf_index(hdata, mode);
1997 	if (conf_idx >= 0)
1998 		hdata->cur_conf = conf_idx;
1999 	else
2000 		DRM_DEBUG_KMS("not supported mode\n");
2001 }
2002 
2003 static void hdmi_get_max_resol(void *ctx, unsigned int *width,
2004 					unsigned int *height)
2005 {
2006 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2007 
2008 	*width = MAX_WIDTH;
2009 	*height = MAX_HEIGHT;
2010 }
2011 
2012 static void hdmi_commit(void *ctx)
2013 {
2014 	struct hdmi_context *hdata = ctx;
2015 
2016 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2017 
2018 	hdmi_conf_apply(hdata);
2019 }
2020 
2021 static void hdmi_poweron(struct hdmi_context *hdata)
2022 {
2023 	struct hdmi_resources *res = &hdata->res;
2024 
2025 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2026 
2027 	mutex_lock(&hdata->hdmi_mutex);
2028 	if (hdata->powered) {
2029 		mutex_unlock(&hdata->hdmi_mutex);
2030 		return;
2031 	}
2032 
2033 	hdata->powered = true;
2034 
2035 	mutex_unlock(&hdata->hdmi_mutex);
2036 
2037 	pm_runtime_get_sync(hdata->dev);
2038 
2039 	regulator_bulk_enable(res->regul_count, res->regul_bulk);
2040 	clk_enable(res->hdmiphy);
2041 	clk_enable(res->hdmi);
2042 	clk_enable(res->sclk_hdmi);
2043 }
2044 
2045 static void hdmi_poweroff(struct hdmi_context *hdata)
2046 {
2047 	struct hdmi_resources *res = &hdata->res;
2048 
2049 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2050 
2051 	mutex_lock(&hdata->hdmi_mutex);
2052 	if (!hdata->powered)
2053 		goto out;
2054 	mutex_unlock(&hdata->hdmi_mutex);
2055 
2056 	/*
2057 	 * The TV power domain needs any condition of hdmiphy to turn off and
2058 	 * its reset state seems to meet the condition.
2059 	 */
2060 	hdmiphy_conf_reset(hdata);
2061 
2062 	clk_disable(res->sclk_hdmi);
2063 	clk_disable(res->hdmi);
2064 	clk_disable(res->hdmiphy);
2065 	regulator_bulk_disable(res->regul_count, res->regul_bulk);
2066 
2067 	pm_runtime_put_sync(hdata->dev);
2068 
2069 	mutex_lock(&hdata->hdmi_mutex);
2070 
2071 	hdata->powered = false;
2072 
2073 out:
2074 	mutex_unlock(&hdata->hdmi_mutex);
2075 }
2076 
2077 static void hdmi_dpms(void *ctx, int mode)
2078 {
2079 	struct hdmi_context *hdata = ctx;
2080 
2081 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2082 
2083 	switch (mode) {
2084 	case DRM_MODE_DPMS_ON:
2085 		hdmi_poweron(hdata);
2086 		break;
2087 	case DRM_MODE_DPMS_STANDBY:
2088 	case DRM_MODE_DPMS_SUSPEND:
2089 	case DRM_MODE_DPMS_OFF:
2090 		hdmi_poweroff(hdata);
2091 		break;
2092 	default:
2093 		DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
2094 		break;
2095 	}
2096 }
2097 
2098 static struct exynos_hdmi_ops hdmi_ops = {
2099 	/* display */
2100 	.is_connected	= hdmi_is_connected,
2101 	.get_edid	= hdmi_get_edid,
2102 	.check_timing	= hdmi_check_timing,
2103 
2104 	/* manager */
2105 	.mode_fixup	= hdmi_mode_fixup,
2106 	.mode_set	= hdmi_mode_set,
2107 	.get_max_resol	= hdmi_get_max_resol,
2108 	.commit		= hdmi_commit,
2109 	.dpms		= hdmi_dpms,
2110 };
2111 
2112 static irqreturn_t hdmi_external_irq_thread(int irq, void *arg)
2113 {
2114 	struct exynos_drm_hdmi_context *ctx = arg;
2115 	struct hdmi_context *hdata = ctx->ctx;
2116 
2117 	mutex_lock(&hdata->hdmi_mutex);
2118 	hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2119 	mutex_unlock(&hdata->hdmi_mutex);
2120 
2121 	if (ctx->drm_dev)
2122 		drm_helper_hpd_irq_event(ctx->drm_dev);
2123 
2124 	return IRQ_HANDLED;
2125 }
2126 
2127 static irqreturn_t hdmi_internal_irq_thread(int irq, void *arg)
2128 {
2129 	struct exynos_drm_hdmi_context *ctx = arg;
2130 	struct hdmi_context *hdata = ctx->ctx;
2131 	u32 intc_flag;
2132 
2133 	intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG);
2134 	/* clearing flags for HPD plug/unplug */
2135 	if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) {
2136 		DRM_DEBUG_KMS("unplugged\n");
2137 		hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
2138 			HDMI_INTC_FLAG_HPD_UNPLUG);
2139 	}
2140 	if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) {
2141 		DRM_DEBUG_KMS("plugged\n");
2142 		hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
2143 			HDMI_INTC_FLAG_HPD_PLUG);
2144 	}
2145 
2146 	if (ctx->drm_dev)
2147 		drm_helper_hpd_irq_event(ctx->drm_dev);
2148 
2149 	return IRQ_HANDLED;
2150 }
2151 
2152 static int __devinit hdmi_resources_init(struct hdmi_context *hdata)
2153 {
2154 	struct device *dev = hdata->dev;
2155 	struct hdmi_resources *res = &hdata->res;
2156 	static char *supply[] = {
2157 		"hdmi-en",
2158 		"vdd",
2159 		"vdd_osc",
2160 		"vdd_pll",
2161 	};
2162 	int i, ret;
2163 
2164 	DRM_DEBUG_KMS("HDMI resource init\n");
2165 
2166 	memset(res, 0, sizeof(*res));
2167 
2168 	/* get clocks, power */
2169 	res->hdmi = clk_get(dev, "hdmi");
2170 	if (IS_ERR_OR_NULL(res->hdmi)) {
2171 		DRM_ERROR("failed to get clock 'hdmi'\n");
2172 		goto fail;
2173 	}
2174 	res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
2175 	if (IS_ERR_OR_NULL(res->sclk_hdmi)) {
2176 		DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
2177 		goto fail;
2178 	}
2179 	res->sclk_pixel = clk_get(dev, "sclk_pixel");
2180 	if (IS_ERR_OR_NULL(res->sclk_pixel)) {
2181 		DRM_ERROR("failed to get clock 'sclk_pixel'\n");
2182 		goto fail;
2183 	}
2184 	res->sclk_hdmiphy = clk_get(dev, "sclk_hdmiphy");
2185 	if (IS_ERR_OR_NULL(res->sclk_hdmiphy)) {
2186 		DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
2187 		goto fail;
2188 	}
2189 	res->hdmiphy = clk_get(dev, "hdmiphy");
2190 	if (IS_ERR_OR_NULL(res->hdmiphy)) {
2191 		DRM_ERROR("failed to get clock 'hdmiphy'\n");
2192 		goto fail;
2193 	}
2194 
2195 	clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
2196 
2197 	res->regul_bulk = kzalloc(ARRAY_SIZE(supply) *
2198 		sizeof(res->regul_bulk[0]), GFP_KERNEL);
2199 	if (!res->regul_bulk) {
2200 		DRM_ERROR("failed to get memory for regulators\n");
2201 		goto fail;
2202 	}
2203 	for (i = 0; i < ARRAY_SIZE(supply); ++i) {
2204 		res->regul_bulk[i].supply = supply[i];
2205 		res->regul_bulk[i].consumer = NULL;
2206 	}
2207 	ret = regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
2208 	if (ret) {
2209 		DRM_ERROR("failed to get regulators\n");
2210 		goto fail;
2211 	}
2212 	res->regul_count = ARRAY_SIZE(supply);
2213 
2214 	return 0;
2215 fail:
2216 	DRM_ERROR("HDMI resource init - failed\n");
2217 	return -ENODEV;
2218 }
2219 
2220 static int hdmi_resources_cleanup(struct hdmi_context *hdata)
2221 {
2222 	struct hdmi_resources *res = &hdata->res;
2223 
2224 	regulator_bulk_free(res->regul_count, res->regul_bulk);
2225 	/* kfree is NULL-safe */
2226 	kfree(res->regul_bulk);
2227 	if (!IS_ERR_OR_NULL(res->hdmiphy))
2228 		clk_put(res->hdmiphy);
2229 	if (!IS_ERR_OR_NULL(res->sclk_hdmiphy))
2230 		clk_put(res->sclk_hdmiphy);
2231 	if (!IS_ERR_OR_NULL(res->sclk_pixel))
2232 		clk_put(res->sclk_pixel);
2233 	if (!IS_ERR_OR_NULL(res->sclk_hdmi))
2234 		clk_put(res->sclk_hdmi);
2235 	if (!IS_ERR_OR_NULL(res->hdmi))
2236 		clk_put(res->hdmi);
2237 	memset(res, 0, sizeof(*res));
2238 
2239 	return 0;
2240 }
2241 
2242 static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
2243 
2244 void hdmi_attach_ddc_client(struct i2c_client *ddc)
2245 {
2246 	if (ddc)
2247 		hdmi_ddc = ddc;
2248 }
2249 
2250 void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
2251 {
2252 	if (hdmiphy)
2253 		hdmi_hdmiphy = hdmiphy;
2254 }
2255 
2256 #ifdef CONFIG_OF
2257 static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
2258 					(struct device *dev)
2259 {
2260 	struct device_node *np = dev->of_node;
2261 	struct s5p_hdmi_platform_data *pd;
2262 	enum of_gpio_flags flags;
2263 	u32 value;
2264 
2265 	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
2266 	if (!pd) {
2267 		DRM_ERROR("memory allocation for pdata failed\n");
2268 		goto err_data;
2269 	}
2270 
2271 	if (!of_find_property(np, "hpd-gpio", &value)) {
2272 		DRM_ERROR("no hpd gpio property found\n");
2273 		goto err_data;
2274 	}
2275 
2276 	pd->hpd_gpio = of_get_named_gpio_flags(np, "hpd-gpio", 0, &flags);
2277 
2278 	return pd;
2279 
2280 err_data:
2281 	return NULL;
2282 }
2283 #else
2284 static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
2285 					(struct device *dev)
2286 {
2287 	return NULL;
2288 }
2289 #endif
2290 
2291 static struct platform_device_id hdmi_driver_types[] = {
2292 	{
2293 		.name		= "s5pv210-hdmi",
2294 		.driver_data    = HDMI_TYPE13,
2295 	}, {
2296 		.name		= "exynos4-hdmi",
2297 		.driver_data    = HDMI_TYPE13,
2298 	}, {
2299 		.name		= "exynos4-hdmi14",
2300 		.driver_data	= HDMI_TYPE14,
2301 	}, {
2302 		.name		= "exynos5-hdmi",
2303 		.driver_data	= HDMI_TYPE14,
2304 	}, {
2305 		/* end node */
2306 	}
2307 };
2308 
2309 static struct of_device_id hdmi_match_types[] = {
2310 	{
2311 		.compatible = "samsung,exynos5-hdmi",
2312 		.data	= (void	*)HDMI_TYPE14,
2313 	}, {
2314 		/* end node */
2315 	}
2316 };
2317 
2318 static int __devinit hdmi_probe(struct platform_device *pdev)
2319 {
2320 	struct device *dev = &pdev->dev;
2321 	struct exynos_drm_hdmi_context *drm_hdmi_ctx;
2322 	struct hdmi_context *hdata;
2323 	struct s5p_hdmi_platform_data *pdata;
2324 	struct resource *res;
2325 	int ret;
2326 
2327 	DRM_DEBUG_KMS("[%d]\n", __LINE__);
2328 
2329 	if (pdev->dev.of_node) {
2330 		pdata = drm_hdmi_dt_parse_pdata(dev);
2331 		if (IS_ERR(pdata)) {
2332 			DRM_ERROR("failed to parse dt\n");
2333 			return PTR_ERR(pdata);
2334 		}
2335 	} else {
2336 		pdata = pdev->dev.platform_data;
2337 	}
2338 
2339 	if (!pdata) {
2340 		DRM_ERROR("no platform data specified\n");
2341 		return -EINVAL;
2342 	}
2343 
2344 	drm_hdmi_ctx = devm_kzalloc(&pdev->dev, sizeof(*drm_hdmi_ctx),
2345 								GFP_KERNEL);
2346 	if (!drm_hdmi_ctx) {
2347 		DRM_ERROR("failed to allocate common hdmi context.\n");
2348 		return -ENOMEM;
2349 	}
2350 
2351 	hdata = devm_kzalloc(&pdev->dev, sizeof(struct hdmi_context),
2352 								GFP_KERNEL);
2353 	if (!hdata) {
2354 		DRM_ERROR("out of memory\n");
2355 		return -ENOMEM;
2356 	}
2357 
2358 	mutex_init(&hdata->hdmi_mutex);
2359 
2360 	drm_hdmi_ctx->ctx = (void *)hdata;
2361 	hdata->parent_ctx = (void *)drm_hdmi_ctx;
2362 
2363 	platform_set_drvdata(pdev, drm_hdmi_ctx);
2364 
2365 	if (dev->of_node) {
2366 		const struct of_device_id *match;
2367 		match = of_match_node(of_match_ptr(hdmi_match_types),
2368 					pdev->dev.of_node);
2369 		hdata->type = (enum hdmi_type)match->data;
2370 	} else {
2371 		hdata->type = (enum hdmi_type)platform_get_device_id
2372 					(pdev)->driver_data;
2373 	}
2374 
2375 	hdata->hpd_gpio = pdata->hpd_gpio;
2376 	hdata->dev = dev;
2377 
2378 	ret = hdmi_resources_init(hdata);
2379 
2380 	if (ret) {
2381 		ret = -EINVAL;
2382 		DRM_ERROR("hdmi_resources_init failed\n");
2383 		goto err_data;
2384 	}
2385 
2386 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2387 	if (!res) {
2388 		DRM_ERROR("failed to find registers\n");
2389 		ret = -ENOENT;
2390 		goto err_resource;
2391 	}
2392 
2393 	hdata->regs = devm_request_and_ioremap(&pdev->dev, res);
2394 	if (!hdata->regs) {
2395 		DRM_ERROR("failed to map registers\n");
2396 		ret = -ENXIO;
2397 		goto err_resource;
2398 	}
2399 
2400 	ret = gpio_request(hdata->hpd_gpio, "HPD");
2401 	if (ret) {
2402 		DRM_ERROR("failed to request HPD gpio\n");
2403 		goto err_resource;
2404 	}
2405 
2406 	/* DDC i2c driver */
2407 	if (i2c_add_driver(&ddc_driver)) {
2408 		DRM_ERROR("failed to register ddc i2c driver\n");
2409 		ret = -ENOENT;
2410 		goto err_gpio;
2411 	}
2412 
2413 	hdata->ddc_port = hdmi_ddc;
2414 
2415 	/* hdmiphy i2c driver */
2416 	if (i2c_add_driver(&hdmiphy_driver)) {
2417 		DRM_ERROR("failed to register hdmiphy i2c driver\n");
2418 		ret = -ENOENT;
2419 		goto err_ddc;
2420 	}
2421 
2422 	hdata->hdmiphy_port = hdmi_hdmiphy;
2423 
2424 	hdata->external_irq = gpio_to_irq(hdata->hpd_gpio);
2425 	if (hdata->external_irq < 0) {
2426 		DRM_ERROR("failed to get GPIO external irq\n");
2427 		ret = hdata->external_irq;
2428 		goto err_hdmiphy;
2429 	}
2430 
2431 	hdata->internal_irq = platform_get_irq(pdev, 0);
2432 	if (hdata->internal_irq < 0) {
2433 		DRM_ERROR("failed to get platform internal irq\n");
2434 		ret = hdata->internal_irq;
2435 		goto err_hdmiphy;
2436 	}
2437 
2438 	hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2439 
2440 	ret = request_threaded_irq(hdata->external_irq, NULL,
2441 			hdmi_external_irq_thread, IRQF_TRIGGER_RISING |
2442 			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
2443 			"hdmi_external", drm_hdmi_ctx);
2444 	if (ret) {
2445 		DRM_ERROR("failed to register hdmi external interrupt\n");
2446 		goto err_hdmiphy;
2447 	}
2448 
2449 	ret = request_threaded_irq(hdata->internal_irq, NULL,
2450 			hdmi_internal_irq_thread, IRQF_ONESHOT,
2451 			"hdmi_internal", drm_hdmi_ctx);
2452 	if (ret) {
2453 		DRM_ERROR("failed to register hdmi internal interrupt\n");
2454 		goto err_free_irq;
2455 	}
2456 
2457 	/* Attach HDMI Driver to common hdmi. */
2458 	exynos_hdmi_drv_attach(drm_hdmi_ctx);
2459 
2460 	/* register specific callbacks to common hdmi. */
2461 	exynos_hdmi_ops_register(&hdmi_ops);
2462 
2463 	pm_runtime_enable(dev);
2464 
2465 	return 0;
2466 
2467 err_free_irq:
2468 	free_irq(hdata->external_irq, drm_hdmi_ctx);
2469 err_hdmiphy:
2470 	i2c_del_driver(&hdmiphy_driver);
2471 err_ddc:
2472 	i2c_del_driver(&ddc_driver);
2473 err_gpio:
2474 	gpio_free(hdata->hpd_gpio);
2475 err_resource:
2476 	hdmi_resources_cleanup(hdata);
2477 err_data:
2478 	return ret;
2479 }
2480 
2481 static int __devexit hdmi_remove(struct platform_device *pdev)
2482 {
2483 	struct device *dev = &pdev->dev;
2484 	struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev);
2485 	struct hdmi_context *hdata = ctx->ctx;
2486 
2487 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2488 
2489 	pm_runtime_disable(dev);
2490 
2491 	free_irq(hdata->internal_irq, hdata);
2492 	free_irq(hdata->external_irq, hdata);
2493 
2494 	gpio_free(hdata->hpd_gpio);
2495 
2496 	hdmi_resources_cleanup(hdata);
2497 
2498 	/* hdmiphy i2c driver */
2499 	i2c_del_driver(&hdmiphy_driver);
2500 	/* DDC i2c driver */
2501 	i2c_del_driver(&ddc_driver);
2502 
2503 	return 0;
2504 }
2505 
2506 #ifdef CONFIG_PM_SLEEP
2507 static int hdmi_suspend(struct device *dev)
2508 {
2509 	struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2510 	struct hdmi_context *hdata = ctx->ctx;
2511 
2512 	disable_irq(hdata->internal_irq);
2513 	disable_irq(hdata->external_irq);
2514 
2515 	hdata->hpd = false;
2516 	if (ctx->drm_dev)
2517 		drm_helper_hpd_irq_event(ctx->drm_dev);
2518 
2519 	hdmi_poweroff(hdata);
2520 
2521 	return 0;
2522 }
2523 
2524 static int hdmi_resume(struct device *dev)
2525 {
2526 	struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2527 	struct hdmi_context *hdata = ctx->ctx;
2528 
2529 	enable_irq(hdata->external_irq);
2530 	enable_irq(hdata->internal_irq);
2531 	return 0;
2532 }
2533 #endif
2534 
2535 static SIMPLE_DEV_PM_OPS(hdmi_pm_ops, hdmi_suspend, hdmi_resume);
2536 
2537 struct platform_driver hdmi_driver = {
2538 	.probe		= hdmi_probe,
2539 	.remove		= __devexit_p(hdmi_remove),
2540 	.id_table = hdmi_driver_types,
2541 	.driver		= {
2542 		.name	= "exynos-hdmi",
2543 		.owner	= THIS_MODULE,
2544 		.pm	= &hdmi_pm_ops,
2545 		.of_match_table = hdmi_match_types,
2546 	},
2547 };
2548