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