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