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 	u32 mod;
871 	u8 ar;
872 
873 	mod = hdmi_reg_read(hdata, HDMI_MODE_SEL);
874 	if (hdata->dvi_mode) {
875 		hdmi_reg_writeb(hdata, HDMI_VSI_CON,
876 				HDMI_VSI_CON_DO_NOT_TRANSMIT);
877 		hdmi_reg_writeb(hdata, HDMI_AVI_CON,
878 				HDMI_AVI_CON_DO_NOT_TRANSMIT);
879 		hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_NO_TRAN);
880 		return;
881 	}
882 
883 	switch (infoframe->any.type) {
884 	case HDMI_INFOFRAME_TYPE_AVI:
885 		hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC);
886 		hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->any.type);
887 		hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1,
888 				infoframe->any.version);
889 		hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->any.length);
890 		hdr_sum = infoframe->any.type + infoframe->any.version +
891 			  infoframe->any.length;
892 
893 		/* Output format zero hardcoded ,RGB YBCR selection */
894 		hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 |
895 			AVI_ACTIVE_FORMAT_VALID |
896 			AVI_UNDERSCANNED_DISPLAY_VALID);
897 
898 		/*
899 		 * Set the aspect ratio as per the mode, mentioned in
900 		 * Table 9 AVI InfoFrame Data Byte 2 of CEA-861-D Standard
901 		 */
902 		ar = hdata->current_mode.picture_aspect_ratio;
903 		switch (ar) {
904 		case HDMI_PICTURE_ASPECT_4_3:
905 			ar |= AVI_4_3_CENTER_RATIO;
906 			break;
907 		case HDMI_PICTURE_ASPECT_16_9:
908 			ar |= AVI_16_9_CENTER_RATIO;
909 			break;
910 		case HDMI_PICTURE_ASPECT_NONE:
911 		default:
912 			ar |= AVI_SAME_AS_PIC_ASPECT_RATIO;
913 			break;
914 		}
915 		hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2), ar);
916 
917 		hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), hdata->cea_video_id);
918 
919 		chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1),
920 					infoframe->any.length, hdr_sum);
921 		DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum);
922 		hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum);
923 		break;
924 	case HDMI_INFOFRAME_TYPE_AUDIO:
925 		hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02);
926 		hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->any.type);
927 		hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1,
928 				infoframe->any.version);
929 		hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->any.length);
930 		hdr_sum = infoframe->any.type + infoframe->any.version +
931 			  infoframe->any.length;
932 		chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1),
933 					infoframe->any.length, hdr_sum);
934 		DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum);
935 		hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum);
936 		break;
937 	default:
938 		break;
939 	}
940 }
941 
942 static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
943 				bool force)
944 {
945 	struct hdmi_context *hdata = connector_to_hdmi(connector);
946 
947 	if (gpiod_get_value(hdata->hpd_gpio))
948 		return connector_status_connected;
949 
950 	return connector_status_disconnected;
951 }
952 
953 static void hdmi_connector_destroy(struct drm_connector *connector)
954 {
955 	drm_connector_unregister(connector);
956 	drm_connector_cleanup(connector);
957 }
958 
959 static const struct drm_connector_funcs hdmi_connector_funcs = {
960 	.dpms = drm_atomic_helper_connector_dpms,
961 	.fill_modes = drm_helper_probe_single_connector_modes,
962 	.detect = hdmi_detect,
963 	.destroy = hdmi_connector_destroy,
964 	.reset = drm_atomic_helper_connector_reset,
965 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
966 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
967 };
968 
969 static int hdmi_get_modes(struct drm_connector *connector)
970 {
971 	struct hdmi_context *hdata = connector_to_hdmi(connector);
972 	struct edid *edid;
973 	int ret;
974 
975 	if (!hdata->ddc_adpt)
976 		return -ENODEV;
977 
978 	edid = drm_get_edid(connector, hdata->ddc_adpt);
979 	if (!edid)
980 		return -ENODEV;
981 
982 	hdata->dvi_mode = !drm_detect_hdmi_monitor(edid);
983 	DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
984 		(hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
985 		edid->width_cm, edid->height_cm);
986 
987 	drm_mode_connector_update_edid_property(connector, edid);
988 
989 	ret = drm_add_edid_modes(connector, edid);
990 
991 	kfree(edid);
992 
993 	return ret;
994 }
995 
996 static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
997 {
998 	int i;
999 
1000 	for (i = 0; i < hdata->drv_data->phy_conf_count; i++)
1001 		if (hdata->drv_data->phy_confs[i].pixel_clock == pixel_clock)
1002 			return i;
1003 
1004 	DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
1005 	return -EINVAL;
1006 }
1007 
1008 static int hdmi_mode_valid(struct drm_connector *connector,
1009 			struct drm_display_mode *mode)
1010 {
1011 	struct hdmi_context *hdata = connector_to_hdmi(connector);
1012 	int ret;
1013 
1014 	DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
1015 		mode->hdisplay, mode->vdisplay, mode->vrefresh,
1016 		(mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
1017 		false, mode->clock * 1000);
1018 
1019 	ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
1020 	if (ret < 0)
1021 		return MODE_BAD;
1022 
1023 	return MODE_OK;
1024 }
1025 
1026 static struct drm_encoder *hdmi_best_encoder(struct drm_connector *connector)
1027 {
1028 	struct hdmi_context *hdata = connector_to_hdmi(connector);
1029 
1030 	return &hdata->encoder;
1031 }
1032 
1033 static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
1034 	.get_modes = hdmi_get_modes,
1035 	.mode_valid = hdmi_mode_valid,
1036 	.best_encoder = hdmi_best_encoder,
1037 };
1038 
1039 static int hdmi_create_connector(struct drm_encoder *encoder)
1040 {
1041 	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1042 	struct drm_connector *connector = &hdata->connector;
1043 	int ret;
1044 
1045 	connector->interlace_allowed = true;
1046 	connector->polled = DRM_CONNECTOR_POLL_HPD;
1047 
1048 	ret = drm_connector_init(hdata->drm_dev, connector,
1049 			&hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA);
1050 	if (ret) {
1051 		DRM_ERROR("Failed to initialize connector with drm\n");
1052 		return ret;
1053 	}
1054 
1055 	drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
1056 	drm_connector_register(connector);
1057 	drm_mode_connector_attach_encoder(connector, encoder);
1058 
1059 	return 0;
1060 }
1061 
1062 static bool hdmi_mode_fixup(struct drm_encoder *encoder,
1063 			    const struct drm_display_mode *mode,
1064 			    struct drm_display_mode *adjusted_mode)
1065 {
1066 	struct drm_device *dev = encoder->dev;
1067 	struct drm_connector *connector;
1068 	struct drm_display_mode *m;
1069 	int mode_ok;
1070 
1071 	drm_mode_set_crtcinfo(adjusted_mode, 0);
1072 
1073 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1074 		if (connector->encoder == encoder)
1075 			break;
1076 	}
1077 
1078 	if (connector->encoder != encoder)
1079 		return true;
1080 
1081 	mode_ok = hdmi_mode_valid(connector, adjusted_mode);
1082 
1083 	/* just return if user desired mode exists. */
1084 	if (mode_ok == MODE_OK)
1085 		return true;
1086 
1087 	/*
1088 	 * otherwise, find the most suitable mode among modes and change it
1089 	 * to adjusted_mode.
1090 	 */
1091 	list_for_each_entry(m, &connector->modes, head) {
1092 		mode_ok = hdmi_mode_valid(connector, m);
1093 
1094 		if (mode_ok == MODE_OK) {
1095 			DRM_INFO("desired mode doesn't exist so\n");
1096 			DRM_INFO("use the most suitable mode among modes.\n");
1097 
1098 			DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n",
1099 				m->hdisplay, m->vdisplay, m->vrefresh);
1100 
1101 			drm_mode_copy(adjusted_mode, m);
1102 			break;
1103 		}
1104 	}
1105 
1106 	return true;
1107 }
1108 
1109 static void hdmi_reg_acr(struct hdmi_context *hdata, u32 freq)
1110 {
1111 	u32 n, cts;
1112 
1113 	cts = (freq % 9) ? 27000 : 30000;
1114 	n = 128 * freq / (27000000 / cts);
1115 
1116 	hdmi_reg_writev(hdata, HDMI_ACR_N0, 3, n);
1117 	hdmi_reg_writev(hdata, HDMI_ACR_MCTS0, 3, cts);
1118 	hdmi_reg_writev(hdata, HDMI_ACR_CTS0, 3, cts);
1119 	hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1120 }
1121 
1122 static void hdmi_audio_init(struct hdmi_context *hdata)
1123 {
1124 	u32 sample_rate, bits_per_sample;
1125 	u32 data_num, bit_ch, sample_frq;
1126 	u32 val;
1127 
1128 	sample_rate = 44100;
1129 	bits_per_sample = 16;
1130 
1131 	switch (bits_per_sample) {
1132 	case 20:
1133 		data_num = 2;
1134 		bit_ch  = 1;
1135 		break;
1136 	case 24:
1137 		data_num = 3;
1138 		bit_ch  = 1;
1139 		break;
1140 	default:
1141 		data_num = 1;
1142 		bit_ch  = 0;
1143 		break;
1144 	}
1145 
1146 	hdmi_reg_acr(hdata, sample_rate);
1147 
1148 	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1149 				| HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1150 				| HDMI_I2S_MUX_ENABLE);
1151 
1152 	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1153 			| HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1154 
1155 	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1156 
1157 	sample_frq = (sample_rate == 44100) ? 0 :
1158 			(sample_rate == 48000) ? 2 :
1159 			(sample_rate == 32000) ? 3 :
1160 			(sample_rate == 96000) ? 0xa : 0x0;
1161 
1162 	hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1163 	hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1164 
1165 	val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1166 	hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1167 
1168 	/* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1169 	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1170 			| HDMI_I2S_SEL_LRCK(6));
1171 	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1172 			| HDMI_I2S_SEL_SDATA2(4));
1173 	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1174 			| HDMI_I2S_SEL_SDATA2(2));
1175 	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1176 
1177 	/* I2S_CON_1 & 2 */
1178 	hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1179 			| HDMI_I2S_L_CH_LOW_POL);
1180 	hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1181 			| HDMI_I2S_SET_BIT_CH(bit_ch)
1182 			| HDMI_I2S_SET_SDATA_BIT(data_num)
1183 			| HDMI_I2S_BASIC_FORMAT);
1184 
1185 	/* Configure register related to CUV information */
1186 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
1187 			| HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1188 			| HDMI_I2S_COPYRIGHT
1189 			| HDMI_I2S_LINEAR_PCM
1190 			| HDMI_I2S_CONSUMER_FORMAT);
1191 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1192 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1193 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1194 			| HDMI_I2S_SET_SMP_FREQ(sample_frq));
1195 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1196 			HDMI_I2S_ORG_SMP_FREQ_44_1
1197 			| HDMI_I2S_WORD_LEN_MAX24_24BITS
1198 			| HDMI_I2S_WORD_LEN_MAX_24BITS);
1199 
1200 	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1201 }
1202 
1203 static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1204 {
1205 	if (hdata->dvi_mode)
1206 		return;
1207 
1208 	hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
1209 	hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ?
1210 			HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1211 }
1212 
1213 static void hdmi_start(struct hdmi_context *hdata, bool start)
1214 {
1215 	u32 val = start ? HDMI_TG_EN : 0;
1216 
1217 	if (hdata->current_mode.flags & DRM_MODE_FLAG_INTERLACE)
1218 		val |= HDMI_FIELD_EN;
1219 
1220 	hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN);
1221 	hdmi_reg_writemask(hdata, HDMI_TG_CMD, val, HDMI_TG_EN | HDMI_FIELD_EN);
1222 }
1223 
1224 static void hdmi_conf_init(struct hdmi_context *hdata)
1225 {
1226 	union hdmi_infoframe infoframe;
1227 
1228 	/* disable HPD interrupts from HDMI IP block, use GPIO instead */
1229 	hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1230 		HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1231 
1232 	/* choose HDMI mode */
1233 	hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1234 		HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1235 	/* Apply Video preable and Guard band in HDMI mode only */
1236 	hdmi_reg_writeb(hdata, HDMI_CON_2, 0);
1237 	/* disable bluescreen */
1238 	hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1239 
1240 	if (hdata->dvi_mode) {
1241 		/* choose DVI mode */
1242 		hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1243 				HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1244 		hdmi_reg_writeb(hdata, HDMI_CON_2,
1245 				HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1246 	}
1247 
1248 	if (hdata->drv_data->type == HDMI_TYPE13) {
1249 		/* choose bluescreen (fecal) color */
1250 		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1251 		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1252 		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1253 
1254 		/* enable AVI packet every vsync, fixes purple line problem */
1255 		hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1256 		/* force RGB, look to CEA-861-D, table 7 for more detail */
1257 		hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1258 		hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1259 
1260 		hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1261 		hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1262 		hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1263 	} else {
1264 		infoframe.any.type = HDMI_INFOFRAME_TYPE_AVI;
1265 		infoframe.any.version = HDMI_AVI_VERSION;
1266 		infoframe.any.length = HDMI_AVI_LENGTH;
1267 		hdmi_reg_infoframe(hdata, &infoframe);
1268 
1269 		infoframe.any.type = HDMI_INFOFRAME_TYPE_AUDIO;
1270 		infoframe.any.version = HDMI_AUI_VERSION;
1271 		infoframe.any.length = HDMI_AUI_LENGTH;
1272 		hdmi_reg_infoframe(hdata, &infoframe);
1273 
1274 		/* enable AVI packet every vsync, fixes purple line problem */
1275 		hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1276 	}
1277 }
1278 
1279 static void hdmiphy_wait_for_pll(struct hdmi_context *hdata)
1280 {
1281 	int tries;
1282 
1283 	for (tries = 0; tries < 10; ++tries) {
1284 		u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS);
1285 
1286 		if (val & HDMI_PHY_STATUS_READY) {
1287 			DRM_DEBUG_KMS("PLL stabilized after %d tries\n", tries);
1288 			return;
1289 		}
1290 		usleep_range(10, 20);
1291 	}
1292 
1293 	DRM_ERROR("PLL could not reach steady state\n");
1294 }
1295 
1296 static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1297 {
1298 	struct drm_display_mode *m = &hdata->current_mode;
1299 	unsigned int val;
1300 
1301 	hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1302 	hdmi_reg_writev(hdata, HDMI_V13_H_V_LINE_0, 3,
1303 			(m->htotal << 12) | m->vtotal);
1304 
1305 	val = (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
1306 	hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1, val);
1307 
1308 	val = (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0;
1309 	hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1, val);
1310 
1311 	val = (m->hsync_start - m->hdisplay - 2);
1312 	val |= ((m->hsync_end - m->hdisplay - 2) << 10);
1313 	val |= ((m->flags & DRM_MODE_FLAG_NHSYNC)  ? 1 : 0)<<20;
1314 	hdmi_reg_writev(hdata, HDMI_V13_H_SYNC_GEN_0, 3, val);
1315 
1316 	/*
1317 	 * Quirk requirement for exynos HDMI IP design,
1318 	 * 2 pixels less than the actual calculation for hsync_start
1319 	 * and end.
1320 	 */
1321 
1322 	/* Following values & calculations differ for different type of modes */
1323 	if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1324 		/* Interlaced Mode */
1325 		val = ((m->vsync_end - m->vdisplay) / 2);
1326 		val |= ((m->vsync_start - m->vdisplay) / 2) << 12;
1327 		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1328 
1329 		val = m->vtotal / 2;
1330 		val |= ((m->vtotal - m->vdisplay) / 2) << 11;
1331 		hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1332 
1333 		val = (m->vtotal +
1334 			((m->vsync_end - m->vsync_start) * 4) + 5) / 2;
1335 		val |= m->vtotal << 11;
1336 		hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, val);
1337 
1338 		val = ((m->vtotal / 2) + 7);
1339 		val |= ((m->vtotal / 2) + 2) << 12;
1340 		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, val);
1341 
1342 		val = ((m->htotal / 2) + (m->hsync_start - m->hdisplay));
1343 		val |= ((m->htotal / 2) +
1344 			(m->hsync_start - m->hdisplay)) << 12;
1345 		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, val);
1346 
1347 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1348 				(m->vtotal - m->vdisplay) / 2);
1349 		hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1350 
1351 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x249);
1352 	} else {
1353 		/* Progressive Mode */
1354 
1355 		val = m->vtotal;
1356 		val |= (m->vtotal - m->vdisplay) << 11;
1357 		hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1358 
1359 		hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, 0);
1360 
1361 		val = (m->vsync_end - m->vdisplay);
1362 		val |= ((m->vsync_start - m->vdisplay) << 12);
1363 		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1364 
1365 		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, 0x1001);
1366 		hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, 0x1001);
1367 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1368 				m->vtotal - m->vdisplay);
1369 		hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1370 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x248);
1371 	}
1372 
1373 	/* Timing generator registers */
1374 	hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1375 	hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1376 	hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1377 	hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1378 	hdmi_reg_writev(hdata, HDMI_TG_VSYNC_L, 2, 0x1);
1379 	hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2, 0x233);
1380 	hdmi_reg_writev(hdata, HDMI_TG_FIELD_CHG_L, 2, 0x233);
1381 	hdmi_reg_writev(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, 2, 0x1);
1382 	hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2, 0x233);
1383 	hdmi_reg_writev(hdata, HDMI_TG_FIELD_TOP_HDMI_L, 2, 0x1);
1384 	hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2, 0x233);
1385 }
1386 
1387 static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1388 {
1389 	struct drm_display_mode *m = &hdata->current_mode;
1390 
1391 	hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1392 	hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
1393 	hdmi_reg_writev(hdata, HDMI_H_LINE_0, 2, m->htotal);
1394 	hdmi_reg_writev(hdata, HDMI_HSYNC_POL, 1,
1395 			(m->flags & DRM_MODE_FLAG_NHSYNC)  ? 1 : 0);
1396 	hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1,
1397 			(m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
1398 	hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1,
1399 			(m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1400 
1401 	/*
1402 	 * Quirk requirement for exynos 5 HDMI IP design,
1403 	 * 2 pixels less than the actual calculation for hsync_start
1404 	 * and end.
1405 	 */
1406 
1407 	/* Following values & calculations differ for different type of modes */
1408 	if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1409 		/* Interlaced Mode */
1410 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1411 			(m->vsync_end - m->vdisplay) / 2);
1412 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1413 			(m->vsync_start - m->vdisplay) / 2);
1414 		hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal / 2);
1415 		hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1416 				(m->vtotal - m->vdisplay) / 2);
1417 		hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2,
1418 				m->vtotal - m->vdisplay / 2);
1419 		hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, m->vtotal);
1420 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2,
1421 				(m->vtotal / 2) + 7);
1422 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2,
1423 				(m->vtotal / 2) + 2);
1424 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2,
1425 			(m->htotal / 2) + (m->hsync_start - m->hdisplay));
1426 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2,
1427 			(m->htotal / 2) + (m->hsync_start - m->hdisplay));
1428 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1429 				(m->vtotal - m->vdisplay) / 2);
1430 		hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1431 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2,
1432 				m->vtotal - m->vdisplay / 2);
1433 		hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2,
1434 				(m->vtotal / 2) + 1);
1435 		hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2,
1436 				(m->vtotal / 2) + 1);
1437 		hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2,
1438 				(m->vtotal / 2) + 1);
1439 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x0);
1440 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x0);
1441 	} else {
1442 		/* Progressive Mode */
1443 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1444 			m->vsync_end - m->vdisplay);
1445 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1446 			m->vsync_start - m->vdisplay);
1447 		hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal);
1448 		hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1449 				m->vtotal - m->vdisplay);
1450 		hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2, 0xffff);
1451 		hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, 0xffff);
1452 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2, 0xffff);
1453 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2, 0xffff);
1454 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2, 0xffff);
1455 		hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2, 0xffff);
1456 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1457 				m->vtotal - m->vdisplay);
1458 		hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1459 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x248);
1460 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x47b);
1461 		hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x6ae);
1462 		hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2, 0x233);
1463 		hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2, 0x233);
1464 		hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2, 0x233);
1465 	}
1466 
1467 	/* Following values & calculations are same irrespective of mode type */
1468 	hdmi_reg_writev(hdata, HDMI_H_SYNC_START_0, 2,
1469 			m->hsync_start - m->hdisplay - 2);
1470 	hdmi_reg_writev(hdata, HDMI_H_SYNC_END_0, 2,
1471 			m->hsync_end - m->hdisplay - 2);
1472 	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_1_0, 2, 0xffff);
1473 	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_2_0, 2, 0xffff);
1474 	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_3_0, 2, 0xffff);
1475 	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_4_0, 2, 0xffff);
1476 	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_5_0, 2, 0xffff);
1477 	hdmi_reg_writev(hdata, HDMI_VACT_SPACE_6_0, 2, 0xffff);
1478 	hdmi_reg_writev(hdata, HDMI_V_BLANK_F2_0, 2, 0xffff);
1479 	hdmi_reg_writev(hdata, HDMI_V_BLANK_F3_0, 2, 0xffff);
1480 	hdmi_reg_writev(hdata, HDMI_V_BLANK_F4_0, 2, 0xffff);
1481 	hdmi_reg_writev(hdata, HDMI_V_BLANK_F5_0, 2, 0xffff);
1482 	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_3_0, 2, 0xffff);
1483 	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_4_0, 2, 0xffff);
1484 	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_5_0, 2, 0xffff);
1485 	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_6_0, 2, 0xffff);
1486 	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0, 2, 0xffff);
1487 	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0, 2, 0xffff);
1488 	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, 2, 0xffff);
1489 	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
1490 
1491 	/* Timing generator registers */
1492 	hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1493 	hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1494 	hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1495 	hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1496 	hdmi_reg_writev(hdata, HDMI_TG_VSYNC_L, 2, 0x1);
1497 	hdmi_reg_writev(hdata, HDMI_TG_FIELD_CHG_L, 2, 0x233);
1498 	hdmi_reg_writev(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, 2, 0x1);
1499 	hdmi_reg_writev(hdata, HDMI_TG_FIELD_TOP_HDMI_L, 2, 0x1);
1500 	hdmi_reg_writev(hdata, HDMI_TG_3D, 1, 0x0);
1501 }
1502 
1503 static void hdmi_mode_apply(struct hdmi_context *hdata)
1504 {
1505 	if (hdata->drv_data->type == HDMI_TYPE13)
1506 		hdmi_v13_mode_apply(hdata);
1507 	else
1508 		hdmi_v14_mode_apply(hdata);
1509 
1510 	hdmiphy_wait_for_pll(hdata);
1511 
1512 	clk_set_parent(hdata->mout_hdmi, hdata->sclk_hdmiphy);
1513 
1514 	/* enable HDMI and timing generator */
1515 	hdmi_start(hdata, true);
1516 }
1517 
1518 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1519 {
1520 	clk_set_parent(hdata->mout_hdmi, hdata->sclk_pixel);
1521 
1522 	/* reset hdmiphy */
1523 	hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
1524 	usleep_range(10000, 12000);
1525 	hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT,  0, HDMI_PHY_SW_RSTOUT);
1526 	usleep_range(10000, 12000);
1527 }
1528 
1529 static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1530 {
1531 	int ret;
1532 	int i;
1533 
1534 	/* pixel clock */
1535 	i = hdmi_find_phy_conf(hdata, hdata->current_mode.clock * 1000);
1536 	if (i < 0) {
1537 		DRM_ERROR("failed to find hdmiphy conf\n");
1538 		return;
1539 	}
1540 
1541 	ret = hdmiphy_reg_write_buf(hdata, 0,
1542 			hdata->drv_data->phy_confs[i].conf, 32);
1543 	if (ret) {
1544 		DRM_ERROR("failed to configure hdmiphy\n");
1545 		return;
1546 	}
1547 
1548 	usleep_range(10000, 12000);
1549 }
1550 
1551 static void hdmi_conf_apply(struct hdmi_context *hdata)
1552 {
1553 	hdmiphy_conf_reset(hdata);
1554 	hdmiphy_conf_apply(hdata);
1555 
1556 	hdmi_start(hdata, false);
1557 	hdmi_conf_init(hdata);
1558 
1559 	hdmi_audio_init(hdata);
1560 
1561 	/* setting core registers */
1562 	hdmi_mode_apply(hdata);
1563 	hdmi_audio_control(hdata, true);
1564 
1565 	hdmi_regs_dump(hdata, "start");
1566 }
1567 
1568 static void hdmi_mode_set(struct drm_encoder *encoder,
1569 			  struct drm_display_mode *mode,
1570 			  struct drm_display_mode *adjusted_mode)
1571 {
1572 	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1573 	struct drm_display_mode *m = adjusted_mode;
1574 
1575 	DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n",
1576 		m->hdisplay, m->vdisplay,
1577 		m->vrefresh, (m->flags & DRM_MODE_FLAG_INTERLACE) ?
1578 		"INTERLACED" : "PROGRESSIVE");
1579 
1580 	drm_mode_copy(&hdata->current_mode, m);
1581 	hdata->cea_video_id = drm_match_cea_mode(mode);
1582 }
1583 
1584 static void hdmi_enable(struct drm_encoder *encoder)
1585 {
1586 	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1587 
1588 	if (hdata->powered)
1589 		return;
1590 
1591 	pm_runtime_get_sync(hdata->dev);
1592 
1593 	if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk))
1594 		DRM_DEBUG_KMS("failed to enable regulator bulk\n");
1595 
1596 	/* set pmu hdmiphy control bit to enable hdmiphy */
1597 	regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1598 			PMU_HDMI_PHY_ENABLE_BIT, 1);
1599 
1600 	hdmi_conf_apply(hdata);
1601 
1602 	hdata->powered = true;
1603 }
1604 
1605 static void hdmi_disable(struct drm_encoder *encoder)
1606 {
1607 	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1608 	struct drm_crtc *crtc = encoder->crtc;
1609 	const struct drm_crtc_helper_funcs *funcs = NULL;
1610 
1611 	if (!hdata->powered)
1612 		return;
1613 
1614 	/*
1615 	 * The SFRs of VP and Mixer are updated by Vertical Sync of
1616 	 * Timing generator which is a part of HDMI so the sequence
1617 	 * to disable TV Subsystem should be as following,
1618 	 *	VP -> Mixer -> HDMI
1619 	 *
1620 	 * Below codes will try to disable Mixer and VP(if used)
1621 	 * prior to disabling HDMI.
1622 	 */
1623 	if (crtc)
1624 		funcs = crtc->helper_private;
1625 	if (funcs && funcs->disable)
1626 		(*funcs->disable)(crtc);
1627 
1628 	/* HDMI System Disable */
1629 	hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
1630 
1631 	cancel_delayed_work(&hdata->hotplug_work);
1632 
1633 	/* reset pmu hdmiphy control bit to disable hdmiphy */
1634 	regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1635 			PMU_HDMI_PHY_ENABLE_BIT, 0);
1636 
1637 	regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
1638 
1639 	pm_runtime_put_sync(hdata->dev);
1640 
1641 	hdata->powered = false;
1642 }
1643 
1644 static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
1645 	.mode_fixup	= hdmi_mode_fixup,
1646 	.mode_set	= hdmi_mode_set,
1647 	.enable		= hdmi_enable,
1648 	.disable	= hdmi_disable,
1649 };
1650 
1651 static const struct drm_encoder_funcs exynos_hdmi_encoder_funcs = {
1652 	.destroy = drm_encoder_cleanup,
1653 };
1654 
1655 static void hdmi_hotplug_work_func(struct work_struct *work)
1656 {
1657 	struct hdmi_context *hdata;
1658 
1659 	hdata = container_of(work, struct hdmi_context, hotplug_work.work);
1660 
1661 	if (hdata->drm_dev)
1662 		drm_helper_hpd_irq_event(hdata->drm_dev);
1663 }
1664 
1665 static irqreturn_t hdmi_irq_thread(int irq, void *arg)
1666 {
1667 	struct hdmi_context *hdata = arg;
1668 
1669 	mod_delayed_work(system_wq, &hdata->hotplug_work,
1670 			msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
1671 
1672 	return IRQ_HANDLED;
1673 }
1674 
1675 static int hdmi_resources_init(struct hdmi_context *hdata)
1676 {
1677 	struct device *dev = hdata->dev;
1678 	int i, ret;
1679 
1680 	DRM_DEBUG_KMS("HDMI resource init\n");
1681 
1682 	hdata->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
1683 	if (IS_ERR(hdata->hpd_gpio)) {
1684 		DRM_ERROR("cannot get hpd gpio property\n");
1685 		return PTR_ERR(hdata->hpd_gpio);
1686 	}
1687 
1688 	hdata->irq = gpiod_to_irq(hdata->hpd_gpio);
1689 	if (hdata->irq < 0) {
1690 		DRM_ERROR("failed to get GPIO irq\n");
1691 		return  hdata->irq;
1692 	}
1693 	/* get clocks, power */
1694 	hdata->hdmi = devm_clk_get(dev, "hdmi");
1695 	if (IS_ERR(hdata->hdmi)) {
1696 		DRM_ERROR("failed to get clock 'hdmi'\n");
1697 		ret = PTR_ERR(hdata->hdmi);
1698 		goto fail;
1699 	}
1700 	hdata->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
1701 	if (IS_ERR(hdata->sclk_hdmi)) {
1702 		DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
1703 		ret = PTR_ERR(hdata->sclk_hdmi);
1704 		goto fail;
1705 	}
1706 	hdata->sclk_pixel = devm_clk_get(dev, "sclk_pixel");
1707 	if (IS_ERR(hdata->sclk_pixel)) {
1708 		DRM_ERROR("failed to get clock 'sclk_pixel'\n");
1709 		ret = PTR_ERR(hdata->sclk_pixel);
1710 		goto fail;
1711 	}
1712 	hdata->sclk_hdmiphy = devm_clk_get(dev, "sclk_hdmiphy");
1713 	if (IS_ERR(hdata->sclk_hdmiphy)) {
1714 		DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
1715 		ret = PTR_ERR(hdata->sclk_hdmiphy);
1716 		goto fail;
1717 	}
1718 	hdata->mout_hdmi = devm_clk_get(dev, "mout_hdmi");
1719 	if (IS_ERR(hdata->mout_hdmi)) {
1720 		DRM_ERROR("failed to get clock 'mout_hdmi'\n");
1721 		ret = PTR_ERR(hdata->mout_hdmi);
1722 		goto fail;
1723 	}
1724 
1725 	clk_set_parent(hdata->mout_hdmi, hdata->sclk_pixel);
1726 
1727 	for (i = 0; i < ARRAY_SIZE(supply); ++i) {
1728 		hdata->regul_bulk[i].supply = supply[i];
1729 		hdata->regul_bulk[i].consumer = NULL;
1730 	}
1731 	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), hdata->regul_bulk);
1732 	if (ret) {
1733 		DRM_ERROR("failed to get regulators\n");
1734 		return ret;
1735 	}
1736 
1737 	hdata->reg_hdmi_en = devm_regulator_get_optional(dev, "hdmi-en");
1738 
1739 	if (PTR_ERR(hdata->reg_hdmi_en) == -ENODEV)
1740 		return 0;
1741 
1742 	if (IS_ERR(hdata->reg_hdmi_en))
1743 		return PTR_ERR(hdata->reg_hdmi_en);
1744 
1745 	ret = regulator_enable(hdata->reg_hdmi_en);
1746 	if (ret)
1747 		DRM_ERROR("failed to enable hdmi-en regulator\n");
1748 
1749 	return ret;
1750 fail:
1751 	DRM_ERROR("HDMI resource init - failed\n");
1752 	return ret;
1753 }
1754 
1755 static struct of_device_id hdmi_match_types[] = {
1756 	{
1757 		.compatible = "samsung,exynos4210-hdmi",
1758 		.data = &exynos4210_hdmi_driver_data,
1759 	}, {
1760 		.compatible = "samsung,exynos4212-hdmi",
1761 		.data = &exynos4212_hdmi_driver_data,
1762 	}, {
1763 		.compatible = "samsung,exynos5420-hdmi",
1764 		.data = &exynos5420_hdmi_driver_data,
1765 	}, {
1766 		/* end node */
1767 	}
1768 };
1769 MODULE_DEVICE_TABLE (of, hdmi_match_types);
1770 
1771 static int hdmi_bind(struct device *dev, struct device *master, void *data)
1772 {
1773 	struct drm_device *drm_dev = data;
1774 	struct hdmi_context *hdata = dev_get_drvdata(dev);
1775 	struct drm_encoder *encoder = &hdata->encoder;
1776 	int ret, pipe;
1777 
1778 	hdata->drm_dev = drm_dev;
1779 
1780 	pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
1781 						  EXYNOS_DISPLAY_TYPE_HDMI);
1782 	if (pipe < 0)
1783 		return pipe;
1784 
1785 	encoder->possible_crtcs = 1 << pipe;
1786 
1787 	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
1788 
1789 	drm_encoder_init(drm_dev, encoder, &exynos_hdmi_encoder_funcs,
1790 			 DRM_MODE_ENCODER_TMDS, NULL);
1791 
1792 	drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
1793 
1794 	ret = hdmi_create_connector(encoder);
1795 	if (ret) {
1796 		DRM_ERROR("failed to create connector ret = %d\n", ret);
1797 		drm_encoder_cleanup(encoder);
1798 		return ret;
1799 	}
1800 
1801 	return 0;
1802 }
1803 
1804 static void hdmi_unbind(struct device *dev, struct device *master, void *data)
1805 {
1806 }
1807 
1808 static const struct component_ops hdmi_component_ops = {
1809 	.bind	= hdmi_bind,
1810 	.unbind = hdmi_unbind,
1811 };
1812 
1813 static struct device_node *hdmi_legacy_ddc_dt_binding(struct device *dev)
1814 {
1815 	const char *compatible_str = "samsung,exynos4210-hdmiddc";
1816 	struct device_node *np;
1817 
1818 	np = of_find_compatible_node(NULL, NULL, compatible_str);
1819 	if (np)
1820 		return of_get_next_parent(np);
1821 
1822 	return NULL;
1823 }
1824 
1825 static struct device_node *hdmi_legacy_phy_dt_binding(struct device *dev)
1826 {
1827 	const char *compatible_str = "samsung,exynos4212-hdmiphy";
1828 
1829 	return of_find_compatible_node(NULL, NULL, compatible_str);
1830 }
1831 
1832 static int hdmi_probe(struct platform_device *pdev)
1833 {
1834 	struct device_node *ddc_node, *phy_node;
1835 	const struct of_device_id *match;
1836 	struct device *dev = &pdev->dev;
1837 	struct hdmi_context *hdata;
1838 	struct resource *res;
1839 	int ret;
1840 
1841 	hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
1842 	if (!hdata)
1843 		return -ENOMEM;
1844 
1845 	match = of_match_device(hdmi_match_types, dev);
1846 	if (!match)
1847 		return -ENODEV;
1848 
1849 	hdata->drv_data = match->data;
1850 
1851 	platform_set_drvdata(pdev, hdata);
1852 
1853 	hdata->dev = dev;
1854 
1855 	ret = hdmi_resources_init(hdata);
1856 	if (ret) {
1857 		DRM_ERROR("hdmi_resources_init failed\n");
1858 		return ret;
1859 	}
1860 
1861 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1862 	hdata->regs = devm_ioremap_resource(dev, res);
1863 	if (IS_ERR(hdata->regs)) {
1864 		ret = PTR_ERR(hdata->regs);
1865 		return ret;
1866 	}
1867 
1868 	ddc_node = hdmi_legacy_ddc_dt_binding(dev);
1869 	if (ddc_node)
1870 		goto out_get_ddc_adpt;
1871 
1872 	/* DDC i2c driver */
1873 	ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
1874 	if (!ddc_node) {
1875 		DRM_ERROR("Failed to find ddc node in device tree\n");
1876 		return -ENODEV;
1877 	}
1878 
1879 out_get_ddc_adpt:
1880 	hdata->ddc_adpt = of_find_i2c_adapter_by_node(ddc_node);
1881 	if (!hdata->ddc_adpt) {
1882 		DRM_ERROR("Failed to get ddc i2c adapter by node\n");
1883 		return -EPROBE_DEFER;
1884 	}
1885 
1886 	phy_node = hdmi_legacy_phy_dt_binding(dev);
1887 	if (phy_node)
1888 		goto out_get_phy_port;
1889 
1890 	/* hdmiphy i2c driver */
1891 	phy_node = of_parse_phandle(dev->of_node, "phy", 0);
1892 	if (!phy_node) {
1893 		DRM_ERROR("Failed to find hdmiphy node in device tree\n");
1894 		ret = -ENODEV;
1895 		goto err_ddc;
1896 	}
1897 
1898 out_get_phy_port:
1899 	if (hdata->drv_data->is_apb_phy) {
1900 		hdata->regs_hdmiphy = of_iomap(phy_node, 0);
1901 		if (!hdata->regs_hdmiphy) {
1902 			DRM_ERROR("failed to ioremap hdmi phy\n");
1903 			ret = -ENOMEM;
1904 			goto err_ddc;
1905 		}
1906 	} else {
1907 		hdata->hdmiphy_port = of_find_i2c_device_by_node(phy_node);
1908 		if (!hdata->hdmiphy_port) {
1909 			DRM_ERROR("Failed to get hdmi phy i2c client\n");
1910 			ret = -EPROBE_DEFER;
1911 			goto err_ddc;
1912 		}
1913 	}
1914 
1915 	INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
1916 
1917 	ret = devm_request_threaded_irq(dev, hdata->irq, NULL,
1918 			hdmi_irq_thread, IRQF_TRIGGER_RISING |
1919 			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1920 			"hdmi", hdata);
1921 	if (ret) {
1922 		DRM_ERROR("failed to register hdmi interrupt\n");
1923 		goto err_hdmiphy;
1924 	}
1925 
1926 	hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
1927 			"samsung,syscon-phandle");
1928 	if (IS_ERR(hdata->pmureg)) {
1929 		DRM_ERROR("syscon regmap lookup failed.\n");
1930 		ret = -EPROBE_DEFER;
1931 		goto err_hdmiphy;
1932 	}
1933 
1934 	pm_runtime_enable(dev);
1935 
1936 	ret = component_add(&pdev->dev, &hdmi_component_ops);
1937 	if (ret)
1938 		goto err_disable_pm_runtime;
1939 
1940 	return ret;
1941 
1942 err_disable_pm_runtime:
1943 	pm_runtime_disable(dev);
1944 
1945 err_hdmiphy:
1946 	if (hdata->hdmiphy_port)
1947 		put_device(&hdata->hdmiphy_port->dev);
1948 err_ddc:
1949 	put_device(&hdata->ddc_adpt->dev);
1950 
1951 	return ret;
1952 }
1953 
1954 static int hdmi_remove(struct platform_device *pdev)
1955 {
1956 	struct hdmi_context *hdata = platform_get_drvdata(pdev);
1957 
1958 	cancel_delayed_work_sync(&hdata->hotplug_work);
1959 
1960 	component_del(&pdev->dev, &hdmi_component_ops);
1961 
1962 	pm_runtime_disable(&pdev->dev);
1963 
1964 	if (!IS_ERR(hdata->reg_hdmi_en))
1965 		regulator_disable(hdata->reg_hdmi_en);
1966 
1967 	if (hdata->hdmiphy_port)
1968 		put_device(&hdata->hdmiphy_port->dev);
1969 
1970 	put_device(&hdata->ddc_adpt->dev);
1971 
1972 	return 0;
1973 }
1974 
1975 #ifdef CONFIG_PM
1976 static int exynos_hdmi_suspend(struct device *dev)
1977 {
1978 	struct hdmi_context *hdata = dev_get_drvdata(dev);
1979 
1980 	clk_disable_unprepare(hdata->sclk_hdmi);
1981 	clk_disable_unprepare(hdata->hdmi);
1982 
1983 	return 0;
1984 }
1985 
1986 static int exynos_hdmi_resume(struct device *dev)
1987 {
1988 	struct hdmi_context *hdata = dev_get_drvdata(dev);
1989 	int ret;
1990 
1991 	ret = clk_prepare_enable(hdata->hdmi);
1992 	if (ret < 0) {
1993 		DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret);
1994 		return ret;
1995 	}
1996 	ret = clk_prepare_enable(hdata->sclk_hdmi);
1997 	if (ret < 0) {
1998 		DRM_ERROR("Failed to prepare_enable the sclk_mixer clk [%d]\n",
1999 			  ret);
2000 		return ret;
2001 	}
2002 
2003 	return 0;
2004 }
2005 #endif
2006 
2007 static const struct dev_pm_ops exynos_hdmi_pm_ops = {
2008 	SET_RUNTIME_PM_OPS(exynos_hdmi_suspend, exynos_hdmi_resume, NULL)
2009 };
2010 
2011 struct platform_driver hdmi_driver = {
2012 	.probe		= hdmi_probe,
2013 	.remove		= hdmi_remove,
2014 	.driver		= {
2015 		.name	= "exynos-hdmi",
2016 		.owner	= THIS_MODULE,
2017 		.pm	= &exynos_hdmi_pm_ops,
2018 		.of_match_table = hdmi_match_types,
2019 	},
2020 };
2021