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