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