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