Version:  2.0.40 2.2.26 2.4.37 3.9 3.10 3.11 3.12 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

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

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