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
21#include "regs-hdmi.h"
22
23#include <linux/kernel.h>
24#include <linux/spinlock.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/regulator/consumer.h>
34#include <linux/io.h>
35#include <linux/of.h>
36#include <linux/of_address.h>
37#include <linux/of_gpio.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#include "exynos_mixer.h"
48
49#include <linux/gpio.h>
50#include <media/s5p_hdmi.h>
51
52#define ctx_from_connector(c)	container_of(c, struct hdmi_context, connector)
53
54#define HOTPLUG_DEBOUNCE_MS		1100
55
56/* AVI header and aspect ratio */
57#define HDMI_AVI_VERSION		0x02
58#define HDMI_AVI_LENGTH		0x0D
59
60/* AUI header info */
61#define HDMI_AUI_VERSION	0x01
62#define HDMI_AUI_LENGTH	0x0A
63#define AVI_SAME_AS_PIC_ASPECT_RATIO 0x8
64#define AVI_4_3_CENTER_RATIO	0x9
65#define AVI_16_9_CENTER_RATIO	0xa
66
67enum hdmi_type {
68	HDMI_TYPE13,
69	HDMI_TYPE14,
70};
71
72struct hdmi_driver_data {
73	unsigned int type;
74	const struct hdmiphy_config *phy_confs;
75	unsigned int phy_conf_count;
76	unsigned int is_apb_phy:1;
77};
78
79struct hdmi_resources {
80	struct clk			*hdmi;
81	struct clk			*sclk_hdmi;
82	struct clk			*sclk_pixel;
83	struct clk			*sclk_hdmiphy;
84	struct clk			*mout_hdmi;
85	struct regulator_bulk_data	*regul_bulk;
86	struct regulator		*reg_hdmi_en;
87	int				regul_count;
88};
89
90struct hdmi_tg_regs {
91	u8 cmd[1];
92	u8 h_fsz[2];
93	u8 hact_st[2];
94	u8 hact_sz[2];
95	u8 v_fsz[2];
96	u8 vsync[2];
97	u8 vsync2[2];
98	u8 vact_st[2];
99	u8 vact_sz[2];
100	u8 field_chg[2];
101	u8 vact_st2[2];
102	u8 vact_st3[2];
103	u8 vact_st4[2];
104	u8 vsync_top_hdmi[2];
105	u8 vsync_bot_hdmi[2];
106	u8 field_top_hdmi[2];
107	u8 field_bot_hdmi[2];
108	u8 tg_3d[1];
109};
110
111struct hdmi_v13_core_regs {
112	u8 h_blank[2];
113	u8 v_blank[3];
114	u8 h_v_line[3];
115	u8 vsync_pol[1];
116	u8 int_pro_mode[1];
117	u8 v_blank_f[3];
118	u8 h_sync_gen[3];
119	u8 v_sync_gen1[3];
120	u8 v_sync_gen2[3];
121	u8 v_sync_gen3[3];
122};
123
124struct hdmi_v14_core_regs {
125	u8 h_blank[2];
126	u8 v2_blank[2];
127	u8 v1_blank[2];
128	u8 v_line[2];
129	u8 h_line[2];
130	u8 hsync_pol[1];
131	u8 vsync_pol[1];
132	u8 int_pro_mode[1];
133	u8 v_blank_f0[2];
134	u8 v_blank_f1[2];
135	u8 h_sync_start[2];
136	u8 h_sync_end[2];
137	u8 v_sync_line_bef_2[2];
138	u8 v_sync_line_bef_1[2];
139	u8 v_sync_line_aft_2[2];
140	u8 v_sync_line_aft_1[2];
141	u8 v_sync_line_aft_pxl_2[2];
142	u8 v_sync_line_aft_pxl_1[2];
143	u8 v_blank_f2[2]; /* for 3D mode */
144	u8 v_blank_f3[2]; /* for 3D mode */
145	u8 v_blank_f4[2]; /* for 3D mode */
146	u8 v_blank_f5[2]; /* for 3D mode */
147	u8 v_sync_line_aft_3[2];
148	u8 v_sync_line_aft_4[2];
149	u8 v_sync_line_aft_5[2];
150	u8 v_sync_line_aft_6[2];
151	u8 v_sync_line_aft_pxl_3[2];
152	u8 v_sync_line_aft_pxl_4[2];
153	u8 v_sync_line_aft_pxl_5[2];
154	u8 v_sync_line_aft_pxl_6[2];
155	u8 vact_space_1[2];
156	u8 vact_space_2[2];
157	u8 vact_space_3[2];
158	u8 vact_space_4[2];
159	u8 vact_space_5[2];
160	u8 vact_space_6[2];
161};
162
163struct hdmi_v13_conf {
164	struct hdmi_v13_core_regs core;
165	struct hdmi_tg_regs tg;
166};
167
168struct hdmi_v14_conf {
169	struct hdmi_v14_core_regs core;
170	struct hdmi_tg_regs tg;
171};
172
173struct hdmi_conf_regs {
174	int pixel_clock;
175	int cea_video_id;
176	enum hdmi_picture_aspect aspect_ratio;
177	union {
178		struct hdmi_v13_conf v13_conf;
179		struct hdmi_v14_conf v14_conf;
180	} conf;
181};
182
183struct hdmi_context {
184	struct exynos_drm_display	display;
185	struct device			*dev;
186	struct drm_device		*drm_dev;
187	struct drm_connector		connector;
188	struct drm_encoder		*encoder;
189	bool				hpd;
190	bool				powered;
191	bool				dvi_mode;
192	struct mutex			hdmi_mutex;
193
194	void __iomem			*regs;
195	int				irq;
196	struct delayed_work		hotplug_work;
197
198	struct i2c_adapter		*ddc_adpt;
199	struct i2c_client		*hdmiphy_port;
200
201	/* current hdmiphy conf regs */
202	struct drm_display_mode		current_mode;
203	struct hdmi_conf_regs		mode_conf;
204
205	struct hdmi_resources		res;
206
207	int				hpd_gpio;
208	void __iomem			*regs_hdmiphy;
209	const struct hdmiphy_config		*phy_confs;
210	unsigned int			phy_conf_count;
211
212	struct regmap			*pmureg;
213	enum hdmi_type			type;
214};
215
216static inline struct hdmi_context *display_to_hdmi(struct exynos_drm_display *d)
217{
218	return container_of(d, struct hdmi_context, display);
219}
220
221struct hdmiphy_config {
222	int pixel_clock;
223	u8 conf[32];
224};
225
226/* list of phy config settings */
227static const struct hdmiphy_config hdmiphy_v13_configs[] = {
228	{
229		.pixel_clock = 27000000,
230		.conf = {
231			0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
232			0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
233			0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
234			0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
235		},
236	},
237	{
238		.pixel_clock = 27027000,
239		.conf = {
240			0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
241			0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
242			0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
243			0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
244		},
245	},
246	{
247		.pixel_clock = 74176000,
248		.conf = {
249			0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
250			0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
251			0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
252			0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
253		},
254	},
255	{
256		.pixel_clock = 74250000,
257		.conf = {
258			0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
259			0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
260			0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
261			0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
262		},
263	},
264	{
265		.pixel_clock = 148500000,
266		.conf = {
267			0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
268			0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
269			0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
270			0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
271		},
272	},
273};
274
275static const struct hdmiphy_config hdmiphy_v14_configs[] = {
276	{
277		.pixel_clock = 25200000,
278		.conf = {
279			0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
280			0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
281			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
282			0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
283		},
284	},
285	{
286		.pixel_clock = 27000000,
287		.conf = {
288			0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
289			0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
290			0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
291			0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
292		},
293	},
294	{
295		.pixel_clock = 27027000,
296		.conf = {
297			0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
298			0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
299			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
300			0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
301		},
302	},
303	{
304		.pixel_clock = 36000000,
305		.conf = {
306			0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
307			0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
308			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
309			0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
310		},
311	},
312	{
313		.pixel_clock = 40000000,
314		.conf = {
315			0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
316			0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
317			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
318			0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
319		},
320	},
321	{
322		.pixel_clock = 65000000,
323		.conf = {
324			0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
325			0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
326			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
327			0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
328		},
329	},
330	{
331		.pixel_clock = 71000000,
332		.conf = {
333			0x01, 0xd1, 0x3b, 0x35, 0x40, 0x0c, 0x04, 0x08,
334			0x85, 0xa0, 0x63, 0xd9, 0x45, 0xa0, 0xac, 0x80,
335			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
336			0x54, 0xad, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
337		},
338	},
339	{
340		.pixel_clock = 73250000,
341		.conf = {
342			0x01, 0xd1, 0x3d, 0x35, 0x40, 0x18, 0x02, 0x08,
343			0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
344			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
345			0x54, 0xa8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
346		},
347	},
348	{
349		.pixel_clock = 74176000,
350		.conf = {
351			0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
352			0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
353			0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
354			0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
355		},
356	},
357	{
358		.pixel_clock = 74250000,
359		.conf = {
360			0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
361			0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
362			0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
363			0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
364		},
365	},
366	{
367		.pixel_clock = 83500000,
368		.conf = {
369			0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
370			0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
371			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
372			0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
373		},
374	},
375	{
376		.pixel_clock = 106500000,
377		.conf = {
378			0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
379			0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
380			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
381			0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
382		},
383	},
384	{
385		.pixel_clock = 108000000,
386		.conf = {
387			0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
388			0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
389			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
390			0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
391		},
392	},
393	{
394		.pixel_clock = 115500000,
395		.conf = {
396			0x01, 0xd1, 0x30, 0x12, 0x40, 0x40, 0x10, 0x08,
397			0x80, 0x80, 0x21, 0xd9, 0x45, 0xa0, 0xac, 0x80,
398			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
399			0x54, 0xaa, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
400		},
401	},
402	{
403		.pixel_clock = 119000000,
404		.conf = {
405			0x01, 0xd1, 0x32, 0x1a, 0x40, 0x30, 0xd8, 0x08,
406			0x04, 0xa0, 0x2a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
407			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
408			0x54, 0x9d, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
409		},
410	},
411	{
412		.pixel_clock = 146250000,
413		.conf = {
414			0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
415			0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
416			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
417			0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
418		},
419	},
420	{
421		.pixel_clock = 148500000,
422		.conf = {
423			0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
424			0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
425			0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
426			0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
427		},
428	},
429};
430
431static const struct hdmiphy_config hdmiphy_5420_configs[] = {
432	{
433		.pixel_clock = 25200000,
434		.conf = {
435			0x01, 0x52, 0x3F, 0x55, 0x40, 0x01, 0x00, 0xC8,
436			0x82, 0xC8, 0xBD, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
437			0x06, 0x80, 0x01, 0x84, 0x05, 0x02, 0x24, 0x66,
438			0x54, 0xF4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
439		},
440	},
441	{
442		.pixel_clock = 27000000,
443		.conf = {
444			0x01, 0xD1, 0x22, 0x51, 0x40, 0x08, 0xFC, 0xE0,
445			0x98, 0xE8, 0xCB, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
446			0x06, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
447			0x54, 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
448		},
449	},
450	{
451		.pixel_clock = 27027000,
452		.conf = {
453			0x01, 0xD1, 0x2D, 0x72, 0x40, 0x64, 0x12, 0xC8,
454			0x43, 0xE8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
455			0x26, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
456			0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
457		},
458	},
459	{
460		.pixel_clock = 36000000,
461		.conf = {
462			0x01, 0x51, 0x2D, 0x55, 0x40, 0x40, 0x00, 0xC8,
463			0x02, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
464			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
465			0x54, 0xAB, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
466		},
467	},
468	{
469		.pixel_clock = 40000000,
470		.conf = {
471			0x01, 0xD1, 0x21, 0x31, 0x40, 0x3C, 0x28, 0xC8,
472			0x87, 0xE8, 0xC8, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
473			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
474			0x54, 0x9A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
475		},
476	},
477	{
478		.pixel_clock = 65000000,
479		.conf = {
480			0x01, 0xD1, 0x36, 0x34, 0x40, 0x0C, 0x04, 0xC8,
481			0x82, 0xE8, 0x45, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
482			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
483			0x54, 0xBD, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
484		},
485	},
486	{
487		.pixel_clock = 71000000,
488		.conf = {
489			0x01, 0xD1, 0x3B, 0x35, 0x40, 0x0C, 0x04, 0xC8,
490			0x85, 0xE8, 0x63, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
491			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
492			0x54, 0x57, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
493		},
494	},
495	{
496		.pixel_clock = 73250000,
497		.conf = {
498			0x01, 0xD1, 0x1F, 0x10, 0x40, 0x78, 0x8D, 0xC8,
499			0x81, 0xE8, 0xB7, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
500			0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
501			0x54, 0xA8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
502		},
503	},
504	{
505		.pixel_clock = 74176000,
506		.conf = {
507			0x01, 0xD1, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0xC8,
508			0x81, 0xE8, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
509			0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
510			0x54, 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
511		},
512	},
513	{
514		.pixel_clock = 74250000,
515		.conf = {
516			0x01, 0xD1, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0x08,
517			0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
518			0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
519			0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
520		},
521	},
522	{
523		.pixel_clock = 83500000,
524		.conf = {
525			0x01, 0xD1, 0x23, 0x11, 0x40, 0x0C, 0xFB, 0xC8,
526			0x85, 0xE8, 0xD1, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
527			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
528			0x54, 0x4A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
529		},
530	},
531	{
532		.pixel_clock = 88750000,
533		.conf = {
534			0x01, 0xD1, 0x25, 0x11, 0x40, 0x18, 0xFF, 0xC8,
535			0x83, 0xE8, 0xDE, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
536			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
537			0x54, 0x45, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
538		},
539	},
540	{
541		.pixel_clock = 106500000,
542		.conf = {
543			0x01, 0xD1, 0x2C, 0x12, 0x40, 0x0C, 0x09, 0xC8,
544			0x84, 0xE8, 0x0A, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
545			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
546			0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
547		},
548	},
549	{
550		.pixel_clock = 108000000,
551		.conf = {
552			0x01, 0x51, 0x2D, 0x15, 0x40, 0x01, 0x00, 0xC8,
553			0x82, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
554			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
555			0x54, 0xC7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
556		},
557	},
558	{
559		.pixel_clock = 115500000,
560		.conf = {
561			0x01, 0xD1, 0x30, 0x14, 0x40, 0x0C, 0x03, 0xC8,
562			0x88, 0xE8, 0x21, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
563			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
564			0x54, 0x6A, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
565		},
566	},
567	{
568		.pixel_clock = 146250000,
569		.conf = {
570			0x01, 0xD1, 0x3D, 0x15, 0x40, 0x18, 0xFD, 0xC8,
571			0x83, 0xE8, 0x6E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
572			0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
573			0x54, 0x54, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
574		},
575	},
576	{
577		.pixel_clock = 148500000,
578		.conf = {
579			0x01, 0xD1, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0x08,
580			0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
581			0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
582			0x54, 0x4B, 0x25, 0x03, 0x00, 0x80, 0x01, 0x80,
583		},
584	},
585};
586
587static struct hdmi_driver_data exynos5420_hdmi_driver_data = {
588	.type		= HDMI_TYPE14,
589	.phy_confs	= hdmiphy_5420_configs,
590	.phy_conf_count	= ARRAY_SIZE(hdmiphy_5420_configs),
591	.is_apb_phy	= 1,
592};
593
594static struct hdmi_driver_data exynos4212_hdmi_driver_data = {
595	.type		= HDMI_TYPE14,
596	.phy_confs	= hdmiphy_v14_configs,
597	.phy_conf_count	= ARRAY_SIZE(hdmiphy_v14_configs),
598	.is_apb_phy	= 0,
599};
600
601static struct hdmi_driver_data exynos4210_hdmi_driver_data = {
602	.type		= HDMI_TYPE13,
603	.phy_confs	= hdmiphy_v13_configs,
604	.phy_conf_count	= ARRAY_SIZE(hdmiphy_v13_configs),
605	.is_apb_phy	= 0,
606};
607
608static struct hdmi_driver_data exynos5_hdmi_driver_data = {
609	.type		= HDMI_TYPE14,
610	.phy_confs	= hdmiphy_v13_configs,
611	.phy_conf_count	= ARRAY_SIZE(hdmiphy_v13_configs),
612	.is_apb_phy	= 0,
613};
614
615static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
616{
617	return readl(hdata->regs + reg_id);
618}
619
620static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
621				 u32 reg_id, u8 value)
622{
623	writeb(value, hdata->regs + reg_id);
624}
625
626static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
627				 u32 reg_id, u32 value, u32 mask)
628{
629	u32 old = readl(hdata->regs + reg_id);
630	value = (value & mask) | (old & ~mask);
631	writel(value, hdata->regs + reg_id);
632}
633
634static int hdmiphy_reg_writeb(struct hdmi_context *hdata,
635			u32 reg_offset, u8 value)
636{
637	if (hdata->hdmiphy_port) {
638		u8 buffer[2];
639		int ret;
640
641		buffer[0] = reg_offset;
642		buffer[1] = value;
643
644		ret = i2c_master_send(hdata->hdmiphy_port, buffer, 2);
645		if (ret == 2)
646			return 0;
647		return ret;
648	} else {
649		writeb(value, hdata->regs_hdmiphy + (reg_offset<<2));
650		return 0;
651	}
652}
653
654static int hdmiphy_reg_write_buf(struct hdmi_context *hdata,
655			u32 reg_offset, const u8 *buf, u32 len)
656{
657	if ((reg_offset + len) > 32)
658		return -EINVAL;
659
660	if (hdata->hdmiphy_port) {
661		int ret;
662
663		ret = i2c_master_send(hdata->hdmiphy_port, buf, len);
664		if (ret == len)
665			return 0;
666		return ret;
667	} else {
668		int i;
669		for (i = 0; i < len; i++)
670			writeb(buf[i], hdata->regs_hdmiphy +
671				((reg_offset + i)<<2));
672		return 0;
673	}
674}
675
676static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix)
677{
678#define DUMPREG(reg_id) \
679	DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
680	readl(hdata->regs + reg_id))
681	DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
682	DUMPREG(HDMI_INTC_FLAG);
683	DUMPREG(HDMI_INTC_CON);
684	DUMPREG(HDMI_HPD_STATUS);
685	DUMPREG(HDMI_V13_PHY_RSTOUT);
686	DUMPREG(HDMI_V13_PHY_VPLL);
687	DUMPREG(HDMI_V13_PHY_CMU);
688	DUMPREG(HDMI_V13_CORE_RSTOUT);
689
690	DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
691	DUMPREG(HDMI_CON_0);
692	DUMPREG(HDMI_CON_1);
693	DUMPREG(HDMI_CON_2);
694	DUMPREG(HDMI_SYS_STATUS);
695	DUMPREG(HDMI_V13_PHY_STATUS);
696	DUMPREG(HDMI_STATUS_EN);
697	DUMPREG(HDMI_HPD);
698	DUMPREG(HDMI_MODE_SEL);
699	DUMPREG(HDMI_V13_HPD_GEN);
700	DUMPREG(HDMI_V13_DC_CONTROL);
701	DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN);
702
703	DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
704	DUMPREG(HDMI_H_BLANK_0);
705	DUMPREG(HDMI_H_BLANK_1);
706	DUMPREG(HDMI_V13_V_BLANK_0);
707	DUMPREG(HDMI_V13_V_BLANK_1);
708	DUMPREG(HDMI_V13_V_BLANK_2);
709	DUMPREG(HDMI_V13_H_V_LINE_0);
710	DUMPREG(HDMI_V13_H_V_LINE_1);
711	DUMPREG(HDMI_V13_H_V_LINE_2);
712	DUMPREG(HDMI_VSYNC_POL);
713	DUMPREG(HDMI_INT_PRO_MODE);
714	DUMPREG(HDMI_V13_V_BLANK_F_0);
715	DUMPREG(HDMI_V13_V_BLANK_F_1);
716	DUMPREG(HDMI_V13_V_BLANK_F_2);
717	DUMPREG(HDMI_V13_H_SYNC_GEN_0);
718	DUMPREG(HDMI_V13_H_SYNC_GEN_1);
719	DUMPREG(HDMI_V13_H_SYNC_GEN_2);
720	DUMPREG(HDMI_V13_V_SYNC_GEN_1_0);
721	DUMPREG(HDMI_V13_V_SYNC_GEN_1_1);
722	DUMPREG(HDMI_V13_V_SYNC_GEN_1_2);
723	DUMPREG(HDMI_V13_V_SYNC_GEN_2_0);
724	DUMPREG(HDMI_V13_V_SYNC_GEN_2_1);
725	DUMPREG(HDMI_V13_V_SYNC_GEN_2_2);
726	DUMPREG(HDMI_V13_V_SYNC_GEN_3_0);
727	DUMPREG(HDMI_V13_V_SYNC_GEN_3_1);
728	DUMPREG(HDMI_V13_V_SYNC_GEN_3_2);
729
730	DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
731	DUMPREG(HDMI_TG_CMD);
732	DUMPREG(HDMI_TG_H_FSZ_L);
733	DUMPREG(HDMI_TG_H_FSZ_H);
734	DUMPREG(HDMI_TG_HACT_ST_L);
735	DUMPREG(HDMI_TG_HACT_ST_H);
736	DUMPREG(HDMI_TG_HACT_SZ_L);
737	DUMPREG(HDMI_TG_HACT_SZ_H);
738	DUMPREG(HDMI_TG_V_FSZ_L);
739	DUMPREG(HDMI_TG_V_FSZ_H);
740	DUMPREG(HDMI_TG_VSYNC_L);
741	DUMPREG(HDMI_TG_VSYNC_H);
742	DUMPREG(HDMI_TG_VSYNC2_L);
743	DUMPREG(HDMI_TG_VSYNC2_H);
744	DUMPREG(HDMI_TG_VACT_ST_L);
745	DUMPREG(HDMI_TG_VACT_ST_H);
746	DUMPREG(HDMI_TG_VACT_SZ_L);
747	DUMPREG(HDMI_TG_VACT_SZ_H);
748	DUMPREG(HDMI_TG_FIELD_CHG_L);
749	DUMPREG(HDMI_TG_FIELD_CHG_H);
750	DUMPREG(HDMI_TG_VACT_ST2_L);
751	DUMPREG(HDMI_TG_VACT_ST2_H);
752	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
753	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
754	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
755	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
756	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
757	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
758	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
759	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
760#undef DUMPREG
761}
762
763static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix)
764{
765	int i;
766
767#define DUMPREG(reg_id) \
768	DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
769	readl(hdata->regs + reg_id))
770
771	DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
772	DUMPREG(HDMI_INTC_CON);
773	DUMPREG(HDMI_INTC_FLAG);
774	DUMPREG(HDMI_HPD_STATUS);
775	DUMPREG(HDMI_INTC_CON_1);
776	DUMPREG(HDMI_INTC_FLAG_1);
777	DUMPREG(HDMI_PHY_STATUS_0);
778	DUMPREG(HDMI_PHY_STATUS_PLL);
779	DUMPREG(HDMI_PHY_CON_0);
780	DUMPREG(HDMI_PHY_RSTOUT);
781	DUMPREG(HDMI_PHY_VPLL);
782	DUMPREG(HDMI_PHY_CMU);
783	DUMPREG(HDMI_CORE_RSTOUT);
784
785	DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
786	DUMPREG(HDMI_CON_0);
787	DUMPREG(HDMI_CON_1);
788	DUMPREG(HDMI_CON_2);
789	DUMPREG(HDMI_SYS_STATUS);
790	DUMPREG(HDMI_PHY_STATUS_0);
791	DUMPREG(HDMI_STATUS_EN);
792	DUMPREG(HDMI_HPD);
793	DUMPREG(HDMI_MODE_SEL);
794	DUMPREG(HDMI_ENC_EN);
795	DUMPREG(HDMI_DC_CONTROL);
796	DUMPREG(HDMI_VIDEO_PATTERN_GEN);
797
798	DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
799	DUMPREG(HDMI_H_BLANK_0);
800	DUMPREG(HDMI_H_BLANK_1);
801	DUMPREG(HDMI_V2_BLANK_0);
802	DUMPREG(HDMI_V2_BLANK_1);
803	DUMPREG(HDMI_V1_BLANK_0);
804	DUMPREG(HDMI_V1_BLANK_1);
805	DUMPREG(HDMI_V_LINE_0);
806	DUMPREG(HDMI_V_LINE_1);
807	DUMPREG(HDMI_H_LINE_0);
808	DUMPREG(HDMI_H_LINE_1);
809	DUMPREG(HDMI_HSYNC_POL);
810
811	DUMPREG(HDMI_VSYNC_POL);
812	DUMPREG(HDMI_INT_PRO_MODE);
813	DUMPREG(HDMI_V_BLANK_F0_0);
814	DUMPREG(HDMI_V_BLANK_F0_1);
815	DUMPREG(HDMI_V_BLANK_F1_0);
816	DUMPREG(HDMI_V_BLANK_F1_1);
817
818	DUMPREG(HDMI_H_SYNC_START_0);
819	DUMPREG(HDMI_H_SYNC_START_1);
820	DUMPREG(HDMI_H_SYNC_END_0);
821	DUMPREG(HDMI_H_SYNC_END_1);
822
823	DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0);
824	DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1);
825	DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0);
826	DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1);
827
828	DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0);
829	DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1);
830	DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0);
831	DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1);
832
833	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0);
834	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1);
835	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0);
836	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1);
837
838	DUMPREG(HDMI_V_BLANK_F2_0);
839	DUMPREG(HDMI_V_BLANK_F2_1);
840	DUMPREG(HDMI_V_BLANK_F3_0);
841	DUMPREG(HDMI_V_BLANK_F3_1);
842	DUMPREG(HDMI_V_BLANK_F4_0);
843	DUMPREG(HDMI_V_BLANK_F4_1);
844	DUMPREG(HDMI_V_BLANK_F5_0);
845	DUMPREG(HDMI_V_BLANK_F5_1);
846
847	DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0);
848	DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1);
849	DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0);
850	DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1);
851	DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0);
852	DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1);
853	DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0);
854	DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1);
855
856	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0);
857	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1);
858	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0);
859	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1);
860	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0);
861	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1);
862	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0);
863	DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1);
864
865	DUMPREG(HDMI_VACT_SPACE_1_0);
866	DUMPREG(HDMI_VACT_SPACE_1_1);
867	DUMPREG(HDMI_VACT_SPACE_2_0);
868	DUMPREG(HDMI_VACT_SPACE_2_1);
869	DUMPREG(HDMI_VACT_SPACE_3_0);
870	DUMPREG(HDMI_VACT_SPACE_3_1);
871	DUMPREG(HDMI_VACT_SPACE_4_0);
872	DUMPREG(HDMI_VACT_SPACE_4_1);
873	DUMPREG(HDMI_VACT_SPACE_5_0);
874	DUMPREG(HDMI_VACT_SPACE_5_1);
875	DUMPREG(HDMI_VACT_SPACE_6_0);
876	DUMPREG(HDMI_VACT_SPACE_6_1);
877
878	DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
879	DUMPREG(HDMI_TG_CMD);
880	DUMPREG(HDMI_TG_H_FSZ_L);
881	DUMPREG(HDMI_TG_H_FSZ_H);
882	DUMPREG(HDMI_TG_HACT_ST_L);
883	DUMPREG(HDMI_TG_HACT_ST_H);
884	DUMPREG(HDMI_TG_HACT_SZ_L);
885	DUMPREG(HDMI_TG_HACT_SZ_H);
886	DUMPREG(HDMI_TG_V_FSZ_L);
887	DUMPREG(HDMI_TG_V_FSZ_H);
888	DUMPREG(HDMI_TG_VSYNC_L);
889	DUMPREG(HDMI_TG_VSYNC_H);
890	DUMPREG(HDMI_TG_VSYNC2_L);
891	DUMPREG(HDMI_TG_VSYNC2_H);
892	DUMPREG(HDMI_TG_VACT_ST_L);
893	DUMPREG(HDMI_TG_VACT_ST_H);
894	DUMPREG(HDMI_TG_VACT_SZ_L);
895	DUMPREG(HDMI_TG_VACT_SZ_H);
896	DUMPREG(HDMI_TG_FIELD_CHG_L);
897	DUMPREG(HDMI_TG_FIELD_CHG_H);
898	DUMPREG(HDMI_TG_VACT_ST2_L);
899	DUMPREG(HDMI_TG_VACT_ST2_H);
900	DUMPREG(HDMI_TG_VACT_ST3_L);
901	DUMPREG(HDMI_TG_VACT_ST3_H);
902	DUMPREG(HDMI_TG_VACT_ST4_L);
903	DUMPREG(HDMI_TG_VACT_ST4_H);
904	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
905	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
906	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
907	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
908	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
909	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
910	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
911	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
912	DUMPREG(HDMI_TG_3D);
913
914	DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix);
915	DUMPREG(HDMI_AVI_CON);
916	DUMPREG(HDMI_AVI_HEADER0);
917	DUMPREG(HDMI_AVI_HEADER1);
918	DUMPREG(HDMI_AVI_HEADER2);
919	DUMPREG(HDMI_AVI_CHECK_SUM);
920	DUMPREG(HDMI_VSI_CON);
921	DUMPREG(HDMI_VSI_HEADER0);
922	DUMPREG(HDMI_VSI_HEADER1);
923	DUMPREG(HDMI_VSI_HEADER2);
924	for (i = 0; i < 7; ++i)
925		DUMPREG(HDMI_VSI_DATA(i));
926
927#undef DUMPREG
928}
929
930static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
931{
932	if (hdata->type == HDMI_TYPE13)
933		hdmi_v13_regs_dump(hdata, prefix);
934	else
935		hdmi_v14_regs_dump(hdata, prefix);
936}
937
938static u8 hdmi_chksum(struct hdmi_context *hdata,
939			u32 start, u8 len, u32 hdr_sum)
940{
941	int i;
942
943	/* hdr_sum : header0 + header1 + header2
944	* start : start address of packet byte1
945	* len : packet bytes - 1 */
946	for (i = 0; i < len; ++i)
947		hdr_sum += 0xff & hdmi_reg_read(hdata, start + i * 4);
948
949	/* return 2's complement of 8 bit hdr_sum */
950	return (u8)(~(hdr_sum & 0xff) + 1);
951}
952
953static void hdmi_reg_infoframe(struct hdmi_context *hdata,
954			union hdmi_infoframe *infoframe)
955{
956	u32 hdr_sum;
957	u8 chksum;
958	u32 mod;
959	u32 vic;
960
961	mod = hdmi_reg_read(hdata, HDMI_MODE_SEL);
962	if (hdata->dvi_mode) {
963		hdmi_reg_writeb(hdata, HDMI_VSI_CON,
964				HDMI_VSI_CON_DO_NOT_TRANSMIT);
965		hdmi_reg_writeb(hdata, HDMI_AVI_CON,
966				HDMI_AVI_CON_DO_NOT_TRANSMIT);
967		hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_NO_TRAN);
968		return;
969	}
970
971	switch (infoframe->any.type) {
972	case HDMI_INFOFRAME_TYPE_AVI:
973		hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC);
974		hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->any.type);
975		hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1,
976				infoframe->any.version);
977		hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->any.length);
978		hdr_sum = infoframe->any.type + infoframe->any.version +
979			  infoframe->any.length;
980
981		/* Output format zero hardcoded ,RGB YBCR selection */
982		hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 |
983			AVI_ACTIVE_FORMAT_VALID |
984			AVI_UNDERSCANNED_DISPLAY_VALID);
985
986		/*
987		 * Set the aspect ratio as per the mode, mentioned in
988		 * Table 9 AVI InfoFrame Data Byte 2 of CEA-861-D Standard
989		 */
990		switch (hdata->mode_conf.aspect_ratio) {
991		case HDMI_PICTURE_ASPECT_4_3:
992			hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2),
993					hdata->mode_conf.aspect_ratio |
994					AVI_4_3_CENTER_RATIO);
995			break;
996		case HDMI_PICTURE_ASPECT_16_9:
997			hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2),
998					hdata->mode_conf.aspect_ratio |
999					AVI_16_9_CENTER_RATIO);
1000			break;
1001		case HDMI_PICTURE_ASPECT_NONE:
1002		default:
1003			hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2),
1004					hdata->mode_conf.aspect_ratio |
1005					AVI_SAME_AS_PIC_ASPECT_RATIO);
1006			break;
1007		}
1008
1009		vic = hdata->mode_conf.cea_video_id;
1010		hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), vic);
1011
1012		chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1),
1013					infoframe->any.length, hdr_sum);
1014		DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum);
1015		hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum);
1016		break;
1017	case HDMI_INFOFRAME_TYPE_AUDIO:
1018		hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02);
1019		hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->any.type);
1020		hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1,
1021				infoframe->any.version);
1022		hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->any.length);
1023		hdr_sum = infoframe->any.type + infoframe->any.version +
1024			  infoframe->any.length;
1025		chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1),
1026					infoframe->any.length, hdr_sum);
1027		DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum);
1028		hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum);
1029		break;
1030	default:
1031		break;
1032	}
1033}
1034
1035static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
1036				bool force)
1037{
1038	struct hdmi_context *hdata = ctx_from_connector(connector);
1039
1040	hdata->hpd = gpio_get_value(hdata->hpd_gpio);
1041
1042	return hdata->hpd ? connector_status_connected :
1043			connector_status_disconnected;
1044}
1045
1046static void hdmi_connector_destroy(struct drm_connector *connector)
1047{
1048	drm_connector_unregister(connector);
1049	drm_connector_cleanup(connector);
1050}
1051
1052static struct drm_connector_funcs hdmi_connector_funcs = {
1053	.dpms = drm_helper_connector_dpms,
1054	.fill_modes = drm_helper_probe_single_connector_modes,
1055	.detect = hdmi_detect,
1056	.destroy = hdmi_connector_destroy,
1057};
1058
1059static int hdmi_get_modes(struct drm_connector *connector)
1060{
1061	struct hdmi_context *hdata = ctx_from_connector(connector);
1062	struct edid *edid;
1063
1064	if (!hdata->ddc_adpt)
1065		return -ENODEV;
1066
1067	edid = drm_get_edid(connector, hdata->ddc_adpt);
1068	if (!edid)
1069		return -ENODEV;
1070
1071	hdata->dvi_mode = !drm_detect_hdmi_monitor(edid);
1072	DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
1073		(hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
1074		edid->width_cm, edid->height_cm);
1075
1076	drm_mode_connector_update_edid_property(connector, edid);
1077
1078	return drm_add_edid_modes(connector, edid);
1079}
1080
1081static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
1082{
1083	int i;
1084
1085	for (i = 0; i < hdata->phy_conf_count; i++)
1086		if (hdata->phy_confs[i].pixel_clock == pixel_clock)
1087			return i;
1088
1089	DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
1090	return -EINVAL;
1091}
1092
1093static int hdmi_mode_valid(struct drm_connector *connector,
1094			struct drm_display_mode *mode)
1095{
1096	struct hdmi_context *hdata = ctx_from_connector(connector);
1097	int ret;
1098
1099	DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
1100		mode->hdisplay, mode->vdisplay, mode->vrefresh,
1101		(mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
1102		false, mode->clock * 1000);
1103
1104	ret = mixer_check_mode(mode);
1105	if (ret)
1106		return MODE_BAD;
1107
1108	ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
1109	if (ret < 0)
1110		return MODE_BAD;
1111
1112	return MODE_OK;
1113}
1114
1115static struct drm_encoder *hdmi_best_encoder(struct drm_connector *connector)
1116{
1117	struct hdmi_context *hdata = ctx_from_connector(connector);
1118
1119	return hdata->encoder;
1120}
1121
1122static struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
1123	.get_modes = hdmi_get_modes,
1124	.mode_valid = hdmi_mode_valid,
1125	.best_encoder = hdmi_best_encoder,
1126};
1127
1128static int hdmi_create_connector(struct exynos_drm_display *display,
1129			struct drm_encoder *encoder)
1130{
1131	struct hdmi_context *hdata = display_to_hdmi(display);
1132	struct drm_connector *connector = &hdata->connector;
1133	int ret;
1134
1135	hdata->encoder = encoder;
1136	connector->interlace_allowed = true;
1137	connector->polled = DRM_CONNECTOR_POLL_HPD;
1138
1139	ret = drm_connector_init(hdata->drm_dev, connector,
1140			&hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA);
1141	if (ret) {
1142		DRM_ERROR("Failed to initialize connector with drm\n");
1143		return ret;
1144	}
1145
1146	drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
1147	drm_connector_register(connector);
1148	drm_mode_connector_attach_encoder(connector, encoder);
1149
1150	return 0;
1151}
1152
1153static void hdmi_mode_fixup(struct exynos_drm_display *display,
1154				struct drm_connector *connector,
1155				const struct drm_display_mode *mode,
1156				struct drm_display_mode *adjusted_mode)
1157{
1158	struct drm_display_mode *m;
1159	int mode_ok;
1160
1161	DRM_DEBUG_KMS("%s\n", __FILE__);
1162
1163	drm_mode_set_crtcinfo(adjusted_mode, 0);
1164
1165	mode_ok = hdmi_mode_valid(connector, adjusted_mode);
1166
1167	/* just return if user desired mode exists. */
1168	if (mode_ok == MODE_OK)
1169		return;
1170
1171	/*
1172	 * otherwise, find the most suitable mode among modes and change it
1173	 * to adjusted_mode.
1174	 */
1175	list_for_each_entry(m, &connector->modes, head) {
1176		mode_ok = hdmi_mode_valid(connector, m);
1177
1178		if (mode_ok == MODE_OK) {
1179			DRM_INFO("desired mode doesn't exist so\n");
1180			DRM_INFO("use the most suitable mode among modes.\n");
1181
1182			DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n",
1183				m->hdisplay, m->vdisplay, m->vrefresh);
1184
1185			drm_mode_copy(adjusted_mode, m);
1186			break;
1187		}
1188	}
1189}
1190
1191static void hdmi_set_acr(u32 freq, u8 *acr)
1192{
1193	u32 n, cts;
1194
1195	switch (freq) {
1196	case 32000:
1197		n = 4096;
1198		cts = 27000;
1199		break;
1200	case 44100:
1201		n = 6272;
1202		cts = 30000;
1203		break;
1204	case 88200:
1205		n = 12544;
1206		cts = 30000;
1207		break;
1208	case 176400:
1209		n = 25088;
1210		cts = 30000;
1211		break;
1212	case 48000:
1213		n = 6144;
1214		cts = 27000;
1215		break;
1216	case 96000:
1217		n = 12288;
1218		cts = 27000;
1219		break;
1220	case 192000:
1221		n = 24576;
1222		cts = 27000;
1223		break;
1224	default:
1225		n = 0;
1226		cts = 0;
1227		break;
1228	}
1229
1230	acr[1] = cts >> 16;
1231	acr[2] = cts >> 8 & 0xff;
1232	acr[3] = cts & 0xff;
1233
1234	acr[4] = n >> 16;
1235	acr[5] = n >> 8 & 0xff;
1236	acr[6] = n & 0xff;
1237}
1238
1239static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr)
1240{
1241	hdmi_reg_writeb(hdata, HDMI_ACR_N0, acr[6]);
1242	hdmi_reg_writeb(hdata, HDMI_ACR_N1, acr[5]);
1243	hdmi_reg_writeb(hdata, HDMI_ACR_N2, acr[4]);
1244	hdmi_reg_writeb(hdata, HDMI_ACR_MCTS0, acr[3]);
1245	hdmi_reg_writeb(hdata, HDMI_ACR_MCTS1, acr[2]);
1246	hdmi_reg_writeb(hdata, HDMI_ACR_MCTS2, acr[1]);
1247	hdmi_reg_writeb(hdata, HDMI_ACR_CTS0, acr[3]);
1248	hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]);
1249	hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]);
1250
1251	if (hdata->type == HDMI_TYPE13)
1252		hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4);
1253	else
1254		hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1255}
1256
1257static void hdmi_audio_init(struct hdmi_context *hdata)
1258{
1259	u32 sample_rate, bits_per_sample;
1260	u32 data_num, bit_ch, sample_frq;
1261	u32 val;
1262	u8 acr[7];
1263
1264	sample_rate = 44100;
1265	bits_per_sample = 16;
1266
1267	switch (bits_per_sample) {
1268	case 20:
1269		data_num = 2;
1270		bit_ch  = 1;
1271		break;
1272	case 24:
1273		data_num = 3;
1274		bit_ch  = 1;
1275		break;
1276	default:
1277		data_num = 1;
1278		bit_ch  = 0;
1279		break;
1280	}
1281
1282	hdmi_set_acr(sample_rate, acr);
1283	hdmi_reg_acr(hdata, acr);
1284
1285	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1286				| HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1287				| HDMI_I2S_MUX_ENABLE);
1288
1289	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1290			| HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1291
1292	hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1293
1294	sample_frq = (sample_rate == 44100) ? 0 :
1295			(sample_rate == 48000) ? 2 :
1296			(sample_rate == 32000) ? 3 :
1297			(sample_rate == 96000) ? 0xa : 0x0;
1298
1299	hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1300	hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1301
1302	val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1303	hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1304
1305	/* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1306	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1307			| HDMI_I2S_SEL_LRCK(6));
1308	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1309			| HDMI_I2S_SEL_SDATA2(4));
1310	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1311			| HDMI_I2S_SEL_SDATA2(2));
1312	hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1313
1314	/* I2S_CON_1 & 2 */
1315	hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1316			| HDMI_I2S_L_CH_LOW_POL);
1317	hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1318			| HDMI_I2S_SET_BIT_CH(bit_ch)
1319			| HDMI_I2S_SET_SDATA_BIT(data_num)
1320			| HDMI_I2S_BASIC_FORMAT);
1321
1322	/* Configure register related to CUV information */
1323	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
1324			| HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1325			| HDMI_I2S_COPYRIGHT
1326			| HDMI_I2S_LINEAR_PCM
1327			| HDMI_I2S_CONSUMER_FORMAT);
1328	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1329	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1330	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1331			| HDMI_I2S_SET_SMP_FREQ(sample_frq));
1332	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1333			HDMI_I2S_ORG_SMP_FREQ_44_1
1334			| HDMI_I2S_WORD_LEN_MAX24_24BITS
1335			| HDMI_I2S_WORD_LEN_MAX_24BITS);
1336
1337	hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1338}
1339
1340static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1341{
1342	if (hdata->dvi_mode)
1343		return;
1344
1345	hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
1346	hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ?
1347			HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1348}
1349
1350static void hdmi_start(struct hdmi_context *hdata, bool start)
1351{
1352	u32 val = start ? HDMI_TG_EN : 0;
1353
1354	if (hdata->current_mode.flags & DRM_MODE_FLAG_INTERLACE)
1355		val |= HDMI_FIELD_EN;
1356
1357	hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN);
1358	hdmi_reg_writemask(hdata, HDMI_TG_CMD, val, HDMI_TG_EN | HDMI_FIELD_EN);
1359}
1360
1361static void hdmi_conf_init(struct hdmi_context *hdata)
1362{
1363	union hdmi_infoframe infoframe;
1364
1365	/* disable HPD interrupts from HDMI IP block, use GPIO instead */
1366	hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1367		HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1368
1369	/* choose HDMI mode */
1370	hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1371		HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1372	/* Apply Video preable and Guard band in HDMI mode only */
1373	hdmi_reg_writeb(hdata, HDMI_CON_2, 0);
1374	/* disable bluescreen */
1375	hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1376
1377	if (hdata->dvi_mode) {
1378		/* choose DVI mode */
1379		hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1380				HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1381		hdmi_reg_writeb(hdata, HDMI_CON_2,
1382				HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1383	}
1384
1385	if (hdata->type == HDMI_TYPE13) {
1386		/* choose bluescreen (fecal) color */
1387		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1388		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1389		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1390
1391		/* enable AVI packet every vsync, fixes purple line problem */
1392		hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1393		/* force RGB, look to CEA-861-D, table 7 for more detail */
1394		hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1395		hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1396
1397		hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1398		hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1399		hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1400	} else {
1401		infoframe.any.type = HDMI_INFOFRAME_TYPE_AVI;
1402		infoframe.any.version = HDMI_AVI_VERSION;
1403		infoframe.any.length = HDMI_AVI_LENGTH;
1404		hdmi_reg_infoframe(hdata, &infoframe);
1405
1406		infoframe.any.type = HDMI_INFOFRAME_TYPE_AUDIO;
1407		infoframe.any.version = HDMI_AUI_VERSION;
1408		infoframe.any.length = HDMI_AUI_LENGTH;
1409		hdmi_reg_infoframe(hdata, &infoframe);
1410
1411		/* enable AVI packet every vsync, fixes purple line problem */
1412		hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1413	}
1414}
1415
1416static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1417{
1418	const struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v13_conf.tg;
1419	const struct hdmi_v13_core_regs *core =
1420		&hdata->mode_conf.conf.v13_conf.core;
1421	int tries;
1422
1423	/* setting core registers */
1424	hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1425	hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1426	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_0, core->v_blank[0]);
1427	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_1, core->v_blank[1]);
1428	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_2, core->v_blank[2]);
1429	hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_0, core->h_v_line[0]);
1430	hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_1, core->h_v_line[1]);
1431	hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_2, core->h_v_line[2]);
1432	hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1433	hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1434	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_0, core->v_blank_f[0]);
1435	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_1, core->v_blank_f[1]);
1436	hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_2, core->v_blank_f[2]);
1437	hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_0, core->h_sync_gen[0]);
1438	hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_1, core->h_sync_gen[1]);
1439	hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_2, core->h_sync_gen[2]);
1440	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_0, core->v_sync_gen1[0]);
1441	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_1, core->v_sync_gen1[1]);
1442	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_2, core->v_sync_gen1[2]);
1443	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_0, core->v_sync_gen2[0]);
1444	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_1, core->v_sync_gen2[1]);
1445	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_2, core->v_sync_gen2[2]);
1446	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_0, core->v_sync_gen3[0]);
1447	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]);
1448	hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]);
1449	/* Timing generator registers */
1450	hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz[0]);
1451	hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz[1]);
1452	hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st[0]);
1453	hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st[1]);
1454	hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz[0]);
1455	hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz[1]);
1456	hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz[0]);
1457	hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz[1]);
1458	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync[0]);
1459	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync[1]);
1460	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2[0]);
1461	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2[1]);
1462	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st[0]);
1463	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st[1]);
1464	hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz[0]);
1465	hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz[1]);
1466	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg[0]);
1467	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg[1]);
1468	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2[0]);
1469	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2[1]);
1470	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi[0]);
1471	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi[1]);
1472	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi[0]);
1473	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi[1]);
1474	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi[0]);
1475	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi[1]);
1476	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi[0]);
1477	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi[1]);
1478
1479	/* waiting for HDMIPHY's PLL to get to steady state */
1480	for (tries = 100; tries; --tries) {
1481		u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS);
1482		if (val & HDMI_PHY_STATUS_READY)
1483			break;
1484		usleep_range(1000, 2000);
1485	}
1486	/* steady state not achieved */
1487	if (tries == 0) {
1488		DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1489		hdmi_regs_dump(hdata, "timing apply");
1490	}
1491
1492	clk_disable_unprepare(hdata->res.sclk_hdmi);
1493	clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_hdmiphy);
1494	clk_prepare_enable(hdata->res.sclk_hdmi);
1495
1496	/* enable HDMI and timing generator */
1497	hdmi_start(hdata, true);
1498}
1499
1500static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1501{
1502	const struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v14_conf.tg;
1503	const struct hdmi_v14_core_regs *core =
1504		&hdata->mode_conf.conf.v14_conf.core;
1505	int tries;
1506
1507	/* setting core registers */
1508	hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1509	hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1510	hdmi_reg_writeb(hdata, HDMI_V2_BLANK_0, core->v2_blank[0]);
1511	hdmi_reg_writeb(hdata, HDMI_V2_BLANK_1, core->v2_blank[1]);
1512	hdmi_reg_writeb(hdata, HDMI_V1_BLANK_0, core->v1_blank[0]);
1513	hdmi_reg_writeb(hdata, HDMI_V1_BLANK_1, core->v1_blank[1]);
1514	hdmi_reg_writeb(hdata, HDMI_V_LINE_0, core->v_line[0]);
1515	hdmi_reg_writeb(hdata, HDMI_V_LINE_1, core->v_line[1]);
1516	hdmi_reg_writeb(hdata, HDMI_H_LINE_0, core->h_line[0]);
1517	hdmi_reg_writeb(hdata, HDMI_H_LINE_1, core->h_line[1]);
1518	hdmi_reg_writeb(hdata, HDMI_HSYNC_POL, core->hsync_pol[0]);
1519	hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1520	hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1521	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_0, core->v_blank_f0[0]);
1522	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_1, core->v_blank_f0[1]);
1523	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_0, core->v_blank_f1[0]);
1524	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_1, core->v_blank_f1[1]);
1525	hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_0, core->h_sync_start[0]);
1526	hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_1, core->h_sync_start[1]);
1527	hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_0, core->h_sync_end[0]);
1528	hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_1, core->h_sync_end[1]);
1529	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_0,
1530			core->v_sync_line_bef_2[0]);
1531	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_1,
1532			core->v_sync_line_bef_2[1]);
1533	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_0,
1534			core->v_sync_line_bef_1[0]);
1535	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_1,
1536			core->v_sync_line_bef_1[1]);
1537	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_0,
1538			core->v_sync_line_aft_2[0]);
1539	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_1,
1540			core->v_sync_line_aft_2[1]);
1541	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_0,
1542			core->v_sync_line_aft_1[0]);
1543	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_1,
1544			core->v_sync_line_aft_1[1]);
1545	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0,
1546			core->v_sync_line_aft_pxl_2[0]);
1547	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_1,
1548			core->v_sync_line_aft_pxl_2[1]);
1549	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0,
1550			core->v_sync_line_aft_pxl_1[0]);
1551	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_1,
1552			core->v_sync_line_aft_pxl_1[1]);
1553	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_0, core->v_blank_f2[0]);
1554	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_1, core->v_blank_f2[1]);
1555	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_0, core->v_blank_f3[0]);
1556	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_1, core->v_blank_f3[1]);
1557	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_0, core->v_blank_f4[0]);
1558	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_1, core->v_blank_f4[1]);
1559	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_0, core->v_blank_f5[0]);
1560	hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_1, core->v_blank_f5[1]);
1561	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_0,
1562			core->v_sync_line_aft_3[0]);
1563	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_1,
1564			core->v_sync_line_aft_3[1]);
1565	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_0,
1566			core->v_sync_line_aft_4[0]);
1567	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_1,
1568			core->v_sync_line_aft_4[1]);
1569	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_0,
1570			core->v_sync_line_aft_5[0]);
1571	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_1,
1572			core->v_sync_line_aft_5[1]);
1573	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_0,
1574			core->v_sync_line_aft_6[0]);
1575	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_1,
1576			core->v_sync_line_aft_6[1]);
1577	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0,
1578			core->v_sync_line_aft_pxl_3[0]);
1579	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_1,
1580			core->v_sync_line_aft_pxl_3[1]);
1581	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0,
1582			core->v_sync_line_aft_pxl_4[0]);
1583	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_1,
1584			core->v_sync_line_aft_pxl_4[1]);
1585	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0,
1586			core->v_sync_line_aft_pxl_5[0]);
1587	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_1,
1588			core->v_sync_line_aft_pxl_5[1]);
1589	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0,
1590			core->v_sync_line_aft_pxl_6[0]);
1591	hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_1,
1592			core->v_sync_line_aft_pxl_6[1]);
1593	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_0, core->vact_space_1[0]);
1594	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_1, core->vact_space_1[1]);
1595	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_0, core->vact_space_2[0]);
1596	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_1, core->vact_space_2[1]);
1597	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_0, core->vact_space_3[0]);
1598	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_1, core->vact_space_3[1]);
1599	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_0, core->vact_space_4[0]);
1600	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_1, core->vact_space_4[1]);
1601	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_0, core->vact_space_5[0]);
1602	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_1, core->vact_space_5[1]);
1603	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_0, core->vact_space_6[0]);
1604	hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]);
1605
1606	/* Timing generator registers */
1607	hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz[0]);
1608	hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz[1]);
1609	hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st[0]);
1610	hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st[1]);
1611	hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz[0]);
1612	hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz[1]);
1613	hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz[0]);
1614	hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz[1]);
1615	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync[0]);
1616	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync[1]);
1617	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2[0]);
1618	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2[1]);
1619	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st[0]);
1620	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st[1]);
1621	hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz[0]);
1622	hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz[1]);
1623	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg[0]);
1624	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg[1]);
1625	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2[0]);
1626	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2[1]);
1627	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3[0]);
1628	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3[1]);
1629	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4[0]);
1630	hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4[1]);
1631	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi[0]);
1632	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi[1]);
1633	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi[0]);
1634	hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi[1]);
1635	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi[0]);
1636	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi[1]);
1637	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi[0]);
1638	hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi[1]);
1639	hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d[0]);
1640
1641	/* waiting for HDMIPHY's PLL to get to steady state */
1642	for (tries = 100; tries; --tries) {
1643		u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0);
1644		if (val & HDMI_PHY_STATUS_READY)
1645			break;
1646		usleep_range(1000, 2000);
1647	}
1648	/* steady state not achieved */
1649	if (tries == 0) {
1650		DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1651		hdmi_regs_dump(hdata, "timing apply");
1652	}
1653
1654	clk_disable_unprepare(hdata->res.sclk_hdmi);
1655	clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_hdmiphy);
1656	clk_prepare_enable(hdata->res.sclk_hdmi);
1657
1658	/* enable HDMI and timing generator */
1659	hdmi_start(hdata, true);
1660}
1661
1662static void hdmi_mode_apply(struct hdmi_context *hdata)
1663{
1664	if (hdata->type == HDMI_TYPE13)
1665		hdmi_v13_mode_apply(hdata);
1666	else
1667		hdmi_v14_mode_apply(hdata);
1668}
1669
1670static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1671{
1672	u32 reg;
1673
1674	clk_disable_unprepare(hdata->res.sclk_hdmi);
1675	clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_pixel);
1676	clk_prepare_enable(hdata->res.sclk_hdmi);
1677
1678	/* operation mode */
1679	hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1680				HDMI_PHY_ENABLE_MODE_SET);
1681
1682	if (hdata->type == HDMI_TYPE13)
1683		reg = HDMI_V13_PHY_RSTOUT;
1684	else
1685		reg = HDMI_PHY_RSTOUT;
1686
1687	/* reset hdmiphy */
1688	hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT);
1689	usleep_range(10000, 12000);
1690	hdmi_reg_writemask(hdata, reg,  0, HDMI_PHY_SW_RSTOUT);
1691	usleep_range(10000, 12000);
1692}
1693
1694static void hdmiphy_poweron(struct hdmi_context *hdata)
1695{
1696	if (hdata->type != HDMI_TYPE14)
1697		return;
1698
1699	DRM_DEBUG_KMS("\n");
1700
1701	/* For PHY Mode Setting */
1702	hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1703				HDMI_PHY_ENABLE_MODE_SET);
1704	/* Phy Power On */
1705	hdmiphy_reg_writeb(hdata, HDMIPHY_POWER,
1706				HDMI_PHY_POWER_ON);
1707	/* For PHY Mode Setting */
1708	hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1709				HDMI_PHY_DISABLE_MODE_SET);
1710	/* PHY SW Reset */
1711	hdmiphy_conf_reset(hdata);
1712}
1713
1714static void hdmiphy_poweroff(struct hdmi_context *hdata)
1715{
1716	if (hdata->type != HDMI_TYPE14)
1717		return;
1718
1719	DRM_DEBUG_KMS("\n");
1720
1721	/* PHY SW Reset */
1722	hdmiphy_conf_reset(hdata);
1723	/* For PHY Mode Setting */
1724	hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1725				HDMI_PHY_ENABLE_MODE_SET);
1726
1727	/* PHY Power Off */
1728	hdmiphy_reg_writeb(hdata, HDMIPHY_POWER,
1729				HDMI_PHY_POWER_OFF);
1730
1731	/* For PHY Mode Setting */
1732	hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1733				HDMI_PHY_DISABLE_MODE_SET);
1734}
1735
1736static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1737{
1738	int ret;
1739	int i;
1740
1741	/* pixel clock */
1742	i = hdmi_find_phy_conf(hdata, hdata->mode_conf.pixel_clock);
1743	if (i < 0) {
1744		DRM_ERROR("failed to find hdmiphy conf\n");
1745		return;
1746	}
1747
1748	ret = hdmiphy_reg_write_buf(hdata, 0, hdata->phy_confs[i].conf, 32);
1749	if (ret) {
1750		DRM_ERROR("failed to configure hdmiphy\n");
1751		return;
1752	}
1753
1754	usleep_range(10000, 12000);
1755
1756	ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1757				HDMI_PHY_DISABLE_MODE_SET);
1758	if (ret) {
1759		DRM_ERROR("failed to enable hdmiphy\n");
1760		return;
1761	}
1762
1763}
1764
1765static void hdmi_conf_apply(struct hdmi_context *hdata)
1766{
1767	hdmiphy_conf_reset(hdata);
1768	hdmiphy_conf_apply(hdata);
1769
1770	mutex_lock(&hdata->hdmi_mutex);
1771	hdmi_start(hdata, false);
1772	hdmi_conf_init(hdata);
1773	mutex_unlock(&hdata->hdmi_mutex);
1774
1775	hdmi_audio_init(hdata);
1776
1777	/* setting core registers */
1778	hdmi_mode_apply(hdata);
1779	hdmi_audio_control(hdata, true);
1780
1781	hdmi_regs_dump(hdata, "start");
1782}
1783
1784static void hdmi_set_reg(u8 *reg_pair, int num_bytes, u32 value)
1785{
1786	int i;
1787	BUG_ON(num_bytes > 4);
1788	for (i = 0; i < num_bytes; i++)
1789		reg_pair[i] = (value >> (8 * i)) & 0xff;
1790}
1791
1792static void hdmi_v13_mode_set(struct hdmi_context *hdata,
1793			struct drm_display_mode *m)
1794{
1795	struct hdmi_v13_core_regs *core = &hdata->mode_conf.conf.v13_conf.core;
1796	struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v13_conf.tg;
1797	unsigned int val;
1798
1799	hdata->mode_conf.cea_video_id =
1800		drm_match_cea_mode((struct drm_display_mode *)m);
1801	hdata->mode_conf.pixel_clock = m->clock * 1000;
1802	hdata->mode_conf.aspect_ratio = m->picture_aspect_ratio;
1803
1804	hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
1805	hdmi_set_reg(core->h_v_line, 3, (m->htotal << 12) | m->vtotal);
1806
1807	val = (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
1808	hdmi_set_reg(core->vsync_pol, 1, val);
1809
1810	val = (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0;
1811	hdmi_set_reg(core->int_pro_mode, 1, val);
1812
1813	val = (m->hsync_start - m->hdisplay - 2);
1814	val |= ((m->hsync_end - m->hdisplay - 2) << 10);
1815	val |= ((m->flags & DRM_MODE_FLAG_NHSYNC)  ? 1 : 0)<<20;
1816	hdmi_set_reg(core->h_sync_gen, 3, val);
1817
1818	/*
1819	 * Quirk requirement for exynos HDMI IP design,
1820	 * 2 pixels less than the actual calculation for hsync_start
1821	 * and end.
1822	 */
1823
1824	/* Following values & calculations differ for different type of modes */
1825	if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1826		/* Interlaced Mode */
1827		val = ((m->vsync_end - m->vdisplay) / 2);
1828		val |= ((m->vsync_start - m->vdisplay) / 2) << 12;
1829		hdmi_set_reg(core->v_sync_gen1, 3, val);
1830
1831		val = m->vtotal / 2;
1832		val |= ((m->vtotal - m->vdisplay) / 2) << 11;
1833		hdmi_set_reg(core->v_blank, 3, val);
1834
1835		val = (m->vtotal +
1836			((m->vsync_end - m->vsync_start) * 4) + 5) / 2;
1837		val |= m->vtotal << 11;
1838		hdmi_set_reg(core->v_blank_f, 3, val);
1839
1840		val = ((m->vtotal / 2) + 7);
1841		val |= ((m->vtotal / 2) + 2) << 12;
1842		hdmi_set_reg(core->v_sync_gen2, 3, val);
1843
1844		val = ((m->htotal / 2) + (m->hsync_start - m->hdisplay));
1845		val |= ((m->htotal / 2) +
1846			(m->hsync_start - m->hdisplay)) << 12;
1847		hdmi_set_reg(core->v_sync_gen3, 3, val);
1848
1849		hdmi_set_reg(tg->vact_st, 2, (m->vtotal - m->vdisplay) / 2);
1850		hdmi_set_reg(tg->vact_sz, 2, m->vdisplay / 2);
1851
1852		hdmi_set_reg(tg->vact_st2, 2, 0x249);/* Reset value + 1*/
1853	} else {
1854		/* Progressive Mode */
1855
1856		val = m->vtotal;
1857		val |= (m->vtotal - m->vdisplay) << 11;
1858		hdmi_set_reg(core->v_blank, 3, val);
1859
1860		hdmi_set_reg(core->v_blank_f, 3, 0);
1861
1862		val = (m->vsync_end - m->vdisplay);
1863		val |= ((m->vsync_start - m->vdisplay) << 12);
1864		hdmi_set_reg(core->v_sync_gen1, 3, val);
1865
1866		hdmi_set_reg(core->v_sync_gen2, 3, 0x1001);/* Reset value  */
1867		hdmi_set_reg(core->v_sync_gen3, 3, 0x1001);/* Reset value  */
1868		hdmi_set_reg(tg->vact_st, 2, m->vtotal - m->vdisplay);
1869		hdmi_set_reg(tg->vact_sz, 2, m->vdisplay);
1870		hdmi_set_reg(tg->vact_st2, 2, 0x248); /* Reset value */
1871	}
1872
1873	/* Timing generator registers */
1874	hdmi_set_reg(tg->cmd, 1, 0x0);
1875	hdmi_set_reg(tg->h_fsz, 2, m->htotal);
1876	hdmi_set_reg(tg->hact_st, 2, m->htotal - m->hdisplay);
1877	hdmi_set_reg(tg->hact_sz, 2, m->hdisplay);
1878	hdmi_set_reg(tg->v_fsz, 2, m->vtotal);
1879	hdmi_set_reg(tg->vsync, 2, 0x1);
1880	hdmi_set_reg(tg->vsync2, 2, 0x233); /* Reset value */
1881	hdmi_set_reg(tg->field_chg, 2, 0x233); /* Reset value */
1882	hdmi_set_reg(tg->vsync_top_hdmi, 2, 0x1); /* Reset value */
1883	hdmi_set_reg(tg->vsync_bot_hdmi, 2, 0x233); /* Reset value */
1884	hdmi_set_reg(tg->field_top_hdmi, 2, 0x1); /* Reset value */
1885	hdmi_set_reg(tg->field_bot_hdmi, 2, 0x233); /* Reset value */
1886	hdmi_set_reg(tg->tg_3d, 1, 0x0); /* Not used */
1887}
1888
1889static void hdmi_v14_mode_set(struct hdmi_context *hdata,
1890			struct drm_display_mode *m)
1891{
1892	struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v14_conf.tg;
1893	struct hdmi_v14_core_regs *core =
1894		&hdata->mode_conf.conf.v14_conf.core;
1895
1896	hdata->mode_conf.cea_video_id =
1897		drm_match_cea_mode((struct drm_display_mode *)m);
1898	hdata->mode_conf.pixel_clock = m->clock * 1000;
1899	hdata->mode_conf.aspect_ratio = m->picture_aspect_ratio;
1900
1901	hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
1902	hdmi_set_reg(core->v_line, 2, m->vtotal);
1903	hdmi_set_reg(core->h_line, 2, m->htotal);
1904	hdmi_set_reg(core->hsync_pol, 1,
1905			(m->flags & DRM_MODE_FLAG_NHSYNC)  ? 1 : 0);
1906	hdmi_set_reg(core->vsync_pol, 1,
1907			(m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
1908	hdmi_set_reg(core->int_pro_mode, 1,
1909			(m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1910
1911	/*
1912	 * Quirk requirement for exynos 5 HDMI IP design,
1913	 * 2 pixels less than the actual calculation for hsync_start
1914	 * and end.
1915	 */
1916
1917	/* Following values & calculations differ for different type of modes */
1918	if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1919		/* Interlaced Mode */
1920		hdmi_set_reg(core->v_sync_line_bef_2, 2,
1921			(m->vsync_end - m->vdisplay) / 2);
1922		hdmi_set_reg(core->v_sync_line_bef_1, 2,
1923			(m->vsync_start - m->vdisplay) / 2);
1924		hdmi_set_reg(core->v2_blank, 2, m->vtotal / 2);
1925		hdmi_set_reg(core->v1_blank, 2, (m->vtotal - m->vdisplay) / 2);
1926		hdmi_set_reg(core->v_blank_f0, 2, m->vtotal - m->vdisplay / 2);
1927		hdmi_set_reg(core->v_blank_f1, 2, m->vtotal);
1928		hdmi_set_reg(core->v_sync_line_aft_2, 2, (m->vtotal / 2) + 7);
1929		hdmi_set_reg(core->v_sync_line_aft_1, 2, (m->vtotal / 2) + 2);
1930		hdmi_set_reg(core->v_sync_line_aft_pxl_2, 2,
1931			(m->htotal / 2) + (m->hsync_start - m->hdisplay));
1932		hdmi_set_reg(core->v_sync_line_aft_pxl_1, 2,
1933			(m->htotal / 2) + (m->hsync_start - m->hdisplay));
1934		hdmi_set_reg(tg->vact_st, 2, (m->vtotal - m->vdisplay) / 2);
1935		hdmi_set_reg(tg->vact_sz, 2, m->vdisplay / 2);
1936		hdmi_set_reg(tg->vact_st2, 2, m->vtotal - m->vdisplay / 2);
1937		hdmi_set_reg(tg->vsync2, 2, (m->vtotal / 2) + 1);
1938		hdmi_set_reg(tg->vsync_bot_hdmi, 2, (m->vtotal / 2) + 1);
1939		hdmi_set_reg(tg->field_bot_hdmi, 2, (m->vtotal / 2) + 1);
1940		hdmi_set_reg(tg->vact_st3, 2, 0x0);
1941		hdmi_set_reg(tg->vact_st4, 2, 0x0);
1942	} else {
1943		/* Progressive Mode */
1944		hdmi_set_reg(core->v_sync_line_bef_2, 2,
1945			m->vsync_end - m->vdisplay);
1946		hdmi_set_reg(core->v_sync_line_bef_1, 2,
1947			m->vsync_start - m->vdisplay);
1948		hdmi_set_reg(core->v2_blank, 2, m->vtotal);
1949		hdmi_set_reg(core->v1_blank, 2, m->vtotal - m->vdisplay);
1950		hdmi_set_reg(core->v_blank_f0, 2, 0xffff);
1951		hdmi_set_reg(core->v_blank_f1, 2, 0xffff);
1952		hdmi_set_reg(core->v_sync_line_aft_2, 2, 0xffff);
1953		hdmi_set_reg(core->v_sync_line_aft_1, 2, 0xffff);
1954		hdmi_set_reg(core->v_sync_line_aft_pxl_2, 2, 0xffff);
1955		hdmi_set_reg(core->v_sync_line_aft_pxl_1, 2, 0xffff);
1956		hdmi_set_reg(tg->vact_st, 2, m->vtotal - m->vdisplay);
1957		hdmi_set_reg(tg->vact_sz, 2, m->vdisplay);
1958		hdmi_set_reg(tg->vact_st2, 2, 0x248); /* Reset value */
1959		hdmi_set_reg(tg->vact_st3, 2, 0x47b); /* Reset value */
1960		hdmi_set_reg(tg->vact_st4, 2, 0x6ae); /* Reset value */
1961		hdmi_set_reg(tg->vsync2, 2, 0x233); /* Reset value */
1962		hdmi_set_reg(tg->vsync_bot_hdmi, 2, 0x233); /* Reset value */
1963		hdmi_set_reg(tg->field_bot_hdmi, 2, 0x233); /* Reset value */
1964	}
1965
1966	/* Following values & calculations are same irrespective of mode type */
1967	hdmi_set_reg(core->h_sync_start, 2, m->hsync_start - m->hdisplay - 2);
1968	hdmi_set_reg(core->h_sync_end, 2, m->hsync_end - m->hdisplay - 2);
1969	hdmi_set_reg(core->vact_space_1, 2, 0xffff);
1970	hdmi_set_reg(core->vact_space_2, 2, 0xffff);
1971	hdmi_set_reg(core->vact_space_3, 2, 0xffff);
1972	hdmi_set_reg(core->vact_space_4, 2, 0xffff);
1973	hdmi_set_reg(core->vact_space_5, 2, 0xffff);
1974	hdmi_set_reg(core->vact_space_6, 2, 0xffff);
1975	hdmi_set_reg(core->v_blank_f2, 2, 0xffff);
1976	hdmi_set_reg(core->v_blank_f3, 2, 0xffff);
1977	hdmi_set_reg(core->v_blank_f4, 2, 0xffff);
1978	hdmi_set_reg(core->v_blank_f5, 2, 0xffff);
1979	hdmi_set_reg(core->v_sync_line_aft_3, 2, 0xffff);
1980	hdmi_set_reg(core->v_sync_line_aft_4, 2, 0xffff);
1981	hdmi_set_reg(core->v_sync_line_aft_5, 2, 0xffff);
1982	hdmi_set_reg(core->v_sync_line_aft_6, 2, 0xffff);
1983	hdmi_set_reg(core->v_sync_line_aft_pxl_3, 2, 0xffff);
1984	hdmi_set_reg(core->v_sync_line_aft_pxl_4, 2, 0xffff);
1985	hdmi_set_reg(core->v_sync_line_aft_pxl_5, 2, 0xffff);
1986	hdmi_set_reg(core->v_sync_line_aft_pxl_6, 2, 0xffff);
1987
1988	/* Timing generator registers */
1989	hdmi_set_reg(tg->cmd, 1, 0x0);
1990	hdmi_set_reg(tg->h_fsz, 2, m->htotal);
1991	hdmi_set_reg(tg->hact_st, 2, m->htotal - m->hdisplay);
1992	hdmi_set_reg(tg->hact_sz, 2, m->hdisplay);
1993	hdmi_set_reg(tg->v_fsz, 2, m->vtotal);
1994	hdmi_set_reg(tg->vsync, 2, 0x1);
1995	hdmi_set_reg(tg->field_chg, 2, 0x233); /* Reset value */
1996	hdmi_set_reg(tg->vsync_top_hdmi, 2, 0x1); /* Reset value */
1997	hdmi_set_reg(tg->field_top_hdmi, 2, 0x1); /* Reset value */
1998	hdmi_set_reg(tg->tg_3d, 1, 0x0);
1999}
2000
2001static void hdmi_mode_set(struct exynos_drm_display *display,
2002			struct drm_display_mode *mode)
2003{
2004	struct hdmi_context *hdata = display_to_hdmi(display);
2005	struct drm_display_mode *m = mode;
2006
2007	DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n",
2008		m->hdisplay, m->vdisplay,
2009		m->vrefresh, (m->flags & DRM_MODE_FLAG_INTERLACE) ?
2010		"INTERLACED" : "PROGRESSIVE");
2011
2012	/* preserve mode information for later use. */
2013	drm_mode_copy(&hdata->current_mode, mode);
2014
2015	if (hdata->type == HDMI_TYPE13)
2016		hdmi_v13_mode_set(hdata, mode);
2017	else
2018		hdmi_v14_mode_set(hdata, mode);
2019}
2020
2021static void hdmi_commit(struct exynos_drm_display *display)
2022{
2023	struct hdmi_context *hdata = display_to_hdmi(display);
2024
2025	mutex_lock(&hdata->hdmi_mutex);
2026	if (!hdata->powered) {
2027		mutex_unlock(&hdata->hdmi_mutex);
2028		return;
2029	}
2030	mutex_unlock(&hdata->hdmi_mutex);
2031
2032	hdmi_conf_apply(hdata);
2033}
2034
2035static void hdmi_poweron(struct hdmi_context *hdata)
2036{
2037	struct hdmi_resources *res = &hdata->res;
2038
2039	mutex_lock(&hdata->hdmi_mutex);
2040	if (hdata->powered) {
2041		mutex_unlock(&hdata->hdmi_mutex);
2042		return;
2043	}
2044
2045	hdata->powered = true;
2046
2047	mutex_unlock(&hdata->hdmi_mutex);
2048
2049	pm_runtime_get_sync(hdata->dev);
2050
2051	if (regulator_bulk_enable(res->regul_count, res->regul_bulk))
2052		DRM_DEBUG_KMS("failed to enable regulator bulk\n");
2053
2054	/* set pmu hdmiphy control bit to enable hdmiphy */
2055	regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
2056			PMU_HDMI_PHY_ENABLE_BIT, 1);
2057
2058	clk_prepare_enable(res->hdmi);
2059	clk_prepare_enable(res->sclk_hdmi);
2060
2061	hdmiphy_poweron(hdata);
2062	hdmi_commit(&hdata->display);
2063}
2064
2065static void hdmi_poweroff(struct hdmi_context *hdata)
2066{
2067	struct hdmi_resources *res = &hdata->res;
2068
2069	mutex_lock(&hdata->hdmi_mutex);
2070	if (!hdata->powered)
2071		goto out;
2072	mutex_unlock(&hdata->hdmi_mutex);
2073
2074	/* HDMI System Disable */
2075	hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
2076
2077	hdmiphy_poweroff(hdata);
2078
2079	cancel_delayed_work(&hdata->hotplug_work);
2080
2081	clk_disable_unprepare(res->sclk_hdmi);
2082	clk_disable_unprepare(res->hdmi);
2083
2084	/* reset pmu hdmiphy control bit to disable hdmiphy */
2085	regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
2086			PMU_HDMI_PHY_ENABLE_BIT, 0);
2087
2088	regulator_bulk_disable(res->regul_count, res->regul_bulk);
2089
2090	pm_runtime_put_sync(hdata->dev);
2091
2092	mutex_lock(&hdata->hdmi_mutex);
2093	hdata->powered = false;
2094
2095out:
2096	mutex_unlock(&hdata->hdmi_mutex);
2097}
2098
2099static void hdmi_dpms(struct exynos_drm_display *display, int mode)
2100{
2101	struct hdmi_context *hdata = display_to_hdmi(display);
2102	struct drm_encoder *encoder = hdata->encoder;
2103	struct drm_crtc *crtc = encoder->crtc;
2104	const struct drm_crtc_helper_funcs *funcs = NULL;
2105
2106	DRM_DEBUG_KMS("mode %d\n", mode);
2107
2108	switch (mode) {
2109	case DRM_MODE_DPMS_ON:
2110		hdmi_poweron(hdata);
2111		break;
2112	case DRM_MODE_DPMS_STANDBY:
2113	case DRM_MODE_DPMS_SUSPEND:
2114	case DRM_MODE_DPMS_OFF:
2115		/*
2116		 * The SFRs of VP and Mixer are updated by Vertical Sync of
2117		 * Timing generator which is a part of HDMI so the sequence
2118		 * to disable TV Subsystem should be as following,
2119		 *	VP -> Mixer -> HDMI
2120		 *
2121		 * Below codes will try to disable Mixer and VP(if used)
2122		 * prior to disabling HDMI.
2123		 */
2124		if (crtc)
2125			funcs = crtc->helper_private;
2126		if (funcs && funcs->dpms)
2127			(*funcs->dpms)(crtc, mode);
2128
2129		hdmi_poweroff(hdata);
2130		break;
2131	default:
2132		DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
2133		break;
2134	}
2135}
2136
2137static struct exynos_drm_display_ops hdmi_display_ops = {
2138	.create_connector = hdmi_create_connector,
2139	.mode_fixup	= hdmi_mode_fixup,
2140	.mode_set	= hdmi_mode_set,
2141	.dpms		= hdmi_dpms,
2142	.commit		= hdmi_commit,
2143};
2144
2145static void hdmi_hotplug_work_func(struct work_struct *work)
2146{
2147	struct hdmi_context *hdata;
2148
2149	hdata = container_of(work, struct hdmi_context, hotplug_work.work);
2150
2151	mutex_lock(&hdata->hdmi_mutex);
2152	hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2153	mutex_unlock(&hdata->hdmi_mutex);
2154
2155	if (hdata->drm_dev)
2156		drm_helper_hpd_irq_event(hdata->drm_dev);
2157}
2158
2159static irqreturn_t hdmi_irq_thread(int irq, void *arg)
2160{
2161	struct hdmi_context *hdata = arg;
2162
2163	mod_delayed_work(system_wq, &hdata->hotplug_work,
2164			msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
2165
2166	return IRQ_HANDLED;
2167}
2168
2169static int hdmi_resources_init(struct hdmi_context *hdata)
2170{
2171	struct device *dev = hdata->dev;
2172	struct hdmi_resources *res = &hdata->res;
2173	static char *supply[] = {
2174		"vdd",
2175		"vdd_osc",
2176		"vdd_pll",
2177	};
2178	int i, ret;
2179
2180	DRM_DEBUG_KMS("HDMI resource init\n");
2181
2182	/* get clocks, power */
2183	res->hdmi = devm_clk_get(dev, "hdmi");
2184	if (IS_ERR(res->hdmi)) {
2185		DRM_ERROR("failed to get clock 'hdmi'\n");
2186		ret = PTR_ERR(res->hdmi);
2187		goto fail;
2188	}
2189	res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
2190	if (IS_ERR(res->sclk_hdmi)) {
2191		DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
2192		ret = PTR_ERR(res->sclk_hdmi);
2193		goto fail;
2194	}
2195	res->sclk_pixel = devm_clk_get(dev, "sclk_pixel");
2196	if (IS_ERR(res->sclk_pixel)) {
2197		DRM_ERROR("failed to get clock 'sclk_pixel'\n");
2198		ret = PTR_ERR(res->sclk_pixel);
2199		goto fail;
2200	}
2201	res->sclk_hdmiphy = devm_clk_get(dev, "sclk_hdmiphy");
2202	if (IS_ERR(res->sclk_hdmiphy)) {
2203		DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
2204		ret = PTR_ERR(res->sclk_hdmiphy);
2205		goto fail;
2206	}
2207	res->mout_hdmi = devm_clk_get(dev, "mout_hdmi");
2208	if (IS_ERR(res->mout_hdmi)) {
2209		DRM_ERROR("failed to get clock 'mout_hdmi'\n");
2210		ret = PTR_ERR(res->mout_hdmi);
2211		goto fail;
2212	}
2213
2214	clk_set_parent(res->mout_hdmi, res->sclk_pixel);
2215
2216	res->regul_bulk = devm_kzalloc(dev, ARRAY_SIZE(supply) *
2217		sizeof(res->regul_bulk[0]), GFP_KERNEL);
2218	if (!res->regul_bulk) {
2219		ret = -ENOMEM;
2220		goto fail;
2221	}
2222	for (i = 0; i < ARRAY_SIZE(supply); ++i) {
2223		res->regul_bulk[i].supply = supply[i];
2224		res->regul_bulk[i].consumer = NULL;
2225	}
2226	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
2227	if (ret) {
2228		DRM_ERROR("failed to get regulators\n");
2229		return ret;
2230	}
2231	res->regul_count = ARRAY_SIZE(supply);
2232
2233	res->reg_hdmi_en = devm_regulator_get(dev, "hdmi-en");
2234	if (IS_ERR(res->reg_hdmi_en) && PTR_ERR(res->reg_hdmi_en) != -ENOENT) {
2235		DRM_ERROR("failed to get hdmi-en regulator\n");
2236		return PTR_ERR(res->reg_hdmi_en);
2237	}
2238	if (!IS_ERR(res->reg_hdmi_en)) {
2239		ret = regulator_enable(res->reg_hdmi_en);
2240		if (ret) {
2241			DRM_ERROR("failed to enable hdmi-en regulator\n");
2242			return ret;
2243		}
2244	} else
2245		res->reg_hdmi_en = NULL;
2246
2247	return ret;
2248fail:
2249	DRM_ERROR("HDMI resource init - failed\n");
2250	return ret;
2251}
2252
2253static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
2254					(struct device *dev)
2255{
2256	struct device_node *np = dev->of_node;
2257	struct s5p_hdmi_platform_data *pd;
2258	u32 value;
2259
2260	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
2261	if (!pd)
2262		goto err_data;
2263
2264	if (!of_find_property(np, "hpd-gpio", &value)) {
2265		DRM_ERROR("no hpd gpio property found\n");
2266		goto err_data;
2267	}
2268
2269	pd->hpd_gpio = of_get_named_gpio(np, "hpd-gpio", 0);
2270
2271	return pd;
2272
2273err_data:
2274	return NULL;
2275}
2276
2277static struct of_device_id hdmi_match_types[] = {
2278	{
2279		.compatible = "samsung,exynos5-hdmi",
2280		.data = &exynos5_hdmi_driver_data,
2281	}, {
2282		.compatible = "samsung,exynos4210-hdmi",
2283		.data = &exynos4210_hdmi_driver_data,
2284	}, {
2285		.compatible = "samsung,exynos4212-hdmi",
2286		.data = &exynos4212_hdmi_driver_data,
2287	}, {
2288		.compatible = "samsung,exynos5420-hdmi",
2289		.data = &exynos5420_hdmi_driver_data,
2290	}, {
2291		/* end node */
2292	}
2293};
2294MODULE_DEVICE_TABLE (of, hdmi_match_types);
2295
2296static int hdmi_bind(struct device *dev, struct device *master, void *data)
2297{
2298	struct drm_device *drm_dev = data;
2299	struct hdmi_context *hdata = dev_get_drvdata(dev);
2300
2301	hdata->drm_dev = drm_dev;
2302
2303	return exynos_drm_create_enc_conn(drm_dev, &hdata->display);
2304}
2305
2306static void hdmi_unbind(struct device *dev, struct device *master, void *data)
2307{
2308}
2309
2310static const struct component_ops hdmi_component_ops = {
2311	.bind	= hdmi_bind,
2312	.unbind = hdmi_unbind,
2313};
2314
2315static struct device_node *hdmi_legacy_ddc_dt_binding(struct device *dev)
2316{
2317	const char *compatible_str = "samsung,exynos4210-hdmiddc";
2318	struct device_node *np;
2319
2320	np = of_find_compatible_node(NULL, NULL, compatible_str);
2321	if (np)
2322		return of_get_next_parent(np);
2323
2324	return NULL;
2325}
2326
2327static struct device_node *hdmi_legacy_phy_dt_binding(struct device *dev)
2328{
2329	const char *compatible_str = "samsung,exynos4212-hdmiphy";
2330
2331	return of_find_compatible_node(NULL, NULL, compatible_str);
2332}
2333
2334static int hdmi_probe(struct platform_device *pdev)
2335{
2336	struct device_node *ddc_node, *phy_node;
2337	struct s5p_hdmi_platform_data *pdata;
2338	struct hdmi_driver_data *drv_data;
2339	const struct of_device_id *match;
2340	struct device *dev = &pdev->dev;
2341	struct hdmi_context *hdata;
2342	struct resource *res;
2343	int ret;
2344
2345	if (!dev->of_node)
2346		return -ENODEV;
2347
2348	pdata = drm_hdmi_dt_parse_pdata(dev);
2349	if (!pdata)
2350		return -EINVAL;
2351
2352	hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
2353	if (!hdata)
2354		return -ENOMEM;
2355
2356	hdata->display.type = EXYNOS_DISPLAY_TYPE_HDMI;
2357	hdata->display.ops = &hdmi_display_ops;
2358
2359	ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
2360					hdata->display.type);
2361	if (ret)
2362		return ret;
2363
2364	mutex_init(&hdata->hdmi_mutex);
2365
2366	platform_set_drvdata(pdev, hdata);
2367
2368	match = of_match_node(hdmi_match_types, dev->of_node);
2369	if (!match) {
2370		ret = -ENODEV;
2371		goto err_del_component;
2372	}
2373
2374	drv_data = (struct hdmi_driver_data *)match->data;
2375	hdata->type = drv_data->type;
2376	hdata->phy_confs = drv_data->phy_confs;
2377	hdata->phy_conf_count = drv_data->phy_conf_count;
2378
2379	hdata->hpd_gpio = pdata->hpd_gpio;
2380	hdata->dev = dev;
2381
2382	ret = hdmi_resources_init(hdata);
2383	if (ret) {
2384		DRM_ERROR("hdmi_resources_init failed\n");
2385		return ret;
2386	}
2387
2388	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2389	hdata->regs = devm_ioremap_resource(dev, res);
2390	if (IS_ERR(hdata->regs)) {
2391		ret = PTR_ERR(hdata->regs);
2392		goto err_del_component;
2393	}
2394
2395	ret = devm_gpio_request(dev, hdata->hpd_gpio, "HPD");
2396	if (ret) {
2397		DRM_ERROR("failed to request HPD gpio\n");
2398		goto err_del_component;
2399	}
2400
2401	ddc_node = hdmi_legacy_ddc_dt_binding(dev);
2402	if (ddc_node)
2403		goto out_get_ddc_adpt;
2404
2405	/* DDC i2c driver */
2406	ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
2407	if (!ddc_node) {
2408		DRM_ERROR("Failed to find ddc node in device tree\n");
2409		ret = -ENODEV;
2410		goto err_del_component;
2411	}
2412
2413out_get_ddc_adpt:
2414	hdata->ddc_adpt = of_find_i2c_adapter_by_node(ddc_node);
2415	if (!hdata->ddc_adpt) {
2416		DRM_ERROR("Failed to get ddc i2c adapter by node\n");
2417		return -EPROBE_DEFER;
2418	}
2419
2420	phy_node = hdmi_legacy_phy_dt_binding(dev);
2421	if (phy_node)
2422		goto out_get_phy_port;
2423
2424	/* hdmiphy i2c driver */
2425	phy_node = of_parse_phandle(dev->of_node, "phy", 0);
2426	if (!phy_node) {
2427		DRM_ERROR("Failed to find hdmiphy node in device tree\n");
2428		ret = -ENODEV;
2429		goto err_ddc;
2430	}
2431
2432out_get_phy_port:
2433	if (drv_data->is_apb_phy) {
2434		hdata->regs_hdmiphy = of_iomap(phy_node, 0);
2435		if (!hdata->regs_hdmiphy) {
2436			DRM_ERROR("failed to ioremap hdmi phy\n");
2437			ret = -ENOMEM;
2438			goto err_ddc;
2439		}
2440	} else {
2441		hdata->hdmiphy_port = of_find_i2c_device_by_node(phy_node);
2442		if (!hdata->hdmiphy_port) {
2443			DRM_ERROR("Failed to get hdmi phy i2c client\n");
2444			ret = -EPROBE_DEFER;
2445			goto err_ddc;
2446		}
2447	}
2448
2449	hdata->irq = gpio_to_irq(hdata->hpd_gpio);
2450	if (hdata->irq < 0) {
2451		DRM_ERROR("failed to get GPIO irq\n");
2452		ret = hdata->irq;
2453		goto err_hdmiphy;
2454	}
2455
2456	hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2457
2458	INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
2459
2460	ret = devm_request_threaded_irq(dev, hdata->irq, NULL,
2461			hdmi_irq_thread, IRQF_TRIGGER_RISING |
2462			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
2463			"hdmi", hdata);
2464	if (ret) {
2465		DRM_ERROR("failed to register hdmi interrupt\n");
2466		goto err_hdmiphy;
2467	}
2468
2469	hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
2470			"samsung,syscon-phandle");
2471	if (IS_ERR(hdata->pmureg)) {
2472		DRM_ERROR("syscon regmap lookup failed.\n");
2473		ret = -EPROBE_DEFER;
2474		goto err_hdmiphy;
2475	}
2476
2477	pm_runtime_enable(dev);
2478
2479	ret = component_add(&pdev->dev, &hdmi_component_ops);
2480	if (ret)
2481		goto err_disable_pm_runtime;
2482
2483	return ret;
2484
2485err_disable_pm_runtime:
2486	pm_runtime_disable(dev);
2487
2488err_hdmiphy:
2489	if (hdata->hdmiphy_port)
2490		put_device(&hdata->hdmiphy_port->dev);
2491err_ddc:
2492	put_device(&hdata->ddc_adpt->dev);
2493
2494err_del_component:
2495	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
2496
2497	return ret;
2498}
2499
2500static int hdmi_remove(struct platform_device *pdev)
2501{
2502	struct hdmi_context *hdata = platform_get_drvdata(pdev);
2503
2504	cancel_delayed_work_sync(&hdata->hotplug_work);
2505
2506	if (hdata->res.reg_hdmi_en)
2507		regulator_disable(hdata->res.reg_hdmi_en);
2508
2509	if (hdata->hdmiphy_port)
2510		put_device(&hdata->hdmiphy_port->dev);
2511	put_device(&hdata->ddc_adpt->dev);
2512
2513	pm_runtime_disable(&pdev->dev);
2514	component_del(&pdev->dev, &hdmi_component_ops);
2515
2516	exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
2517	return 0;
2518}
2519
2520struct platform_driver hdmi_driver = {
2521	.probe		= hdmi_probe,
2522	.remove		= hdmi_remove,
2523	.driver		= {
2524		.name	= "exynos-hdmi",
2525		.owner	= THIS_MODULE,
2526		.of_match_table = hdmi_match_types,
2527	},
2528};
2529