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 #include <drm/drm_atomic_helper.h>
21 
22 #include "regs-hdmi.h"
23 
24 #include <linux/kernel.h>
25 #include <linux/wait.h>
26 #include <linux/i2c.h>
27 #include <linux/platform_device.h>
28 #include <linux/interrupt.h>
29 #include <linux/irq.h>
30 #include <linux/delay.h>
31 #include <linux/pm_runtime.h>
32 #include <linux/clk.h>
33 #include <linux/gpio/consumer.h>
34 #include <linux/regulator/consumer.h>
35 #include <linux/io.h>
36 #include <linux/of_address.h>
37 #include <linux/of_device.h>
38 #include <linux/hdmi.h>
39 #include <linux/component.h>
40 #include <linux/mfd/syscon.h>
41 #include <linux/regmap.h>
42 
43 #include <drm/exynos_drm.h>
44 
45 #include "exynos_drm_drv.h"
46 #include "exynos_drm_crtc.h"
47 
48 #define HOTPLUG_DEBOUNCE_MS		1100
49 
50 /* AVI header and aspect ratio */
51 #define HDMI_AVI_VERSION		0x02
52 #define HDMI_AVI_LENGTH		0x0D
53 
54 /* AUI header info */
55 #define HDMI_AUI_VERSION	0x01
56 #define HDMI_AUI_LENGTH	0x0A
57 #define AVI_SAME_AS_PIC_ASPECT_RATIO 0x8
58 #define AVI_4_3_CENTER_RATIO	0x9
59 #define AVI_16_9_CENTER_RATIO	0xa
60 
61 enum hdmi_type {
62 	HDMI_TYPE13,
63 	HDMI_TYPE14,
64 	HDMI_TYPE_COUNT
65 };
66 
67 #define HDMI_MAPPED_BASE 0xffff0000
68 
69 enum hdmi_mapped_regs {
70 	HDMI_PHY_STATUS = HDMI_MAPPED_BASE,
71 	HDMI_PHY_RSTOUT,
72 	HDMI_ACR_CON,
73 	HDMI_ACR_MCTS0,
74 	HDMI_ACR_CTS0,
75 	HDMI_ACR_N0
76 };
77 
78 static const u32 hdmi_reg_map[][HDMI_TYPE_COUNT] = {
79 	{ HDMI_V13_PHY_STATUS, HDMI_PHY_STATUS_0 },
80 	{ HDMI_V13_PHY_RSTOUT, HDMI_V14_PHY_RSTOUT },
81 	{ HDMI_V13_ACR_CON, HDMI_V14_ACR_CON },
82 	{ HDMI_V13_ACR_MCTS0, HDMI_V14_ACR_MCTS0 },
83 	{ HDMI_V13_ACR_CTS0, HDMI_V14_ACR_CTS0 },
84 	{ HDMI_V13_ACR_N0, HDMI_V14_ACR_N0 },
85 };
86 
87 static const char * const supply[] = {
88 	"vdd",
89 	"vdd_osc",
90 	"vdd_pll",
91 };
92 
93 struct hdmi_driver_data {
94 	unsigned int type;
95 	const struct hdmiphy_config *phy_confs;
96 	unsigned int phy_conf_count;
97 	unsigned int is_apb_phy:1;
98 };
99 
100 struct hdmi_context {
101 	struct drm_encoder		encoder;
102 	struct device			*dev;
103 	struct drm_device		*drm_dev;
104 	struct drm_connector		connector;
105 	bool				powered;
106 	bool				dvi_mode;
107 	struct delayed_work		hotplug_work;
108 	struct drm_display_mode		current_mode;
109 	u8				cea_video_id;
110 	const struct hdmi_driver_data	*drv_data;
111 
112 	void __iomem			*regs;
113 	void __iomem			*regs_hdmiphy;
114 	struct i2c_client		*hdmiphy_port;
115 	struct i2c_adapter		*ddc_adpt;
116 	struct gpio_desc		*hpd_gpio;
117 	int				irq;
118 	struct regmap			*pmureg;
119 	struct clk			*hdmi;
120 	struct clk			*sclk_hdmi;
121 	struct clk			*sclk_pixel;
122 	struct clk			*sclk_hdmiphy;
123 	struct clk			*mout_hdmi;
124 	struct regulator_bulk_data	regul_bulk[ARRAY_SIZE(supply)];
125 	struct regulator		*reg_hdmi_en;
126 };
127 
128 static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e)
129 {
130 	return container_of(e, struct hdmi_context, encoder);
131 }
132 
133 static inline struct hdmi_context *connector_to_hdmi(struct drm_connector *c)
134 {
135 	return container_of(c, struct hdmi_context, connector);
136 }
137 
138 struct hdmiphy_config {
139 	int pixel_clock;
140 	u8 conf[32];
141 };
142 
143 /* list of phy config settings */
144 static const struct hdmiphy_config hdmiphy_v13_configs[] = {
145 	{
146 		.pixel_clock = 27000000,
147 		.conf = {
148 			0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
149 			0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
150 			0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
151 			0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x80,
152 		},
153 	},
154 	{
155 		.pixel_clock = 27027000,
156 		.conf = {
157 			0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
158 			0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
159 			0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
160 			0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x80,
161 		},
162 	},
163 	{
164 		.pixel_clock = 74176000,
165 		.conf = {
166 			0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
167 			0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
168 			0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
169 			0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x80,
170 		},
171 	},
172 	{
173 		.pixel_clock = 74250000,
174 		.conf = {
175 			0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
176 			0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
177 			0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
178 			0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x80,
179 		},
180 	},
181 	{
182 		.pixel_clock = 148500000,
183 		.conf = {
184 			0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
185 			0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
186 			0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
187 			0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x80,
188 		},
189 	},
190 };
191 
192 static const struct hdmiphy_config hdmiphy_v14_configs[] = {
193 	{
194 		.pixel_clock = 25200000,
195 		.conf = {
196 			0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
197 			0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
198 			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
199 			0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
200 		},
201 	},
202 	{
203 		.pixel_clock = 27000000,
204 		.conf = {
205 			0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
206 			0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
207 			0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
208 			0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
209 		},
210 	},
211 	{
212 		.pixel_clock = 27027000,
213 		.conf = {
214 			0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
215 			0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
216 			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
217 			0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
218 		},
219 	},
220 	{
221 		.pixel_clock = 36000000,
222 		.conf = {
223 			0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
224 			0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
225 			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
226 			0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
227 		},
228 	},
229 	{
230 		.pixel_clock = 40000000,
231 		.conf = {
232 			0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
233 			0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
234 			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
235 			0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
236 		},
237 	},
238 	{
239 		.pixel_clock = 65000000,
240 		.conf = {
241 			0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
242 			0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
243 			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
244 			0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
245 		},
246 	},
247 	{
248 		.pixel_clock = 71000000,
249 		.conf = {
250 			0x01, 0xd1, 0x3b, 0x35, 0x40, 0x0c, 0x04, 0x08,
251 			0x85, 0xa0, 0x63, 0xd9, 0x45, 0xa0, 0xac, 0x80,
252 			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
253 			0x54, 0xad, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
254 		},
255 	},
256 	{
257 		.pixel_clock = 73250000,
258 		.conf = {
259 			0x01, 0xd1, 0x3d, 0x35, 0x40, 0x18, 0x02, 0x08,
260 			0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
261 			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
262 			0x54, 0xa8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
263 		},
264 	},
265 	{
266 		.pixel_clock = 74176000,
267 		.conf = {
268 			0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
269 			0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
270 			0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
271 			0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
272 		},
273 	},
274 	{
275 		.pixel_clock = 74250000,
276 		.conf = {
277 			0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
278 			0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
279 			0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
280 			0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
281 		},
282 	},
283 	{
284 		.pixel_clock = 83500000,
285 		.conf = {
286 			0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
287 			0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
288 			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
289 			0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
290 		},
291 	},
292 	{
293 		.pixel_clock = 106500000,
294 		.conf = {
295 			0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
296 			0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
297 			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
298 			0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
299 		},
300 	},
301 	{
302 		.pixel_clock = 108000000,
303 		.conf = {
304 			0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
305 			0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
306 			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
307 			0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
308 		},
309 	},
310 	{
311 		.pixel_clock = 115500000,
312 		.conf = {
313 			0x01, 0xd1, 0x30, 0x12, 0x40, 0x40, 0x10, 0x08,
314 			0x80, 0x80, 0x21, 0xd9, 0x45, 0xa0, 0xac, 0x80,
315 			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
316 			0x54, 0xaa, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
317 		},
318 	},
319 	{
320 		.pixel_clock = 119000000,
321 		.conf = {
322 			0x01, 0xd1, 0x32, 0x1a, 0x40, 0x30, 0xd8, 0x08,
323 			0x04, 0xa0, 0x2a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
324 			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
325 			0x54, 0x9d, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
326 		},
327 	},
328 	{
329 		.pixel_clock = 146250000,
330 		.conf = {
331 			0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
332 			0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
333 			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
334 			0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
335 		},
336 	},
337 	{
338 		.pixel_clock = 148500000,
339 		.conf = {
340 			0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
341 			0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
342 			0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
343 			0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
344 		},
345 	},
346 };
347 
348 static const struct hdmiphy_config hdmiphy_5420_configs[] = {
349 	{
350 		.pixel_clock = 25200000,
351 		.conf = {
352 			0x01, 0x52, 0x3F, 0x55, 0x40, 0x01, 0x00, 0xC8,
353 			0x82, 0xC8, 0xBD, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
354 			0x06, 0x80, 0x01, 0x84, 0x05, 0x02, 0x24, 0x66,
355 			0x54, 0xF4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
356 		},
357 	},
358 	{
359 		.pixel_clock = 27000000,
360 		.conf = {
361 			0x01, 0xD1, 0x22, 0x51, 0x40, 0x08, 0xFC, 0xE0,
362 			0x98, 0xE8, 0xCB, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
363 			0x06, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
364 			0x54, 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
365 		},
366 	},
367 	{
368 		.pixel_clock = 27027000,
369 		.conf = {
370 			0x01, 0xD1, 0x2D, 0x72, 0x40, 0x64, 0x12, 0xC8,
371 			0x43, 0xE8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
372 			0x26, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
373 			0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
374 		},
375 	},
376 	{
377 		.pixel_clock = 36000000,
378 		.conf = {
379 			0x01, 0x51, 0x2D, 0x55, 0x40, 0x40, 0x00, 0xC8,
380 			0x02, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
381 			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
382 			0x54, 0xAB, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
383 		},
384 	},
385 	{
386 		.pixel_clock = 40000000,
387 		.conf = {
388 			0x01, 0xD1, 0x21, 0x31, 0x40, 0x3C, 0x28, 0xC8,
389 			0x87, 0xE8, 0xC8, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
390 			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
391 			0x54, 0x9A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
392 		},
393 	},
394 	{
395 		.pixel_clock = 65000000,
396 		.conf = {
397 			0x01, 0xD1, 0x36, 0x34, 0x40, 0x0C, 0x04, 0xC8,
398 			0x82, 0xE8, 0x45, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
399 			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
400 			0x54, 0xBD, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
401 		},
402 	},
403 	{
404 		.pixel_clock = 71000000,
405 		.conf = {
406 			0x01, 0xD1, 0x3B, 0x35, 0x40, 0x0C, 0x04, 0xC8,
407 			0x85, 0xE8, 0x63, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
408 			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
409 			0x54, 0x57, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
410 		},
411 	},
412 	{
413 		.pixel_clock = 73250000,
414 		.conf = {
415 			0x01, 0xD1, 0x1F, 0x10, 0x40, 0x78, 0x8D, 0xC8,
416 			0x81, 0xE8, 0xB7, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
417 			0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
418 			0x54, 0xA8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
419 		},
420 	},
421 	{
422 		.pixel_clock = 74176000,
423 		.conf = {
424 			0x01, 0xD1, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0xC8,
425 			0x81, 0xE8, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
426 			0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
427 			0x54, 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
428 		},
429 	},
430 	{
431 		.pixel_clock = 74250000,
432 		.conf = {
433 			0x01, 0xD1, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0x08,
434 			0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
435 			0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
436 			0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
437 		},
438 	},
439 	{
440 		.pixel_clock = 83500000,
441 		.conf = {
442 			0x01, 0xD1, 0x23, 0x11, 0x40, 0x0C, 0xFB, 0xC8,
443 			0x85, 0xE8, 0xD1, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
444 			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
445 			0x54, 0x4A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
446 		},
447 	},
448 	{
449 		.pixel_clock = 88750000,
450 		.conf = {
451 			0x01, 0xD1, 0x25, 0x11, 0x40, 0x18, 0xFF, 0xC8,
452 			0x83, 0xE8, 0xDE, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
453 			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
454 			0x54, 0x45, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
455 		},
456 	},
457 	{
458 		.pixel_clock = 106500000,
459 		.conf = {
460 			0x01, 0xD1, 0x2C, 0x12, 0x40, 0x0C, 0x09, 0xC8,
461 			0x84, 0xE8, 0x0A, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
462 			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
463 			0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
464 		},
465 	},
466 	{
467 		.pixel_clock = 108000000,
468 		.conf = {
469 			0x01, 0x51, 0x2D, 0x15, 0x40, 0x01, 0x00, 0xC8,
470 			0x82, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
471 			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
472 			0x54, 0xC7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
473 		},
474 	},
475 	{
476 		.pixel_clock = 115500000,
477 		.conf = {
478 			0x01, 0xD1, 0x30, 0x14, 0x40, 0x0C, 0x03, 0xC8,
479 			0x88, 0xE8, 0x21, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
480 			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
481 			0x54, 0x6A, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
482 		},
483 	},
484 	{
485 		.pixel_clock = 146250000,
486 		.conf = {
487 			0x01, 0xD1, 0x3D, 0x15, 0x40, 0x18, 0xFD, 0xC8,
488 			0x83, 0xE8, 0x6E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
489 			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
490 			0x54, 0x54, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
491 		},
492 	},
493 	{
494 		.pixel_clock = 148500000,
495 		.conf = {
496 			0x01, 0xD1, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0x08,
497 			0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
498 			0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
499 			0x54, 0x4B, 0x25, 0x03, 0x00, 0x80, 0x01, 0x80,
500 		},
501 	},
502 };
503 
504 static struct hdmi_driver_data exynos5420_hdmi_driver_data = {
505 	.type		= HDMI_TYPE14,
506 	.phy_confs	= hdmiphy_5420_configs,
507 	.phy_conf_count	= ARRAY_SIZE(hdmiphy_5420_configs),
508 	.is_apb_phy	= 1,
509 };
510 
511 static struct hdmi_driver_data exynos4212_hdmi_driver_data = {
512 	.type		= HDMI_TYPE14,
513 	.phy_confs	= hdmiphy_v14_configs,
514 	.phy_conf_count	= ARRAY_SIZE(hdmiphy_v14_configs),
515 	.is_apb_phy	= 0,
516 };
517 
518 static struct hdmi_driver_data exynos4210_hdmi_driver_data = {
519 	.type		= HDMI_TYPE13,
520 	.phy_confs	= hdmiphy_v13_configs,
521 	.phy_conf_count	= ARRAY_SIZE(hdmiphy_v13_configs),
522 	.is_apb_phy	= 0,
523 };
524 
525 static inline u32 hdmi_map_reg(struct hdmi_context *hdata, u32 reg_id)
526 {
527 	if ((reg_id & 0xffff0000) == HDMI_MAPPED_BASE)
528 		return hdmi_reg_map[reg_id & 0xffff][hdata->drv_data->type];
529 	return reg_id;
530 }
531 
532 static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
533 {
534 	return readl(hdata->regs + hdmi_map_reg(hdata, reg_id));
535 }
536 
537 static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
538 				 u32 reg_id, u8 value)
539 {
540 	writel(value, hdata->regs + hdmi_map_reg(hdata, reg_id));
541 }
542 
543 static inline void hdmi_reg_writev(struct hdmi_context *hdata, u32 reg_id,
544 				   int bytes, u32 val)
545 {
546 	reg_id = hdmi_map_reg(hdata, reg_id);
547 
548 	while (--bytes >= 0) {
549 		writel(val & 0xff, hdata->regs + reg_id);
550 		val >>= 8;
551 		reg_id += 4;
552 	}
553 }
554 
555 static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
556 				 u32 reg_id, u32 value, u32 mask)
557 {
558 	u32 old;
559 
560 	reg_id = hdmi_map_reg(hdata, reg_id);
561 	old = readl(hdata->regs + reg_id);
562 	value = (value & mask) | (old & ~mask);
563 	writel(value, hdata->regs + reg_id);
564 }
565 
566 static int hdmiphy_reg_write_buf(struct hdmi_context *hdata,
567 			u32 reg_offset, const u8 *buf, u32 len)
568 {
569 	if ((reg_offset + len) > 32)
570 		return -EINVAL;
571 
572 	if (hdata->hdmiphy_port) {
573 		int ret;
574 
575 		ret = i2c_master_send(hdata->hdmiphy_port, buf, len);
576 		if (ret == len)
577 			return 0;
578 		return ret;
579 	} else {
580 		int i;
581 		for (i = 0; i < len; i++)
582 			writel(buf[i], hdata->regs_hdmiphy +
583 				((reg_offset + i)<<2));
584 		return 0;
585 	}
586 }
587 
588 static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix)
589 {
590 #define DUMPREG(reg_id) \
591 	DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
592 	readl(hdata->regs + reg_id))
593 	DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
594 	DUMPREG(HDMI_INTC_FLAG);
595 	DUMPREG(HDMI_INTC_CON);
596 	DUMPREG(HDMI_HPD_STATUS);
597 	DUMPREG(HDMI_V13_PHY_RSTOUT);
598 	DUMPREG(HDMI_V13_PHY_VPLL);
599 	DUMPREG(HDMI_V13_PHY_CMU);
600 	DUMPREG(HDMI_V13_CORE_RSTOUT);
601 
602 	DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
603 	DUMPREG(HDMI_CON_0);
604 	DUMPREG(HDMI_CON_1);
605 	DUMPREG(HDMI_CON_2);
606 	DUMPREG(HDMI_SYS_STATUS);
607 	DUMPREG(HDMI_V13_PHY_STATUS);
608 	DUMPREG(HDMI_STATUS_EN);
609 	DUMPREG(HDMI_HPD);
610 	DUMPREG(HDMI_MODE_SEL);
611 	DUMPREG(HDMI_V13_HPD_GEN);
612 	DUMPREG(HDMI_V13_DC_CONTROL);
613 	DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN);
614 
615 	DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
616 	DUMPREG(HDMI_H_BLANK_0);
617 	DUMPREG(HDMI_H_BLANK_1);
618 	DUMPREG(HDMI_V13_V_BLANK_0);
619 	DUMPREG(HDMI_V13_V_BLANK_1);
620 	DUMPREG(HDMI_V13_V_BLANK_2);
621 	DUMPREG(HDMI_V13_H_V_LINE_0);
622 	DUMPREG(HDMI_V13_H_V_LINE_1);
623 	DUMPREG(HDMI_V13_H_V_LINE_2);
624 	DUMPREG(HDMI_VSYNC_POL);
625 	DUMPREG(HDMI_INT_PRO_MODE);
626 	DUMPREG(HDMI_V13_V_BLANK_F_0);
627 	DUMPREG(HDMI_V13_V_BLANK_F_1);
628 	DUMPREG(HDMI_V13_V_BLANK_F_2);
629 	DUMPREG(HDMI_V13_H_SYNC_GEN_0);
630 	DUMPREG(HDMI_V13_H_SYNC_GEN_1);
631 	DUMPREG(HDMI_V13_H_SYNC_GEN_2);
632 	DUMPREG(HDMI_V13_V_SYNC_GEN_1_0);
633 	DUMPREG(HDMI_V13_V_SYNC_GEN_1_1);
634 	DUMPREG(HDMI_V13_V_SYNC_GEN_1_2);
635 	DUMPREG(HDMI_V13_V_SYNC_GEN_2_0);
636 	DUMPREG(HDMI_V13_V_SYNC_GEN_2_1);
637 	DUMPREG(HDMI_V13_V_SYNC_GEN_2_2);
638 	DUMPREG(HDMI_V13_V_SYNC_GEN_3_0);
639 	DUMPREG(HDMI_V13_V_SYNC_GEN_3_1);
640 	DUMPREG(HDMI_V13_V_SYNC_GEN_3_2);
641 
642 	DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
643 	DUMPREG(HDMI_TG_CMD);
644 	DUMPREG(HDMI_TG_H_FSZ_L);
645 	DUMPREG(HDMI_TG_H_FSZ_H);
646 	DUMPREG(HDMI_TG_HACT_ST_L);
647 	DUMPREG(HDMI_TG_HACT_ST_H);
648 	DUMPREG(HDMI_TG_HACT_SZ_L);
649 	DUMPREG(HDMI_TG_HACT_SZ_H);
650 	DUMPREG(HDMI_TG_V_FSZ_L);
651 	DUMPREG(HDMI_TG_V_FSZ_H);
652 	DUMPREG(HDMI_TG_VSYNC_L);
653 	DUMPREG(HDMI_TG_VSYNC_H);
654 	DUMPREG(HDMI_TG_VSYNC2_L);
655 	DUMPREG(HDMI_TG_VSYNC2_H);
656 	DUMPREG(HDMI_TG_VACT_ST_L);
657 	DUMPREG(HDMI_TG_VACT_ST_H);
658 	DUMPREG(HDMI_TG_VACT_SZ_L);
659 	DUMPREG(HDMI_TG_VACT_SZ_H);
660 	DUMPREG(HDMI_TG_FIELD_CHG_L);
661 	DUMPREG(HDMI_TG_FIELD_CHG_H);
662 	DUMPREG(HDMI_TG_VACT_ST2_L);
663 	DUMPREG(HDMI_TG_VACT_ST2_H);
664 	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
665 	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
666 	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
667 	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
668 	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
669 	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
670 	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
671 	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
672 #undef DUMPREG
673 }
674 
675 static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix)
676 {
677 	int i;
678 
679 #define DUMPREG(reg_id) \
680 	DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
681 	readl(hdata->regs + reg_id))
682 
683 	DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
684 	DUMPREG(HDMI_INTC_CON);
685 	DUMPREG(HDMI_INTC_FLAG);
686 	DUMPREG(HDMI_HPD_STATUS);
687 	DUMPREG(HDMI_INTC_CON_1);
688 	DUMPREG(HDMI_INTC_FLAG_1);
689 	DUMPREG(HDMI_PHY_STATUS_0);
690 	DUMPREG(HDMI_PHY_STATUS_PLL);
691 	DUMPREG(HDMI_PHY_CON_0);
692 	DUMPREG(HDMI_V14_PHY_RSTOUT);
693 	DUMPREG(HDMI_PHY_VPLL);
694 	DUMPREG(HDMI_PHY_CMU);
695 	DUMPREG(HDMI_CORE_RSTOUT);
696 
697 	DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
698 	DUMPREG(HDMI_CON_0);
699 	DUMPREG(HDMI_CON_1);
700 	DUMPREG(HDMI_CON_2);
701 	DUMPREG(HDMI_SYS_STATUS);
702 	DUMPREG(HDMI_PHY_STATUS_0);
703 	DUMPREG(HDMI_STATUS_EN);
704 	DUMPREG(HDMI_HPD);
705 	DUMPREG(HDMI_MODE_SEL);
706 	DUMPREG(HDMI_ENC_EN);
707 	DUMPREG(HDMI_DC_CONTROL);
708 	DUMPREG(HDMI_VIDEO_PATTERN_GEN);
709 
710 	DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
711 	DUMPREG(HDMI_H_BLANK_0);
712 	DUMPREG(HDMI_H_BLANK_1);
713 	DUMPREG(HDMI_V2_BLANK_0);
714 	DUMPREG(HDMI_V2_BLANK_1);
715 	DUMPREG(HDMI_V1_BLANK_0);
716 	DUMPREG(HDMI_V1_BLANK_1);
717 	DUMPREG(HDMI_V_LINE_0);
718 	DUMPREG(HDMI_V_LINE_1);
719 	DUMPREG(HDMI_H_LINE_0);
720 	DUMPREG(HDMI_H_LINE_1);
721 	DUMPREG(HDMI_HSYNC_POL);
722 
723 	DUMPREG(HDMI_VSYNC_POL);
724 	DUMPREG(HDMI_INT_PRO_MODE);
725 	DUMPREG(HDMI_V_BLANK_F0_0);
726 	DUMPREG(HDMI_V_BLANK_F0_1);
727 	DUMPREG(HDMI_V_BLANK_F1_0);
728 	DUMPREG(HDMI_V_BLANK_F1_1);
729 
730 	DUMPREG(HDMI_H_SYNC_START_0);
731 	DUMPREG(HDMI_H_SYNC_START_1);
732 	DUMPREG(HDMI_H_SYNC_END_0);
733 	DUMPREG(HDMI_H_SYNC_END_1);
734 
735 	DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0);
736 	DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1);
737 	DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0);
738 	DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1);
739 
740 	DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0);
741 	DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1);
742 	DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0);
743 	DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1);
744 
745 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0);
746 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1);
747 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0);
748 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1);
749 
750 	DUMPREG(HDMI_V_BLANK_F2_0);
751 	DUMPREG(HDMI_V_BLANK_F2_1);
752 	DUMPREG(HDMI_V_BLANK_F3_0);
753 	DUMPREG(HDMI_V_BLANK_F3_1);
754 	DUMPREG(HDMI_V_BLANK_F4_0);
755 	DUMPREG(HDMI_V_BLANK_F4_1);
756 	DUMPREG(HDMI_V_BLANK_F5_0);
757 	DUMPREG(HDMI_V_BLANK_F5_1);
758 
759 	DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0);
760 	DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1);
761 	DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0);
762 	DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1);
763 	DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0);
764 	DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1);
765 	DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0);
766 	DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1);
767 
768 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0);
769 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1);
770 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0);
771 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1);
772 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0);
773 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1);
774 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0);
775 	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1);
776 
777 	DUMPREG(HDMI_VACT_SPACE_1_0);
778 	DUMPREG(HDMI_VACT_SPACE_1_1);
779 	DUMPREG(HDMI_VACT_SPACE_2_0);
780 	DUMPREG(HDMI_VACT_SPACE_2_1);
781 	DUMPREG(HDMI_VACT_SPACE_3_0);
782 	DUMPREG(HDMI_VACT_SPACE_3_1);
783 	DUMPREG(HDMI_VACT_SPACE_4_0);
784 	DUMPREG(HDMI_VACT_SPACE_4_1);
785 	DUMPREG(HDMI_VACT_SPACE_5_0);
786 	DUMPREG(HDMI_VACT_SPACE_5_1);
787 	DUMPREG(HDMI_VACT_SPACE_6_0);
788 	DUMPREG(HDMI_VACT_SPACE_6_1);
789 
790 	DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
791 	DUMPREG(HDMI_TG_CMD);
792 	DUMPREG(HDMI_TG_H_FSZ_L);
793 	DUMPREG(HDMI_TG_H_FSZ_H);
794 	DUMPREG(HDMI_TG_HACT_ST_L);
795 	DUMPREG(HDMI_TG_HACT_ST_H);
796 	DUMPREG(HDMI_TG_HACT_SZ_L);
797 	DUMPREG(HDMI_TG_HACT_SZ_H);
798 	DUMPREG(HDMI_TG_V_FSZ_L);
799 	DUMPREG(HDMI_TG_V_FSZ_H);
800 	DUMPREG(HDMI_TG_VSYNC_L);
801 	DUMPREG(HDMI_TG_VSYNC_H);
802 	DUMPREG(HDMI_TG_VSYNC2_L);
803 	DUMPREG(HDMI_TG_VSYNC2_H);
804 	DUMPREG(HDMI_TG_VACT_ST_L);
805 	DUMPREG(HDMI_TG_VACT_ST_H);
806 	DUMPREG(HDMI_TG_VACT_SZ_L);
807 	DUMPREG(HDMI_TG_VACT_SZ_H);
808 	DUMPREG(HDMI_TG_FIELD_CHG_L);
809 	DUMPREG(HDMI_TG_FIELD_CHG_H);
810 	DUMPREG(HDMI_TG_VACT_ST2_L);
811 	DUMPREG(HDMI_TG_VACT_ST2_H);
812 	DUMPREG(HDMI_TG_VACT_ST3_L);
813 	DUMPREG(HDMI_TG_VACT_ST3_H);
814 	DUMPREG(HDMI_TG_VACT_ST4_L);
815 	DUMPREG(HDMI_TG_VACT_ST4_H);
816 	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
817 	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
818 	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
819 	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
820 	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
821 	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
822 	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
823 	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
824 	DUMPREG(HDMI_TG_3D);
825 
826 	DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix);
827 	DUMPREG(HDMI_AVI_CON);
828 	DUMPREG(HDMI_AVI_HEADER0);
829 	DUMPREG(HDMI_AVI_HEADER1);
830 	DUMPREG(HDMI_AVI_HEADER2);
831 	DUMPREG(HDMI_AVI_CHECK_SUM);
832 	DUMPREG(HDMI_VSI_CON);
833 	DUMPREG(HDMI_VSI_HEADER0);
834 	DUMPREG(HDMI_VSI_HEADER1);
835 	DUMPREG(HDMI_VSI_HEADER2);
836 	for (i = 0; i < 7; ++i)
837 		DUMPREG(HDMI_VSI_DATA(i));
838 
839 #undef DUMPREG
840 }
841 
842 static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
843 {
844 	if (hdata->drv_data->type == HDMI_TYPE13)
845 		hdmi_v13_regs_dump(hdata, prefix);
846 	else
847 		hdmi_v14_regs_dump(hdata, prefix);
848 }
849 
850 static u8 hdmi_chksum(struct hdmi_context *hdata,
851 			u32 start, u8 len, u32 hdr_sum)
852 {
853 	int i;
854 
855 	/* hdr_sum : header0 + header1 + header2
856 	* start : start address of packet byte1
857 	* len : packet bytes - 1 */
858 	for (i = 0; i < len; ++i)
859 		hdr_sum += 0xff & hdmi_reg_read(hdata, start + i * 4);
860 
861 	/* return 2's complement of 8 bit hdr_sum */
862 	return (u8)(~(hdr_sum & 0xff) + 1);
863 }
864 
865 static void hdmi_reg_infoframe(struct hdmi_context *hdata,
866 			union hdmi_infoframe *infoframe)
867 {
868 	u32 hdr_sum;
869 	u8 chksum;
870 	u8 ar;
871 
872 	if (hdata->dvi_mode) {
873 		hdmi_reg_writeb(hdata, HDMI_VSI_CON,
874 				HDMI_VSI_CON_DO_NOT_TRANSMIT);
875 		hdmi_reg_writeb(hdata, HDMI_AVI_CON,
876 				HDMI_AVI_CON_DO_NOT_TRANSMIT);
877 		hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_NO_TRAN);
878 		return;
879 	}
880 
881 	switch (infoframe->any.type) {
882 	case HDMI_INFOFRAME_TYPE_AVI:
883 		hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC);
884 		hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->any.type);
885 		hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1,
886 				infoframe->any.version);
887 		hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->any.length);
888 		hdr_sum = infoframe->any.type + infoframe->any.version +
889 			  infoframe->any.length;
890 
891 		/* Output format zero hardcoded ,RGB YBCR selection */
892 		hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 |
893 			AVI_ACTIVE_FORMAT_VALID |
894 			AVI_UNDERSCANNED_DISPLAY_VALID);
895 
896 		/*
897 		 * Set the aspect ratio as per the mode, mentioned in
898 		 * Table 9 AVI InfoFrame Data Byte 2 of CEA-861-D Standard
899 		 */
900 		ar = hdata->current_mode.picture_aspect_ratio;
901 		switch (ar) {
902 		case HDMI_PICTURE_ASPECT_4_3:
903 			ar |= AVI_4_3_CENTER_RATIO;
904 			break;
905 		case HDMI_PICTURE_ASPECT_16_9:
906 			ar |= AVI_16_9_CENTER_RATIO;
907 			break;
908 		case HDMI_PICTURE_ASPECT_NONE:
909 		default:
910 			ar |= AVI_SAME_AS_PIC_ASPECT_RATIO;
911 			break;
912 		}
913 		hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2), ar);
914 
915 		hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), hdata->cea_video_id);
916 
917 		chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1),
918 					infoframe->any.length, hdr_sum);
919 		DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum);
920 		hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum);
921 		break;
922 	case HDMI_INFOFRAME_TYPE_AUDIO:
923 		hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02);
924 		hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->any.type);
925 		hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1,
926 				infoframe->any.version);
927 		hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->any.length);
928 		hdr_sum = infoframe->any.type + infoframe->any.version +
929 			  infoframe->any.length;
930 		chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1),
931 					infoframe->any.length, hdr_sum);
932 		DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum);
933 		hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum);
934 		break;
935 	default:
936 		break;
937 	}
938 }
939 
940 static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
941 				bool force)
942 {
943 	struct hdmi_context *hdata = connector_to_hdmi(connector);
944 
945 	if (gpiod_get_value(hdata->hpd_gpio))
946 		return connector_status_connected;
947 
948 	return connector_status_disconnected;
949 }
950 
951 static void hdmi_connector_destroy(struct drm_connector *connector)
952 {
953 	drm_connector_unregister(connector);
954 	drm_connector_cleanup(connector);
955 }
956 
957 static const struct drm_connector_funcs hdmi_connector_funcs = {
958 	.dpms = drm_atomic_helper_connector_dpms,
959 	.fill_modes = drm_helper_probe_single_connector_modes,
960 	.detect = hdmi_detect,
961 	.destroy = hdmi_connector_destroy,
962 	.reset = drm_atomic_helper_connector_reset,
963 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
964 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
965 };
966 
967 static int hdmi_get_modes(struct drm_connector *connector)
968 {
969 	struct hdmi_context *hdata = connector_to_hdmi(connector);
970 	struct edid *edid;
971 	int ret;
972 
973 	if (!hdata->ddc_adpt)
974 		return -ENODEV;
975 
976 	edid = drm_get_edid(connector, hdata->ddc_adpt);
977 	if (!edid)
978 		return -ENODEV;
979 
980 	hdata->dvi_mode = !drm_detect_hdmi_monitor(edid);
981 	DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
982 		(hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
983 		edid->width_cm, edid->height_cm);
984 
985 	drm_mode_connector_update_edid_property(connector, edid);
986 
987 	ret = drm_add_edid_modes(connector, edid);
988 
989 	kfree(edid);
990 
991 	return ret;
992 }
993 
994 static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
995 {
996 	int i;
997 
998 	for (i = 0; i < hdata->drv_data->phy_conf_count; i++)
999 		if (hdata->drv_data->phy_confs[i].pixel_clock == pixel_clock)
1000 			return i;
1001 
1002 	DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
1003 	return -EINVAL;
1004 }
1005 
1006 static int hdmi_mode_valid(struct drm_connector *connector,
1007 			struct drm_display_mode *mode)
1008 {
1009 	struct hdmi_context *hdata = connector_to_hdmi(connector);
1010 	int ret;
1011 
1012 	DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
1013 		mode->hdisplay, mode->vdisplay, mode->vrefresh,
1014 		(mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
1015 		false, mode->clock * 1000);
1016 
1017 	ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
1018 	if (ret < 0)
1019 		return MODE_BAD;
1020 
1021 	return MODE_OK;
1022 }
1023 
1024 static struct drm_encoder *hdmi_best_encoder(struct drm_connector *connector)
1025 {
1026 	struct hdmi_context *hdata = connector_to_hdmi(connector);
1027 
1028 	return &hdata->encoder;
1029 }
1030 
1031 static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
1032 	.get_modes = hdmi_get_modes,
1033 	.mode_valid = hdmi_mode_valid,
1034 	.best_encoder = hdmi_best_encoder,
1035 };
1036 
1037 static int hdmi_create_connector(struct drm_encoder *encoder)
1038 {
1039 	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1040 	struct drm_connector *connector = &hdata->connector;
1041 	int ret;
1042 
1043 	connector->interlace_allowed = true;
1044 	connector->polled = DRM_CONNECTOR_POLL_HPD;
1045 
1046 	ret = drm_connector_init(hdata->drm_dev, connector,
1047 			&hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA);
1048 	if (ret) {
1049 		DRM_ERROR("Failed to initialize connector with drm\n");
1050 		return ret;
1051 	}
1052 
1053 	drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
1054 	drm_connector_register(connector);
1055 	drm_mode_connector_attach_encoder(connector, encoder);
1056 
1057 	return 0;
1058 }
1059 
1060 static bool hdmi_mode_fixup(struct drm_encoder *encoder,
1061 			    const struct drm_display_mode *mode,
1062 			    struct drm_display_mode *adjusted_mode)
1063 {
1064 	struct drm_device *dev = encoder->dev;
1065 	struct drm_connector *connector;
1066 	struct drm_display_mode *m;
1067 	int mode_ok;
1068 
1069 	drm_mode_set_crtcinfo(adjusted_mode, 0);
1070 
1071 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1072 		if (connector->encoder == encoder)
1073 			break;
1074 	}
1075 
1076 	if (connector->encoder != encoder)
1077 		return true;
1078 
1079 	mode_ok = hdmi_mode_valid(connector, adjusted_mode);
1080 
1081 	/* just return if user desired mode exists. */
1082 	if (mode_ok == MODE_OK)
1083 		return true;
1084 
1085 	/*
1086 	 * otherwise, find the most suitable mode among modes and change it
1087 	 * to adjusted_mode.
1088 	 */
1089 	list_for_each_entry(m, &connector->modes, head) {
1090 		mode_ok = hdmi_mode_valid(connector, m);
1091 
1092 		if (mode_ok == MODE_OK) {
1093 			DRM_INFO("desired mode doesn't exist so\n");
1094 			DRM_INFO("use the most suitable mode among modes.\n");
1095 
1096 			DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n",
1097 				m->hdisplay, m->vdisplay, m->vrefresh);
1098 
1099 			drm_mode_copy(adjusted_mode, m);
1100 			break;
1101 		}
1102 	}
1103 
1104 	return true;
1105 }
1106 
1107 static void hdmi_reg_acr(struct hdmi_context *hdata, u32 freq)
1108 {
1109 	u32 n, cts;
1110 
1111 	cts = (freq % 9) ? 27000 : 30000;
1112 	n = 128 * freq / (27000000 / cts);
1113 
1114 	hdmi_reg_writev(hdata, HDMI_ACR_N0, 3, n);
1115 	hdmi_reg_writev(hdata, HDMI_ACR_MCTS0, 3, cts);
1116 	hdmi_reg_writev(hdata, HDMI_ACR_CTS0, 3, cts);
1117 	hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1118 }
1119 
1120 static void hdmi_audio_init(struct hdmi_context *hdata)
1121 {
1122 	u32 sample_rate, bits_per_sample;
1123 	u32 data_num, bit_ch, sample_frq;
1124 	u32 val;
1125 
1126 	sample_rate = 44100;
1127 	bits_per_sample = 16;
1128 
1129 	switch (bits_per_sample) {
1130 	case 20:
1131 		data_num = 2;
1132 		bit_ch  = 1;
1133 		break;
1134 	case 24:
1135 		data_num = 3;
1136 		bit_ch  = 1;
1137 		break;
1138 	default:
1139 		data_num = 1;
1140 		bit_ch  = 0;
1141 		break;
1142 	}
1143 
1144 	hdmi_reg_acr(hdata, sample_rate);
1145 
1146 	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1147 				| HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1148 				| HDMI_I2S_MUX_ENABLE);
1149 
1150 	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1151 			| HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1152 
1153 	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1154 
1155 	sample_frq = (sample_rate == 44100) ? 0 :
1156 			(sample_rate == 48000) ? 2 :
1157 			(sample_rate == 32000) ? 3 :
1158 			(sample_rate == 96000) ? 0xa : 0x0;
1159 
1160 	hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1161 	hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1162 
1163 	val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1164 	hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1165 
1166 	/* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1167 	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1168 			| HDMI_I2S_SEL_LRCK(6));
1169 	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1170 			| HDMI_I2S_SEL_SDATA2(4));
1171 	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1172 			| HDMI_I2S_SEL_SDATA2(2));
1173 	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1174 
1175 	/* I2S_CON_1 & 2 */
1176 	hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1177 			| HDMI_I2S_L_CH_LOW_POL);
1178 	hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1179 			| HDMI_I2S_SET_BIT_CH(bit_ch)
1180 			| HDMI_I2S_SET_SDATA_BIT(data_num)
1181 			| HDMI_I2S_BASIC_FORMAT);
1182 
1183 	/* Configure register related to CUV information */
1184 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
1185 			| HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1186 			| HDMI_I2S_COPYRIGHT
1187 			| HDMI_I2S_LINEAR_PCM
1188 			| HDMI_I2S_CONSUMER_FORMAT);
1189 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1190 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1191 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1192 			| HDMI_I2S_SET_SMP_FREQ(sample_frq));
1193 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1194 			HDMI_I2S_ORG_SMP_FREQ_44_1
1195 			| HDMI_I2S_WORD_LEN_MAX24_24BITS
1196 			| HDMI_I2S_WORD_LEN_MAX_24BITS);
1197 
1198 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1199 }
1200 
1201 static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1202 {
1203 	if (hdata->dvi_mode)
1204 		return;
1205 
1206 	hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
1207 	hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ?
1208 			HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1209 }
1210 
1211 static void hdmi_start(struct hdmi_context *hdata, bool start)
1212 {
1213 	u32 val = start ? HDMI_TG_EN : 0;
1214 
1215 	if (hdata->current_mode.flags & DRM_MODE_FLAG_INTERLACE)
1216 		val |= HDMI_FIELD_EN;
1217 
1218 	hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN);
1219 	hdmi_reg_writemask(hdata, HDMI_TG_CMD, val, HDMI_TG_EN | HDMI_FIELD_EN);
1220 }
1221 
1222 static void hdmi_conf_init(struct hdmi_context *hdata)
1223 {
1224 	union hdmi_infoframe infoframe;
1225 
1226 	/* disable HPD interrupts from HDMI IP block, use GPIO instead */
1227 	hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1228 		HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1229 
1230 	/* choose HDMI mode */
1231 	hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1232 		HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1233 	/* Apply Video preable and Guard band in HDMI mode only */
1234 	hdmi_reg_writeb(hdata, HDMI_CON_2, 0);
1235 	/* disable bluescreen */
1236 	hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1237 
1238 	if (hdata->dvi_mode) {
1239 		/* choose DVI mode */
1240 		hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1241 				HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1242 		hdmi_reg_writeb(hdata, HDMI_CON_2,
1243 				HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1244 	}
1245 
1246 	if (hdata->drv_data->type == HDMI_TYPE13) {
1247 		/* choose bluescreen (fecal) color */
1248 		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1249 		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1250 		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1251 
1252 		/* enable AVI packet every vsync, fixes purple line problem */
1253 		hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1254 		/* force RGB, look to CEA-861-D, table 7 for more detail */
1255 		hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1256 		hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1257 
1258 		hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1259 		hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1260 		hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1261 	} else {
1262 		infoframe.any.type = HDMI_INFOFRAME_TYPE_AVI;
1263 		infoframe.any.version = HDMI_AVI_VERSION;
1264 		infoframe.any.length = HDMI_AVI_LENGTH;
1265 		hdmi_reg_infoframe(hdata, &infoframe);
1266 
1267 		infoframe.any.type = HDMI_INFOFRAME_TYPE_AUDIO;
1268 		infoframe.any.version = HDMI_AUI_VERSION;
1269 		infoframe.any.length = HDMI_AUI_LENGTH;
1270 		hdmi_reg_infoframe(hdata, &infoframe);
1271 
1272 		/* enable AVI packet every vsync, fixes purple line problem */
1273 		hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1274 	}
1275 }
1276 
1277 static void hdmiphy_wait_for_pll(struct hdmi_context *hdata)
1278 {
1279 	int tries;
1280 
1281 	for (tries = 0; tries < 10; ++tries) {
1282 		u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS);
1283 
1284 		if (val & HDMI_PHY_STATUS_READY) {
1285 			DRM_DEBUG_KMS("PLL stabilized after %d tries\n", tries);
1286 			return;
1287 		}
1288 		usleep_range(10, 20);
1289 	}
1290 
1291 	DRM_ERROR("PLL could not reach steady state\n");
1292 }
1293 
1294 static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1295 {
1296 	struct drm_display_mode *m = &hdata->current_mode;
1297 	unsigned int val;
1298 
1299 	hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1300 	hdmi_reg_writev(hdata, HDMI_V13_H_V_LINE_0, 3,
1301 			(m->htotal << 12) | m->vtotal);
1302 
1303 	val = (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
1304 	hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1, val);
1305 
1306 	val = (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0;
1307 	hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1, val);
1308 
1309 	val = (m->hsync_start - m->hdisplay - 2);
1310 	val |= ((m->hsync_end - m->hdisplay - 2) << 10);
1311 	val |= ((m->flags & DRM_MODE_FLAG_NHSYNC)  ? 1 : 0)<<20;
1312 	hdmi_reg_writev(hdata, HDMI_V13_H_SYNC_GEN_0, 3, val);
1313 
1314 	/*
1315 	 * Quirk requirement for exynos HDMI IP design,
1316 	 * 2 pixels less than the actual calculation for hsync_start
1317 	 * and end.
1318 	 */
1319 
1320 	/* Following values & calculations differ for different type of modes */
1321 	if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1322 		/* Interlaced Mode */
1323 		val = ((m->vsync_end - m->vdisplay) / 2);
1324 		val |= ((m->vsync_start - m->vdisplay) / 2) << 12;
1325 		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1326 
1327 		val = m->vtotal / 2;
1328 		val |= ((m->vtotal - m->vdisplay) / 2) << 11;
1329 		hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1330 
1331 		val = (m->vtotal +
1332 			((m->vsync_end - m->vsync_start) * 4) + 5) / 2;
1333 		val |= m->vtotal << 11;
1334 		hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, val);
1335 
1336 		val = ((m->vtotal / 2) + 7);
1337 		val |= ((m->vtotal / 2) + 2) << 12;
1338 		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, val);
1339 
1340 		val = ((m->htotal / 2) + (m->hsync_start - m->hdisplay));
1341 		val |= ((m->htotal / 2) +
1342 			(m->hsync_start - m->hdisplay)) << 12;
1343 		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, val);
1344 
1345 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1346 				(m->vtotal - m->vdisplay) / 2);
1347 		hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1348 
1349 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x249);
1350 	} else {
1351 		/* Progressive Mode */
1352 
1353 		val = m->vtotal;
1354 		val |= (m->vtotal - m->vdisplay) << 11;
1355 		hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1356 
1357 		hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, 0);
1358 
1359 		val = (m->vsync_end - m->vdisplay);
1360 		val |= ((m->vsync_start - m->vdisplay) << 12);
1361 		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1362 
1363 		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, 0x1001);
1364 		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, 0x1001);
1365 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1366 				m->vtotal - m->vdisplay);
1367 		hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1368 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x248);
1369 	}
1370 
1371 	/* Timing generator registers */
1372 	hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1373 	hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1374 	hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1375 	hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1376 	hdmi_reg_writev(hdata, HDMI_TG_VSYNC_L, 2, 0x1);
1377 	hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2, 0x233);
1378 	hdmi_reg_writev(hdata, HDMI_TG_FIELD_CHG_L, 2, 0x233);
1379 	hdmi_reg_writev(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, 2, 0x1);
1380 	hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2, 0x233);
1381 	hdmi_reg_writev(hdata, HDMI_TG_FIELD_TOP_HDMI_L, 2, 0x1);
1382 	hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2, 0x233);
1383 }
1384 
1385 static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1386 {
1387 	struct drm_display_mode *m = &hdata->current_mode;
1388 
1389 	hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1390 	hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
1391 	hdmi_reg_writev(hdata, HDMI_H_LINE_0, 2, m->htotal);
1392 	hdmi_reg_writev(hdata, HDMI_HSYNC_POL, 1,
1393 			(m->flags & DRM_MODE_FLAG_NHSYNC)  ? 1 : 0);
1394 	hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1,
1395 			(m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
1396 	hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1,
1397 			(m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1398 
1399 	/*
1400 	 * Quirk requirement for exynos 5 HDMI IP design,
1401 	 * 2 pixels less than the actual calculation for hsync_start
1402 	 * and end.
1403 	 */
1404 
1405 	/* Following values & calculations differ for different type of modes */
1406 	if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1407 		/* Interlaced Mode */
1408 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1409 			(m->vsync_end - m->vdisplay) / 2);
1410 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1411 			(m->vsync_start - m->vdisplay) / 2);
1412 		hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal / 2);
1413 		hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1414 				(m->vtotal - m->vdisplay) / 2);
1415 		hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2,
1416 				m->vtotal - m->vdisplay / 2);
1417 		hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, m->vtotal);
1418 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2,
1419 				(m->vtotal / 2) + 7);
1420 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2,
1421 				(m->vtotal / 2) + 2);
1422 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2,
1423 			(m->htotal / 2) + (m->hsync_start - m->hdisplay));
1424 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2,
1425 			(m->htotal / 2) + (m->hsync_start - m->hdisplay));
1426 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1427 				(m->vtotal - m->vdisplay) / 2);
1428 		hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1429 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2,
1430 				m->vtotal - m->vdisplay / 2);
1431 		hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2,
1432 				(m->vtotal / 2) + 1);
1433 		hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2,
1434 				(m->vtotal / 2) + 1);
1435 		hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2,
1436 				(m->vtotal / 2) + 1);
1437 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x0);
1438 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x0);
1439 	} else {
1440 		/* Progressive Mode */
1441 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1442 			m->vsync_end - m->vdisplay);
1443 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1444 			m->vsync_start - m->vdisplay);
1445 		hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal);
1446 		hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1447 				m->vtotal - m->vdisplay);
1448 		hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2, 0xffff);
1449 		hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, 0xffff);
1450 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2, 0xffff);
1451 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2, 0xffff);
1452 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2, 0xffff);
1453 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2, 0xffff);
1454 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1455 				m->vtotal - m->vdisplay);
1456 		hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1457 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x248);
1458 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x47b);
1459 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x6ae);
1460 		hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2, 0x233);
1461 		hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2, 0x233);
1462 		hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2, 0x233);
1463 	}
1464 
1465 	/* Following values & calculations are same irrespective of mode type */
1466 	hdmi_reg_writev(hdata, HDMI_H_SYNC_START_0, 2,
1467 			m->hsync_start - m->hdisplay - 2);
1468 	hdmi_reg_writev(hdata, HDMI_H_SYNC_END_0, 2,
1469 			m->hsync_end - m->hdisplay - 2);
1470 	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_1_0, 2, 0xffff);
1471 	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_2_0, 2, 0xffff);
1472 	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_3_0, 2, 0xffff);
1473 	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_4_0, 2, 0xffff);
1474 	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_5_0, 2, 0xffff);
1475 	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_6_0, 2, 0xffff);
1476 	hdmi_reg_writev(hdata, HDMI_V_BLANK_F2_0, 2, 0xffff);
1477 	hdmi_reg_writev(hdata, HDMI_V_BLANK_F3_0, 2, 0xffff);
1478 	hdmi_reg_writev(hdata, HDMI_V_BLANK_F4_0, 2, 0xffff);
1479 	hdmi_reg_writev(hdata, HDMI_V_BLANK_F5_0, 2, 0xffff);
1480 	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_3_0, 2, 0xffff);
1481 	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_4_0, 2, 0xffff);
1482 	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_5_0, 2, 0xffff);
1483 	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_6_0, 2, 0xffff);
1484 	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0, 2, 0xffff);
1485 	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0, 2, 0xffff);
1486 	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, 2, 0xffff);
1487 	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
1488 
1489 	/* Timing generator registers */
1490 	hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1491 	hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1492 	hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1493 	hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1494 	hdmi_reg_writev(hdata, HDMI_TG_VSYNC_L, 2, 0x1);
1495 	hdmi_reg_writev(hdata, HDMI_TG_FIELD_CHG_L, 2, 0x233);
1496 	hdmi_reg_writev(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, 2, 0x1);
1497 	hdmi_reg_writev(hdata, HDMI_TG_FIELD_TOP_HDMI_L, 2, 0x1);
1498 	hdmi_reg_writev(hdata, HDMI_TG_3D, 1, 0x0);
1499 }
1500 
1501 static void hdmi_mode_apply(struct hdmi_context *hdata)
1502 {
1503 	if (hdata->drv_data->type == HDMI_TYPE13)
1504 		hdmi_v13_mode_apply(hdata);
1505 	else
1506 		hdmi_v14_mode_apply(hdata);
1507 
1508 	hdmiphy_wait_for_pll(hdata);
1509 
1510 	clk_set_parent(hdata->mout_hdmi, hdata->sclk_hdmiphy);
1511 
1512 	/* enable HDMI and timing generator */
1513 	hdmi_start(hdata, true);
1514 }
1515 
1516 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1517 {
1518 	clk_set_parent(hdata->mout_hdmi, hdata->sclk_pixel);
1519 
1520 	/* reset hdmiphy */
1521 	hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
1522 	usleep_range(10000, 12000);
1523 	hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT,  0, HDMI_PHY_SW_RSTOUT);
1524 	usleep_range(10000, 12000);
1525 }
1526 
1527 static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1528 {
1529 	int ret;
1530 	int i;
1531 
1532 	/* pixel clock */
1533 	i = hdmi_find_phy_conf(hdata, hdata->current_mode.clock * 1000);
1534 	if (i < 0) {
1535 		DRM_ERROR("failed to find hdmiphy conf\n");
1536 		return;
1537 	}
1538 
1539 	ret = hdmiphy_reg_write_buf(hdata, 0,
1540 			hdata->drv_data->phy_confs[i].conf, 32);
1541 	if (ret) {
1542 		DRM_ERROR("failed to configure hdmiphy\n");
1543 		return;
1544 	}
1545 
1546 	usleep_range(10000, 12000);
1547 }
1548 
1549 static void hdmi_conf_apply(struct hdmi_context *hdata)
1550 {
1551 	hdmiphy_conf_reset(hdata);
1552 	hdmiphy_conf_apply(hdata);
1553 
1554 	hdmi_start(hdata, false);
1555 	hdmi_conf_init(hdata);
1556 
1557 	hdmi_audio_init(hdata);
1558 
1559 	/* setting core registers */
1560 	hdmi_mode_apply(hdata);
1561 	hdmi_audio_control(hdata, true);
1562 
1563 	hdmi_regs_dump(hdata, "start");
1564 }
1565 
1566 static void hdmi_mode_set(struct drm_encoder *encoder,
1567 			  struct drm_display_mode *mode,
1568 			  struct drm_display_mode *adjusted_mode)
1569 {
1570 	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1571 	struct drm_display_mode *m = adjusted_mode;
1572 
1573 	DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n",
1574 		m->hdisplay, m->vdisplay,
1575 		m->vrefresh, (m->flags & DRM_MODE_FLAG_INTERLACE) ?
1576 		"INTERLACED" : "PROGRESSIVE");
1577 
1578 	drm_mode_copy(&hdata->current_mode, m);
1579 	hdata->cea_video_id = drm_match_cea_mode(mode);
1580 }
1581 
1582 static void hdmi_enable(struct drm_encoder *encoder)
1583 {
1584 	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1585 
1586 	if (hdata->powered)
1587 		return;
1588 
1589 	pm_runtime_get_sync(hdata->dev);
1590 
1591 	if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk))
1592 		DRM_DEBUG_KMS("failed to enable regulator bulk\n");
1593 
1594 	/* set pmu hdmiphy control bit to enable hdmiphy */
1595 	regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1596 			PMU_HDMI_PHY_ENABLE_BIT, 1);
1597 
1598 	hdmi_conf_apply(hdata);
1599 
1600 	hdata->powered = true;
1601 }
1602 
1603 static void hdmi_disable(struct drm_encoder *encoder)
1604 {
1605 	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1606 	struct drm_crtc *crtc = encoder->crtc;
1607 	const struct drm_crtc_helper_funcs *funcs = NULL;
1608 
1609 	if (!hdata->powered)
1610 		return;
1611 
1612 	/*
1613 	 * The SFRs of VP and Mixer are updated by Vertical Sync of
1614 	 * Timing generator which is a part of HDMI so the sequence
1615 	 * to disable TV Subsystem should be as following,
1616 	 *	VP -> Mixer -> HDMI
1617 	 *
1618 	 * Below codes will try to disable Mixer and VP(if used)
1619 	 * prior to disabling HDMI.
1620 	 */
1621 	if (crtc)
1622 		funcs = crtc->helper_private;
1623 	if (funcs && funcs->disable)
1624 		(*funcs->disable)(crtc);
1625 
1626 	/* HDMI System Disable */
1627 	hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
1628 
1629 	cancel_delayed_work(&hdata->hotplug_work);
1630 
1631 	/* reset pmu hdmiphy control bit to disable hdmiphy */
1632 	regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1633 			PMU_HDMI_PHY_ENABLE_BIT, 0);
1634 
1635 	regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
1636 
1637 	pm_runtime_put_sync(hdata->dev);
1638 
1639 	hdata->powered = false;
1640 }
1641 
1642 static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
1643 	.mode_fixup	= hdmi_mode_fixup,
1644 	.mode_set	= hdmi_mode_set,
1645 	.enable		= hdmi_enable,
1646 	.disable	= hdmi_disable,
1647 };
1648 
1649 static const struct drm_encoder_funcs exynos_hdmi_encoder_funcs = {
1650 	.destroy = drm_encoder_cleanup,
1651 };
1652 
1653 static void hdmi_hotplug_work_func(struct work_struct *work)
1654 {
1655 	struct hdmi_context *hdata;
1656 
1657 	hdata = container_of(work, struct hdmi_context, hotplug_work.work);
1658 
1659 	if (hdata->drm_dev)
1660 		drm_helper_hpd_irq_event(hdata->drm_dev);
1661 }
1662 
1663 static irqreturn_t hdmi_irq_thread(int irq, void *arg)
1664 {
1665 	struct hdmi_context *hdata = arg;
1666 
1667 	mod_delayed_work(system_wq, &hdata->hotplug_work,
1668 			msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
1669 
1670 	return IRQ_HANDLED;
1671 }
1672 
1673 static int hdmi_resources_init(struct hdmi_context *hdata)
1674 {
1675 	struct device *dev = hdata->dev;
1676 	int i, ret;
1677 
1678 	DRM_DEBUG_KMS("HDMI resource init\n");
1679 
1680 	hdata->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
1681 	if (IS_ERR(hdata->hpd_gpio)) {
1682 		DRM_ERROR("cannot get hpd gpio property\n");
1683 		return PTR_ERR(hdata->hpd_gpio);
1684 	}
1685 
1686 	hdata->irq = gpiod_to_irq(hdata->hpd_gpio);
1687 	if (hdata->irq < 0) {
1688 		DRM_ERROR("failed to get GPIO irq\n");
1689 		return  hdata->irq;
1690 	}
1691 	/* get clocks, power */
1692 	hdata->hdmi = devm_clk_get(dev, "hdmi");
1693 	if (IS_ERR(hdata->hdmi)) {
1694 		DRM_ERROR("failed to get clock 'hdmi'\n");
1695 		ret = PTR_ERR(hdata->hdmi);
1696 		goto fail;
1697 	}
1698 	hdata->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
1699 	if (IS_ERR(hdata->sclk_hdmi)) {
1700 		DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
1701 		ret = PTR_ERR(hdata->sclk_hdmi);
1702 		goto fail;
1703 	}
1704 	hdata->sclk_pixel = devm_clk_get(dev, "sclk_pixel");
1705 	if (IS_ERR(hdata->sclk_pixel)) {
1706 		DRM_ERROR("failed to get clock 'sclk_pixel'\n");
1707 		ret = PTR_ERR(hdata->sclk_pixel);
1708 		goto fail;
1709 	}
1710 	hdata->sclk_hdmiphy = devm_clk_get(dev, "sclk_hdmiphy");
1711 	if (IS_ERR(hdata->sclk_hdmiphy)) {
1712 		DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
1713 		ret = PTR_ERR(hdata->sclk_hdmiphy);
1714 		goto fail;
1715 	}
1716 	hdata->mout_hdmi = devm_clk_get(dev, "mout_hdmi");
1717 	if (IS_ERR(hdata->mout_hdmi)) {
1718 		DRM_ERROR("failed to get clock 'mout_hdmi'\n");
1719 		ret = PTR_ERR(hdata->mout_hdmi);
1720 		goto fail;
1721 	}
1722 
1723 	clk_set_parent(hdata->mout_hdmi, hdata->sclk_pixel);
1724 
1725 	for (i = 0; i < ARRAY_SIZE(supply); ++i) {
1726 		hdata->regul_bulk[i].supply = supply[i];
1727 		hdata->regul_bulk[i].consumer = NULL;
1728 	}
1729 	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), hdata->regul_bulk);
1730 	if (ret) {
1731 		DRM_ERROR("failed to get regulators\n");
1732 		return ret;
1733 	}
1734 
1735 	hdata->reg_hdmi_en = devm_regulator_get_optional(dev, "hdmi-en");
1736 
1737 	if (PTR_ERR(hdata->reg_hdmi_en) == -ENODEV)
1738 		return 0;
1739 
1740 	if (IS_ERR(hdata->reg_hdmi_en))
1741 		return PTR_ERR(hdata->reg_hdmi_en);
1742 
1743 	ret = regulator_enable(hdata->reg_hdmi_en);
1744 	if (ret)
1745 		DRM_ERROR("failed to enable hdmi-en regulator\n");
1746 
1747 	return ret;
1748 fail:
1749 	DRM_ERROR("HDMI resource init - failed\n");
1750 	return ret;
1751 }
1752 
1753 static struct of_device_id hdmi_match_types[] = {
1754 	{
1755 		.compatible = "samsung,exynos4210-hdmi",
1756 		.data = &exynos4210_hdmi_driver_data,
1757 	}, {
1758 		.compatible = "samsung,exynos4212-hdmi",
1759 		.data = &exynos4212_hdmi_driver_data,
1760 	}, {
1761 		.compatible = "samsung,exynos5420-hdmi",
1762 		.data = &exynos5420_hdmi_driver_data,
1763 	}, {
1764 		/* end node */
1765 	}
1766 };
1767 MODULE_DEVICE_TABLE (of, hdmi_match_types);
1768 
1769 static int hdmi_bind(struct device *dev, struct device *master, void *data)
1770 {
1771 	struct drm_device *drm_dev = data;
1772 	struct hdmi_context *hdata = dev_get_drvdata(dev);
1773 	struct drm_encoder *encoder = &hdata->encoder;
1774 	int ret, pipe;
1775 
1776 	hdata->drm_dev = drm_dev;
1777 
1778 	pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
1779 						  EXYNOS_DISPLAY_TYPE_HDMI);
1780 	if (pipe < 0)
1781 		return pipe;
1782 
1783 	encoder->possible_crtcs = 1 << pipe;
1784 
1785 	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
1786 
1787 	drm_encoder_init(drm_dev, encoder, &exynos_hdmi_encoder_funcs,
1788 			 DRM_MODE_ENCODER_TMDS, NULL);
1789 
1790 	drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
1791 
1792 	ret = hdmi_create_connector(encoder);
1793 	if (ret) {
1794 		DRM_ERROR("failed to create connector ret = %d\n", ret);
1795 		drm_encoder_cleanup(encoder);
1796 		return ret;
1797 	}
1798 
1799 	return 0;
1800 }
1801 
1802 static void hdmi_unbind(struct device *dev, struct device *master, void *data)
1803 {
1804 }
1805 
1806 static const struct component_ops hdmi_component_ops = {
1807 	.bind	= hdmi_bind,
1808 	.unbind = hdmi_unbind,
1809 };
1810 
1811 static struct device_node *hdmi_legacy_ddc_dt_binding(struct device *dev)
1812 {
1813 	const char *compatible_str = "samsung,exynos4210-hdmiddc";
1814 	struct device_node *np;
1815 
1816 	np = of_find_compatible_node(NULL, NULL, compatible_str);
1817 	if (np)
1818 		return of_get_next_parent(np);
1819 
1820 	return NULL;
1821 }
1822 
1823 static struct device_node *hdmi_legacy_phy_dt_binding(struct device *dev)
1824 {
1825 	const char *compatible_str = "samsung,exynos4212-hdmiphy";
1826 
1827 	return of_find_compatible_node(NULL, NULL, compatible_str);
1828 }
1829 
1830 static int hdmi_probe(struct platform_device *pdev)
1831 {
1832 	struct device_node *ddc_node, *phy_node;
1833 	const struct of_device_id *match;
1834 	struct device *dev = &pdev->dev;
1835 	struct hdmi_context *hdata;
1836 	struct resource *res;
1837 	int ret;
1838 
1839 	hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
1840 	if (!hdata)
1841 		return -ENOMEM;
1842 
1843 	match = of_match_device(hdmi_match_types, dev);
1844 	if (!match)
1845 		return -ENODEV;
1846 
1847 	hdata->drv_data = match->data;
1848 
1849 	platform_set_drvdata(pdev, hdata);
1850 
1851 	hdata->dev = dev;
1852 
1853 	ret = hdmi_resources_init(hdata);
1854 	if (ret) {
1855 		DRM_ERROR("hdmi_resources_init failed\n");
1856 		return ret;
1857 	}
1858 
1859 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1860 	hdata->regs = devm_ioremap_resource(dev, res);
1861 	if (IS_ERR(hdata->regs)) {
1862 		ret = PTR_ERR(hdata->regs);
1863 		return ret;
1864 	}
1865 
1866 	ddc_node = hdmi_legacy_ddc_dt_binding(dev);
1867 	if (ddc_node)
1868 		goto out_get_ddc_adpt;
1869 
1870 	/* DDC i2c driver */
1871 	ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
1872 	if (!ddc_node) {
1873 		DRM_ERROR("Failed to find ddc node in device tree\n");
1874 		return -ENODEV;
1875 	}
1876 
1877 out_get_ddc_adpt:
1878 	hdata->ddc_adpt = of_find_i2c_adapter_by_node(ddc_node);
1879 	if (!hdata->ddc_adpt) {
1880 		DRM_ERROR("Failed to get ddc i2c adapter by node\n");
1881 		return -EPROBE_DEFER;
1882 	}
1883 
1884 	phy_node = hdmi_legacy_phy_dt_binding(dev);
1885 	if (phy_node)
1886 		goto out_get_phy_port;
1887 
1888 	/* hdmiphy i2c driver */
1889 	phy_node = of_parse_phandle(dev->of_node, "phy", 0);
1890 	if (!phy_node) {
1891 		DRM_ERROR("Failed to find hdmiphy node in device tree\n");
1892 		ret = -ENODEV;
1893 		goto err_ddc;
1894 	}
1895 
1896 out_get_phy_port:
1897 	if (hdata->drv_data->is_apb_phy) {
1898 		hdata->regs_hdmiphy = of_iomap(phy_node, 0);
1899 		if (!hdata->regs_hdmiphy) {
1900 			DRM_ERROR("failed to ioremap hdmi phy\n");
1901 			ret = -ENOMEM;
1902 			goto err_ddc;
1903 		}
1904 	} else {
1905 		hdata->hdmiphy_port = of_find_i2c_device_by_node(phy_node);
1906 		if (!hdata->hdmiphy_port) {
1907 			DRM_ERROR("Failed to get hdmi phy i2c client\n");
1908 			ret = -EPROBE_DEFER;
1909 			goto err_ddc;
1910 		}
1911 	}
1912 
1913 	INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
1914 
1915 	ret = devm_request_threaded_irq(dev, hdata->irq, NULL,
1916 			hdmi_irq_thread, IRQF_TRIGGER_RISING |
1917 			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1918 			"hdmi", hdata);
1919 	if (ret) {
1920 		DRM_ERROR("failed to register hdmi interrupt\n");
1921 		goto err_hdmiphy;
1922 	}
1923 
1924 	hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
1925 			"samsung,syscon-phandle");
1926 	if (IS_ERR(hdata->pmureg)) {
1927 		DRM_ERROR("syscon regmap lookup failed.\n");
1928 		ret = -EPROBE_DEFER;
1929 		goto err_hdmiphy;
1930 	}
1931 
1932 	pm_runtime_enable(dev);
1933 
1934 	ret = component_add(&pdev->dev, &hdmi_component_ops);
1935 	if (ret)
1936 		goto err_disable_pm_runtime;
1937 
1938 	return ret;
1939 
1940 err_disable_pm_runtime:
1941 	pm_runtime_disable(dev);
1942 
1943 err_hdmiphy:
1944 	if (hdata->hdmiphy_port)
1945 		put_device(&hdata->hdmiphy_port->dev);
1946 err_ddc:
1947 	put_device(&hdata->ddc_adpt->dev);
1948 
1949 	return ret;
1950 }
1951 
1952 static int hdmi_remove(struct platform_device *pdev)
1953 {
1954 	struct hdmi_context *hdata = platform_get_drvdata(pdev);
1955 
1956 	cancel_delayed_work_sync(&hdata->hotplug_work);
1957 
1958 	component_del(&pdev->dev, &hdmi_component_ops);
1959 
1960 	pm_runtime_disable(&pdev->dev);
1961 
1962 	if (!IS_ERR(hdata->reg_hdmi_en))
1963 		regulator_disable(hdata->reg_hdmi_en);
1964 
1965 	if (hdata->hdmiphy_port)
1966 		put_device(&hdata->hdmiphy_port->dev);
1967 
1968 	put_device(&hdata->ddc_adpt->dev);
1969 
1970 	return 0;
1971 }
1972 
1973 #ifdef CONFIG_PM
1974 static int exynos_hdmi_suspend(struct device *dev)
1975 {
1976 	struct hdmi_context *hdata = dev_get_drvdata(dev);
1977 
1978 	clk_disable_unprepare(hdata->sclk_hdmi);
1979 	clk_disable_unprepare(hdata->hdmi);
1980 
1981 	return 0;
1982 }
1983 
1984 static int exynos_hdmi_resume(struct device *dev)
1985 {
1986 	struct hdmi_context *hdata = dev_get_drvdata(dev);
1987 	int ret;
1988 
1989 	ret = clk_prepare_enable(hdata->hdmi);
1990 	if (ret < 0) {
1991 		DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret);
1992 		return ret;
1993 	}
1994 	ret = clk_prepare_enable(hdata->sclk_hdmi);
1995 	if (ret < 0) {
1996 		DRM_ERROR("Failed to prepare_enable the sclk_mixer clk [%d]\n",
1997 			  ret);
1998 		return ret;
1999 	}
2000 
2001 	return 0;
2002 }
2003 #endif
2004 
2005 static const struct dev_pm_ops exynos_hdmi_pm_ops = {
2006 	SET_RUNTIME_PM_OPS(exynos_hdmi_suspend, exynos_hdmi_resume, NULL)
2007 };
2008 
2009 struct platform_driver hdmi_driver = {
2010 	.probe		= hdmi_probe,
2011 	.remove		= hdmi_remove,
2012 	.driver		= {
2013 		.name	= "exynos-hdmi",
2014 		.owner	= THIS_MODULE,
2015 		.pm	= &exynos_hdmi_pm_ops,
2016 		.of_match_table = hdmi_match_types,
2017 	},
2018 };
2019