2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
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/of_graph.h>
39 #include <linux/hdmi.h>
40 #include <linux/component.h>
41 #include <linux/mfd/syscon.h>
42 #include <linux/regmap.h>
44 #include <drm/exynos_drm.h>
46 #include <media/cec-notifier.h>
48 #include "exynos_drm_crtc.h"
50 #define HOTPLUG_DEBOUNCE_MS 1100
58 #define HDMI_MAPPED_BASE 0xffff0000
60 enum hdmi_mapped_regs {
61 HDMI_PHY_STATUS = HDMI_MAPPED_BASE,
69 static const u32 hdmi_reg_map[][HDMI_TYPE_COUNT] = {
70 { HDMI_V13_PHY_STATUS, HDMI_PHY_STATUS_0 },
71 { HDMI_V13_PHY_RSTOUT, HDMI_V14_PHY_RSTOUT },
72 { HDMI_V13_ACR_CON, HDMI_V14_ACR_CON },
73 { HDMI_V13_ACR_MCTS0, HDMI_V14_ACR_MCTS0 },
74 { HDMI_V13_ACR_CTS0, HDMI_V14_ACR_CTS0 },
75 { HDMI_V13_ACR_N0, HDMI_V14_ACR_N0 },
78 static const char * const supply[] = {
84 struct hdmiphy_config {
89 struct hdmiphy_configs {
91 const struct hdmiphy_config *data;
94 struct string_array_spec {
96 const char * const *data;
99 #define INIT_ARRAY_SPEC(a) { .count = ARRAY_SIZE(a), .data = a }
101 struct hdmi_driver_data {
103 unsigned int is_apb_phy:1;
104 unsigned int has_sysreg:1;
105 struct hdmiphy_configs phy_confs;
106 struct string_array_spec clk_gates;
108 * Array of triplets (p_off, p_on, clock), where p_off and p_on are
109 * required parents of clock when HDMI-PHY is respectively off or on.
111 struct string_array_spec clk_muxes;
114 struct hdmi_context {
115 struct drm_encoder encoder;
117 struct drm_device *drm_dev;
118 struct drm_connector connector;
121 struct delayed_work hotplug_work;
122 struct drm_display_mode current_mode;
123 struct cec_notifier *notifier;
124 const struct hdmi_driver_data *drv_data;
127 void __iomem *regs_hdmiphy;
128 struct i2c_client *hdmiphy_port;
129 struct i2c_adapter *ddc_adpt;
130 struct gpio_desc *hpd_gpio;
132 struct regmap *pmureg;
133 struct regmap *sysreg;
134 struct clk **clk_gates;
135 struct clk **clk_muxes;
136 struct regulator_bulk_data regul_bulk[ARRAY_SIZE(supply)];
137 struct regulator *reg_hdmi_en;
138 struct exynos_drm_clk phy_clk;
139 struct drm_bridge *bridge;
142 static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e)
144 return container_of(e, struct hdmi_context, encoder);
147 static inline struct hdmi_context *connector_to_hdmi(struct drm_connector *c)
149 return container_of(c, struct hdmi_context, connector);
152 static const struct hdmiphy_config hdmiphy_v13_configs[] = {
154 .pixel_clock = 27000000,
156 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
157 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
158 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
159 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x80,
163 .pixel_clock = 27027000,
165 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
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 = 74176000,
174 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
175 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
176 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
177 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x80,
181 .pixel_clock = 74250000,
183 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
184 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
185 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
186 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x80,
190 .pixel_clock = 148500000,
192 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
193 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
194 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
195 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x80,
200 static const struct hdmiphy_config hdmiphy_v14_configs[] = {
202 .pixel_clock = 25200000,
204 0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
205 0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
206 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
207 0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
211 .pixel_clock = 27000000,
213 0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
214 0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
215 0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
216 0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
220 .pixel_clock = 27027000,
222 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
223 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
224 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
225 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
229 .pixel_clock = 36000000,
231 0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
232 0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
233 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
234 0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
238 .pixel_clock = 40000000,
240 0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
241 0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
242 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
243 0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
247 .pixel_clock = 65000000,
249 0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
250 0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
251 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
252 0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
256 .pixel_clock = 71000000,
258 0x01, 0xd1, 0x3b, 0x35, 0x40, 0x0c, 0x04, 0x08,
259 0x85, 0xa0, 0x63, 0xd9, 0x45, 0xa0, 0xac, 0x80,
260 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
261 0x54, 0xad, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
265 .pixel_clock = 73250000,
267 0x01, 0xd1, 0x3d, 0x35, 0x40, 0x18, 0x02, 0x08,
268 0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
269 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
270 0x54, 0xa8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
274 .pixel_clock = 74176000,
276 0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
277 0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
278 0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
279 0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
283 .pixel_clock = 74250000,
285 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
286 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
287 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
288 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
292 .pixel_clock = 83500000,
294 0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
295 0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
296 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
297 0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
301 .pixel_clock = 106500000,
303 0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
304 0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
305 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
306 0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
310 .pixel_clock = 108000000,
312 0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
313 0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
314 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
315 0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
319 .pixel_clock = 115500000,
321 0x01, 0xd1, 0x30, 0x12, 0x40, 0x40, 0x10, 0x08,
322 0x80, 0x80, 0x21, 0xd9, 0x45, 0xa0, 0xac, 0x80,
323 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
324 0x54, 0xaa, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
328 .pixel_clock = 119000000,
330 0x01, 0xd1, 0x32, 0x1a, 0x40, 0x30, 0xd8, 0x08,
331 0x04, 0xa0, 0x2a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
332 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
333 0x54, 0x9d, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
337 .pixel_clock = 146250000,
339 0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
340 0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
341 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
342 0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
346 .pixel_clock = 148500000,
348 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
349 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
350 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
351 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
356 static const struct hdmiphy_config hdmiphy_5420_configs[] = {
358 .pixel_clock = 25200000,
360 0x01, 0x52, 0x3F, 0x55, 0x40, 0x01, 0x00, 0xC8,
361 0x82, 0xC8, 0xBD, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
362 0x06, 0x80, 0x01, 0x84, 0x05, 0x02, 0x24, 0x66,
363 0x54, 0xF4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
367 .pixel_clock = 27000000,
369 0x01, 0xD1, 0x22, 0x51, 0x40, 0x08, 0xFC, 0xE0,
370 0x98, 0xE8, 0xCB, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
371 0x06, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
372 0x54, 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
376 .pixel_clock = 27027000,
378 0x01, 0xD1, 0x2D, 0x72, 0x40, 0x64, 0x12, 0xC8,
379 0x43, 0xE8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
380 0x26, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
381 0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
385 .pixel_clock = 36000000,
387 0x01, 0x51, 0x2D, 0x55, 0x40, 0x40, 0x00, 0xC8,
388 0x02, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
389 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
390 0x54, 0xAB, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
394 .pixel_clock = 40000000,
396 0x01, 0xD1, 0x21, 0x31, 0x40, 0x3C, 0x28, 0xC8,
397 0x87, 0xE8, 0xC8, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
398 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
399 0x54, 0x9A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
403 .pixel_clock = 65000000,
405 0x01, 0xD1, 0x36, 0x34, 0x40, 0x0C, 0x04, 0xC8,
406 0x82, 0xE8, 0x45, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
407 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
408 0x54, 0xBD, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
412 .pixel_clock = 71000000,
414 0x01, 0xD1, 0x3B, 0x35, 0x40, 0x0C, 0x04, 0xC8,
415 0x85, 0xE8, 0x63, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
416 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
417 0x54, 0x57, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
421 .pixel_clock = 73250000,
423 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x78, 0x8D, 0xC8,
424 0x81, 0xE8, 0xB7, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
425 0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
426 0x54, 0xA8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
430 .pixel_clock = 74176000,
432 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0xC8,
433 0x81, 0xE8, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
434 0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
435 0x54, 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
439 .pixel_clock = 74250000,
441 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0x08,
442 0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
443 0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
444 0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
448 .pixel_clock = 83500000,
450 0x01, 0xD1, 0x23, 0x11, 0x40, 0x0C, 0xFB, 0xC8,
451 0x85, 0xE8, 0xD1, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
452 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
453 0x54, 0x4A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
457 .pixel_clock = 88750000,
459 0x01, 0xD1, 0x25, 0x11, 0x40, 0x18, 0xFF, 0xC8,
460 0x83, 0xE8, 0xDE, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
461 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
462 0x54, 0x45, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
466 .pixel_clock = 106500000,
468 0x01, 0xD1, 0x2C, 0x12, 0x40, 0x0C, 0x09, 0xC8,
469 0x84, 0xE8, 0x0A, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
470 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
471 0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
475 .pixel_clock = 108000000,
477 0x01, 0x51, 0x2D, 0x15, 0x40, 0x01, 0x00, 0xC8,
478 0x82, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
479 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
480 0x54, 0xC7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
484 .pixel_clock = 115500000,
486 0x01, 0xD1, 0x30, 0x14, 0x40, 0x0C, 0x03, 0xC8,
487 0x88, 0xE8, 0x21, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
488 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
489 0x54, 0x6A, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
493 .pixel_clock = 146250000,
495 0x01, 0xD1, 0x3D, 0x15, 0x40, 0x18, 0xFD, 0xC8,
496 0x83, 0xE8, 0x6E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
497 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
498 0x54, 0x54, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
502 .pixel_clock = 148500000,
504 0x01, 0xD1, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0x08,
505 0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
506 0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
507 0x54, 0x4B, 0x25, 0x03, 0x00, 0x80, 0x01, 0x80,
512 static const struct hdmiphy_config hdmiphy_5433_configs[] = {
514 .pixel_clock = 27000000,
516 0x01, 0x51, 0x2d, 0x75, 0x01, 0x00, 0x88, 0x02,
517 0x72, 0x50, 0x44, 0x8c, 0x27, 0x00, 0x7c, 0xac,
518 0xd6, 0x2b, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
519 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
523 .pixel_clock = 27027000,
525 0x01, 0x51, 0x2d, 0x72, 0x64, 0x09, 0x88, 0xc3,
526 0x71, 0x50, 0x44, 0x8c, 0x27, 0x00, 0x7c, 0xac,
527 0xd6, 0x2b, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
528 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
532 .pixel_clock = 40000000,
534 0x01, 0x51, 0x32, 0x55, 0x01, 0x00, 0x88, 0x02,
535 0x4d, 0x50, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
536 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
537 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
541 .pixel_clock = 50000000,
543 0x01, 0x51, 0x34, 0x40, 0x64, 0x09, 0x88, 0xc3,
544 0x3d, 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 = 65000000,
552 0x01, 0x51, 0x36, 0x31, 0x40, 0x10, 0x04, 0xc6,
553 0x2e, 0xe8, 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 = 74176000,
561 0x01, 0x51, 0x3E, 0x35, 0x5B, 0xDE, 0x88, 0x42,
562 0x53, 0x51, 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 = 74250000,
570 0x01, 0x51, 0x3E, 0x35, 0x40, 0xF0, 0x88, 0xC2,
571 0x52, 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 = 108000000,
579 0x01, 0x51, 0x2d, 0x15, 0x01, 0x00, 0x88, 0x02,
580 0x72, 0x52, 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 = 148500000,
588 0x01, 0x51, 0x1f, 0x00, 0x40, 0xf8, 0x88, 0xc1,
589 0x52, 0x52, 0x24, 0x0c, 0x24, 0x0f, 0x7c, 0xa5,
590 0xd4, 0x2b, 0x87, 0x00, 0x00, 0x04, 0x00, 0x30,
591 0x08, 0x10, 0x01, 0x01, 0x48, 0x4a, 0x00, 0x40,
595 .pixel_clock = 297000000,
597 0x01, 0x51, 0x3E, 0x05, 0x40, 0xF0, 0x88, 0xC2,
598 0x52, 0x53, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
599 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
600 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 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_write_buf(struct hdmi_context *hdata, u32 reg_id,
686 for (reg_id = hdmi_map_reg(hdata, reg_id); size; --size, reg_id += 4)
687 writel(*buf++, hdata->regs + reg_id);
690 static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
691 u32 reg_id, u32 value, u32 mask)
695 reg_id = hdmi_map_reg(hdata, reg_id);
696 old = readl(hdata->regs + reg_id);
697 value = (value & mask) | (old & ~mask);
698 writel(value, hdata->regs + reg_id);
701 static int hdmiphy_reg_write_buf(struct hdmi_context *hdata,
702 u32 reg_offset, const u8 *buf, u32 len)
704 if ((reg_offset + len) > 32)
707 if (hdata->hdmiphy_port) {
710 ret = i2c_master_send(hdata->hdmiphy_port, buf, len);
716 for (i = 0; i < len; i++)
717 writel(buf[i], hdata->regs_hdmiphy +
718 ((reg_offset + i)<<2));
723 static int hdmi_clk_enable_gates(struct hdmi_context *hdata)
727 for (i = 0; i < hdata->drv_data->clk_gates.count; ++i) {
728 ret = clk_prepare_enable(hdata->clk_gates[i]);
732 dev_err(hdata->dev, "Cannot enable clock '%s', %d\n",
733 hdata->drv_data->clk_gates.data[i], ret);
735 clk_disable_unprepare(hdata->clk_gates[i]);
742 static void hdmi_clk_disable_gates(struct hdmi_context *hdata)
744 int i = hdata->drv_data->clk_gates.count;
747 clk_disable_unprepare(hdata->clk_gates[i]);
750 static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy)
752 struct device *dev = hdata->dev;
756 for (i = 0; i < hdata->drv_data->clk_muxes.count; i += 3) {
757 struct clk **c = &hdata->clk_muxes[i];
759 ret = clk_set_parent(c[2], c[to_phy]);
763 dev_err(dev, "Cannot set clock parent of '%s' to '%s', %d\n",
764 hdata->drv_data->clk_muxes.data[i + 2],
765 hdata->drv_data->clk_muxes.data[i + to_phy], ret);
771 static void hdmi_reg_infoframes(struct hdmi_context *hdata)
773 union hdmi_infoframe frm;
777 if (hdata->dvi_mode) {
778 hdmi_reg_writeb(hdata, HDMI_AVI_CON,
779 HDMI_AVI_CON_DO_NOT_TRANSMIT);
780 hdmi_reg_writeb(hdata, HDMI_VSI_CON,
781 HDMI_VSI_CON_DO_NOT_TRANSMIT);
782 hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_NO_TRAN);
786 ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi,
787 &hdata->current_mode, false);
789 ret = hdmi_avi_infoframe_pack(&frm.avi, buf, sizeof(buf));
791 hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC);
792 hdmi_reg_write_buf(hdata, HDMI_AVI_HEADER0, buf, ret);
794 DRM_INFO("%s: invalid AVI infoframe (%d)\n", __func__, ret);
797 ret = drm_hdmi_vendor_infoframe_from_display_mode(&frm.vendor.hdmi,
798 &hdata->current_mode);
800 ret = hdmi_vendor_infoframe_pack(&frm.vendor.hdmi, buf,
803 hdmi_reg_writeb(hdata, HDMI_VSI_CON, HDMI_VSI_CON_EVERY_VSYNC);
804 hdmi_reg_write_buf(hdata, HDMI_VSI_HEADER0, buf, 3);
805 hdmi_reg_write_buf(hdata, HDMI_VSI_DATA(0), buf + 3, ret - 3);
808 ret = hdmi_audio_infoframe_init(&frm.audio);
810 frm.audio.channels = 2;
811 ret = hdmi_audio_infoframe_pack(&frm.audio, buf, sizeof(buf));
814 hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_EVERY_VSYNC);
815 hdmi_reg_write_buf(hdata, HDMI_AUI_HEADER0, buf, ret);
819 static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
822 struct hdmi_context *hdata = connector_to_hdmi(connector);
824 if (gpiod_get_value(hdata->hpd_gpio))
825 return connector_status_connected;
827 cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
828 return connector_status_disconnected;
831 static void hdmi_connector_destroy(struct drm_connector *connector)
833 drm_connector_unregister(connector);
834 drm_connector_cleanup(connector);
837 static const struct drm_connector_funcs hdmi_connector_funcs = {
838 .fill_modes = drm_helper_probe_single_connector_modes,
839 .detect = hdmi_detect,
840 .destroy = hdmi_connector_destroy,
841 .reset = drm_atomic_helper_connector_reset,
842 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
843 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
846 static int hdmi_get_modes(struct drm_connector *connector)
848 struct hdmi_context *hdata = connector_to_hdmi(connector);
852 if (!hdata->ddc_adpt)
855 edid = drm_get_edid(connector, hdata->ddc_adpt);
859 hdata->dvi_mode = !drm_detect_hdmi_monitor(edid);
860 DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
861 (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
862 edid->width_cm, edid->height_cm);
864 drm_mode_connector_update_edid_property(connector, edid);
865 cec_notifier_set_phys_addr_from_edid(hdata->notifier, edid);
867 ret = drm_add_edid_modes(connector, edid);
874 static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
876 const struct hdmiphy_configs *confs = &hdata->drv_data->phy_confs;
879 for (i = 0; i < confs->count; i++)
880 if (confs->data[i].pixel_clock == pixel_clock)
883 DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
887 static int hdmi_mode_valid(struct drm_connector *connector,
888 struct drm_display_mode *mode)
890 struct hdmi_context *hdata = connector_to_hdmi(connector);
893 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
894 mode->hdisplay, mode->vdisplay, mode->vrefresh,
895 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
896 false, mode->clock * 1000);
898 ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
905 static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
906 .get_modes = hdmi_get_modes,
907 .mode_valid = hdmi_mode_valid,
910 static int hdmi_create_connector(struct drm_encoder *encoder)
912 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
913 struct drm_connector *connector = &hdata->connector;
916 connector->interlace_allowed = true;
917 connector->polled = DRM_CONNECTOR_POLL_HPD;
919 ret = drm_connector_init(hdata->drm_dev, connector,
920 &hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA);
922 DRM_ERROR("Failed to initialize connector with drm\n");
926 drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
927 drm_mode_connector_attach_encoder(connector, encoder);
930 encoder->bridge = hdata->bridge;
931 hdata->bridge->encoder = encoder;
932 ret = drm_bridge_attach(encoder, hdata->bridge, NULL);
934 DRM_ERROR("Failed to attach bridge\n");
940 static bool hdmi_mode_fixup(struct drm_encoder *encoder,
941 const struct drm_display_mode *mode,
942 struct drm_display_mode *adjusted_mode)
944 struct drm_device *dev = encoder->dev;
945 struct drm_connector *connector;
946 struct drm_display_mode *m;
949 drm_mode_set_crtcinfo(adjusted_mode, 0);
951 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
952 if (connector->encoder == encoder)
956 if (connector->encoder != encoder)
959 mode_ok = hdmi_mode_valid(connector, adjusted_mode);
961 if (mode_ok == MODE_OK)
965 * Find the most suitable mode and copy it to adjusted_mode.
967 list_for_each_entry(m, &connector->modes, head) {
968 mode_ok = hdmi_mode_valid(connector, m);
970 if (mode_ok == MODE_OK) {
971 DRM_INFO("desired mode doesn't exist so\n");
972 DRM_INFO("use the most suitable mode among modes.\n");
974 DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n",
975 m->hdisplay, m->vdisplay, m->vrefresh);
977 drm_mode_copy(adjusted_mode, m);
985 static void hdmi_reg_acr(struct hdmi_context *hdata, u32 freq)
989 cts = (freq % 9) ? 27000 : 30000;
990 n = 128 * freq / (27000000 / cts);
992 hdmi_reg_writev(hdata, HDMI_ACR_N0, 3, n);
993 hdmi_reg_writev(hdata, HDMI_ACR_MCTS0, 3, cts);
994 hdmi_reg_writev(hdata, HDMI_ACR_CTS0, 3, cts);
995 hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
998 static void hdmi_audio_init(struct hdmi_context *hdata)
1000 u32 sample_rate, bits_per_sample;
1001 u32 data_num, bit_ch, sample_frq;
1004 sample_rate = 44100;
1005 bits_per_sample = 16;
1007 switch (bits_per_sample) {
1022 hdmi_reg_acr(hdata, sample_rate);
1024 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1025 | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1026 | HDMI_I2S_MUX_ENABLE);
1028 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1029 | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1031 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1033 sample_frq = (sample_rate == 44100) ? 0 :
1034 (sample_rate == 48000) ? 2 :
1035 (sample_rate == 32000) ? 3 :
1036 (sample_rate == 96000) ? 0xa : 0x0;
1038 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1039 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1041 val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1042 hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1044 /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1045 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1046 | HDMI_I2S_SEL_LRCK(6));
1047 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1048 | HDMI_I2S_SEL_SDATA2(4));
1049 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1050 | HDMI_I2S_SEL_SDATA2(2));
1051 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1054 hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1055 | HDMI_I2S_L_CH_LOW_POL);
1056 hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1057 | HDMI_I2S_SET_BIT_CH(bit_ch)
1058 | HDMI_I2S_SET_SDATA_BIT(data_num)
1059 | HDMI_I2S_BASIC_FORMAT);
1061 /* Configure register related to CUV information */
1062 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
1063 | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1064 | HDMI_I2S_COPYRIGHT
1065 | HDMI_I2S_LINEAR_PCM
1066 | HDMI_I2S_CONSUMER_FORMAT);
1067 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1068 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1069 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1070 | HDMI_I2S_SET_SMP_FREQ(sample_frq));
1071 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1072 HDMI_I2S_ORG_SMP_FREQ_44_1
1073 | HDMI_I2S_WORD_LEN_MAX24_24BITS
1074 | HDMI_I2S_WORD_LEN_MAX_24BITS);
1076 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1079 static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1081 if (hdata->dvi_mode)
1084 hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
1085 hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ?
1086 HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1089 static void hdmi_start(struct hdmi_context *hdata, bool start)
1091 u32 val = start ? HDMI_TG_EN : 0;
1093 if (hdata->current_mode.flags & DRM_MODE_FLAG_INTERLACE)
1094 val |= HDMI_FIELD_EN;
1096 hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN);
1097 hdmi_reg_writemask(hdata, HDMI_TG_CMD, val, HDMI_TG_EN | HDMI_FIELD_EN);
1100 static void hdmi_conf_init(struct hdmi_context *hdata)
1102 /* disable HPD interrupts from HDMI IP block, use GPIO instead */
1103 hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1104 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1106 /* choose HDMI mode */
1107 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1108 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1109 /* apply video pre-amble and guard band in HDMI mode only */
1110 hdmi_reg_writeb(hdata, HDMI_CON_2, 0);
1111 /* disable bluescreen */
1112 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1114 if (hdata->dvi_mode) {
1115 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1116 HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1117 hdmi_reg_writeb(hdata, HDMI_CON_2,
1118 HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1121 if (hdata->drv_data->type == HDMI_TYPE13) {
1122 /* choose bluescreen (fecal) color */
1123 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1124 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1125 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1127 /* enable AVI packet every vsync, fixes purple line problem */
1128 hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1129 /* force RGB, look to CEA-861-D, table 7 for more detail */
1130 hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1131 hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1133 hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1134 hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1135 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1137 hdmi_reg_infoframes(hdata);
1139 /* enable AVI packet every vsync, fixes purple line problem */
1140 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1144 static void hdmiphy_wait_for_pll(struct hdmi_context *hdata)
1148 for (tries = 0; tries < 10; ++tries) {
1149 u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS);
1151 if (val & HDMI_PHY_STATUS_READY) {
1152 DRM_DEBUG_KMS("PLL stabilized after %d tries\n", tries);
1155 usleep_range(10, 20);
1158 DRM_ERROR("PLL could not reach steady state\n");
1161 static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1163 struct drm_display_mode *m = &hdata->current_mode;
1166 hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1167 hdmi_reg_writev(hdata, HDMI_V13_H_V_LINE_0, 3,
1168 (m->htotal << 12) | m->vtotal);
1170 val = (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
1171 hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1, val);
1173 val = (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0;
1174 hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1, val);
1176 val = (m->hsync_start - m->hdisplay - 2);
1177 val |= ((m->hsync_end - m->hdisplay - 2) << 10);
1178 val |= ((m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0)<<20;
1179 hdmi_reg_writev(hdata, HDMI_V13_H_SYNC_GEN_0, 3, val);
1182 * Quirk requirement for exynos HDMI IP design,
1183 * 2 pixels less than the actual calculation for hsync_start
1187 /* Following values & calculations differ for different type of modes */
1188 if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1189 val = ((m->vsync_end - m->vdisplay) / 2);
1190 val |= ((m->vsync_start - m->vdisplay) / 2) << 12;
1191 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1193 val = m->vtotal / 2;
1194 val |= ((m->vtotal - m->vdisplay) / 2) << 11;
1195 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1198 ((m->vsync_end - m->vsync_start) * 4) + 5) / 2;
1199 val |= m->vtotal << 11;
1200 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, val);
1202 val = ((m->vtotal / 2) + 7);
1203 val |= ((m->vtotal / 2) + 2) << 12;
1204 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, val);
1206 val = ((m->htotal / 2) + (m->hsync_start - m->hdisplay));
1207 val |= ((m->htotal / 2) +
1208 (m->hsync_start - m->hdisplay)) << 12;
1209 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, val);
1211 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1212 (m->vtotal - m->vdisplay) / 2);
1213 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1215 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x249);
1218 val |= (m->vtotal - m->vdisplay) << 11;
1219 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1221 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, 0);
1223 val = (m->vsync_end - m->vdisplay);
1224 val |= ((m->vsync_start - m->vdisplay) << 12);
1225 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1227 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, 0x1001);
1228 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, 0x1001);
1229 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1230 m->vtotal - m->vdisplay);
1231 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1234 hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1235 hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1236 hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1237 hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1240 static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1242 struct drm_display_mode *m = &hdata->current_mode;
1244 hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1245 hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
1246 hdmi_reg_writev(hdata, HDMI_H_LINE_0, 2, m->htotal);
1247 hdmi_reg_writev(hdata, HDMI_HSYNC_POL, 1,
1248 (m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0);
1249 hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1,
1250 (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
1251 hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1,
1252 (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1255 * Quirk requirement for exynos 5 HDMI IP design,
1256 * 2 pixels less than the actual calculation for hsync_start
1260 /* Following values & calculations differ for different type of modes */
1261 if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1262 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1263 (m->vsync_end - m->vdisplay) / 2);
1264 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1265 (m->vsync_start - m->vdisplay) / 2);
1266 hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal / 2);
1267 hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1268 (m->vtotal - m->vdisplay) / 2);
1269 hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2,
1270 m->vtotal - m->vdisplay / 2);
1271 hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, m->vtotal);
1272 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2,
1273 (m->vtotal / 2) + 7);
1274 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2,
1275 (m->vtotal / 2) + 2);
1276 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2,
1277 (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1278 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2,
1279 (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1280 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1281 (m->vtotal - m->vdisplay) / 2);
1282 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1283 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2,
1284 m->vtotal - m->vdisplay / 2);
1285 hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2,
1286 (m->vtotal / 2) + 1);
1287 hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2,
1288 (m->vtotal / 2) + 1);
1289 hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2,
1290 (m->vtotal / 2) + 1);
1291 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x0);
1292 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x0);
1294 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1295 m->vsync_end - m->vdisplay);
1296 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1297 m->vsync_start - m->vdisplay);
1298 hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal);
1299 hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1300 m->vtotal - m->vdisplay);
1301 hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2, 0xffff);
1302 hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, 0xffff);
1303 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2, 0xffff);
1304 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2, 0xffff);
1305 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2, 0xffff);
1306 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2, 0xffff);
1307 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1308 m->vtotal - m->vdisplay);
1309 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1312 hdmi_reg_writev(hdata, HDMI_H_SYNC_START_0, 2,
1313 m->hsync_start - m->hdisplay - 2);
1314 hdmi_reg_writev(hdata, HDMI_H_SYNC_END_0, 2,
1315 m->hsync_end - m->hdisplay - 2);
1316 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_1_0, 2, 0xffff);
1317 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_2_0, 2, 0xffff);
1318 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_3_0, 2, 0xffff);
1319 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_4_0, 2, 0xffff);
1320 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_5_0, 2, 0xffff);
1321 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_6_0, 2, 0xffff);
1322 hdmi_reg_writev(hdata, HDMI_V_BLANK_F2_0, 2, 0xffff);
1323 hdmi_reg_writev(hdata, HDMI_V_BLANK_F3_0, 2, 0xffff);
1324 hdmi_reg_writev(hdata, HDMI_V_BLANK_F4_0, 2, 0xffff);
1325 hdmi_reg_writev(hdata, HDMI_V_BLANK_F5_0, 2, 0xffff);
1326 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_3_0, 2, 0xffff);
1327 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_4_0, 2, 0xffff);
1328 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_5_0, 2, 0xffff);
1329 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_6_0, 2, 0xffff);
1330 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0, 2, 0xffff);
1331 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0, 2, 0xffff);
1332 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, 2, 0xffff);
1333 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
1335 hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1336 hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1337 hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1338 hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1339 if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1340 hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1);
1343 static void hdmi_mode_apply(struct hdmi_context *hdata)
1345 if (hdata->drv_data->type == HDMI_TYPE13)
1346 hdmi_v13_mode_apply(hdata);
1348 hdmi_v14_mode_apply(hdata);
1350 hdmi_start(hdata, true);
1353 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1355 hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, 0, 1);
1356 usleep_range(10000, 12000);
1357 hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, ~0, 1);
1358 usleep_range(10000, 12000);
1359 hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
1360 usleep_range(10000, 12000);
1361 hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT);
1362 usleep_range(10000, 12000);
1365 static void hdmiphy_enable_mode_set(struct hdmi_context *hdata, bool enable)
1367 u8 v = enable ? HDMI_PHY_ENABLE_MODE_SET : HDMI_PHY_DISABLE_MODE_SET;
1369 if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1370 writel(v, hdata->regs_hdmiphy + HDMIPHY5433_MODE_SET_DONE);
1373 static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1378 ret = hdmi_find_phy_conf(hdata, hdata->current_mode.clock * 1000);
1380 DRM_ERROR("failed to find hdmiphy conf\n");
1383 phy_conf = hdata->drv_data->phy_confs.data[ret].conf;
1385 hdmi_clk_set_parents(hdata, false);
1387 hdmiphy_conf_reset(hdata);
1389 hdmiphy_enable_mode_set(hdata, true);
1390 ret = hdmiphy_reg_write_buf(hdata, 0, phy_conf, 32);
1392 DRM_ERROR("failed to configure hdmiphy\n");
1395 hdmiphy_enable_mode_set(hdata, false);
1396 hdmi_clk_set_parents(hdata, true);
1397 usleep_range(10000, 12000);
1398 hdmiphy_wait_for_pll(hdata);
1401 static void hdmi_conf_apply(struct hdmi_context *hdata)
1403 hdmi_start(hdata, false);
1404 hdmi_conf_init(hdata);
1405 hdmi_audio_init(hdata);
1406 hdmi_mode_apply(hdata);
1407 hdmi_audio_control(hdata, true);
1410 static void hdmi_mode_set(struct drm_encoder *encoder,
1411 struct drm_display_mode *mode,
1412 struct drm_display_mode *adjusted_mode)
1414 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1415 struct drm_display_mode *m = adjusted_mode;
1417 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n",
1418 m->hdisplay, m->vdisplay,
1419 m->vrefresh, (m->flags & DRM_MODE_FLAG_INTERLACE) ?
1420 "INTERLACED" : "PROGRESSIVE");
1422 drm_mode_copy(&hdata->current_mode, m);
1425 static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
1430 regmap_update_bits(hdata->sysreg, EXYNOS5433_SYSREG_DISP_HDMI_PHY,
1431 SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0);
1434 static void hdmiphy_enable(struct hdmi_context *hdata)
1439 pm_runtime_get_sync(hdata->dev);
1441 if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk))
1442 DRM_DEBUG_KMS("failed to enable regulator bulk\n");
1444 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1445 PMU_HDMI_PHY_ENABLE_BIT, 1);
1447 hdmi_set_refclk(hdata, true);
1449 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN);
1451 hdmiphy_conf_apply(hdata);
1453 hdata->powered = true;
1456 static void hdmiphy_disable(struct hdmi_context *hdata)
1458 if (!hdata->powered)
1461 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
1463 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN);
1465 hdmi_set_refclk(hdata, false);
1467 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1468 PMU_HDMI_PHY_ENABLE_BIT, 0);
1470 regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
1472 pm_runtime_put_sync(hdata->dev);
1474 hdata->powered = false;
1477 static void hdmi_enable(struct drm_encoder *encoder)
1479 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1481 hdmiphy_enable(hdata);
1482 hdmi_conf_apply(hdata);
1485 static void hdmi_disable(struct drm_encoder *encoder)
1487 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1489 if (!hdata->powered)
1493 * The SFRs of VP and Mixer are updated by Vertical Sync of
1494 * Timing generator which is a part of HDMI so the sequence
1495 * to disable TV Subsystem should be as following,
1496 * VP -> Mixer -> HDMI
1498 * To achieve such sequence HDMI is disabled together with HDMI PHY, via
1499 * pipe clock callback.
1501 cancel_delayed_work(&hdata->hotplug_work);
1502 cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
1505 static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
1506 .mode_fixup = hdmi_mode_fixup,
1507 .mode_set = hdmi_mode_set,
1508 .enable = hdmi_enable,
1509 .disable = hdmi_disable,
1512 static const struct drm_encoder_funcs exynos_hdmi_encoder_funcs = {
1513 .destroy = drm_encoder_cleanup,
1516 static void hdmi_hotplug_work_func(struct work_struct *work)
1518 struct hdmi_context *hdata;
1520 hdata = container_of(work, struct hdmi_context, hotplug_work.work);
1523 drm_helper_hpd_irq_event(hdata->drm_dev);
1526 static irqreturn_t hdmi_irq_thread(int irq, void *arg)
1528 struct hdmi_context *hdata = arg;
1530 mod_delayed_work(system_wq, &hdata->hotplug_work,
1531 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
1536 static int hdmi_clks_get(struct hdmi_context *hdata,
1537 const struct string_array_spec *names,
1540 struct device *dev = hdata->dev;
1543 for (i = 0; i < names->count; ++i) {
1544 struct clk *clk = devm_clk_get(dev, names->data[i]);
1547 int ret = PTR_ERR(clk);
1549 dev_err(dev, "Cannot get clock %s, %d\n",
1550 names->data[i], ret);
1561 static int hdmi_clk_init(struct hdmi_context *hdata)
1563 const struct hdmi_driver_data *drv_data = hdata->drv_data;
1564 int count = drv_data->clk_gates.count + drv_data->clk_muxes.count;
1565 struct device *dev = hdata->dev;
1572 clks = devm_kzalloc(dev, sizeof(*clks) * count, GFP_KERNEL);
1576 hdata->clk_gates = clks;
1577 hdata->clk_muxes = clks + drv_data->clk_gates.count;
1579 ret = hdmi_clks_get(hdata, &drv_data->clk_gates, hdata->clk_gates);
1583 return hdmi_clks_get(hdata, &drv_data->clk_muxes, hdata->clk_muxes);
1587 static void hdmiphy_clk_enable(struct exynos_drm_clk *clk, bool enable)
1589 struct hdmi_context *hdata = container_of(clk, struct hdmi_context,
1593 hdmiphy_enable(hdata);
1595 hdmiphy_disable(hdata);
1598 static int hdmi_bridge_init(struct hdmi_context *hdata)
1600 struct device *dev = hdata->dev;
1601 struct device_node *ep, *np;
1603 ep = of_graph_get_endpoint_by_regs(dev->of_node, 1, -1);
1607 np = of_graph_get_remote_port_parent(ep);
1610 DRM_ERROR("failed to get remote port parent");
1614 hdata->bridge = of_drm_find_bridge(np);
1618 return -EPROBE_DEFER;
1623 static int hdmi_resources_init(struct hdmi_context *hdata)
1625 struct device *dev = hdata->dev;
1628 DRM_DEBUG_KMS("HDMI resource init\n");
1630 hdata->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
1631 if (IS_ERR(hdata->hpd_gpio)) {
1632 DRM_ERROR("cannot get hpd gpio property\n");
1633 return PTR_ERR(hdata->hpd_gpio);
1636 hdata->irq = gpiod_to_irq(hdata->hpd_gpio);
1637 if (hdata->irq < 0) {
1638 DRM_ERROR("failed to get GPIO irq\n");
1642 ret = hdmi_clk_init(hdata);
1646 ret = hdmi_clk_set_parents(hdata, false);
1650 for (i = 0; i < ARRAY_SIZE(supply); ++i)
1651 hdata->regul_bulk[i].supply = supply[i];
1653 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), hdata->regul_bulk);
1655 if (ret != -EPROBE_DEFER)
1656 DRM_ERROR("failed to get regulators\n");
1660 hdata->reg_hdmi_en = devm_regulator_get_optional(dev, "hdmi-en");
1662 if (PTR_ERR(hdata->reg_hdmi_en) != -ENODEV) {
1663 if (IS_ERR(hdata->reg_hdmi_en))
1664 return PTR_ERR(hdata->reg_hdmi_en);
1666 ret = regulator_enable(hdata->reg_hdmi_en);
1668 DRM_ERROR("failed to enable hdmi-en regulator\n");
1673 return hdmi_bridge_init(hdata);
1676 static const struct of_device_id hdmi_match_types[] = {
1678 .compatible = "samsung,exynos4210-hdmi",
1679 .data = &exynos4210_hdmi_driver_data,
1681 .compatible = "samsung,exynos4212-hdmi",
1682 .data = &exynos4212_hdmi_driver_data,
1684 .compatible = "samsung,exynos5420-hdmi",
1685 .data = &exynos5420_hdmi_driver_data,
1687 .compatible = "samsung,exynos5433-hdmi",
1688 .data = &exynos5433_hdmi_driver_data,
1693 MODULE_DEVICE_TABLE (of, hdmi_match_types);
1695 static int hdmi_bind(struct device *dev, struct device *master, void *data)
1697 struct drm_device *drm_dev = data;
1698 struct hdmi_context *hdata = dev_get_drvdata(dev);
1699 struct drm_encoder *encoder = &hdata->encoder;
1700 struct exynos_drm_crtc *crtc;
1703 hdata->drm_dev = drm_dev;
1705 hdata->phy_clk.enable = hdmiphy_clk_enable;
1707 drm_encoder_init(drm_dev, encoder, &exynos_hdmi_encoder_funcs,
1708 DRM_MODE_ENCODER_TMDS, NULL);
1710 drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
1712 ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_HDMI);
1716 crtc = exynos_drm_crtc_get_by_type(drm_dev, EXYNOS_DISPLAY_TYPE_HDMI);
1717 crtc->pipe_clk = &hdata->phy_clk;
1719 ret = hdmi_create_connector(encoder);
1721 DRM_ERROR("failed to create connector ret = %d\n", ret);
1722 drm_encoder_cleanup(encoder);
1729 static void hdmi_unbind(struct device *dev, struct device *master, void *data)
1733 static const struct component_ops hdmi_component_ops = {
1735 .unbind = hdmi_unbind,
1738 static int hdmi_get_ddc_adapter(struct hdmi_context *hdata)
1740 const char *compatible_str = "samsung,exynos4210-hdmiddc";
1741 struct device_node *np;
1742 struct i2c_adapter *adpt;
1744 np = of_find_compatible_node(NULL, NULL, compatible_str);
1746 np = of_get_next_parent(np);
1748 np = of_parse_phandle(hdata->dev->of_node, "ddc", 0);
1751 DRM_ERROR("Failed to find ddc node in device tree\n");
1755 adpt = of_find_i2c_adapter_by_node(np);
1759 DRM_INFO("Failed to get ddc i2c adapter by node\n");
1760 return -EPROBE_DEFER;
1763 hdata->ddc_adpt = adpt;
1768 static int hdmi_get_phy_io(struct hdmi_context *hdata)
1770 const char *compatible_str = "samsung,exynos4212-hdmiphy";
1771 struct device_node *np;
1774 np = of_find_compatible_node(NULL, NULL, compatible_str);
1776 np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
1778 DRM_ERROR("Failed to find hdmiphy node in device tree\n");
1783 if (hdata->drv_data->is_apb_phy) {
1784 hdata->regs_hdmiphy = of_iomap(np, 0);
1785 if (!hdata->regs_hdmiphy) {
1786 DRM_ERROR("failed to ioremap hdmi phy\n");
1791 hdata->hdmiphy_port = of_find_i2c_device_by_node(np);
1792 if (!hdata->hdmiphy_port) {
1793 DRM_INFO("Failed to get hdmi phy i2c client\n");
1794 ret = -EPROBE_DEFER;
1804 static int hdmi_probe(struct platform_device *pdev)
1806 struct device *dev = &pdev->dev;
1807 struct hdmi_context *hdata;
1808 struct resource *res;
1811 hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
1815 hdata->drv_data = of_device_get_match_data(dev);
1817 platform_set_drvdata(pdev, hdata);
1821 ret = hdmi_resources_init(hdata);
1823 if (ret != -EPROBE_DEFER)
1824 DRM_ERROR("hdmi_resources_init failed\n");
1828 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1829 hdata->regs = devm_ioremap_resource(dev, res);
1830 if (IS_ERR(hdata->regs)) {
1831 ret = PTR_ERR(hdata->regs);
1835 ret = hdmi_get_ddc_adapter(hdata);
1839 ret = hdmi_get_phy_io(hdata);
1843 INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
1845 ret = devm_request_threaded_irq(dev, hdata->irq, NULL,
1846 hdmi_irq_thread, IRQF_TRIGGER_RISING |
1847 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1850 DRM_ERROR("failed to register hdmi interrupt\n");
1854 hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
1855 "samsung,syscon-phandle");
1856 if (IS_ERR(hdata->pmureg)) {
1857 DRM_ERROR("syscon regmap lookup failed.\n");
1858 ret = -EPROBE_DEFER;
1862 if (hdata->drv_data->has_sysreg) {
1863 hdata->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
1864 "samsung,sysreg-phandle");
1865 if (IS_ERR(hdata->sysreg)) {
1866 DRM_ERROR("sysreg regmap lookup failed.\n");
1867 ret = -EPROBE_DEFER;
1872 hdata->notifier = cec_notifier_get(&pdev->dev);
1873 if (hdata->notifier == NULL) {
1878 pm_runtime_enable(dev);
1880 ret = component_add(&pdev->dev, &hdmi_component_ops);
1882 goto err_notifier_put;
1887 cec_notifier_put(hdata->notifier);
1888 pm_runtime_disable(dev);
1891 if (hdata->hdmiphy_port)
1892 put_device(&hdata->hdmiphy_port->dev);
1893 if (hdata->regs_hdmiphy)
1894 iounmap(hdata->regs_hdmiphy);
1896 put_device(&hdata->ddc_adpt->dev);
1901 static int hdmi_remove(struct platform_device *pdev)
1903 struct hdmi_context *hdata = platform_get_drvdata(pdev);
1905 cancel_delayed_work_sync(&hdata->hotplug_work);
1906 cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
1908 component_del(&pdev->dev, &hdmi_component_ops);
1910 cec_notifier_put(hdata->notifier);
1911 pm_runtime_disable(&pdev->dev);
1913 if (!IS_ERR(hdata->reg_hdmi_en))
1914 regulator_disable(hdata->reg_hdmi_en);
1916 if (hdata->hdmiphy_port)
1917 put_device(&hdata->hdmiphy_port->dev);
1919 if (hdata->regs_hdmiphy)
1920 iounmap(hdata->regs_hdmiphy);
1922 put_device(&hdata->ddc_adpt->dev);
1927 static int __maybe_unused exynos_hdmi_suspend(struct device *dev)
1929 struct hdmi_context *hdata = dev_get_drvdata(dev);
1931 hdmi_clk_disable_gates(hdata);
1936 static int __maybe_unused exynos_hdmi_resume(struct device *dev)
1938 struct hdmi_context *hdata = dev_get_drvdata(dev);
1941 ret = hdmi_clk_enable_gates(hdata);
1948 static const struct dev_pm_ops exynos_hdmi_pm_ops = {
1949 SET_RUNTIME_PM_OPS(exynos_hdmi_suspend, exynos_hdmi_resume, NULL)
1952 struct platform_driver hdmi_driver = {
1953 .probe = hdmi_probe,
1954 .remove = hdmi_remove,
1956 .name = "exynos-hdmi",
1957 .owner = THIS_MODULE,
1958 .pm = &exynos_hdmi_pm_ops,
1959 .of_match_table = hdmi_match_types,