Version:  2.0.40 2.2.26 2.4.37 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 4.7

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

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