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