Linux 4.9.243
[linux/fpc-iii.git] / drivers / gpu / drm / exynos / exynos_hdmi.c
blob4198e50fa27b119a3b707678eb4740b9b101bf4f
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>
8 * Based on drivers/media/video/s5p-tv/hdmi_drv.c
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.
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>
22 #include "regs-hdmi.h"
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>
43 #include <drm/exynos_drm.h>
45 #include "exynos_drm_drv.h"
46 #include "exynos_drm_crtc.h"
48 #define HOTPLUG_DEBOUNCE_MS 1100
50 /* AVI header and aspect ratio */
51 #define HDMI_AVI_VERSION 0x02
52 #define HDMI_AVI_LENGTH 0x0d
54 /* AUI header info */
55 #define HDMI_AUI_VERSION 0x01
56 #define HDMI_AUI_LENGTH 0x0a
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
63 enum hdmi_type {
64 HDMI_TYPE13,
65 HDMI_TYPE14,
66 HDMI_TYPE_COUNT
69 #define HDMI_MAPPED_BASE 0xffff0000
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
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 },
89 static const char * const supply[] = {
90 "vdd",
91 "vdd_osc",
92 "vdd_pll",
95 struct hdmiphy_config {
96 int pixel_clock;
97 u8 conf[32];
100 struct hdmiphy_configs {
101 int count;
102 const struct hdmiphy_config *data;
105 struct string_array_spec {
106 int count;
107 const char * const *data;
110 #define INIT_ARRAY_SPEC(a) { .count = ARRAY_SIZE(a), .data = a }
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;
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.
122 struct string_array_spec clk_muxes;
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;
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;
152 static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e)
154 return container_of(e, struct hdmi_context, encoder);
157 static inline struct hdmi_context *connector_to_hdmi(struct drm_connector *c)
159 return container_of(c, struct hdmi_context, connector);
162 static const struct hdmiphy_config hdmiphy_v13_configs[] = {
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,
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,
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,
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,
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,
210 static const struct hdmiphy_config hdmiphy_v14_configs[] = {
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
366 static const struct hdmiphy_config hdmiphy_5420_configs[] = {
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
522 static const struct hdmiphy_config hdmiphy_5433_configs[] = {
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,
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,
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,
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,
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,
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,
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,
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,
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,
606 static const char * const hdmi_clk_gates4[] = {
607 "hdmi", "sclk_hdmi"
610 static const char * const hdmi_clk_muxes4[] = {
611 "sclk_pixel", "sclk_hdmiphy", "mout_hdmi"
614 static const char * const hdmi_clk_gates5433[] = {
615 "hdmi_pclk", "hdmi_i_pclk", "i_tmds_clk", "i_pixel_clk", "i_spdif_clk"
618 static const char * const hdmi_clk_muxes5433[] = {
619 "oscclk", "tmds_clko", "tmds_clko_user",
620 "oscclk", "pixel_clko", "pixel_clko_user"
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),
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),
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),
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),
654 static inline u32 hdmi_map_reg(struct hdmi_context *hdata, u32 reg_id)
656 if ((reg_id & 0xffff0000) == HDMI_MAPPED_BASE)
657 return hdmi_reg_map[reg_id & 0xffff][hdata->drv_data->type];
658 return reg_id;
661 static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
663 return readl(hdata->regs + hdmi_map_reg(hdata, reg_id));
666 static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
667 u32 reg_id, u8 value)
669 writel(value, hdata->regs + hdmi_map_reg(hdata, reg_id));
672 static inline void hdmi_reg_writev(struct hdmi_context *hdata, u32 reg_id,
673 int bytes, u32 val)
675 reg_id = hdmi_map_reg(hdata, reg_id);
677 while (--bytes >= 0) {
678 writel(val & 0xff, hdata->regs + reg_id);
679 val >>= 8;
680 reg_id += 4;
684 static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
685 u32 reg_id, u32 value, u32 mask)
687 u32 old;
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);
695 static int hdmiphy_reg_write_buf(struct hdmi_context *hdata,
696 u32 reg_offset, const u8 *buf, u32 len)
698 if ((reg_offset + len) > 32)
699 return -EINVAL;
701 if (hdata->hdmiphy_port) {
702 int ret;
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;
717 static int hdmi_clk_enable_gates(struct hdmi_context *hdata)
719 int i, ret;
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;
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;
733 return 0;
736 static void hdmi_clk_disable_gates(struct hdmi_context *hdata)
738 int i = hdata->drv_data->clk_gates.count;
740 while (i--)
741 clk_disable_unprepare(hdata->clk_gates[i]);
744 static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy)
746 struct device *dev = hdata->dev;
747 int ret = 0;
748 int i;
750 for (i = 0; i < hdata->drv_data->clk_muxes.count; i += 3) {
751 struct clk **c = &hdata->clk_muxes[i];
753 ret = clk_set_parent(c[2], c[to_phy]);
754 if (!ret)
755 continue;
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);
762 return ret;
765 static u8 hdmi_chksum(struct hdmi_context *hdata,
766 u32 start, u8 len, u32 hdr_sum)
768 int i;
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);
776 /* return 2's complement of 8 bit hdr_sum */
777 return (u8)(~(hdr_sum & 0xff) + 1);
780 static void hdmi_reg_infoframe(struct hdmi_context *hdata,
781 union hdmi_infoframe *infoframe)
783 u32 hdr_sum;
784 u8 chksum;
785 u8 ar;
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;
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;
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);
812 * Set the aspect ratio as per the mode, mentioned in
813 * Table 9 AVI InfoFrame Data Byte 2 of CEA-861-D Standard
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;
828 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2), ar);
830 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), hdata->cea_video_id);
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;
855 static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
856 bool force)
858 struct hdmi_context *hdata = connector_to_hdmi(connector);
860 if (gpiod_get_value(hdata->hpd_gpio))
861 return connector_status_connected;
863 return connector_status_disconnected;
866 static void hdmi_connector_destroy(struct drm_connector *connector)
868 drm_connector_unregister(connector);
869 drm_connector_cleanup(connector);
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,
882 static int hdmi_get_modes(struct drm_connector *connector)
884 struct hdmi_context *hdata = connector_to_hdmi(connector);
885 struct edid *edid;
886 int ret;
888 if (!hdata->ddc_adpt)
889 return -ENODEV;
891 edid = drm_get_edid(connector, hdata->ddc_adpt);
892 if (!edid)
893 return -ENODEV;
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);
900 drm_mode_connector_update_edid_property(connector, edid);
902 ret = drm_add_edid_modes(connector, edid);
904 kfree(edid);
906 return ret;
909 static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
911 const struct hdmiphy_configs *confs = &hdata->drv_data->phy_confs;
912 int i;
914 for (i = 0; i < confs->count; i++)
915 if (confs->data[i].pixel_clock == pixel_clock)
916 return i;
918 DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
919 return -EINVAL;
922 static int hdmi_mode_valid(struct drm_connector *connector,
923 struct drm_display_mode *mode)
925 struct hdmi_context *hdata = connector_to_hdmi(connector);
926 int ret;
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);
933 ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
934 if (ret < 0)
935 return MODE_BAD;
937 return MODE_OK;
940 static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
941 .get_modes = hdmi_get_modes,
942 .mode_valid = hdmi_mode_valid,
945 static int hdmi_create_connector(struct drm_encoder *encoder)
947 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
948 struct drm_connector *connector = &hdata->connector;
949 int ret;
951 connector->interlace_allowed = true;
952 connector->polled = DRM_CONNECTOR_POLL_HPD;
954 ret = drm_connector_init(hdata->drm_dev, connector,
955 &hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA);
956 if (ret) {
957 DRM_ERROR("Failed to initialize connector with drm\n");
958 return ret;
961 drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
962 drm_connector_register(connector);
963 drm_mode_connector_attach_encoder(connector, encoder);
965 return 0;
968 static bool hdmi_mode_fixup(struct drm_encoder *encoder,
969 const struct drm_display_mode *mode,
970 struct drm_display_mode *adjusted_mode)
972 struct drm_device *dev = encoder->dev;
973 struct drm_connector *connector;
974 struct drm_display_mode *m;
975 int mode_ok;
977 drm_mode_set_crtcinfo(adjusted_mode, 0);
979 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
980 if (connector->encoder == encoder)
981 break;
984 if (connector->encoder != encoder)
985 return true;
987 mode_ok = hdmi_mode_valid(connector, adjusted_mode);
989 if (mode_ok == MODE_OK)
990 return true;
993 * Find the most suitable mode and copy it to adjusted_mode.
995 list_for_each_entry(m, &connector->modes, head) {
996 mode_ok = hdmi_mode_valid(connector, m);
998 if (mode_ok == MODE_OK) {
999 DRM_INFO("desired mode doesn't exist so\n");
1000 DRM_INFO("use the most suitable mode among modes.\n");
1002 DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n",
1003 m->hdisplay, m->vdisplay, m->vrefresh);
1005 drm_mode_copy(adjusted_mode, m);
1006 break;
1010 return true;
1013 static void hdmi_reg_acr(struct hdmi_context *hdata, u32 freq)
1015 u32 n, cts;
1017 cts = (freq % 9) ? 27000 : 30000;
1018 n = 128 * freq / (27000000 / cts);
1020 hdmi_reg_writev(hdata, HDMI_ACR_N0, 3, n);
1021 hdmi_reg_writev(hdata, HDMI_ACR_MCTS0, 3, cts);
1022 hdmi_reg_writev(hdata, HDMI_ACR_CTS0, 3, cts);
1023 hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1026 static void hdmi_audio_init(struct hdmi_context *hdata)
1028 u32 sample_rate, bits_per_sample;
1029 u32 data_num, bit_ch, sample_frq;
1030 u32 val;
1032 sample_rate = 44100;
1033 bits_per_sample = 16;
1035 switch (bits_per_sample) {
1036 case 20:
1037 data_num = 2;
1038 bit_ch = 1;
1039 break;
1040 case 24:
1041 data_num = 3;
1042 bit_ch = 1;
1043 break;
1044 default:
1045 data_num = 1;
1046 bit_ch = 0;
1047 break;
1050 hdmi_reg_acr(hdata, sample_rate);
1052 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1053 | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1054 | HDMI_I2S_MUX_ENABLE);
1056 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1057 | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1059 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1061 sample_frq = (sample_rate == 44100) ? 0 :
1062 (sample_rate == 48000) ? 2 :
1063 (sample_rate == 32000) ? 3 :
1064 (sample_rate == 96000) ? 0xa : 0x0;
1066 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1067 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1069 val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1070 hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1072 /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1073 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1074 | HDMI_I2S_SEL_LRCK(6));
1075 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1076 | HDMI_I2S_SEL_SDATA2(4));
1077 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1078 | HDMI_I2S_SEL_SDATA2(2));
1079 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1081 /* I2S_CON_1 & 2 */
1082 hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1083 | HDMI_I2S_L_CH_LOW_POL);
1084 hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1085 | HDMI_I2S_SET_BIT_CH(bit_ch)
1086 | HDMI_I2S_SET_SDATA_BIT(data_num)
1087 | HDMI_I2S_BASIC_FORMAT);
1089 /* Configure register related to CUV information */
1090 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
1091 | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1092 | HDMI_I2S_COPYRIGHT
1093 | HDMI_I2S_LINEAR_PCM
1094 | HDMI_I2S_CONSUMER_FORMAT);
1095 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1096 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1097 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1098 | HDMI_I2S_SET_SMP_FREQ(sample_frq));
1099 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1100 HDMI_I2S_ORG_SMP_FREQ_44_1
1101 | HDMI_I2S_WORD_LEN_MAX24_24BITS
1102 | HDMI_I2S_WORD_LEN_MAX_24BITS);
1104 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1107 static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1109 if (hdata->dvi_mode)
1110 return;
1112 hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
1113 hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ?
1114 HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1117 static void hdmi_start(struct hdmi_context *hdata, bool start)
1119 u32 val = start ? HDMI_TG_EN : 0;
1121 if (hdata->current_mode.flags & DRM_MODE_FLAG_INTERLACE)
1122 val |= HDMI_FIELD_EN;
1124 hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN);
1125 hdmi_reg_writemask(hdata, HDMI_TG_CMD, val, HDMI_TG_EN | HDMI_FIELD_EN);
1128 static void hdmi_conf_init(struct hdmi_context *hdata)
1130 union hdmi_infoframe infoframe;
1132 /* disable HPD interrupts from HDMI IP block, use GPIO instead */
1133 hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1134 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1136 /* choose HDMI mode */
1137 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1138 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1139 /* apply video pre-amble and guard band in HDMI mode only */
1140 hdmi_reg_writeb(hdata, HDMI_CON_2, 0);
1141 /* disable bluescreen */
1142 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1144 if (hdata->dvi_mode) {
1145 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1146 HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1147 hdmi_reg_writeb(hdata, HDMI_CON_2,
1148 HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1151 if (hdata->drv_data->type == HDMI_TYPE13) {
1152 /* choose bluescreen (fecal) color */
1153 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1154 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1155 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1157 /* enable AVI packet every vsync, fixes purple line problem */
1158 hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1159 /* force RGB, look to CEA-861-D, table 7 for more detail */
1160 hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1161 hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1163 hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1164 hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1165 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1166 } else {
1167 infoframe.any.type = HDMI_INFOFRAME_TYPE_AVI;
1168 infoframe.any.version = HDMI_AVI_VERSION;
1169 infoframe.any.length = HDMI_AVI_LENGTH;
1170 hdmi_reg_infoframe(hdata, &infoframe);
1172 infoframe.any.type = HDMI_INFOFRAME_TYPE_AUDIO;
1173 infoframe.any.version = HDMI_AUI_VERSION;
1174 infoframe.any.length = HDMI_AUI_LENGTH;
1175 hdmi_reg_infoframe(hdata, &infoframe);
1177 /* enable AVI packet every vsync, fixes purple line problem */
1178 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1182 static void hdmiphy_wait_for_pll(struct hdmi_context *hdata)
1184 int tries;
1186 for (tries = 0; tries < 10; ++tries) {
1187 u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS);
1189 if (val & HDMI_PHY_STATUS_READY) {
1190 DRM_DEBUG_KMS("PLL stabilized after %d tries\n", tries);
1191 return;
1193 usleep_range(10, 20);
1196 DRM_ERROR("PLL could not reach steady state\n");
1199 static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1201 struct drm_display_mode *m = &hdata->current_mode;
1202 unsigned int val;
1204 hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1205 hdmi_reg_writev(hdata, HDMI_V13_H_V_LINE_0, 3,
1206 (m->htotal << 12) | m->vtotal);
1208 val = (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
1209 hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1, val);
1211 val = (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0;
1212 hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1, val);
1214 val = (m->hsync_start - m->hdisplay - 2);
1215 val |= ((m->hsync_end - m->hdisplay - 2) << 10);
1216 val |= ((m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0)<<20;
1217 hdmi_reg_writev(hdata, HDMI_V13_H_SYNC_GEN_0, 3, val);
1220 * Quirk requirement for exynos HDMI IP design,
1221 * 2 pixels less than the actual calculation for hsync_start
1222 * and end.
1225 /* Following values & calculations differ for different type of modes */
1226 if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1227 val = ((m->vsync_end - m->vdisplay) / 2);
1228 val |= ((m->vsync_start - m->vdisplay) / 2) << 12;
1229 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1231 val = m->vtotal / 2;
1232 val |= ((m->vtotal - m->vdisplay) / 2) << 11;
1233 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1235 val = (m->vtotal +
1236 ((m->vsync_end - m->vsync_start) * 4) + 5) / 2;
1237 val |= m->vtotal << 11;
1238 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, val);
1240 val = ((m->vtotal / 2) + 7);
1241 val |= ((m->vtotal / 2) + 2) << 12;
1242 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, val);
1244 val = ((m->htotal / 2) + (m->hsync_start - m->hdisplay));
1245 val |= ((m->htotal / 2) +
1246 (m->hsync_start - m->hdisplay)) << 12;
1247 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, val);
1249 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1250 (m->vtotal - m->vdisplay) / 2);
1251 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1253 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x249);
1254 } else {
1255 val = m->vtotal;
1256 val |= (m->vtotal - m->vdisplay) << 11;
1257 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1259 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, 0);
1261 val = (m->vsync_end - m->vdisplay);
1262 val |= ((m->vsync_start - m->vdisplay) << 12);
1263 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1265 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, 0x1001);
1266 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, 0x1001);
1267 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1268 m->vtotal - m->vdisplay);
1269 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1272 hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1273 hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1274 hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1275 hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1278 static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1280 struct drm_display_mode *m = &hdata->current_mode;
1282 hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1283 hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
1284 hdmi_reg_writev(hdata, HDMI_H_LINE_0, 2, m->htotal);
1285 hdmi_reg_writev(hdata, HDMI_HSYNC_POL, 1,
1286 (m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0);
1287 hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1,
1288 (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
1289 hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1,
1290 (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1293 * Quirk requirement for exynos 5 HDMI IP design,
1294 * 2 pixels less than the actual calculation for hsync_start
1295 * and end.
1298 /* Following values & calculations differ for different type of modes */
1299 if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1300 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1301 (m->vsync_end - m->vdisplay) / 2);
1302 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1303 (m->vsync_start - m->vdisplay) / 2);
1304 hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal / 2);
1305 hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1306 (m->vtotal - m->vdisplay) / 2);
1307 hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2,
1308 m->vtotal - m->vdisplay / 2);
1309 hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, m->vtotal);
1310 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2,
1311 (m->vtotal / 2) + 7);
1312 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2,
1313 (m->vtotal / 2) + 2);
1314 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2,
1315 (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1316 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2,
1317 (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1318 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1319 (m->vtotal - m->vdisplay) / 2);
1320 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1321 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2,
1322 m->vtotal - m->vdisplay / 2);
1323 hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2,
1324 (m->vtotal / 2) + 1);
1325 hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2,
1326 (m->vtotal / 2) + 1);
1327 hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2,
1328 (m->vtotal / 2) + 1);
1329 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x0);
1330 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x0);
1331 } else {
1332 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1333 m->vsync_end - m->vdisplay);
1334 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1335 m->vsync_start - m->vdisplay);
1336 hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal);
1337 hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1338 m->vtotal - m->vdisplay);
1339 hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2, 0xffff);
1340 hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, 0xffff);
1341 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2, 0xffff);
1342 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2, 0xffff);
1343 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2, 0xffff);
1344 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2, 0xffff);
1345 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1346 m->vtotal - m->vdisplay);
1347 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1350 hdmi_reg_writev(hdata, HDMI_H_SYNC_START_0, 2,
1351 m->hsync_start - m->hdisplay - 2);
1352 hdmi_reg_writev(hdata, HDMI_H_SYNC_END_0, 2,
1353 m->hsync_end - m->hdisplay - 2);
1354 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_1_0, 2, 0xffff);
1355 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_2_0, 2, 0xffff);
1356 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_3_0, 2, 0xffff);
1357 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_4_0, 2, 0xffff);
1358 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_5_0, 2, 0xffff);
1359 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_6_0, 2, 0xffff);
1360 hdmi_reg_writev(hdata, HDMI_V_BLANK_F2_0, 2, 0xffff);
1361 hdmi_reg_writev(hdata, HDMI_V_BLANK_F3_0, 2, 0xffff);
1362 hdmi_reg_writev(hdata, HDMI_V_BLANK_F4_0, 2, 0xffff);
1363 hdmi_reg_writev(hdata, HDMI_V_BLANK_F5_0, 2, 0xffff);
1364 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_3_0, 2, 0xffff);
1365 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_4_0, 2, 0xffff);
1366 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_5_0, 2, 0xffff);
1367 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_6_0, 2, 0xffff);
1368 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0, 2, 0xffff);
1369 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0, 2, 0xffff);
1370 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, 2, 0xffff);
1371 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
1373 hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1374 hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1375 hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1376 hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1377 if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1378 hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1);
1381 static void hdmi_mode_apply(struct hdmi_context *hdata)
1383 if (hdata->drv_data->type == HDMI_TYPE13)
1384 hdmi_v13_mode_apply(hdata);
1385 else
1386 hdmi_v14_mode_apply(hdata);
1388 hdmi_start(hdata, true);
1391 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1393 hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, 0, 1);
1394 usleep_range(10000, 12000);
1395 hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, ~0, 1);
1396 usleep_range(10000, 12000);
1397 hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
1398 usleep_range(10000, 12000);
1399 hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT);
1400 usleep_range(10000, 12000);
1403 static void hdmiphy_enable_mode_set(struct hdmi_context *hdata, bool enable)
1405 u8 v = enable ? HDMI_PHY_ENABLE_MODE_SET : HDMI_PHY_DISABLE_MODE_SET;
1407 if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1408 writel(v, hdata->regs_hdmiphy + HDMIPHY5433_MODE_SET_DONE);
1411 static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1413 int ret;
1414 const u8 *phy_conf;
1416 ret = hdmi_find_phy_conf(hdata, hdata->current_mode.clock * 1000);
1417 if (ret < 0) {
1418 DRM_ERROR("failed to find hdmiphy conf\n");
1419 return;
1421 phy_conf = hdata->drv_data->phy_confs.data[ret].conf;
1423 hdmi_clk_set_parents(hdata, false);
1425 hdmiphy_conf_reset(hdata);
1427 hdmiphy_enable_mode_set(hdata, true);
1428 ret = hdmiphy_reg_write_buf(hdata, 0, phy_conf, 32);
1429 if (ret) {
1430 DRM_ERROR("failed to configure hdmiphy\n");
1431 return;
1433 hdmiphy_enable_mode_set(hdata, false);
1434 hdmi_clk_set_parents(hdata, true);
1435 usleep_range(10000, 12000);
1436 hdmiphy_wait_for_pll(hdata);
1439 static void hdmi_conf_apply(struct hdmi_context *hdata)
1441 hdmi_start(hdata, false);
1442 hdmi_conf_init(hdata);
1443 hdmi_audio_init(hdata);
1444 hdmi_mode_apply(hdata);
1445 hdmi_audio_control(hdata, true);
1448 static void hdmi_mode_set(struct drm_encoder *encoder,
1449 struct drm_display_mode *mode,
1450 struct drm_display_mode *adjusted_mode)
1452 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1453 struct drm_display_mode *m = adjusted_mode;
1455 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n",
1456 m->hdisplay, m->vdisplay,
1457 m->vrefresh, (m->flags & DRM_MODE_FLAG_INTERLACE) ?
1458 "INTERLACED" : "PROGRESSIVE");
1460 drm_mode_copy(&hdata->current_mode, m);
1461 hdata->cea_video_id = drm_match_cea_mode(mode);
1464 static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
1466 if (!hdata->sysreg)
1467 return;
1469 regmap_update_bits(hdata->sysreg, EXYNOS5433_SYSREG_DISP_HDMI_PHY,
1470 SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0);
1473 static void hdmiphy_enable(struct hdmi_context *hdata)
1475 if (hdata->powered)
1476 return;
1478 pm_runtime_get_sync(hdata->dev);
1480 if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk))
1481 DRM_DEBUG_KMS("failed to enable regulator bulk\n");
1483 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1484 PMU_HDMI_PHY_ENABLE_BIT, 1);
1486 hdmi_set_refclk(hdata, true);
1488 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN);
1490 hdmiphy_conf_apply(hdata);
1492 hdata->powered = true;
1495 static void hdmiphy_disable(struct hdmi_context *hdata)
1497 if (!hdata->powered)
1498 return;
1500 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
1502 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN);
1504 hdmi_set_refclk(hdata, false);
1506 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1507 PMU_HDMI_PHY_ENABLE_BIT, 0);
1509 regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
1511 pm_runtime_put_sync(hdata->dev);
1513 hdata->powered = false;
1516 static void hdmi_enable(struct drm_encoder *encoder)
1518 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1520 hdmiphy_enable(hdata);
1521 hdmi_conf_apply(hdata);
1524 static void hdmi_disable(struct drm_encoder *encoder)
1526 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1527 struct drm_crtc *crtc = encoder->crtc;
1528 const struct drm_crtc_helper_funcs *funcs = NULL;
1530 if (!hdata->powered)
1531 return;
1534 * The SFRs of VP and Mixer are updated by Vertical Sync of
1535 * Timing generator which is a part of HDMI so the sequence
1536 * to disable TV Subsystem should be as following,
1537 * VP -> Mixer -> HDMI
1539 * Below codes will try to disable Mixer and VP(if used)
1540 * prior to disabling HDMI.
1542 if (crtc)
1543 funcs = crtc->helper_private;
1544 if (funcs && funcs->disable)
1545 (*funcs->disable)(crtc);
1547 cancel_delayed_work(&hdata->hotplug_work);
1549 hdmiphy_disable(hdata);
1552 static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
1553 .mode_fixup = hdmi_mode_fixup,
1554 .mode_set = hdmi_mode_set,
1555 .enable = hdmi_enable,
1556 .disable = hdmi_disable,
1559 static const struct drm_encoder_funcs exynos_hdmi_encoder_funcs = {
1560 .destroy = drm_encoder_cleanup,
1563 static void hdmi_hotplug_work_func(struct work_struct *work)
1565 struct hdmi_context *hdata;
1567 hdata = container_of(work, struct hdmi_context, hotplug_work.work);
1569 if (hdata->drm_dev)
1570 drm_helper_hpd_irq_event(hdata->drm_dev);
1573 static irqreturn_t hdmi_irq_thread(int irq, void *arg)
1575 struct hdmi_context *hdata = arg;
1577 mod_delayed_work(system_wq, &hdata->hotplug_work,
1578 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
1580 return IRQ_HANDLED;
1583 static int hdmi_clks_get(struct hdmi_context *hdata,
1584 const struct string_array_spec *names,
1585 struct clk **clks)
1587 struct device *dev = hdata->dev;
1588 int i;
1590 for (i = 0; i < names->count; ++i) {
1591 struct clk *clk = devm_clk_get(dev, names->data[i]);
1593 if (IS_ERR(clk)) {
1594 int ret = PTR_ERR(clk);
1596 dev_err(dev, "Cannot get clock %s, %d\n",
1597 names->data[i], ret);
1599 return ret;
1602 clks[i] = clk;
1605 return 0;
1608 static int hdmi_clk_init(struct hdmi_context *hdata)
1610 const struct hdmi_driver_data *drv_data = hdata->drv_data;
1611 int count = drv_data->clk_gates.count + drv_data->clk_muxes.count;
1612 struct device *dev = hdata->dev;
1613 struct clk **clks;
1614 int ret;
1616 if (!count)
1617 return 0;
1619 clks = devm_kzalloc(dev, sizeof(*clks) * count, GFP_KERNEL);
1620 if (!clks)
1621 return -ENOMEM;
1623 hdata->clk_gates = clks;
1624 hdata->clk_muxes = clks + drv_data->clk_gates.count;
1626 ret = hdmi_clks_get(hdata, &drv_data->clk_gates, hdata->clk_gates);
1627 if (ret)
1628 return ret;
1630 return hdmi_clks_get(hdata, &drv_data->clk_muxes, hdata->clk_muxes);
1634 static void hdmiphy_clk_enable(struct exynos_drm_clk *clk, bool enable)
1636 struct hdmi_context *hdata = container_of(clk, struct hdmi_context,
1637 phy_clk);
1639 if (enable)
1640 hdmiphy_enable(hdata);
1641 else
1642 hdmiphy_disable(hdata);
1645 static int hdmi_resources_init(struct hdmi_context *hdata)
1647 struct device *dev = hdata->dev;
1648 int i, ret;
1650 DRM_DEBUG_KMS("HDMI resource init\n");
1652 hdata->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
1653 if (IS_ERR(hdata->hpd_gpio)) {
1654 DRM_ERROR("cannot get hpd gpio property\n");
1655 return PTR_ERR(hdata->hpd_gpio);
1658 hdata->irq = gpiod_to_irq(hdata->hpd_gpio);
1659 if (hdata->irq < 0) {
1660 DRM_ERROR("failed to get GPIO irq\n");
1661 return hdata->irq;
1664 ret = hdmi_clk_init(hdata);
1665 if (ret)
1666 return ret;
1668 ret = hdmi_clk_set_parents(hdata, false);
1669 if (ret)
1670 return ret;
1672 for (i = 0; i < ARRAY_SIZE(supply); ++i)
1673 hdata->regul_bulk[i].supply = supply[i];
1675 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), hdata->regul_bulk);
1676 if (ret) {
1677 if (ret != -EPROBE_DEFER)
1678 DRM_ERROR("failed to get regulators\n");
1679 return ret;
1682 hdata->reg_hdmi_en = devm_regulator_get_optional(dev, "hdmi-en");
1684 if (PTR_ERR(hdata->reg_hdmi_en) == -ENODEV)
1685 return 0;
1687 if (IS_ERR(hdata->reg_hdmi_en))
1688 return PTR_ERR(hdata->reg_hdmi_en);
1690 ret = regulator_enable(hdata->reg_hdmi_en);
1691 if (ret)
1692 DRM_ERROR("failed to enable hdmi-en regulator\n");
1694 return ret;
1697 static struct of_device_id hdmi_match_types[] = {
1699 .compatible = "samsung,exynos4210-hdmi",
1700 .data = &exynos4210_hdmi_driver_data,
1701 }, {
1702 .compatible = "samsung,exynos4212-hdmi",
1703 .data = &exynos4212_hdmi_driver_data,
1704 }, {
1705 .compatible = "samsung,exynos5420-hdmi",
1706 .data = &exynos5420_hdmi_driver_data,
1707 }, {
1708 .compatible = "samsung,exynos5433-hdmi",
1709 .data = &exynos5433_hdmi_driver_data,
1710 }, {
1711 /* end node */
1714 MODULE_DEVICE_TABLE (of, hdmi_match_types);
1716 static int hdmi_bind(struct device *dev, struct device *master, void *data)
1718 struct drm_device *drm_dev = data;
1719 struct hdmi_context *hdata = dev_get_drvdata(dev);
1720 struct drm_encoder *encoder = &hdata->encoder;
1721 int ret, pipe;
1723 hdata->drm_dev = drm_dev;
1725 pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
1726 EXYNOS_DISPLAY_TYPE_HDMI);
1727 if (pipe < 0)
1728 return pipe;
1730 hdata->phy_clk.enable = hdmiphy_clk_enable;
1732 exynos_drm_crtc_from_pipe(drm_dev, pipe)->pipe_clk = &hdata->phy_clk;
1734 encoder->possible_crtcs = 1 << pipe;
1736 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
1738 drm_encoder_init(drm_dev, encoder, &exynos_hdmi_encoder_funcs,
1739 DRM_MODE_ENCODER_TMDS, NULL);
1741 drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
1743 ret = hdmi_create_connector(encoder);
1744 if (ret) {
1745 DRM_ERROR("failed to create connector ret = %d\n", ret);
1746 drm_encoder_cleanup(encoder);
1747 return ret;
1750 return 0;
1753 static void hdmi_unbind(struct device *dev, struct device *master, void *data)
1757 static const struct component_ops hdmi_component_ops = {
1758 .bind = hdmi_bind,
1759 .unbind = hdmi_unbind,
1762 static int hdmi_get_ddc_adapter(struct hdmi_context *hdata)
1764 const char *compatible_str = "samsung,exynos4210-hdmiddc";
1765 struct device_node *np;
1766 struct i2c_adapter *adpt;
1768 np = of_find_compatible_node(NULL, NULL, compatible_str);
1769 if (np)
1770 np = of_get_next_parent(np);
1771 else
1772 np = of_parse_phandle(hdata->dev->of_node, "ddc", 0);
1774 if (!np) {
1775 DRM_ERROR("Failed to find ddc node in device tree\n");
1776 return -ENODEV;
1779 adpt = of_find_i2c_adapter_by_node(np);
1780 of_node_put(np);
1782 if (!adpt) {
1783 DRM_INFO("Failed to get ddc i2c adapter by node\n");
1784 return -EPROBE_DEFER;
1787 hdata->ddc_adpt = adpt;
1789 return 0;
1792 static int hdmi_get_phy_io(struct hdmi_context *hdata)
1794 const char *compatible_str = "samsung,exynos4212-hdmiphy";
1795 struct device_node *np;
1796 int ret = 0;
1798 np = of_find_compatible_node(NULL, NULL, compatible_str);
1799 if (!np) {
1800 np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
1801 if (!np) {
1802 DRM_ERROR("Failed to find hdmiphy node in device tree\n");
1803 return -ENODEV;
1807 if (hdata->drv_data->is_apb_phy) {
1808 hdata->regs_hdmiphy = of_iomap(np, 0);
1809 if (!hdata->regs_hdmiphy) {
1810 DRM_ERROR("failed to ioremap hdmi phy\n");
1811 ret = -ENOMEM;
1812 goto out;
1814 } else {
1815 hdata->hdmiphy_port = of_find_i2c_device_by_node(np);
1816 if (!hdata->hdmiphy_port) {
1817 DRM_INFO("Failed to get hdmi phy i2c client\n");
1818 ret = -EPROBE_DEFER;
1819 goto out;
1823 out:
1824 of_node_put(np);
1825 return ret;
1828 static int hdmi_probe(struct platform_device *pdev)
1830 struct device *dev = &pdev->dev;
1831 struct hdmi_context *hdata;
1832 struct resource *res;
1833 int ret;
1835 hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
1836 if (!hdata)
1837 return -ENOMEM;
1839 hdata->drv_data = of_device_get_match_data(dev);
1841 platform_set_drvdata(pdev, hdata);
1843 hdata->dev = dev;
1845 ret = hdmi_resources_init(hdata);
1846 if (ret) {
1847 if (ret != -EPROBE_DEFER)
1848 DRM_ERROR("hdmi_resources_init failed\n");
1849 return ret;
1852 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1853 hdata->regs = devm_ioremap_resource(dev, res);
1854 if (IS_ERR(hdata->regs)) {
1855 ret = PTR_ERR(hdata->regs);
1856 return ret;
1859 ret = hdmi_get_ddc_adapter(hdata);
1860 if (ret)
1861 return ret;
1863 ret = hdmi_get_phy_io(hdata);
1864 if (ret)
1865 goto err_ddc;
1867 INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
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;
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;
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;
1896 pm_runtime_enable(dev);
1898 ret = component_add(&pdev->dev, &hdmi_component_ops);
1899 if (ret)
1900 goto err_disable_pm_runtime;
1902 return ret;
1904 err_disable_pm_runtime:
1905 pm_runtime_disable(dev);
1907 err_hdmiphy:
1908 if (hdata->hdmiphy_port)
1909 put_device(&hdata->hdmiphy_port->dev);
1910 if (hdata->regs_hdmiphy)
1911 iounmap(hdata->regs_hdmiphy);
1912 err_ddc:
1913 put_device(&hdata->ddc_adpt->dev);
1915 return ret;
1918 static int hdmi_remove(struct platform_device *pdev)
1920 struct hdmi_context *hdata = platform_get_drvdata(pdev);
1922 cancel_delayed_work_sync(&hdata->hotplug_work);
1924 component_del(&pdev->dev, &hdmi_component_ops);
1926 pm_runtime_disable(&pdev->dev);
1928 if (!IS_ERR(hdata->reg_hdmi_en))
1929 regulator_disable(hdata->reg_hdmi_en);
1931 if (hdata->hdmiphy_port)
1932 put_device(&hdata->hdmiphy_port->dev);
1934 if (hdata->regs_hdmiphy)
1935 iounmap(hdata->regs_hdmiphy);
1937 put_device(&hdata->ddc_adpt->dev);
1939 return 0;
1942 static int __maybe_unused exynos_hdmi_suspend(struct device *dev)
1944 struct hdmi_context *hdata = dev_get_drvdata(dev);
1946 hdmi_clk_disable_gates(hdata);
1948 return 0;
1951 static int __maybe_unused exynos_hdmi_resume(struct device *dev)
1953 struct hdmi_context *hdata = dev_get_drvdata(dev);
1954 int ret;
1956 ret = hdmi_clk_enable_gates(hdata);
1957 if (ret < 0)
1958 return ret;
1960 return 0;
1963 static const struct dev_pm_ops exynos_hdmi_pm_ops = {
1964 SET_RUNTIME_PM_OPS(exynos_hdmi_suspend, exynos_hdmi_resume, NULL)
1967 struct platform_driver hdmi_driver = {
1968 .probe = hdmi_probe,
1969 .remove = hdmi_remove,
1970 .driver = {
1971 .name = "exynos-hdmi",
1972 .owner = THIS_MODULE,
1973 .pm = &exynos_hdmi_pm_ops,
1974 .of_match_table = hdmi_match_types,