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