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