2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
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.
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>
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
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
69 #define HDMI_MAPPED_BASE 0xffff0000
71 enum hdmi_mapped_regs {
72 HDMI_PHY_STATUS = HDMI_MAPPED_BASE,
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[] = {
95 struct hdmiphy_config {
100 struct hdmiphy_configs {
102 const struct hdmiphy_config *data;
105 struct string_array_spec {
107 const char * const *data;
110 #define INIT_ARRAY_SPEC(a) { .count = ARRAY_SIZE(a), .data = a }
112 struct hdmi_driver_data {
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;
128 struct drm_device *drm_dev;
129 struct drm_connector connector;
132 struct delayed_work hotplug_work;
133 struct drm_display_mode current_mode;
135 const struct hdmi_driver_data *drv_data;
138 void __iomem *regs_hdmiphy;
139 struct i2c_client *hdmiphy_port;
140 struct i2c_adapter *ddc_adpt;
141 struct gpio_desc *hpd_gpio;
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;
151 static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e)
153 return container_of(e, struct hdmi_context, encoder);
156 static inline struct hdmi_context *connector_to_hdmi(struct drm_connector *c)
158 return container_of(c, struct hdmi_context, connector);
161 static const struct hdmiphy_config hdmiphy_v13_configs[] = {
163 .pixel_clock = 27000000,
165 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
166 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
167 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
168 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x80,
172 .pixel_clock = 27027000,
174 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
175 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
176 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
177 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x80,
181 .pixel_clock = 74176000,
183 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
184 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
185 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
186 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x80,
190 .pixel_clock = 74250000,
192 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
193 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
194 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
195 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x80,
199 .pixel_clock = 148500000,
201 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
202 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
203 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
204 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x80,
209 static const struct hdmiphy_config hdmiphy_v14_configs[] = {
211 .pixel_clock = 25200000,
213 0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
214 0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
215 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
216 0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
220 .pixel_clock = 27000000,
222 0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
223 0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
224 0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
225 0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
229 .pixel_clock = 27027000,
231 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
232 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
233 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
234 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
238 .pixel_clock = 36000000,
240 0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
241 0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
242 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
243 0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
247 .pixel_clock = 40000000,
249 0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
250 0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
251 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
252 0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
256 .pixel_clock = 65000000,
258 0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
259 0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
260 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
261 0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
265 .pixel_clock = 71000000,
267 0x01, 0xd1, 0x3b, 0x35, 0x40, 0x0c, 0x04, 0x08,
268 0x85, 0xa0, 0x63, 0xd9, 0x45, 0xa0, 0xac, 0x80,
269 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
270 0x54, 0xad, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
274 .pixel_clock = 73250000,
276 0x01, 0xd1, 0x3d, 0x35, 0x40, 0x18, 0x02, 0x08,
277 0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
278 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
279 0x54, 0xa8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
283 .pixel_clock = 74176000,
285 0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
286 0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
287 0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
288 0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
292 .pixel_clock = 74250000,
294 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
295 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
296 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
297 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
301 .pixel_clock = 83500000,
303 0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
304 0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
305 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
306 0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
310 .pixel_clock = 106500000,
312 0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
313 0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
314 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
315 0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
319 .pixel_clock = 108000000,
321 0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
322 0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
323 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
324 0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
328 .pixel_clock = 115500000,
330 0x01, 0xd1, 0x30, 0x12, 0x40, 0x40, 0x10, 0x08,
331 0x80, 0x80, 0x21, 0xd9, 0x45, 0xa0, 0xac, 0x80,
332 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
333 0x54, 0xaa, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
337 .pixel_clock = 119000000,
339 0x01, 0xd1, 0x32, 0x1a, 0x40, 0x30, 0xd8, 0x08,
340 0x04, 0xa0, 0x2a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
341 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
342 0x54, 0x9d, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
346 .pixel_clock = 146250000,
348 0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
349 0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
350 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
351 0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
355 .pixel_clock = 148500000,
357 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
358 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
359 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
360 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
365 static const struct hdmiphy_config hdmiphy_5420_configs[] = {
367 .pixel_clock = 25200000,
369 0x01, 0x52, 0x3F, 0x55, 0x40, 0x01, 0x00, 0xC8,
370 0x82, 0xC8, 0xBD, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
371 0x06, 0x80, 0x01, 0x84, 0x05, 0x02, 0x24, 0x66,
372 0x54, 0xF4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
376 .pixel_clock = 27000000,
378 0x01, 0xD1, 0x22, 0x51, 0x40, 0x08, 0xFC, 0xE0,
379 0x98, 0xE8, 0xCB, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
380 0x06, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
381 0x54, 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
385 .pixel_clock = 27027000,
387 0x01, 0xD1, 0x2D, 0x72, 0x40, 0x64, 0x12, 0xC8,
388 0x43, 0xE8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
389 0x26, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
390 0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
394 .pixel_clock = 36000000,
396 0x01, 0x51, 0x2D, 0x55, 0x40, 0x40, 0x00, 0xC8,
397 0x02, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
398 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
399 0x54, 0xAB, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
403 .pixel_clock = 40000000,
405 0x01, 0xD1, 0x21, 0x31, 0x40, 0x3C, 0x28, 0xC8,
406 0x87, 0xE8, 0xC8, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
407 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
408 0x54, 0x9A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
412 .pixel_clock = 65000000,
414 0x01, 0xD1, 0x36, 0x34, 0x40, 0x0C, 0x04, 0xC8,
415 0x82, 0xE8, 0x45, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
416 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
417 0x54, 0xBD, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
421 .pixel_clock = 71000000,
423 0x01, 0xD1, 0x3B, 0x35, 0x40, 0x0C, 0x04, 0xC8,
424 0x85, 0xE8, 0x63, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
425 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
426 0x54, 0x57, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
430 .pixel_clock = 73250000,
432 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x78, 0x8D, 0xC8,
433 0x81, 0xE8, 0xB7, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
434 0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
435 0x54, 0xA8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
439 .pixel_clock = 74176000,
441 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0xC8,
442 0x81, 0xE8, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
443 0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
444 0x54, 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
448 .pixel_clock = 74250000,
450 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0x08,
451 0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
452 0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
453 0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
457 .pixel_clock = 83500000,
459 0x01, 0xD1, 0x23, 0x11, 0x40, 0x0C, 0xFB, 0xC8,
460 0x85, 0xE8, 0xD1, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
461 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
462 0x54, 0x4A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
466 .pixel_clock = 88750000,
468 0x01, 0xD1, 0x25, 0x11, 0x40, 0x18, 0xFF, 0xC8,
469 0x83, 0xE8, 0xDE, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
470 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
471 0x54, 0x45, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
475 .pixel_clock = 106500000,
477 0x01, 0xD1, 0x2C, 0x12, 0x40, 0x0C, 0x09, 0xC8,
478 0x84, 0xE8, 0x0A, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
479 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
480 0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
484 .pixel_clock = 108000000,
486 0x01, 0x51, 0x2D, 0x15, 0x40, 0x01, 0x00, 0xC8,
487 0x82, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
488 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
489 0x54, 0xC7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
493 .pixel_clock = 115500000,
495 0x01, 0xD1, 0x30, 0x14, 0x40, 0x0C, 0x03, 0xC8,
496 0x88, 0xE8, 0x21, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
497 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
498 0x54, 0x6A, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
502 .pixel_clock = 146250000,
504 0x01, 0xD1, 0x3D, 0x15, 0x40, 0x18, 0xFD, 0xC8,
505 0x83, 0xE8, 0x6E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
506 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
507 0x54, 0x54, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
511 .pixel_clock = 148500000,
513 0x01, 0xD1, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0x08,
514 0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
515 0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
516 0x54, 0x4B, 0x25, 0x03, 0x00, 0x80, 0x01, 0x80,
521 static const struct hdmiphy_config hdmiphy_5433_configs[] = {
523 .pixel_clock = 27000000,
525 0x01, 0x51, 0x22, 0x51, 0x08, 0xfc, 0x88, 0x46,
526 0x72, 0x50, 0x24, 0x0c, 0x24, 0x0f, 0x7c, 0xa5,
527 0xd4, 0x2b, 0x87, 0x00, 0x00, 0x04, 0x00, 0x30,
528 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
532 .pixel_clock = 27027000,
534 0x01, 0x51, 0x2d, 0x72, 0x64, 0x09, 0x88, 0xc3,
535 0x71, 0x50, 0x24, 0x14, 0x24, 0x0f, 0x7c, 0xa5,
536 0xd4, 0x2b, 0x87, 0x00, 0x00, 0x04, 0x00, 0x30,
537 0x28, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
541 .pixel_clock = 40000000,
543 0x01, 0x51, 0x32, 0x55, 0x01, 0x00, 0x88, 0x02,
544 0x4d, 0x50, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
545 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
546 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
550 .pixel_clock = 50000000,
552 0x01, 0x51, 0x34, 0x40, 0x64, 0x09, 0x88, 0xc3,
553 0x3d, 0x50, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
554 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
555 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
559 .pixel_clock = 65000000,
561 0x01, 0x51, 0x36, 0x31, 0x40, 0x10, 0x04, 0xc6,
562 0x2e, 0xe8, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
563 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
564 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
568 .pixel_clock = 74176000,
570 0x01, 0x51, 0x3E, 0x35, 0x5B, 0xDE, 0x88, 0x42,
571 0x53, 0x51, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
572 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
573 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
577 .pixel_clock = 74250000,
579 0x01, 0x51, 0x3E, 0x35, 0x40, 0xF0, 0x88, 0xC2,
580 0x52, 0x51, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
581 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
582 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
586 .pixel_clock = 108000000,
588 0x01, 0x51, 0x2d, 0x15, 0x01, 0x00, 0x88, 0x02,
589 0x72, 0x52, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
590 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
591 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
595 .pixel_clock = 148500000,
597 0x01, 0x51, 0x1f, 0x00, 0x40, 0xf8, 0x88, 0xc1,
598 0x52, 0x52, 0x24, 0x0c, 0x24, 0x0f, 0x7c, 0xa5,
599 0xd4, 0x2b, 0x87, 0x00, 0x00, 0x04, 0x00, 0x30,
600 0x08, 0x10, 0x01, 0x01, 0x48, 0x4a, 0x00, 0x40,
605 static const char * const hdmi_clk_gates4[] = {
609 static const char * const hdmi_clk_muxes4[] = {
610 "sclk_pixel", "sclk_hdmiphy", "mout_hdmi"
613 static const char * const hdmi_clk_gates5433[] = {
614 "hdmi_pclk", "hdmi_i_pclk", "i_tmds_clk", "i_pixel_clk", "i_spdif_clk"
617 static const char * const hdmi_clk_muxes5433[] = {
618 "oscclk", "tmds_clko", "tmds_clko_user",
619 "oscclk", "pixel_clko", "pixel_clko_user"
622 static const struct hdmi_driver_data exynos4210_hdmi_driver_data = {
624 .phy_confs = INIT_ARRAY_SPEC(hdmiphy_v13_configs),
625 .clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates4),
626 .clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
629 static const struct hdmi_driver_data exynos4212_hdmi_driver_data = {
631 .phy_confs = INIT_ARRAY_SPEC(hdmiphy_v14_configs),
632 .clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates4),
633 .clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
636 static const struct hdmi_driver_data exynos5420_hdmi_driver_data = {
639 .phy_confs = INIT_ARRAY_SPEC(hdmiphy_5420_configs),
640 .clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates4),
641 .clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
644 static const struct hdmi_driver_data exynos5433_hdmi_driver_data = {
648 .phy_confs = INIT_ARRAY_SPEC(hdmiphy_5433_configs),
649 .clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates5433),
650 .clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes5433),
653 static inline u32 hdmi_map_reg(struct hdmi_context *hdata, u32 reg_id)
655 if ((reg_id & 0xffff0000) == HDMI_MAPPED_BASE)
656 return hdmi_reg_map[reg_id & 0xffff][hdata->drv_data->type];
660 static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
662 return readl(hdata->regs + hdmi_map_reg(hdata, reg_id));
665 static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
666 u32 reg_id, u8 value)
668 writel(value, hdata->regs + hdmi_map_reg(hdata, reg_id));
671 static inline void hdmi_reg_writev(struct hdmi_context *hdata, u32 reg_id,
674 reg_id = hdmi_map_reg(hdata, reg_id);
676 while (--bytes >= 0) {
677 writel(val & 0xff, hdata->regs + reg_id);
683 static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
684 u32 reg_id, u32 value, u32 mask)
688 reg_id = hdmi_map_reg(hdata, reg_id);
689 old = readl(hdata->regs + reg_id);
690 value = (value & mask) | (old & ~mask);
691 writel(value, hdata->regs + reg_id);
694 static int hdmiphy_reg_write_buf(struct hdmi_context *hdata,
695 u32 reg_offset, const u8 *buf, u32 len)
697 if ((reg_offset + len) > 32)
700 if (hdata->hdmiphy_port) {
703 ret = i2c_master_send(hdata->hdmiphy_port, buf, len);
709 for (i = 0; i < len; i++)
710 writel(buf[i], hdata->regs_hdmiphy +
711 ((reg_offset + i)<<2));
716 static int hdmi_clk_enable_gates(struct hdmi_context *hdata)
720 for (i = 0; i < hdata->drv_data->clk_gates.count; ++i) {
721 ret = clk_prepare_enable(hdata->clk_gates[i]);
725 dev_err(hdata->dev, "Cannot enable clock '%s', %d\n",
726 hdata->drv_data->clk_gates.data[i], ret);
728 clk_disable_unprepare(hdata->clk_gates[i]);
735 static void hdmi_clk_disable_gates(struct hdmi_context *hdata)
737 int i = hdata->drv_data->clk_gates.count;
740 clk_disable_unprepare(hdata->clk_gates[i]);
743 static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy)
745 struct device *dev = hdata->dev;
749 for (i = 0; i < hdata->drv_data->clk_muxes.count; i += 3) {
750 struct clk **c = &hdata->clk_muxes[i];
752 ret = clk_set_parent(c[2], c[to_phy]);
756 dev_err(dev, "Cannot set clock parent of '%s' to '%s', %d\n",
757 hdata->drv_data->clk_muxes.data[i + 2],
758 hdata->drv_data->clk_muxes.data[i + to_phy], ret);
764 static u8 hdmi_chksum(struct hdmi_context *hdata,
765 u32 start, u8 len, u32 hdr_sum)
769 /* hdr_sum : header0 + header1 + header2
770 * start : start address of packet byte1
771 * len : packet bytes - 1 */
772 for (i = 0; i < len; ++i)
773 hdr_sum += 0xff & hdmi_reg_read(hdata, start + i * 4);
775 /* return 2's complement of 8 bit hdr_sum */
776 return (u8)(~(hdr_sum & 0xff) + 1);
779 static void hdmi_reg_infoframe(struct hdmi_context *hdata,
780 union hdmi_infoframe *infoframe)
786 if (hdata->dvi_mode) {
787 hdmi_reg_writeb(hdata, HDMI_VSI_CON,
788 HDMI_VSI_CON_DO_NOT_TRANSMIT);
789 hdmi_reg_writeb(hdata, HDMI_AVI_CON,
790 HDMI_AVI_CON_DO_NOT_TRANSMIT);
791 hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_NO_TRAN);
795 switch (infoframe->any.type) {
796 case HDMI_INFOFRAME_TYPE_AVI:
797 hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC);
798 hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->any.type);
799 hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1,
800 infoframe->any.version);
801 hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->any.length);
802 hdr_sum = infoframe->any.type + infoframe->any.version +
803 infoframe->any.length;
805 /* Output format zero hardcoded ,RGB YBCR selection */
806 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 |
807 AVI_ACTIVE_FORMAT_VALID |
808 AVI_UNDERSCANNED_DISPLAY_VALID);
811 * Set the aspect ratio as per the mode, mentioned in
812 * Table 9 AVI InfoFrame Data Byte 2 of CEA-861-D Standard
814 ar = hdata->current_mode.picture_aspect_ratio;
816 case HDMI_PICTURE_ASPECT_4_3:
817 ar |= AVI_4_3_CENTER_RATIO;
819 case HDMI_PICTURE_ASPECT_16_9:
820 ar |= AVI_16_9_CENTER_RATIO;
822 case HDMI_PICTURE_ASPECT_NONE:
824 ar |= AVI_SAME_AS_PIC_ASPECT_RATIO;
827 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2), ar);
829 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), hdata->cea_video_id);
831 chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1),
832 infoframe->any.length, hdr_sum);
833 DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum);
834 hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum);
836 case HDMI_INFOFRAME_TYPE_AUDIO:
837 hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02);
838 hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->any.type);
839 hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1,
840 infoframe->any.version);
841 hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->any.length);
842 hdr_sum = infoframe->any.type + infoframe->any.version +
843 infoframe->any.length;
844 chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1),
845 infoframe->any.length, hdr_sum);
846 DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum);
847 hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum);
854 static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
857 struct hdmi_context *hdata = connector_to_hdmi(connector);
859 if (gpiod_get_value(hdata->hpd_gpio))
860 return connector_status_connected;
862 return connector_status_disconnected;
865 static void hdmi_connector_destroy(struct drm_connector *connector)
867 drm_connector_unregister(connector);
868 drm_connector_cleanup(connector);
871 static const struct drm_connector_funcs hdmi_connector_funcs = {
872 .dpms = drm_atomic_helper_connector_dpms,
873 .fill_modes = drm_helper_probe_single_connector_modes,
874 .detect = hdmi_detect,
875 .destroy = hdmi_connector_destroy,
876 .reset = drm_atomic_helper_connector_reset,
877 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
878 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
881 static int hdmi_get_modes(struct drm_connector *connector)
883 struct hdmi_context *hdata = connector_to_hdmi(connector);
887 if (!hdata->ddc_adpt)
890 edid = drm_get_edid(connector, hdata->ddc_adpt);
894 hdata->dvi_mode = !drm_detect_hdmi_monitor(edid);
895 DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
896 (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
897 edid->width_cm, edid->height_cm);
899 drm_mode_connector_update_edid_property(connector, edid);
901 ret = drm_add_edid_modes(connector, edid);
908 static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
910 const struct hdmiphy_configs *confs = &hdata->drv_data->phy_confs;
913 for (i = 0; i < confs->count; i++)
914 if (confs->data[i].pixel_clock == pixel_clock)
917 DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
921 static int hdmi_mode_valid(struct drm_connector *connector,
922 struct drm_display_mode *mode)
924 struct hdmi_context *hdata = connector_to_hdmi(connector);
927 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
928 mode->hdisplay, mode->vdisplay, mode->vrefresh,
929 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
930 false, mode->clock * 1000);
932 ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
939 static struct drm_encoder *hdmi_best_encoder(struct drm_connector *connector)
941 struct hdmi_context *hdata = connector_to_hdmi(connector);
943 return &hdata->encoder;
946 static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
947 .get_modes = hdmi_get_modes,
948 .mode_valid = hdmi_mode_valid,
949 .best_encoder = hdmi_best_encoder,
952 static int hdmi_create_connector(struct drm_encoder *encoder)
954 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
955 struct drm_connector *connector = &hdata->connector;
958 connector->interlace_allowed = true;
959 connector->polled = DRM_CONNECTOR_POLL_HPD;
961 ret = drm_connector_init(hdata->drm_dev, connector,
962 &hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA);
964 DRM_ERROR("Failed to initialize connector with drm\n");
968 drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
969 drm_connector_register(connector);
970 drm_mode_connector_attach_encoder(connector, encoder);
975 static bool hdmi_mode_fixup(struct drm_encoder *encoder,
976 const struct drm_display_mode *mode,
977 struct drm_display_mode *adjusted_mode)
979 struct drm_device *dev = encoder->dev;
980 struct drm_connector *connector;
981 struct drm_display_mode *m;
984 drm_mode_set_crtcinfo(adjusted_mode, 0);
986 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
987 if (connector->encoder == encoder)
991 if (connector->encoder != encoder)
994 mode_ok = hdmi_mode_valid(connector, adjusted_mode);
996 if (mode_ok == MODE_OK)
1000 * Find the most suitable mode and copy it to adjusted_mode.
1002 list_for_each_entry(m, &connector->modes, head) {
1003 mode_ok = hdmi_mode_valid(connector, m);
1005 if (mode_ok == MODE_OK) {
1006 DRM_INFO("desired mode doesn't exist so\n");
1007 DRM_INFO("use the most suitable mode among modes.\n");
1009 DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n",
1010 m->hdisplay, m->vdisplay, m->vrefresh);
1012 drm_mode_copy(adjusted_mode, m);
1020 static void hdmi_reg_acr(struct hdmi_context *hdata, u32 freq)
1024 cts = (freq % 9) ? 27000 : 30000;
1025 n = 128 * freq / (27000000 / cts);
1027 hdmi_reg_writev(hdata, HDMI_ACR_N0, 3, n);
1028 hdmi_reg_writev(hdata, HDMI_ACR_MCTS0, 3, cts);
1029 hdmi_reg_writev(hdata, HDMI_ACR_CTS0, 3, cts);
1030 hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1033 static void hdmi_audio_init(struct hdmi_context *hdata)
1035 u32 sample_rate, bits_per_sample;
1036 u32 data_num, bit_ch, sample_frq;
1039 sample_rate = 44100;
1040 bits_per_sample = 16;
1042 switch (bits_per_sample) {
1057 hdmi_reg_acr(hdata, sample_rate);
1059 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1060 | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1061 | HDMI_I2S_MUX_ENABLE);
1063 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1064 | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1066 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1068 sample_frq = (sample_rate == 44100) ? 0 :
1069 (sample_rate == 48000) ? 2 :
1070 (sample_rate == 32000) ? 3 :
1071 (sample_rate == 96000) ? 0xa : 0x0;
1073 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1074 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1076 val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1077 hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1079 /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1080 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1081 | HDMI_I2S_SEL_LRCK(6));
1082 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1083 | HDMI_I2S_SEL_SDATA2(4));
1084 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1085 | HDMI_I2S_SEL_SDATA2(2));
1086 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1089 hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1090 | HDMI_I2S_L_CH_LOW_POL);
1091 hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1092 | HDMI_I2S_SET_BIT_CH(bit_ch)
1093 | HDMI_I2S_SET_SDATA_BIT(data_num)
1094 | HDMI_I2S_BASIC_FORMAT);
1096 /* Configure register related to CUV information */
1097 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
1098 | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1099 | HDMI_I2S_COPYRIGHT
1100 | HDMI_I2S_LINEAR_PCM
1101 | HDMI_I2S_CONSUMER_FORMAT);
1102 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1103 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1104 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1105 | HDMI_I2S_SET_SMP_FREQ(sample_frq));
1106 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1107 HDMI_I2S_ORG_SMP_FREQ_44_1
1108 | HDMI_I2S_WORD_LEN_MAX24_24BITS
1109 | HDMI_I2S_WORD_LEN_MAX_24BITS);
1111 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1114 static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1116 if (hdata->dvi_mode)
1119 hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
1120 hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ?
1121 HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1124 static void hdmi_start(struct hdmi_context *hdata, bool start)
1126 u32 val = start ? HDMI_TG_EN : 0;
1128 if (hdata->current_mode.flags & DRM_MODE_FLAG_INTERLACE)
1129 val |= HDMI_FIELD_EN;
1131 hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN);
1132 hdmi_reg_writemask(hdata, HDMI_TG_CMD, val, HDMI_TG_EN | HDMI_FIELD_EN);
1135 static void hdmi_conf_init(struct hdmi_context *hdata)
1137 union hdmi_infoframe infoframe;
1139 /* disable HPD interrupts from HDMI IP block, use GPIO instead */
1140 hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1141 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1143 /* choose HDMI mode */
1144 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1145 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1146 /* apply video pre-amble and guard band in HDMI mode only */
1147 hdmi_reg_writeb(hdata, HDMI_CON_2, 0);
1148 /* disable bluescreen */
1149 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1151 if (hdata->dvi_mode) {
1152 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1153 HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1154 hdmi_reg_writeb(hdata, HDMI_CON_2,
1155 HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1158 if (hdata->drv_data->type == HDMI_TYPE13) {
1159 /* choose bluescreen (fecal) color */
1160 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1161 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1162 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1164 /* enable AVI packet every vsync, fixes purple line problem */
1165 hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1166 /* force RGB, look to CEA-861-D, table 7 for more detail */
1167 hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1168 hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1170 hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1171 hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1172 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1174 infoframe.any.type = HDMI_INFOFRAME_TYPE_AVI;
1175 infoframe.any.version = HDMI_AVI_VERSION;
1176 infoframe.any.length = HDMI_AVI_LENGTH;
1177 hdmi_reg_infoframe(hdata, &infoframe);
1179 infoframe.any.type = HDMI_INFOFRAME_TYPE_AUDIO;
1180 infoframe.any.version = HDMI_AUI_VERSION;
1181 infoframe.any.length = HDMI_AUI_LENGTH;
1182 hdmi_reg_infoframe(hdata, &infoframe);
1184 /* enable AVI packet every vsync, fixes purple line problem */
1185 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1189 static void hdmiphy_wait_for_pll(struct hdmi_context *hdata)
1193 for (tries = 0; tries < 10; ++tries) {
1194 u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS);
1196 if (val & HDMI_PHY_STATUS_READY) {
1197 DRM_DEBUG_KMS("PLL stabilized after %d tries\n", tries);
1200 usleep_range(10, 20);
1203 DRM_ERROR("PLL could not reach steady state\n");
1206 static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1208 struct drm_display_mode *m = &hdata->current_mode;
1211 hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1212 hdmi_reg_writev(hdata, HDMI_V13_H_V_LINE_0, 3,
1213 (m->htotal << 12) | m->vtotal);
1215 val = (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
1216 hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1, val);
1218 val = (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0;
1219 hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1, val);
1221 val = (m->hsync_start - m->hdisplay - 2);
1222 val |= ((m->hsync_end - m->hdisplay - 2) << 10);
1223 val |= ((m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0)<<20;
1224 hdmi_reg_writev(hdata, HDMI_V13_H_SYNC_GEN_0, 3, val);
1227 * Quirk requirement for exynos HDMI IP design,
1228 * 2 pixels less than the actual calculation for hsync_start
1232 /* Following values & calculations differ for different type of modes */
1233 if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1234 val = ((m->vsync_end - m->vdisplay) / 2);
1235 val |= ((m->vsync_start - m->vdisplay) / 2) << 12;
1236 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1238 val = m->vtotal / 2;
1239 val |= ((m->vtotal - m->vdisplay) / 2) << 11;
1240 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1243 ((m->vsync_end - m->vsync_start) * 4) + 5) / 2;
1244 val |= m->vtotal << 11;
1245 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, val);
1247 val = ((m->vtotal / 2) + 7);
1248 val |= ((m->vtotal / 2) + 2) << 12;
1249 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, val);
1251 val = ((m->htotal / 2) + (m->hsync_start - m->hdisplay));
1252 val |= ((m->htotal / 2) +
1253 (m->hsync_start - m->hdisplay)) << 12;
1254 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, val);
1256 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1257 (m->vtotal - m->vdisplay) / 2);
1258 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1260 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x249);
1263 val |= (m->vtotal - m->vdisplay) << 11;
1264 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1266 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, 0);
1268 val = (m->vsync_end - m->vdisplay);
1269 val |= ((m->vsync_start - m->vdisplay) << 12);
1270 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1272 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, 0x1001);
1273 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, 0x1001);
1274 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1275 m->vtotal - m->vdisplay);
1276 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1279 hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1280 hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1281 hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1282 hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1285 static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1287 struct drm_display_mode *m = &hdata->current_mode;
1289 hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1290 hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
1291 hdmi_reg_writev(hdata, HDMI_H_LINE_0, 2, m->htotal);
1292 hdmi_reg_writev(hdata, HDMI_HSYNC_POL, 1,
1293 (m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0);
1294 hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1,
1295 (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
1296 hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1,
1297 (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1300 * Quirk requirement for exynos 5 HDMI IP design,
1301 * 2 pixels less than the actual calculation for hsync_start
1305 /* Following values & calculations differ for different type of modes */
1306 if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1307 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1308 (m->vsync_end - m->vdisplay) / 2);
1309 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1310 (m->vsync_start - m->vdisplay) / 2);
1311 hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal / 2);
1312 hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1313 (m->vtotal - m->vdisplay) / 2);
1314 hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2,
1315 m->vtotal - m->vdisplay / 2);
1316 hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, m->vtotal);
1317 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2,
1318 (m->vtotal / 2) + 7);
1319 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2,
1320 (m->vtotal / 2) + 2);
1321 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2,
1322 (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1323 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2,
1324 (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1325 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1326 (m->vtotal - m->vdisplay) / 2);
1327 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1328 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2,
1329 m->vtotal - m->vdisplay / 2);
1330 hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2,
1331 (m->vtotal / 2) + 1);
1332 hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2,
1333 (m->vtotal / 2) + 1);
1334 hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2,
1335 (m->vtotal / 2) + 1);
1336 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x0);
1337 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x0);
1339 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1340 m->vsync_end - m->vdisplay);
1341 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1342 m->vsync_start - m->vdisplay);
1343 hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal);
1344 hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1345 m->vtotal - m->vdisplay);
1346 hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2, 0xffff);
1347 hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, 0xffff);
1348 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2, 0xffff);
1349 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2, 0xffff);
1350 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2, 0xffff);
1351 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2, 0xffff);
1352 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1353 m->vtotal - m->vdisplay);
1354 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1357 hdmi_reg_writev(hdata, HDMI_H_SYNC_START_0, 2,
1358 m->hsync_start - m->hdisplay - 2);
1359 hdmi_reg_writev(hdata, HDMI_H_SYNC_END_0, 2,
1360 m->hsync_end - m->hdisplay - 2);
1361 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_1_0, 2, 0xffff);
1362 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_2_0, 2, 0xffff);
1363 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_3_0, 2, 0xffff);
1364 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_4_0, 2, 0xffff);
1365 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_5_0, 2, 0xffff);
1366 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_6_0, 2, 0xffff);
1367 hdmi_reg_writev(hdata, HDMI_V_BLANK_F2_0, 2, 0xffff);
1368 hdmi_reg_writev(hdata, HDMI_V_BLANK_F3_0, 2, 0xffff);
1369 hdmi_reg_writev(hdata, HDMI_V_BLANK_F4_0, 2, 0xffff);
1370 hdmi_reg_writev(hdata, HDMI_V_BLANK_F5_0, 2, 0xffff);
1371 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_3_0, 2, 0xffff);
1372 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_4_0, 2, 0xffff);
1373 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_5_0, 2, 0xffff);
1374 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_6_0, 2, 0xffff);
1375 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0, 2, 0xffff);
1376 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0, 2, 0xffff);
1377 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, 2, 0xffff);
1378 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
1380 hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1381 hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1382 hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1383 hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1384 if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1385 hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1);
1388 static void hdmi_mode_apply(struct hdmi_context *hdata)
1390 if (hdata->drv_data->type == HDMI_TYPE13)
1391 hdmi_v13_mode_apply(hdata);
1393 hdmi_v14_mode_apply(hdata);
1395 hdmi_start(hdata, true);
1398 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1400 hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, 0, 1);
1401 usleep_range(10000, 12000);
1402 hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, ~0, 1);
1403 usleep_range(10000, 12000);
1404 hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
1405 usleep_range(10000, 12000);
1406 hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT);
1407 usleep_range(10000, 12000);
1410 static void hdmiphy_enable_mode_set(struct hdmi_context *hdata, bool enable)
1412 u8 v = enable ? HDMI_PHY_ENABLE_MODE_SET : HDMI_PHY_DISABLE_MODE_SET;
1414 if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1415 writel(v, hdata->regs_hdmiphy + HDMIPHY5433_MODE_SET_DONE);
1418 static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1423 ret = hdmi_find_phy_conf(hdata, hdata->current_mode.clock * 1000);
1425 DRM_ERROR("failed to find hdmiphy conf\n");
1428 phy_conf = hdata->drv_data->phy_confs.data[ret].conf;
1430 hdmi_clk_set_parents(hdata, false);
1432 hdmiphy_conf_reset(hdata);
1434 hdmiphy_enable_mode_set(hdata, true);
1435 ret = hdmiphy_reg_write_buf(hdata, 0, phy_conf, 32);
1437 DRM_ERROR("failed to configure hdmiphy\n");
1440 hdmiphy_enable_mode_set(hdata, false);
1441 hdmi_clk_set_parents(hdata, true);
1442 usleep_range(10000, 12000);
1443 hdmiphy_wait_for_pll(hdata);
1446 static void hdmi_conf_apply(struct hdmi_context *hdata)
1448 hdmiphy_conf_apply(hdata);
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);
1456 static void hdmi_mode_set(struct drm_encoder *encoder,
1457 struct drm_display_mode *mode,
1458 struct drm_display_mode *adjusted_mode)
1460 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1461 struct drm_display_mode *m = adjusted_mode;
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");
1468 drm_mode_copy(&hdata->current_mode, m);
1469 hdata->cea_video_id = drm_match_cea_mode(mode);
1472 static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
1477 regmap_update_bits(hdata->sysreg, EXYNOS5433_SYSREG_DISP_HDMI_PHY,
1478 SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0);
1481 static void hdmi_enable(struct drm_encoder *encoder)
1483 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1488 pm_runtime_get_sync(hdata->dev);
1490 if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk))
1491 DRM_DEBUG_KMS("failed to enable regulator bulk\n");
1493 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1494 PMU_HDMI_PHY_ENABLE_BIT, 1);
1496 hdmi_set_refclk(hdata, true);
1498 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN);
1500 hdmi_conf_apply(hdata);
1502 hdata->powered = true;
1505 static void hdmi_disable(struct drm_encoder *encoder)
1507 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1508 struct drm_crtc *crtc = encoder->crtc;
1509 const struct drm_crtc_helper_funcs *funcs = NULL;
1511 if (!hdata->powered)
1515 * The SFRs of VP and Mixer are updated by Vertical Sync of
1516 * Timing generator which is a part of HDMI so the sequence
1517 * to disable TV Subsystem should be as following,
1518 * VP -> Mixer -> HDMI
1520 * Below codes will try to disable Mixer and VP(if used)
1521 * prior to disabling HDMI.
1524 funcs = crtc->helper_private;
1525 if (funcs && funcs->disable)
1526 (*funcs->disable)(crtc);
1528 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
1530 cancel_delayed_work(&hdata->hotplug_work);
1532 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN);
1534 hdmi_set_refclk(hdata, false);
1536 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1537 PMU_HDMI_PHY_ENABLE_BIT, 0);
1539 regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
1541 pm_runtime_put_sync(hdata->dev);
1543 hdata->powered = false;
1546 static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
1547 .mode_fixup = hdmi_mode_fixup,
1548 .mode_set = hdmi_mode_set,
1549 .enable = hdmi_enable,
1550 .disable = hdmi_disable,
1553 static const struct drm_encoder_funcs exynos_hdmi_encoder_funcs = {
1554 .destroy = drm_encoder_cleanup,
1557 static void hdmi_hotplug_work_func(struct work_struct *work)
1559 struct hdmi_context *hdata;
1561 hdata = container_of(work, struct hdmi_context, hotplug_work.work);
1564 drm_helper_hpd_irq_event(hdata->drm_dev);
1567 static irqreturn_t hdmi_irq_thread(int irq, void *arg)
1569 struct hdmi_context *hdata = arg;
1571 mod_delayed_work(system_wq, &hdata->hotplug_work,
1572 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
1577 static int hdmi_clks_get(struct hdmi_context *hdata,
1578 const struct string_array_spec *names,
1581 struct device *dev = hdata->dev;
1584 for (i = 0; i < names->count; ++i) {
1585 struct clk *clk = devm_clk_get(dev, names->data[i]);
1588 int ret = PTR_ERR(clk);
1590 dev_err(dev, "Cannot get clock %s, %d\n",
1591 names->data[i], ret);
1602 static int hdmi_clk_init(struct hdmi_context *hdata)
1604 const struct hdmi_driver_data *drv_data = hdata->drv_data;
1605 int count = drv_data->clk_gates.count + drv_data->clk_muxes.count;
1606 struct device *dev = hdata->dev;
1613 clks = devm_kzalloc(dev, sizeof(*clks) * count, GFP_KERNEL);
1617 hdata->clk_gates = clks;
1618 hdata->clk_muxes = clks + drv_data->clk_gates.count;
1620 ret = hdmi_clks_get(hdata, &drv_data->clk_gates, hdata->clk_gates);
1624 return hdmi_clks_get(hdata, &drv_data->clk_muxes, hdata->clk_muxes);
1628 static int hdmi_resources_init(struct hdmi_context *hdata)
1630 struct device *dev = hdata->dev;
1633 DRM_DEBUG_KMS("HDMI resource init\n");
1635 hdata->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
1636 if (IS_ERR(hdata->hpd_gpio)) {
1637 DRM_ERROR("cannot get hpd gpio property\n");
1638 return PTR_ERR(hdata->hpd_gpio);
1641 hdata->irq = gpiod_to_irq(hdata->hpd_gpio);
1642 if (hdata->irq < 0) {
1643 DRM_ERROR("failed to get GPIO irq\n");
1647 ret = hdmi_clk_init(hdata);
1651 ret = hdmi_clk_set_parents(hdata, false);
1655 for (i = 0; i < ARRAY_SIZE(supply); ++i) {
1656 hdata->regul_bulk[i].supply = supply[i];
1657 hdata->regul_bulk[i].consumer = NULL;
1659 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), hdata->regul_bulk);
1661 DRM_ERROR("failed to get regulators\n");
1665 hdata->reg_hdmi_en = devm_regulator_get_optional(dev, "hdmi-en");
1667 if (PTR_ERR(hdata->reg_hdmi_en) == -ENODEV)
1670 if (IS_ERR(hdata->reg_hdmi_en))
1671 return PTR_ERR(hdata->reg_hdmi_en);
1673 ret = regulator_enable(hdata->reg_hdmi_en);
1675 DRM_ERROR("failed to enable hdmi-en regulator\n");
1680 static struct of_device_id hdmi_match_types[] = {
1682 .compatible = "samsung,exynos4210-hdmi",
1683 .data = &exynos4210_hdmi_driver_data,
1685 .compatible = "samsung,exynos4212-hdmi",
1686 .data = &exynos4212_hdmi_driver_data,
1688 .compatible = "samsung,exynos5420-hdmi",
1689 .data = &exynos5420_hdmi_driver_data,
1691 .compatible = "samsung,exynos5433-hdmi",
1692 .data = &exynos5433_hdmi_driver_data,
1697 MODULE_DEVICE_TABLE (of, hdmi_match_types);
1699 static int hdmi_bind(struct device *dev, struct device *master, void *data)
1701 struct drm_device *drm_dev = data;
1702 struct hdmi_context *hdata = dev_get_drvdata(dev);
1703 struct drm_encoder *encoder = &hdata->encoder;
1706 hdata->drm_dev = drm_dev;
1708 pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
1709 EXYNOS_DISPLAY_TYPE_HDMI);
1713 encoder->possible_crtcs = 1 << pipe;
1715 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
1717 drm_encoder_init(drm_dev, encoder, &exynos_hdmi_encoder_funcs,
1718 DRM_MODE_ENCODER_TMDS, NULL);
1720 drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
1722 ret = hdmi_create_connector(encoder);
1724 DRM_ERROR("failed to create connector ret = %d\n", ret);
1725 drm_encoder_cleanup(encoder);
1732 static void hdmi_unbind(struct device *dev, struct device *master, void *data)
1736 static const struct component_ops hdmi_component_ops = {
1738 .unbind = hdmi_unbind,
1741 static struct device_node *hdmi_legacy_ddc_dt_binding(struct device *dev)
1743 const char *compatible_str = "samsung,exynos4210-hdmiddc";
1744 struct device_node *np;
1746 np = of_find_compatible_node(NULL, NULL, compatible_str);
1748 return of_get_next_parent(np);
1753 static struct device_node *hdmi_legacy_phy_dt_binding(struct device *dev)
1755 const char *compatible_str = "samsung,exynos4212-hdmiphy";
1757 return of_find_compatible_node(NULL, NULL, compatible_str);
1760 static int hdmi_probe(struct platform_device *pdev)
1762 struct device_node *ddc_node, *phy_node;
1763 const struct of_device_id *match;
1764 struct device *dev = &pdev->dev;
1765 struct hdmi_context *hdata;
1766 struct resource *res;
1769 hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
1773 match = of_match_device(hdmi_match_types, dev);
1777 hdata->drv_data = match->data;
1779 platform_set_drvdata(pdev, hdata);
1783 ret = hdmi_resources_init(hdata);
1785 DRM_ERROR("hdmi_resources_init failed\n");
1789 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1790 hdata->regs = devm_ioremap_resource(dev, res);
1791 if (IS_ERR(hdata->regs)) {
1792 ret = PTR_ERR(hdata->regs);
1796 ddc_node = hdmi_legacy_ddc_dt_binding(dev);
1798 goto out_get_ddc_adpt;
1800 ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
1802 DRM_ERROR("Failed to find ddc node in device tree\n");
1807 hdata->ddc_adpt = of_find_i2c_adapter_by_node(ddc_node);
1808 if (!hdata->ddc_adpt) {
1809 DRM_ERROR("Failed to get ddc i2c adapter by node\n");
1810 return -EPROBE_DEFER;
1813 phy_node = hdmi_legacy_phy_dt_binding(dev);
1815 goto out_get_phy_port;
1817 phy_node = of_parse_phandle(dev->of_node, "phy", 0);
1819 DRM_ERROR("Failed to find hdmiphy node in device tree\n");
1825 if (hdata->drv_data->is_apb_phy) {
1826 hdata->regs_hdmiphy = of_iomap(phy_node, 0);
1827 if (!hdata->regs_hdmiphy) {
1828 DRM_ERROR("failed to ioremap hdmi phy\n");
1833 hdata->hdmiphy_port = of_find_i2c_device_by_node(phy_node);
1834 if (!hdata->hdmiphy_port) {
1835 DRM_ERROR("Failed to get hdmi phy i2c client\n");
1836 ret = -EPROBE_DEFER;
1841 INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
1843 ret = devm_request_threaded_irq(dev, hdata->irq, NULL,
1844 hdmi_irq_thread, IRQF_TRIGGER_RISING |
1845 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1848 DRM_ERROR("failed to register hdmi interrupt\n");
1852 hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
1853 "samsung,syscon-phandle");
1854 if (IS_ERR(hdata->pmureg)) {
1855 DRM_ERROR("syscon regmap lookup failed.\n");
1856 ret = -EPROBE_DEFER;
1860 if (hdata->drv_data->has_sysreg) {
1861 hdata->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
1862 "samsung,sysreg-phandle");
1863 if (IS_ERR(hdata->sysreg)) {
1864 DRM_ERROR("sysreg regmap lookup failed.\n");
1865 ret = -EPROBE_DEFER;
1870 pm_runtime_enable(dev);
1872 ret = component_add(&pdev->dev, &hdmi_component_ops);
1874 goto err_disable_pm_runtime;
1878 err_disable_pm_runtime:
1879 pm_runtime_disable(dev);
1882 if (hdata->hdmiphy_port)
1883 put_device(&hdata->hdmiphy_port->dev);
1885 put_device(&hdata->ddc_adpt->dev);
1890 static int hdmi_remove(struct platform_device *pdev)
1892 struct hdmi_context *hdata = platform_get_drvdata(pdev);
1894 cancel_delayed_work_sync(&hdata->hotplug_work);
1896 component_del(&pdev->dev, &hdmi_component_ops);
1898 pm_runtime_disable(&pdev->dev);
1900 if (!IS_ERR(hdata->reg_hdmi_en))
1901 regulator_disable(hdata->reg_hdmi_en);
1903 if (hdata->hdmiphy_port)
1904 put_device(&hdata->hdmiphy_port->dev);
1906 put_device(&hdata->ddc_adpt->dev);
1912 static int exynos_hdmi_suspend(struct device *dev)
1914 struct hdmi_context *hdata = dev_get_drvdata(dev);
1916 hdmi_clk_disable_gates(hdata);
1921 static int exynos_hdmi_resume(struct device *dev)
1923 struct hdmi_context *hdata = dev_get_drvdata(dev);
1926 ret = hdmi_clk_enable_gates(hdata);
1934 static const struct dev_pm_ops exynos_hdmi_pm_ops = {
1935 SET_RUNTIME_PM_OPS(exynos_hdmi_suspend, exynos_hdmi_resume, NULL)
1938 struct platform_driver hdmi_driver = {
1939 .probe = hdmi_probe,
1940 .remove = hdmi_remove,
1942 .name = "exynos-hdmi",
1943 .owner = THIS_MODULE,
1944 .pm = &exynos_hdmi_pm_ops,
1945 .of_match_table = hdmi_match_types,