Version:  2.0.40 2.2.26 2.4.37 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10

Linux/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, 0x22, 0x51, 0x08, 0xfc, 0x88, 0x46,
513                         0x72, 0x50, 0x24, 0x0c, 0x24, 0x0f, 0x7c, 0xa5,
514                         0xd4, 0x2b, 0x87, 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, 0x24, 0x14, 0x24, 0x0f, 0x7c, 0xa5,
523                         0xd4, 0x2b, 0x87, 0x00, 0x00, 0x04, 0x00, 0x30,
524                         0x28, 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 
592 static const char * const hdmi_clk_gates4[] = {
593         "hdmi", "sclk_hdmi"
594 };
595 
596 static const char * const hdmi_clk_muxes4[] = {
597         "sclk_pixel", "sclk_hdmiphy", "mout_hdmi"
598 };
599 
600 static const char * const hdmi_clk_gates5433[] = {
601         "hdmi_pclk", "hdmi_i_pclk", "i_tmds_clk", "i_pixel_clk", "i_spdif_clk"
602 };
603 
604 static const char * const hdmi_clk_muxes5433[] = {
605         "oscclk", "tmds_clko", "tmds_clko_user",
606         "oscclk", "pixel_clko", "pixel_clko_user"
607 };
608 
609 static const struct hdmi_driver_data exynos4210_hdmi_driver_data = {
610         .type           = HDMI_TYPE13,
611         .phy_confs      = INIT_ARRAY_SPEC(hdmiphy_v13_configs),
612         .clk_gates      = INIT_ARRAY_SPEC(hdmi_clk_gates4),
613         .clk_muxes      = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
614 };
615 
616 static const struct hdmi_driver_data exynos4212_hdmi_driver_data = {
617         .type           = HDMI_TYPE14,
618         .phy_confs      = INIT_ARRAY_SPEC(hdmiphy_v14_configs),
619         .clk_gates      = INIT_ARRAY_SPEC(hdmi_clk_gates4),
620         .clk_muxes      = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
621 };
622 
623 static const struct hdmi_driver_data exynos5420_hdmi_driver_data = {
624         .type           = HDMI_TYPE14,
625         .is_apb_phy     = 1,
626         .phy_confs      = INIT_ARRAY_SPEC(hdmiphy_5420_configs),
627         .clk_gates      = INIT_ARRAY_SPEC(hdmi_clk_gates4),
628         .clk_muxes      = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
629 };
630 
631 static const struct hdmi_driver_data exynos5433_hdmi_driver_data = {
632         .type           = HDMI_TYPE14,
633         .is_apb_phy     = 1,
634         .has_sysreg     = 1,
635         .phy_confs      = INIT_ARRAY_SPEC(hdmiphy_5433_configs),
636         .clk_gates      = INIT_ARRAY_SPEC(hdmi_clk_gates5433),
637         .clk_muxes      = INIT_ARRAY_SPEC(hdmi_clk_muxes5433),
638 };
639 
640 static inline u32 hdmi_map_reg(struct hdmi_context *hdata, u32 reg_id)
641 {
642         if ((reg_id & 0xffff0000) == HDMI_MAPPED_BASE)
643                 return hdmi_reg_map[reg_id & 0xffff][hdata->drv_data->type];
644         return reg_id;
645 }
646 
647 static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
648 {
649         return readl(hdata->regs + hdmi_map_reg(hdata, reg_id));
650 }
651 
652 static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
653                                  u32 reg_id, u8 value)
654 {
655         writel(value, hdata->regs + hdmi_map_reg(hdata, reg_id));
656 }
657 
658 static inline void hdmi_reg_writev(struct hdmi_context *hdata, u32 reg_id,
659                                    int bytes, u32 val)
660 {
661         reg_id = hdmi_map_reg(hdata, reg_id);
662 
663         while (--bytes >= 0) {
664                 writel(val & 0xff, hdata->regs + reg_id);
665                 val >>= 8;
666                 reg_id += 4;
667         }
668 }
669 
670 static inline void hdmi_reg_write_buf(struct hdmi_context *hdata, u32 reg_id,
671                                       u8 *buf, int size)
672 {
673         for (reg_id = hdmi_map_reg(hdata, reg_id); size; --size, reg_id += 4)
674                 writel(*buf++, hdata->regs + reg_id);
675 }
676 
677 static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
678                                  u32 reg_id, u32 value, u32 mask)
679 {
680         u32 old;
681 
682         reg_id = hdmi_map_reg(hdata, reg_id);
683         old = readl(hdata->regs + reg_id);
684         value = (value & mask) | (old & ~mask);
685         writel(value, hdata->regs + reg_id);
686 }
687 
688 static int hdmiphy_reg_write_buf(struct hdmi_context *hdata,
689                         u32 reg_offset, const u8 *buf, u32 len)
690 {
691         if ((reg_offset + len) > 32)
692                 return -EINVAL;
693 
694         if (hdata->hdmiphy_port) {
695                 int ret;
696 
697                 ret = i2c_master_send(hdata->hdmiphy_port, buf, len);
698                 if (ret == len)
699                         return 0;
700                 return ret;
701         } else {
702                 int i;
703                 for (i = 0; i < len; i++)
704                         writel(buf[i], hdata->regs_hdmiphy +
705                                 ((reg_offset + i)<<2));
706                 return 0;
707         }
708 }
709 
710 static int hdmi_clk_enable_gates(struct hdmi_context *hdata)
711 {
712         int i, ret;
713 
714         for (i = 0; i < hdata->drv_data->clk_gates.count; ++i) {
715                 ret = clk_prepare_enable(hdata->clk_gates[i]);
716                 if (!ret)
717                         continue;
718 
719                 dev_err(hdata->dev, "Cannot enable clock '%s', %d\n",
720                         hdata->drv_data->clk_gates.data[i], ret);
721                 while (i--)
722                         clk_disable_unprepare(hdata->clk_gates[i]);
723                 return ret;
724         }
725 
726         return 0;
727 }
728 
729 static void hdmi_clk_disable_gates(struct hdmi_context *hdata)
730 {
731         int i = hdata->drv_data->clk_gates.count;
732 
733         while (i--)
734                 clk_disable_unprepare(hdata->clk_gates[i]);
735 }
736 
737 static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy)
738 {
739         struct device *dev = hdata->dev;
740         int ret = 0;
741         int i;
742 
743         for (i = 0; i < hdata->drv_data->clk_muxes.count; i += 3) {
744                 struct clk **c = &hdata->clk_muxes[i];
745 
746                 ret = clk_set_parent(c[2], c[to_phy]);
747                 if (!ret)
748                         continue;
749 
750                 dev_err(dev, "Cannot set clock parent of '%s' to '%s', %d\n",
751                         hdata->drv_data->clk_muxes.data[i + 2],
752                         hdata->drv_data->clk_muxes.data[i + to_phy], ret);
753         }
754 
755         return ret;
756 }
757 
758 static void hdmi_reg_infoframes(struct hdmi_context *hdata)
759 {
760         union hdmi_infoframe frm;
761         u8 buf[25];
762         int ret;
763 
764         if (hdata->dvi_mode) {
765                 hdmi_reg_writeb(hdata, HDMI_AVI_CON,
766                                 HDMI_AVI_CON_DO_NOT_TRANSMIT);
767                 hdmi_reg_writeb(hdata, HDMI_VSI_CON,
768                                 HDMI_VSI_CON_DO_NOT_TRANSMIT);
769                 hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_NO_TRAN);
770                 return;
771         }
772 
773         ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi,
774                         &hdata->current_mode);
775         if (!ret)
776                 ret = hdmi_avi_infoframe_pack(&frm.avi, buf, sizeof(buf));
777         if (ret > 0) {
778                 hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC);
779                 hdmi_reg_write_buf(hdata, HDMI_AVI_HEADER0, buf, ret);
780         } else {
781                 DRM_INFO("%s: invalid AVI infoframe (%d)\n", __func__, ret);
782         }
783 
784         ret = drm_hdmi_vendor_infoframe_from_display_mode(&frm.vendor.hdmi,
785                         &hdata->current_mode);
786         if (!ret)
787                 ret = hdmi_vendor_infoframe_pack(&frm.vendor.hdmi, buf,
788                                 sizeof(buf));
789         if (ret > 0) {
790                 hdmi_reg_writeb(hdata, HDMI_VSI_CON, HDMI_VSI_CON_EVERY_VSYNC);
791                 hdmi_reg_write_buf(hdata, HDMI_VSI_HEADER0, buf, ret);
792         }
793 
794         ret = hdmi_audio_infoframe_init(&frm.audio);
795         if (!ret) {
796                 frm.audio.channels = 2;
797                 ret = hdmi_audio_infoframe_pack(&frm.audio, buf, sizeof(buf));
798         }
799         if (ret > 0) {
800                 hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_EVERY_VSYNC);
801                 hdmi_reg_write_buf(hdata, HDMI_AUI_HEADER0, buf, ret);
802         }
803 }
804 
805 static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
806                                 bool force)
807 {
808         struct hdmi_context *hdata = connector_to_hdmi(connector);
809 
810         if (gpiod_get_value(hdata->hpd_gpio))
811                 return connector_status_connected;
812 
813         return connector_status_disconnected;
814 }
815 
816 static void hdmi_connector_destroy(struct drm_connector *connector)
817 {
818         drm_connector_unregister(connector);
819         drm_connector_cleanup(connector);
820 }
821 
822 static const struct drm_connector_funcs hdmi_connector_funcs = {
823         .dpms = drm_atomic_helper_connector_dpms,
824         .fill_modes = drm_helper_probe_single_connector_modes,
825         .detect = hdmi_detect,
826         .destroy = hdmi_connector_destroy,
827         .reset = drm_atomic_helper_connector_reset,
828         .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
829         .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
830 };
831 
832 static int hdmi_get_modes(struct drm_connector *connector)
833 {
834         struct hdmi_context *hdata = connector_to_hdmi(connector);
835         struct edid *edid;
836         int ret;
837 
838         if (!hdata->ddc_adpt)
839                 return -ENODEV;
840 
841         edid = drm_get_edid(connector, hdata->ddc_adpt);
842         if (!edid)
843                 return -ENODEV;
844 
845         hdata->dvi_mode = !drm_detect_hdmi_monitor(edid);
846         DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
847                 (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
848                 edid->width_cm, edid->height_cm);
849 
850         drm_mode_connector_update_edid_property(connector, edid);
851 
852         ret = drm_add_edid_modes(connector, edid);
853 
854         kfree(edid);
855 
856         return ret;
857 }
858 
859 static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
860 {
861         const struct hdmiphy_configs *confs = &hdata->drv_data->phy_confs;
862         int i;
863 
864         for (i = 0; i < confs->count; i++)
865                 if (confs->data[i].pixel_clock == pixel_clock)
866                         return i;
867 
868         DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
869         return -EINVAL;
870 }
871 
872 static int hdmi_mode_valid(struct drm_connector *connector,
873                         struct drm_display_mode *mode)
874 {
875         struct hdmi_context *hdata = connector_to_hdmi(connector);
876         int ret;
877 
878         DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
879                 mode->hdisplay, mode->vdisplay, mode->vrefresh,
880                 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
881                 false, mode->clock * 1000);
882 
883         ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
884         if (ret < 0)
885                 return MODE_BAD;
886 
887         return MODE_OK;
888 }
889 
890 static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
891         .get_modes = hdmi_get_modes,
892         .mode_valid = hdmi_mode_valid,
893 };
894 
895 static int hdmi_create_connector(struct drm_encoder *encoder)
896 {
897         struct hdmi_context *hdata = encoder_to_hdmi(encoder);
898         struct drm_connector *connector = &hdata->connector;
899         int ret;
900 
901         connector->interlace_allowed = true;
902         connector->polled = DRM_CONNECTOR_POLL_HPD;
903 
904         ret = drm_connector_init(hdata->drm_dev, connector,
905                         &hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA);
906         if (ret) {
907                 DRM_ERROR("Failed to initialize connector with drm\n");
908                 return ret;
909         }
910 
911         drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
912         drm_connector_register(connector);
913         drm_mode_connector_attach_encoder(connector, encoder);
914 
915         return 0;
916 }
917 
918 static bool hdmi_mode_fixup(struct drm_encoder *encoder,
919                             const struct drm_display_mode *mode,
920                             struct drm_display_mode *adjusted_mode)
921 {
922         struct drm_device *dev = encoder->dev;
923         struct drm_connector *connector;
924         struct drm_display_mode *m;
925         int mode_ok;
926 
927         drm_mode_set_crtcinfo(adjusted_mode, 0);
928 
929         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
930                 if (connector->encoder == encoder)
931                         break;
932         }
933 
934         if (connector->encoder != encoder)
935                 return true;
936 
937         mode_ok = hdmi_mode_valid(connector, adjusted_mode);
938 
939         if (mode_ok == MODE_OK)
940                 return true;
941 
942         /*
943          * Find the most suitable mode and copy it to adjusted_mode.
944          */
945         list_for_each_entry(m, &connector->modes, head) {
946                 mode_ok = hdmi_mode_valid(connector, m);
947 
948                 if (mode_ok == MODE_OK) {
949                         DRM_INFO("desired mode doesn't exist so\n");
950                         DRM_INFO("use the most suitable mode among modes.\n");
951 
952                         DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n",
953                                 m->hdisplay, m->vdisplay, m->vrefresh);
954 
955                         drm_mode_copy(adjusted_mode, m);
956                         break;
957                 }
958         }
959 
960         return true;
961 }
962 
963 static void hdmi_reg_acr(struct hdmi_context *hdata, u32 freq)
964 {
965         u32 n, cts;
966 
967         cts = (freq % 9) ? 27000 : 30000;
968         n = 128 * freq / (27000000 / cts);
969 
970         hdmi_reg_writev(hdata, HDMI_ACR_N0, 3, n);
971         hdmi_reg_writev(hdata, HDMI_ACR_MCTS0, 3, cts);
972         hdmi_reg_writev(hdata, HDMI_ACR_CTS0, 3, cts);
973         hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
974 }
975 
976 static void hdmi_audio_init(struct hdmi_context *hdata)
977 {
978         u32 sample_rate, bits_per_sample;
979         u32 data_num, bit_ch, sample_frq;
980         u32 val;
981 
982         sample_rate = 44100;
983         bits_per_sample = 16;
984 
985         switch (bits_per_sample) {
986         case 20:
987                 data_num = 2;
988                 bit_ch = 1;
989                 break;
990         case 24:
991                 data_num = 3;
992                 bit_ch = 1;
993                 break;
994         default:
995                 data_num = 1;
996                 bit_ch = 0;
997                 break;
998         }
999 
1000         hdmi_reg_acr(hdata, sample_rate);
1001 
1002         hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1003                                 | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1004                                 | HDMI_I2S_MUX_ENABLE);
1005 
1006         hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1007                         | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1008 
1009         hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1010 
1011         sample_frq = (sample_rate == 44100) ? 0 :
1012                         (sample_rate == 48000) ? 2 :
1013                         (sample_rate == 32000) ? 3 :
1014                         (sample_rate == 96000) ? 0xa : 0x0;
1015 
1016         hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1017         hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1018 
1019         val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1020         hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1021 
1022         /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1023         hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1024                         | HDMI_I2S_SEL_LRCK(6));
1025         hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1026                         | HDMI_I2S_SEL_SDATA2(4));
1027         hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1028                         | HDMI_I2S_SEL_SDATA2(2));
1029         hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1030 
1031         /* I2S_CON_1 & 2 */
1032         hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1033                         | HDMI_I2S_L_CH_LOW_POL);
1034         hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1035                         | HDMI_I2S_SET_BIT_CH(bit_ch)
1036                         | HDMI_I2S_SET_SDATA_BIT(data_num)
1037                         | HDMI_I2S_BASIC_FORMAT);
1038 
1039         /* Configure register related to CUV information */
1040         hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
1041                         | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1042                         | HDMI_I2S_COPYRIGHT
1043                         | HDMI_I2S_LINEAR_PCM
1044                         | HDMI_I2S_CONSUMER_FORMAT);
1045         hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1046         hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1047         hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1048                         | HDMI_I2S_SET_SMP_FREQ(sample_frq));
1049         hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1050                         HDMI_I2S_ORG_SMP_FREQ_44_1
1051                         | HDMI_I2S_WORD_LEN_MAX24_24BITS
1052                         | HDMI_I2S_WORD_LEN_MAX_24BITS);
1053 
1054         hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1055 }
1056 
1057 static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1058 {
1059         if (hdata->dvi_mode)
1060                 return;
1061 
1062         hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
1063         hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ?
1064                         HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1065 }
1066 
1067 static void hdmi_start(struct hdmi_context *hdata, bool start)
1068 {
1069         u32 val = start ? HDMI_TG_EN : 0;
1070 
1071         if (hdata->current_mode.flags & DRM_MODE_FLAG_INTERLACE)
1072                 val |= HDMI_FIELD_EN;
1073 
1074         hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN);
1075         hdmi_reg_writemask(hdata, HDMI_TG_CMD, val, HDMI_TG_EN | HDMI_FIELD_EN);
1076 }
1077 
1078 static void hdmi_conf_init(struct hdmi_context *hdata)
1079 {
1080         /* disable HPD interrupts from HDMI IP block, use GPIO instead */
1081         hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1082                 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1083 
1084         /* choose HDMI mode */
1085         hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1086                 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1087         /* apply video pre-amble and guard band in HDMI mode only */
1088         hdmi_reg_writeb(hdata, HDMI_CON_2, 0);
1089         /* disable bluescreen */
1090         hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1091 
1092         if (hdata->dvi_mode) {
1093                 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1094                                 HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1095                 hdmi_reg_writeb(hdata, HDMI_CON_2,
1096                                 HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1097         }
1098 
1099         if (hdata->drv_data->type == HDMI_TYPE13) {
1100                 /* choose bluescreen (fecal) color */
1101                 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1102                 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1103                 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1104 
1105                 /* enable AVI packet every vsync, fixes purple line problem */
1106                 hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1107                 /* force RGB, look to CEA-861-D, table 7 for more detail */
1108                 hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1109                 hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1110 
1111                 hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1112                 hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1113                 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1114         } else {
1115                 hdmi_reg_infoframes(hdata);
1116 
1117                 /* enable AVI packet every vsync, fixes purple line problem */
1118                 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1119         }
1120 }
1121 
1122 static void hdmiphy_wait_for_pll(struct hdmi_context *hdata)
1123 {
1124         int tries;
1125 
1126         for (tries = 0; tries < 10; ++tries) {
1127                 u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS);
1128 
1129                 if (val & HDMI_PHY_STATUS_READY) {
1130                         DRM_DEBUG_KMS("PLL stabilized after %d tries\n", tries);
1131                         return;
1132                 }
1133                 usleep_range(10, 20);
1134         }
1135 
1136         DRM_ERROR("PLL could not reach steady state\n");
1137 }
1138 
1139 static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1140 {
1141         struct drm_display_mode *m = &hdata->current_mode;
1142         unsigned int val;
1143 
1144         hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1145         hdmi_reg_writev(hdata, HDMI_V13_H_V_LINE_0, 3,
1146                         (m->htotal << 12) | m->vtotal);
1147 
1148         val = (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
1149         hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1, val);
1150 
1151         val = (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0;
1152         hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1, val);
1153 
1154         val = (m->hsync_start - m->hdisplay - 2);
1155         val |= ((m->hsync_end - m->hdisplay - 2) << 10);
1156         val |= ((m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0)<<20;
1157         hdmi_reg_writev(hdata, HDMI_V13_H_SYNC_GEN_0, 3, val);
1158 
1159         /*
1160          * Quirk requirement for exynos HDMI IP design,
1161          * 2 pixels less than the actual calculation for hsync_start
1162          * and end.
1163          */
1164 
1165         /* Following values & calculations differ for different type of modes */
1166         if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1167                 val = ((m->vsync_end - m->vdisplay) / 2);
1168                 val |= ((m->vsync_start - m->vdisplay) / 2) << 12;
1169                 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1170 
1171                 val = m->vtotal / 2;
1172                 val |= ((m->vtotal - m->vdisplay) / 2) << 11;
1173                 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1174 
1175                 val = (m->vtotal +
1176                         ((m->vsync_end - m->vsync_start) * 4) + 5) / 2;
1177                 val |= m->vtotal << 11;
1178                 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, val);
1179 
1180                 val = ((m->vtotal / 2) + 7);
1181                 val |= ((m->vtotal / 2) + 2) << 12;
1182                 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, val);
1183 
1184                 val = ((m->htotal / 2) + (m->hsync_start - m->hdisplay));
1185                 val |= ((m->htotal / 2) +
1186                         (m->hsync_start - m->hdisplay)) << 12;
1187                 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, val);
1188 
1189                 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1190                                 (m->vtotal - m->vdisplay) / 2);
1191                 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1192 
1193                 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x249);
1194         } else {
1195                 val = m->vtotal;
1196                 val |= (m->vtotal - m->vdisplay) << 11;
1197                 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1198 
1199                 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, 0);
1200 
1201                 val = (m->vsync_end - m->vdisplay);
1202                 val |= ((m->vsync_start - m->vdisplay) << 12);
1203                 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1204 
1205                 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, 0x1001);
1206                 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, 0x1001);
1207                 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1208                                 m->vtotal - m->vdisplay);
1209                 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1210         }
1211 
1212         hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1213         hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1214         hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1215         hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1216 }
1217 
1218 static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1219 {
1220         struct drm_display_mode *m = &hdata->current_mode;
1221 
1222         hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1223         hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
1224         hdmi_reg_writev(hdata, HDMI_H_LINE_0, 2, m->htotal);
1225         hdmi_reg_writev(hdata, HDMI_HSYNC_POL, 1,
1226                         (m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0);
1227         hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1,
1228                         (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
1229         hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1,
1230                         (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1231 
1232         /*
1233          * Quirk requirement for exynos 5 HDMI IP design,
1234          * 2 pixels less than the actual calculation for hsync_start
1235          * and end.
1236          */
1237 
1238         /* Following values & calculations differ for different type of modes */
1239         if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1240                 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1241                         (m->vsync_end - m->vdisplay) / 2);
1242                 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1243                         (m->vsync_start - m->vdisplay) / 2);
1244                 hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal / 2);
1245                 hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1246                                 (m->vtotal - m->vdisplay) / 2);
1247                 hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2,
1248                                 m->vtotal - m->vdisplay / 2);
1249                 hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, m->vtotal);
1250                 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2,
1251                                 (m->vtotal / 2) + 7);
1252                 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2,
1253                                 (m->vtotal / 2) + 2);
1254                 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2,
1255                         (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1256                 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2,
1257                         (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1258                 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1259                                 (m->vtotal - m->vdisplay) / 2);
1260                 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1261                 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2,
1262                                 m->vtotal - m->vdisplay / 2);
1263                 hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2,
1264                                 (m->vtotal / 2) + 1);
1265                 hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2,
1266                                 (m->vtotal / 2) + 1);
1267                 hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2,
1268                                 (m->vtotal / 2) + 1);
1269                 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x0);
1270                 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x0);
1271         } else {
1272                 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1273                         m->vsync_end - m->vdisplay);
1274                 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1275                         m->vsync_start - m->vdisplay);
1276                 hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal);
1277                 hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1278                                 m->vtotal - m->vdisplay);
1279                 hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2, 0xffff);
1280                 hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, 0xffff);
1281                 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2, 0xffff);
1282                 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2, 0xffff);
1283                 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2, 0xffff);
1284                 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2, 0xffff);
1285                 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1286                                 m->vtotal - m->vdisplay);
1287                 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1288         }
1289 
1290         hdmi_reg_writev(hdata, HDMI_H_SYNC_START_0, 2,
1291                         m->hsync_start - m->hdisplay - 2);
1292         hdmi_reg_writev(hdata, HDMI_H_SYNC_END_0, 2,
1293                         m->hsync_end - m->hdisplay - 2);
1294         hdmi_reg_writev(hdata, HDMI_VACT_SPACE_1_0, 2, 0xffff);
1295         hdmi_reg_writev(hdata, HDMI_VACT_SPACE_2_0, 2, 0xffff);
1296         hdmi_reg_writev(hdata, HDMI_VACT_SPACE_3_0, 2, 0xffff);
1297         hdmi_reg_writev(hdata, HDMI_VACT_SPACE_4_0, 2, 0xffff);
1298         hdmi_reg_writev(hdata, HDMI_VACT_SPACE_5_0, 2, 0xffff);
1299         hdmi_reg_writev(hdata, HDMI_VACT_SPACE_6_0, 2, 0xffff);
1300         hdmi_reg_writev(hdata, HDMI_V_BLANK_F2_0, 2, 0xffff);
1301         hdmi_reg_writev(hdata, HDMI_V_BLANK_F3_0, 2, 0xffff);
1302         hdmi_reg_writev(hdata, HDMI_V_BLANK_F4_0, 2, 0xffff);
1303         hdmi_reg_writev(hdata, HDMI_V_BLANK_F5_0, 2, 0xffff);
1304         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_3_0, 2, 0xffff);
1305         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_4_0, 2, 0xffff);
1306         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_5_0, 2, 0xffff);
1307         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_6_0, 2, 0xffff);
1308         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0, 2, 0xffff);
1309         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0, 2, 0xffff);
1310         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, 2, 0xffff);
1311         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
1312 
1313         hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1314         hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1315         hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1316         hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1317         if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1318                 hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1);
1319 }
1320 
1321 static void hdmi_mode_apply(struct hdmi_context *hdata)
1322 {
1323         if (hdata->drv_data->type == HDMI_TYPE13)
1324                 hdmi_v13_mode_apply(hdata);
1325         else
1326                 hdmi_v14_mode_apply(hdata);
1327 
1328         hdmi_start(hdata, true);
1329 }
1330 
1331 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1332 {
1333         hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, 0, 1);
1334         usleep_range(10000, 12000);
1335         hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, ~0, 1);
1336         usleep_range(10000, 12000);
1337         hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
1338         usleep_range(10000, 12000);
1339         hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT);
1340         usleep_range(10000, 12000);
1341 }
1342 
1343 static void hdmiphy_enable_mode_set(struct hdmi_context *hdata, bool enable)
1344 {
1345         u8 v = enable ? HDMI_PHY_ENABLE_MODE_SET : HDMI_PHY_DISABLE_MODE_SET;
1346 
1347         if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1348                 writel(v, hdata->regs_hdmiphy + HDMIPHY5433_MODE_SET_DONE);
1349 }
1350 
1351 static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1352 {
1353         int ret;
1354         const u8 *phy_conf;
1355 
1356         ret = hdmi_find_phy_conf(hdata, hdata->current_mode.clock * 1000);
1357         if (ret < 0) {
1358                 DRM_ERROR("failed to find hdmiphy conf\n");
1359                 return;
1360         }
1361         phy_conf = hdata->drv_data->phy_confs.data[ret].conf;
1362 
1363         hdmi_clk_set_parents(hdata, false);
1364 
1365         hdmiphy_conf_reset(hdata);
1366 
1367         hdmiphy_enable_mode_set(hdata, true);
1368         ret = hdmiphy_reg_write_buf(hdata, 0, phy_conf, 32);
1369         if (ret) {
1370                 DRM_ERROR("failed to configure hdmiphy\n");
1371                 return;
1372         }
1373         hdmiphy_enable_mode_set(hdata, false);
1374         hdmi_clk_set_parents(hdata, true);
1375         usleep_range(10000, 12000);
1376         hdmiphy_wait_for_pll(hdata);
1377 }
1378 
1379 static void hdmi_conf_apply(struct hdmi_context *hdata)
1380 {
1381         hdmi_start(hdata, false);
1382         hdmi_conf_init(hdata);
1383         hdmi_audio_init(hdata);
1384         hdmi_mode_apply(hdata);
1385         hdmi_audio_control(hdata, true);
1386 }
1387 
1388 static void hdmi_mode_set(struct drm_encoder *encoder,
1389                           struct drm_display_mode *mode,
1390                           struct drm_display_mode *adjusted_mode)
1391 {
1392         struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1393         struct drm_display_mode *m = adjusted_mode;
1394 
1395         DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n",
1396                 m->hdisplay, m->vdisplay,
1397                 m->vrefresh, (m->flags & DRM_MODE_FLAG_INTERLACE) ?
1398                 "INTERLACED" : "PROGRESSIVE");
1399 
1400         drm_mode_copy(&hdata->current_mode, m);
1401 }
1402 
1403 static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
1404 {
1405         if (!hdata->sysreg)
1406                 return;
1407 
1408         regmap_update_bits(hdata->sysreg, EXYNOS5433_SYSREG_DISP_HDMI_PHY,
1409                            SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0);
1410 }
1411 
1412 static void hdmiphy_enable(struct hdmi_context *hdata)
1413 {
1414         if (hdata->powered)
1415                 return;
1416 
1417         pm_runtime_get_sync(hdata->dev);
1418 
1419         if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk))
1420                 DRM_DEBUG_KMS("failed to enable regulator bulk\n");
1421 
1422         regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1423                         PMU_HDMI_PHY_ENABLE_BIT, 1);
1424 
1425         hdmi_set_refclk(hdata, true);
1426 
1427         hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN);
1428 
1429         hdmiphy_conf_apply(hdata);
1430 
1431         hdata->powered = true;
1432 }
1433 
1434 static void hdmiphy_disable(struct hdmi_context *hdata)
1435 {
1436         if (!hdata->powered)
1437                 return;
1438 
1439         hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
1440 
1441         hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN);
1442 
1443         hdmi_set_refclk(hdata, false);
1444 
1445         regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1446                         PMU_HDMI_PHY_ENABLE_BIT, 0);
1447 
1448         regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
1449 
1450         pm_runtime_put_sync(hdata->dev);
1451 
1452         hdata->powered = false;
1453 }
1454 
1455 static void hdmi_enable(struct drm_encoder *encoder)
1456 {
1457         struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1458 
1459         hdmiphy_enable(hdata);
1460         hdmi_conf_apply(hdata);
1461 }
1462 
1463 static void hdmi_disable(struct drm_encoder *encoder)
1464 {
1465         struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1466         struct drm_crtc *crtc = encoder->crtc;
1467         const struct drm_crtc_helper_funcs *funcs = NULL;
1468 
1469         if (!hdata->powered)
1470                 return;
1471 
1472         /*
1473          * The SFRs of VP and Mixer are updated by Vertical Sync of
1474          * Timing generator which is a part of HDMI so the sequence
1475          * to disable TV Subsystem should be as following,
1476          *      VP -> Mixer -> HDMI
1477          *
1478          * Below codes will try to disable Mixer and VP(if used)
1479          * prior to disabling HDMI.
1480          */
1481         if (crtc)
1482                 funcs = crtc->helper_private;
1483         if (funcs && funcs->disable)
1484                 (*funcs->disable)(crtc);
1485 
1486         cancel_delayed_work(&hdata->hotplug_work);
1487 
1488         hdmiphy_disable(hdata);
1489 }
1490 
1491 static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
1492         .mode_fixup     = hdmi_mode_fixup,
1493         .mode_set       = hdmi_mode_set,
1494         .enable         = hdmi_enable,
1495         .disable        = hdmi_disable,
1496 };
1497 
1498 static const struct drm_encoder_funcs exynos_hdmi_encoder_funcs = {
1499         .destroy = drm_encoder_cleanup,
1500 };
1501 
1502 static void hdmi_hotplug_work_func(struct work_struct *work)
1503 {
1504         struct hdmi_context *hdata;
1505 
1506         hdata = container_of(work, struct hdmi_context, hotplug_work.work);
1507 
1508         if (hdata->drm_dev)
1509                 drm_helper_hpd_irq_event(hdata->drm_dev);
1510 }
1511 
1512 static irqreturn_t hdmi_irq_thread(int irq, void *arg)
1513 {
1514         struct hdmi_context *hdata = arg;
1515 
1516         mod_delayed_work(system_wq, &hdata->hotplug_work,
1517                         msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
1518 
1519         return IRQ_HANDLED;
1520 }
1521 
1522 static int hdmi_clks_get(struct hdmi_context *hdata,
1523                          const struct string_array_spec *names,
1524                          struct clk **clks)
1525 {
1526         struct device *dev = hdata->dev;
1527         int i;
1528 
1529         for (i = 0; i < names->count; ++i) {
1530                 struct clk *clk = devm_clk_get(dev, names->data[i]);
1531 
1532                 if (IS_ERR(clk)) {
1533                         int ret = PTR_ERR(clk);
1534 
1535                         dev_err(dev, "Cannot get clock %s, %d\n",
1536                                 names->data[i], ret);
1537 
1538                         return ret;
1539                 }
1540 
1541                 clks[i] = clk;
1542         }
1543 
1544         return 0;
1545 }
1546 
1547 static int hdmi_clk_init(struct hdmi_context *hdata)
1548 {
1549         const struct hdmi_driver_data *drv_data = hdata->drv_data;
1550         int count = drv_data->clk_gates.count + drv_data->clk_muxes.count;
1551         struct device *dev = hdata->dev;
1552         struct clk **clks;
1553         int ret;
1554 
1555         if (!count)
1556                 return 0;
1557 
1558         clks = devm_kzalloc(dev, sizeof(*clks) * count, GFP_KERNEL);
1559         if (!clks)
1560                 return -ENOMEM;
1561 
1562         hdata->clk_gates = clks;
1563         hdata->clk_muxes = clks + drv_data->clk_gates.count;
1564 
1565         ret = hdmi_clks_get(hdata, &drv_data->clk_gates, hdata->clk_gates);
1566         if (ret)
1567                 return ret;
1568 
1569         return hdmi_clks_get(hdata, &drv_data->clk_muxes, hdata->clk_muxes);
1570 }
1571 
1572 
1573 static void hdmiphy_clk_enable(struct exynos_drm_clk *clk, bool enable)
1574 {
1575         struct hdmi_context *hdata = container_of(clk, struct hdmi_context,
1576                                                   phy_clk);
1577 
1578         if (enable)
1579                 hdmiphy_enable(hdata);
1580         else
1581                 hdmiphy_disable(hdata);
1582 }
1583 
1584 static int hdmi_resources_init(struct hdmi_context *hdata)
1585 {
1586         struct device *dev = hdata->dev;
1587         int i, ret;
1588 
1589         DRM_DEBUG_KMS("HDMI resource init\n");
1590 
1591         hdata->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
1592         if (IS_ERR(hdata->hpd_gpio)) {
1593                 DRM_ERROR("cannot get hpd gpio property\n");
1594                 return PTR_ERR(hdata->hpd_gpio);
1595         }
1596 
1597         hdata->irq = gpiod_to_irq(hdata->hpd_gpio);
1598         if (hdata->irq < 0) {
1599                 DRM_ERROR("failed to get GPIO irq\n");
1600                 return  hdata->irq;
1601         }
1602 
1603         ret = hdmi_clk_init(hdata);
1604         if (ret)
1605                 return ret;
1606 
1607         ret = hdmi_clk_set_parents(hdata, false);
1608         if (ret)
1609                 return ret;
1610 
1611         for (i = 0; i < ARRAY_SIZE(supply); ++i)
1612                 hdata->regul_bulk[i].supply = supply[i];
1613 
1614         ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), hdata->regul_bulk);
1615         if (ret) {
1616                 if (ret != -EPROBE_DEFER)
1617                         DRM_ERROR("failed to get regulators\n");
1618                 return ret;
1619         }
1620 
1621         hdata->reg_hdmi_en = devm_regulator_get_optional(dev, "hdmi-en");
1622 
1623         if (PTR_ERR(hdata->reg_hdmi_en) == -ENODEV)
1624                 return 0;
1625 
1626         if (IS_ERR(hdata->reg_hdmi_en))
1627                 return PTR_ERR(hdata->reg_hdmi_en);
1628 
1629         ret = regulator_enable(hdata->reg_hdmi_en);
1630         if (ret)
1631                 DRM_ERROR("failed to enable hdmi-en regulator\n");
1632 
1633         return ret;
1634 }
1635 
1636 static struct of_device_id hdmi_match_types[] = {
1637         {
1638                 .compatible = "samsung,exynos4210-hdmi",
1639                 .data = &exynos4210_hdmi_driver_data,
1640         }, {
1641                 .compatible = "samsung,exynos4212-hdmi",
1642                 .data = &exynos4212_hdmi_driver_data,
1643         }, {
1644                 .compatible = "samsung,exynos5420-hdmi",
1645                 .data = &exynos5420_hdmi_driver_data,
1646         }, {
1647                 .compatible = "samsung,exynos5433-hdmi",
1648                 .data = &exynos5433_hdmi_driver_data,
1649         }, {
1650                 /* end node */
1651         }
1652 };
1653 MODULE_DEVICE_TABLE (of, hdmi_match_types);
1654 
1655 static int hdmi_bind(struct device *dev, struct device *master, void *data)
1656 {
1657         struct drm_device *drm_dev = data;
1658         struct hdmi_context *hdata = dev_get_drvdata(dev);
1659         struct drm_encoder *encoder = &hdata->encoder;
1660         int ret, pipe;
1661 
1662         hdata->drm_dev = drm_dev;
1663 
1664         pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
1665                                                   EXYNOS_DISPLAY_TYPE_HDMI);
1666         if (pipe < 0)
1667                 return pipe;
1668 
1669         hdata->phy_clk.enable = hdmiphy_clk_enable;
1670 
1671         exynos_drm_crtc_from_pipe(drm_dev, pipe)->pipe_clk = &hdata->phy_clk;
1672 
1673         encoder->possible_crtcs = 1 << pipe;
1674 
1675         DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
1676 
1677         drm_encoder_init(drm_dev, encoder, &exynos_hdmi_encoder_funcs,
1678                          DRM_MODE_ENCODER_TMDS, NULL);
1679 
1680         drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
1681 
1682         ret = hdmi_create_connector(encoder);
1683         if (ret) {
1684                 DRM_ERROR("failed to create connector ret = %d\n", ret);
1685                 drm_encoder_cleanup(encoder);
1686                 return ret;
1687         }
1688 
1689         return 0;
1690 }
1691 
1692 static void hdmi_unbind(struct device *dev, struct device *master, void *data)
1693 {
1694 }
1695 
1696 static const struct component_ops hdmi_component_ops = {
1697         .bind   = hdmi_bind,
1698         .unbind = hdmi_unbind,
1699 };
1700 
1701 static int hdmi_get_ddc_adapter(struct hdmi_context *hdata)
1702 {
1703         const char *compatible_str = "samsung,exynos4210-hdmiddc";
1704         struct device_node *np;
1705         struct i2c_adapter *adpt;
1706 
1707         np = of_find_compatible_node(NULL, NULL, compatible_str);
1708         if (np)
1709                 np = of_get_next_parent(np);
1710         else
1711                 np = of_parse_phandle(hdata->dev->of_node, "ddc", 0);
1712 
1713         if (!np) {
1714                 DRM_ERROR("Failed to find ddc node in device tree\n");
1715                 return -ENODEV;
1716         }
1717 
1718         adpt = of_find_i2c_adapter_by_node(np);
1719         of_node_put(np);
1720 
1721         if (!adpt) {
1722                 DRM_INFO("Failed to get ddc i2c adapter by node\n");
1723                 return -EPROBE_DEFER;
1724         }
1725 
1726         hdata->ddc_adpt = adpt;
1727 
1728         return 0;
1729 }
1730 
1731 static int hdmi_get_phy_io(struct hdmi_context *hdata)
1732 {
1733         const char *compatible_str = "samsung,exynos4212-hdmiphy";
1734         struct device_node *np;
1735         int ret = 0;
1736 
1737         np = of_find_compatible_node(NULL, NULL, compatible_str);
1738         if (!np) {
1739                 np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
1740                 if (!np) {
1741                         DRM_ERROR("Failed to find hdmiphy node in device tree\n");
1742                         return -ENODEV;
1743                 }
1744         }
1745 
1746         if (hdata->drv_data->is_apb_phy) {
1747                 hdata->regs_hdmiphy = of_iomap(np, 0);
1748                 if (!hdata->regs_hdmiphy) {
1749                         DRM_ERROR("failed to ioremap hdmi phy\n");
1750                         ret = -ENOMEM;
1751                         goto out;
1752                 }
1753         } else {
1754                 hdata->hdmiphy_port = of_find_i2c_device_by_node(np);
1755                 if (!hdata->hdmiphy_port) {
1756                         DRM_INFO("Failed to get hdmi phy i2c client\n");
1757                         ret = -EPROBE_DEFER;
1758                         goto out;
1759                 }
1760         }
1761 
1762 out:
1763         of_node_put(np);
1764         return ret;
1765 }
1766 
1767 static int hdmi_probe(struct platform_device *pdev)
1768 {
1769         struct device *dev = &pdev->dev;
1770         struct hdmi_context *hdata;
1771         struct resource *res;
1772         int ret;
1773 
1774         hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
1775         if (!hdata)
1776                 return -ENOMEM;
1777 
1778         hdata->drv_data = of_device_get_match_data(dev);
1779 
1780         platform_set_drvdata(pdev, hdata);
1781 
1782         hdata->dev = dev;
1783 
1784         ret = hdmi_resources_init(hdata);
1785         if (ret) {
1786                 if (ret != -EPROBE_DEFER)
1787                         DRM_ERROR("hdmi_resources_init failed\n");
1788                 return ret;
1789         }
1790 
1791         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1792         hdata->regs = devm_ioremap_resource(dev, res);
1793         if (IS_ERR(hdata->regs)) {
1794                 ret = PTR_ERR(hdata->regs);
1795                 return ret;
1796         }
1797 
1798         ret = hdmi_get_ddc_adapter(hdata);
1799         if (ret)
1800                 return ret;
1801 
1802         ret = hdmi_get_phy_io(hdata);
1803         if (ret)
1804                 goto err_ddc;
1805 
1806         INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
1807 
1808         ret = devm_request_threaded_irq(dev, hdata->irq, NULL,
1809                         hdmi_irq_thread, IRQF_TRIGGER_RISING |
1810                         IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1811                         "hdmi", hdata);
1812         if (ret) {
1813                 DRM_ERROR("failed to register hdmi interrupt\n");
1814                 goto err_hdmiphy;
1815         }
1816 
1817         hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
1818                         "samsung,syscon-phandle");
1819         if (IS_ERR(hdata->pmureg)) {
1820                 DRM_ERROR("syscon regmap lookup failed.\n");
1821                 ret = -EPROBE_DEFER;
1822                 goto err_hdmiphy;
1823         }
1824 
1825         if (hdata->drv_data->has_sysreg) {
1826                 hdata->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
1827                                 "samsung,sysreg-phandle");
1828                 if (IS_ERR(hdata->sysreg)) {
1829                         DRM_ERROR("sysreg regmap lookup failed.\n");
1830                         ret = -EPROBE_DEFER;
1831                         goto err_hdmiphy;
1832                 }
1833         }
1834 
1835         pm_runtime_enable(dev);
1836 
1837         ret = component_add(&pdev->dev, &hdmi_component_ops);
1838         if (ret)
1839                 goto err_disable_pm_runtime;
1840 
1841         return ret;
1842 
1843 err_disable_pm_runtime:
1844         pm_runtime_disable(dev);
1845 
1846 err_hdmiphy:
1847         if (hdata->hdmiphy_port)
1848                 put_device(&hdata->hdmiphy_port->dev);
1849         if (hdata->regs_hdmiphy)
1850                 iounmap(hdata->regs_hdmiphy);
1851 err_ddc:
1852         put_device(&hdata->ddc_adpt->dev);
1853 
1854         return ret;
1855 }
1856 
1857 static int hdmi_remove(struct platform_device *pdev)
1858 {
1859         struct hdmi_context *hdata = platform_get_drvdata(pdev);
1860 
1861         cancel_delayed_work_sync(&hdata->hotplug_work);
1862 
1863         component_del(&pdev->dev, &hdmi_component_ops);
1864 
1865         pm_runtime_disable(&pdev->dev);
1866 
1867         if (!IS_ERR(hdata->reg_hdmi_en))
1868                 regulator_disable(hdata->reg_hdmi_en);
1869 
1870         if (hdata->hdmiphy_port)
1871                 put_device(&hdata->hdmiphy_port->dev);
1872 
1873         if (hdata->regs_hdmiphy)
1874                 iounmap(hdata->regs_hdmiphy);
1875 
1876         put_device(&hdata->ddc_adpt->dev);
1877 
1878         return 0;
1879 }
1880 
1881 #ifdef CONFIG_PM
1882 static int exynos_hdmi_suspend(struct device *dev)
1883 {
1884         struct hdmi_context *hdata = dev_get_drvdata(dev);
1885 
1886         hdmi_clk_disable_gates(hdata);
1887 
1888         return 0;
1889 }
1890 
1891 static int exynos_hdmi_resume(struct device *dev)
1892 {
1893         struct hdmi_context *hdata = dev_get_drvdata(dev);
1894         int ret;
1895 
1896         ret = hdmi_clk_enable_gates(hdata);
1897         if (ret < 0)
1898                 return ret;
1899 
1900         return 0;
1901 }
1902 #endif
1903 
1904 static const struct dev_pm_ops exynos_hdmi_pm_ops = {
1905         SET_RUNTIME_PM_OPS(exynos_hdmi_suspend, exynos_hdmi_resume, NULL)
1906 };
1907 
1908 struct platform_driver hdmi_driver = {
1909         .probe          = hdmi_probe,
1910         .remove         = hdmi_remove,
1911         .driver         = {
1912                 .name   = "exynos-hdmi",
1913                 .owner  = THIS_MODULE,
1914                 .pm     = &exynos_hdmi_pm_ops,
1915                 .of_match_table = hdmi_match_types,
1916         },
1917 };
1918 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us