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