Linux 4.2.1
[linux/fpc-iii.git] / drivers / gpu / drm / exynos / exynos_hdmi.c
blob4a00990e4ae4e8459b94a9a007044af1cc11af62
1 /*
2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
3 * Authors:
4 * Seung-Woo Kim <sw0312.kim@samsung.com>
5 * Inki Dae <inki.dae@samsung.com>
6 * Joonyoung Shim <jy0922.shim@samsung.com>
8 * Based on drivers/media/video/s5p-tv/hdmi_drv.c
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
17 #include <drm/drmP.h>
18 #include <drm/drm_edid.h>
19 #include <drm/drm_crtc_helper.h>
20 #include <drm/drm_atomic_helper.h>
22 #include "regs-hdmi.h"
24 #include <linux/kernel.h>
25 #include <linux/spinlock.h>
26 #include <linux/wait.h>
27 #include <linux/i2c.h>
28 #include <linux/platform_device.h>
29 #include <linux/interrupt.h>
30 #include <linux/irq.h>
31 #include <linux/delay.h>
32 #include <linux/pm_runtime.h>
33 #include <linux/clk.h>
34 #include <linux/regulator/consumer.h>
35 #include <linux/io.h>
36 #include <linux/of.h>
37 #include <linux/of_address.h>
38 #include <linux/of_gpio.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 "exynos_drm_drv.h"
47 #include "exynos_drm_crtc.h"
48 #include "exynos_mixer.h"
50 #include <linux/gpio.h>
51 #include <media/s5p_hdmi.h>
53 #define ctx_from_connector(c) container_of(c, struct hdmi_context, connector)
55 #define HOTPLUG_DEBOUNCE_MS 1100
57 /* AVI header and aspect ratio */
58 #define HDMI_AVI_VERSION 0x02
59 #define HDMI_AVI_LENGTH 0x0D
61 /* AUI header info */
62 #define HDMI_AUI_VERSION 0x01
63 #define HDMI_AUI_LENGTH 0x0A
64 #define AVI_SAME_AS_PIC_ASPECT_RATIO 0x8
65 #define AVI_4_3_CENTER_RATIO 0x9
66 #define AVI_16_9_CENTER_RATIO 0xa
68 enum hdmi_type {
69 HDMI_TYPE13,
70 HDMI_TYPE14,
73 struct hdmi_driver_data {
74 unsigned int type;
75 const struct hdmiphy_config *phy_confs;
76 unsigned int phy_conf_count;
77 unsigned int is_apb_phy:1;
80 struct hdmi_resources {
81 struct clk *hdmi;
82 struct clk *sclk_hdmi;
83 struct clk *sclk_pixel;
84 struct clk *sclk_hdmiphy;
85 struct clk *mout_hdmi;
86 struct regulator_bulk_data *regul_bulk;
87 struct regulator *reg_hdmi_en;
88 int regul_count;
91 struct hdmi_tg_regs {
92 u8 cmd[1];
93 u8 h_fsz[2];
94 u8 hact_st[2];
95 u8 hact_sz[2];
96 u8 v_fsz[2];
97 u8 vsync[2];
98 u8 vsync2[2];
99 u8 vact_st[2];
100 u8 vact_sz[2];
101 u8 field_chg[2];
102 u8 vact_st2[2];
103 u8 vact_st3[2];
104 u8 vact_st4[2];
105 u8 vsync_top_hdmi[2];
106 u8 vsync_bot_hdmi[2];
107 u8 field_top_hdmi[2];
108 u8 field_bot_hdmi[2];
109 u8 tg_3d[1];
112 struct hdmi_v13_core_regs {
113 u8 h_blank[2];
114 u8 v_blank[3];
115 u8 h_v_line[3];
116 u8 vsync_pol[1];
117 u8 int_pro_mode[1];
118 u8 v_blank_f[3];
119 u8 h_sync_gen[3];
120 u8 v_sync_gen1[3];
121 u8 v_sync_gen2[3];
122 u8 v_sync_gen3[3];
125 struct hdmi_v14_core_regs {
126 u8 h_blank[2];
127 u8 v2_blank[2];
128 u8 v1_blank[2];
129 u8 v_line[2];
130 u8 h_line[2];
131 u8 hsync_pol[1];
132 u8 vsync_pol[1];
133 u8 int_pro_mode[1];
134 u8 v_blank_f0[2];
135 u8 v_blank_f1[2];
136 u8 h_sync_start[2];
137 u8 h_sync_end[2];
138 u8 v_sync_line_bef_2[2];
139 u8 v_sync_line_bef_1[2];
140 u8 v_sync_line_aft_2[2];
141 u8 v_sync_line_aft_1[2];
142 u8 v_sync_line_aft_pxl_2[2];
143 u8 v_sync_line_aft_pxl_1[2];
144 u8 v_blank_f2[2]; /* for 3D mode */
145 u8 v_blank_f3[2]; /* for 3D mode */
146 u8 v_blank_f4[2]; /* for 3D mode */
147 u8 v_blank_f5[2]; /* for 3D mode */
148 u8 v_sync_line_aft_3[2];
149 u8 v_sync_line_aft_4[2];
150 u8 v_sync_line_aft_5[2];
151 u8 v_sync_line_aft_6[2];
152 u8 v_sync_line_aft_pxl_3[2];
153 u8 v_sync_line_aft_pxl_4[2];
154 u8 v_sync_line_aft_pxl_5[2];
155 u8 v_sync_line_aft_pxl_6[2];
156 u8 vact_space_1[2];
157 u8 vact_space_2[2];
158 u8 vact_space_3[2];
159 u8 vact_space_4[2];
160 u8 vact_space_5[2];
161 u8 vact_space_6[2];
164 struct hdmi_v13_conf {
165 struct hdmi_v13_core_regs core;
166 struct hdmi_tg_regs tg;
169 struct hdmi_v14_conf {
170 struct hdmi_v14_core_regs core;
171 struct hdmi_tg_regs tg;
174 struct hdmi_conf_regs {
175 int pixel_clock;
176 int cea_video_id;
177 enum hdmi_picture_aspect aspect_ratio;
178 union {
179 struct hdmi_v13_conf v13_conf;
180 struct hdmi_v14_conf v14_conf;
181 } conf;
184 struct hdmi_context {
185 struct exynos_drm_display display;
186 struct device *dev;
187 struct drm_device *drm_dev;
188 struct drm_connector connector;
189 struct drm_encoder *encoder;
190 bool hpd;
191 bool powered;
192 bool dvi_mode;
193 struct mutex hdmi_mutex;
195 void __iomem *regs;
196 int irq;
197 struct delayed_work hotplug_work;
199 struct i2c_adapter *ddc_adpt;
200 struct i2c_client *hdmiphy_port;
202 /* current hdmiphy conf regs */
203 struct drm_display_mode current_mode;
204 struct hdmi_conf_regs mode_conf;
206 struct hdmi_resources res;
208 int hpd_gpio;
209 void __iomem *regs_hdmiphy;
210 const struct hdmiphy_config *phy_confs;
211 unsigned int phy_conf_count;
213 struct regmap *pmureg;
214 enum hdmi_type type;
217 static inline struct hdmi_context *display_to_hdmi(struct exynos_drm_display *d)
219 return container_of(d, struct hdmi_context, display);
222 struct hdmiphy_config {
223 int pixel_clock;
224 u8 conf[32];
227 /* list of phy config settings */
228 static const struct hdmiphy_config hdmiphy_v13_configs[] = {
230 .pixel_clock = 27000000,
231 .conf = {
232 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
233 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
234 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
235 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
239 .pixel_clock = 27027000,
240 .conf = {
241 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
242 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
243 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
244 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
248 .pixel_clock = 74176000,
249 .conf = {
250 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
251 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
252 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
253 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
257 .pixel_clock = 74250000,
258 .conf = {
259 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
260 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
261 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
262 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
266 .pixel_clock = 148500000,
267 .conf = {
268 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
269 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
270 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
271 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
276 static const struct hdmiphy_config hdmiphy_v14_configs[] = {
278 .pixel_clock = 25200000,
279 .conf = {
280 0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
281 0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
282 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
283 0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
287 .pixel_clock = 27000000,
288 .conf = {
289 0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
290 0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
291 0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
292 0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
296 .pixel_clock = 27027000,
297 .conf = {
298 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
299 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
300 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
301 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
305 .pixel_clock = 36000000,
306 .conf = {
307 0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
308 0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
309 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
310 0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
314 .pixel_clock = 40000000,
315 .conf = {
316 0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
317 0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
318 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
319 0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
323 .pixel_clock = 65000000,
324 .conf = {
325 0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
326 0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
327 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
328 0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
332 .pixel_clock = 71000000,
333 .conf = {
334 0x01, 0xd1, 0x3b, 0x35, 0x40, 0x0c, 0x04, 0x08,
335 0x85, 0xa0, 0x63, 0xd9, 0x45, 0xa0, 0xac, 0x80,
336 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
337 0x54, 0xad, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
341 .pixel_clock = 73250000,
342 .conf = {
343 0x01, 0xd1, 0x3d, 0x35, 0x40, 0x18, 0x02, 0x08,
344 0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
345 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
346 0x54, 0xa8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
350 .pixel_clock = 74176000,
351 .conf = {
352 0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
353 0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
354 0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
355 0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
359 .pixel_clock = 74250000,
360 .conf = {
361 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
362 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
363 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
364 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
368 .pixel_clock = 83500000,
369 .conf = {
370 0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
371 0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
372 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
373 0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
377 .pixel_clock = 106500000,
378 .conf = {
379 0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
380 0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
381 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
382 0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
386 .pixel_clock = 108000000,
387 .conf = {
388 0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
389 0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
390 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
391 0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
395 .pixel_clock = 115500000,
396 .conf = {
397 0x01, 0xd1, 0x30, 0x12, 0x40, 0x40, 0x10, 0x08,
398 0x80, 0x80, 0x21, 0xd9, 0x45, 0xa0, 0xac, 0x80,
399 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
400 0x54, 0xaa, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
404 .pixel_clock = 119000000,
405 .conf = {
406 0x01, 0xd1, 0x32, 0x1a, 0x40, 0x30, 0xd8, 0x08,
407 0x04, 0xa0, 0x2a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
408 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
409 0x54, 0x9d, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
413 .pixel_clock = 146250000,
414 .conf = {
415 0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
416 0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
417 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
418 0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
422 .pixel_clock = 148500000,
423 .conf = {
424 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
425 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
426 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
427 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
432 static const struct hdmiphy_config hdmiphy_5420_configs[] = {
434 .pixel_clock = 25200000,
435 .conf = {
436 0x01, 0x52, 0x3F, 0x55, 0x40, 0x01, 0x00, 0xC8,
437 0x82, 0xC8, 0xBD, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
438 0x06, 0x80, 0x01, 0x84, 0x05, 0x02, 0x24, 0x66,
439 0x54, 0xF4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
443 .pixel_clock = 27000000,
444 .conf = {
445 0x01, 0xD1, 0x22, 0x51, 0x40, 0x08, 0xFC, 0xE0,
446 0x98, 0xE8, 0xCB, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
447 0x06, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
448 0x54, 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
452 .pixel_clock = 27027000,
453 .conf = {
454 0x01, 0xD1, 0x2D, 0x72, 0x40, 0x64, 0x12, 0xC8,
455 0x43, 0xE8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
456 0x26, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
457 0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
461 .pixel_clock = 36000000,
462 .conf = {
463 0x01, 0x51, 0x2D, 0x55, 0x40, 0x40, 0x00, 0xC8,
464 0x02, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
465 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
466 0x54, 0xAB, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
470 .pixel_clock = 40000000,
471 .conf = {
472 0x01, 0xD1, 0x21, 0x31, 0x40, 0x3C, 0x28, 0xC8,
473 0x87, 0xE8, 0xC8, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
474 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
475 0x54, 0x9A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
479 .pixel_clock = 65000000,
480 .conf = {
481 0x01, 0xD1, 0x36, 0x34, 0x40, 0x0C, 0x04, 0xC8,
482 0x82, 0xE8, 0x45, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
483 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
484 0x54, 0xBD, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
488 .pixel_clock = 71000000,
489 .conf = {
490 0x01, 0xD1, 0x3B, 0x35, 0x40, 0x0C, 0x04, 0xC8,
491 0x85, 0xE8, 0x63, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
492 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
493 0x54, 0x57, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
497 .pixel_clock = 73250000,
498 .conf = {
499 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x78, 0x8D, 0xC8,
500 0x81, 0xE8, 0xB7, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
501 0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
502 0x54, 0xA8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
506 .pixel_clock = 74176000,
507 .conf = {
508 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0xC8,
509 0x81, 0xE8, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
510 0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
511 0x54, 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
515 .pixel_clock = 74250000,
516 .conf = {
517 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0x08,
518 0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
519 0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
520 0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
524 .pixel_clock = 83500000,
525 .conf = {
526 0x01, 0xD1, 0x23, 0x11, 0x40, 0x0C, 0xFB, 0xC8,
527 0x85, 0xE8, 0xD1, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
528 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
529 0x54, 0x4A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
533 .pixel_clock = 88750000,
534 .conf = {
535 0x01, 0xD1, 0x25, 0x11, 0x40, 0x18, 0xFF, 0xC8,
536 0x83, 0xE8, 0xDE, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
537 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
538 0x54, 0x45, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
542 .pixel_clock = 106500000,
543 .conf = {
544 0x01, 0xD1, 0x2C, 0x12, 0x40, 0x0C, 0x09, 0xC8,
545 0x84, 0xE8, 0x0A, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
546 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
547 0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
551 .pixel_clock = 108000000,
552 .conf = {
553 0x01, 0x51, 0x2D, 0x15, 0x40, 0x01, 0x00, 0xC8,
554 0x82, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
555 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
556 0x54, 0xC7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
560 .pixel_clock = 115500000,
561 .conf = {
562 0x01, 0xD1, 0x30, 0x14, 0x40, 0x0C, 0x03, 0xC8,
563 0x88, 0xE8, 0x21, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
564 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
565 0x54, 0x6A, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
569 .pixel_clock = 146250000,
570 .conf = {
571 0x01, 0xD1, 0x3D, 0x15, 0x40, 0x18, 0xFD, 0xC8,
572 0x83, 0xE8, 0x6E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
573 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
574 0x54, 0x54, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
578 .pixel_clock = 148500000,
579 .conf = {
580 0x01, 0xD1, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0x08,
581 0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
582 0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
583 0x54, 0x4B, 0x25, 0x03, 0x00, 0x80, 0x01, 0x80,
588 static struct hdmi_driver_data exynos5420_hdmi_driver_data = {
589 .type = HDMI_TYPE14,
590 .phy_confs = hdmiphy_5420_configs,
591 .phy_conf_count = ARRAY_SIZE(hdmiphy_5420_configs),
592 .is_apb_phy = 1,
595 static struct hdmi_driver_data exynos4212_hdmi_driver_data = {
596 .type = HDMI_TYPE14,
597 .phy_confs = hdmiphy_v14_configs,
598 .phy_conf_count = ARRAY_SIZE(hdmiphy_v14_configs),
599 .is_apb_phy = 0,
602 static struct hdmi_driver_data exynos4210_hdmi_driver_data = {
603 .type = HDMI_TYPE13,
604 .phy_confs = hdmiphy_v13_configs,
605 .phy_conf_count = ARRAY_SIZE(hdmiphy_v13_configs),
606 .is_apb_phy = 0,
609 static struct hdmi_driver_data exynos5_hdmi_driver_data = {
610 .type = HDMI_TYPE14,
611 .phy_confs = hdmiphy_v13_configs,
612 .phy_conf_count = ARRAY_SIZE(hdmiphy_v13_configs),
613 .is_apb_phy = 0,
616 static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
618 return readl(hdata->regs + reg_id);
621 static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
622 u32 reg_id, u8 value)
624 writeb(value, hdata->regs + reg_id);
627 static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
628 u32 reg_id, u32 value, u32 mask)
630 u32 old = readl(hdata->regs + reg_id);
631 value = (value & mask) | (old & ~mask);
632 writel(value, hdata->regs + reg_id);
635 static int hdmiphy_reg_writeb(struct hdmi_context *hdata,
636 u32 reg_offset, u8 value)
638 if (hdata->hdmiphy_port) {
639 u8 buffer[2];
640 int ret;
642 buffer[0] = reg_offset;
643 buffer[1] = value;
645 ret = i2c_master_send(hdata->hdmiphy_port, buffer, 2);
646 if (ret == 2)
647 return 0;
648 return ret;
649 } else {
650 writeb(value, hdata->regs_hdmiphy + (reg_offset<<2));
651 return 0;
655 static int hdmiphy_reg_write_buf(struct hdmi_context *hdata,
656 u32 reg_offset, const u8 *buf, u32 len)
658 if ((reg_offset + len) > 32)
659 return -EINVAL;
661 if (hdata->hdmiphy_port) {
662 int ret;
664 ret = i2c_master_send(hdata->hdmiphy_port, buf, len);
665 if (ret == len)
666 return 0;
667 return ret;
668 } else {
669 int i;
670 for (i = 0; i < len; i++)
671 writeb(buf[i], hdata->regs_hdmiphy +
672 ((reg_offset + i)<<2));
673 return 0;
677 static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix)
679 #define DUMPREG(reg_id) \
680 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
681 readl(hdata->regs + reg_id))
682 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
683 DUMPREG(HDMI_INTC_FLAG);
684 DUMPREG(HDMI_INTC_CON);
685 DUMPREG(HDMI_HPD_STATUS);
686 DUMPREG(HDMI_V13_PHY_RSTOUT);
687 DUMPREG(HDMI_V13_PHY_VPLL);
688 DUMPREG(HDMI_V13_PHY_CMU);
689 DUMPREG(HDMI_V13_CORE_RSTOUT);
691 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
692 DUMPREG(HDMI_CON_0);
693 DUMPREG(HDMI_CON_1);
694 DUMPREG(HDMI_CON_2);
695 DUMPREG(HDMI_SYS_STATUS);
696 DUMPREG(HDMI_V13_PHY_STATUS);
697 DUMPREG(HDMI_STATUS_EN);
698 DUMPREG(HDMI_HPD);
699 DUMPREG(HDMI_MODE_SEL);
700 DUMPREG(HDMI_V13_HPD_GEN);
701 DUMPREG(HDMI_V13_DC_CONTROL);
702 DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN);
704 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
705 DUMPREG(HDMI_H_BLANK_0);
706 DUMPREG(HDMI_H_BLANK_1);
707 DUMPREG(HDMI_V13_V_BLANK_0);
708 DUMPREG(HDMI_V13_V_BLANK_1);
709 DUMPREG(HDMI_V13_V_BLANK_2);
710 DUMPREG(HDMI_V13_H_V_LINE_0);
711 DUMPREG(HDMI_V13_H_V_LINE_1);
712 DUMPREG(HDMI_V13_H_V_LINE_2);
713 DUMPREG(HDMI_VSYNC_POL);
714 DUMPREG(HDMI_INT_PRO_MODE);
715 DUMPREG(HDMI_V13_V_BLANK_F_0);
716 DUMPREG(HDMI_V13_V_BLANK_F_1);
717 DUMPREG(HDMI_V13_V_BLANK_F_2);
718 DUMPREG(HDMI_V13_H_SYNC_GEN_0);
719 DUMPREG(HDMI_V13_H_SYNC_GEN_1);
720 DUMPREG(HDMI_V13_H_SYNC_GEN_2);
721 DUMPREG(HDMI_V13_V_SYNC_GEN_1_0);
722 DUMPREG(HDMI_V13_V_SYNC_GEN_1_1);
723 DUMPREG(HDMI_V13_V_SYNC_GEN_1_2);
724 DUMPREG(HDMI_V13_V_SYNC_GEN_2_0);
725 DUMPREG(HDMI_V13_V_SYNC_GEN_2_1);
726 DUMPREG(HDMI_V13_V_SYNC_GEN_2_2);
727 DUMPREG(HDMI_V13_V_SYNC_GEN_3_0);
728 DUMPREG(HDMI_V13_V_SYNC_GEN_3_1);
729 DUMPREG(HDMI_V13_V_SYNC_GEN_3_2);
731 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
732 DUMPREG(HDMI_TG_CMD);
733 DUMPREG(HDMI_TG_H_FSZ_L);
734 DUMPREG(HDMI_TG_H_FSZ_H);
735 DUMPREG(HDMI_TG_HACT_ST_L);
736 DUMPREG(HDMI_TG_HACT_ST_H);
737 DUMPREG(HDMI_TG_HACT_SZ_L);
738 DUMPREG(HDMI_TG_HACT_SZ_H);
739 DUMPREG(HDMI_TG_V_FSZ_L);
740 DUMPREG(HDMI_TG_V_FSZ_H);
741 DUMPREG(HDMI_TG_VSYNC_L);
742 DUMPREG(HDMI_TG_VSYNC_H);
743 DUMPREG(HDMI_TG_VSYNC2_L);
744 DUMPREG(HDMI_TG_VSYNC2_H);
745 DUMPREG(HDMI_TG_VACT_ST_L);
746 DUMPREG(HDMI_TG_VACT_ST_H);
747 DUMPREG(HDMI_TG_VACT_SZ_L);
748 DUMPREG(HDMI_TG_VACT_SZ_H);
749 DUMPREG(HDMI_TG_FIELD_CHG_L);
750 DUMPREG(HDMI_TG_FIELD_CHG_H);
751 DUMPREG(HDMI_TG_VACT_ST2_L);
752 DUMPREG(HDMI_TG_VACT_ST2_H);
753 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
754 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
755 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
756 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
757 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
758 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
759 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
760 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
761 #undef DUMPREG
764 static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix)
766 int i;
768 #define DUMPREG(reg_id) \
769 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
770 readl(hdata->regs + reg_id))
772 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
773 DUMPREG(HDMI_INTC_CON);
774 DUMPREG(HDMI_INTC_FLAG);
775 DUMPREG(HDMI_HPD_STATUS);
776 DUMPREG(HDMI_INTC_CON_1);
777 DUMPREG(HDMI_INTC_FLAG_1);
778 DUMPREG(HDMI_PHY_STATUS_0);
779 DUMPREG(HDMI_PHY_STATUS_PLL);
780 DUMPREG(HDMI_PHY_CON_0);
781 DUMPREG(HDMI_PHY_RSTOUT);
782 DUMPREG(HDMI_PHY_VPLL);
783 DUMPREG(HDMI_PHY_CMU);
784 DUMPREG(HDMI_CORE_RSTOUT);
786 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
787 DUMPREG(HDMI_CON_0);
788 DUMPREG(HDMI_CON_1);
789 DUMPREG(HDMI_CON_2);
790 DUMPREG(HDMI_SYS_STATUS);
791 DUMPREG(HDMI_PHY_STATUS_0);
792 DUMPREG(HDMI_STATUS_EN);
793 DUMPREG(HDMI_HPD);
794 DUMPREG(HDMI_MODE_SEL);
795 DUMPREG(HDMI_ENC_EN);
796 DUMPREG(HDMI_DC_CONTROL);
797 DUMPREG(HDMI_VIDEO_PATTERN_GEN);
799 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
800 DUMPREG(HDMI_H_BLANK_0);
801 DUMPREG(HDMI_H_BLANK_1);
802 DUMPREG(HDMI_V2_BLANK_0);
803 DUMPREG(HDMI_V2_BLANK_1);
804 DUMPREG(HDMI_V1_BLANK_0);
805 DUMPREG(HDMI_V1_BLANK_1);
806 DUMPREG(HDMI_V_LINE_0);
807 DUMPREG(HDMI_V_LINE_1);
808 DUMPREG(HDMI_H_LINE_0);
809 DUMPREG(HDMI_H_LINE_1);
810 DUMPREG(HDMI_HSYNC_POL);
812 DUMPREG(HDMI_VSYNC_POL);
813 DUMPREG(HDMI_INT_PRO_MODE);
814 DUMPREG(HDMI_V_BLANK_F0_0);
815 DUMPREG(HDMI_V_BLANK_F0_1);
816 DUMPREG(HDMI_V_BLANK_F1_0);
817 DUMPREG(HDMI_V_BLANK_F1_1);
819 DUMPREG(HDMI_H_SYNC_START_0);
820 DUMPREG(HDMI_H_SYNC_START_1);
821 DUMPREG(HDMI_H_SYNC_END_0);
822 DUMPREG(HDMI_H_SYNC_END_1);
824 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0);
825 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1);
826 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0);
827 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1);
829 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0);
830 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1);
831 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0);
832 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1);
834 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0);
835 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1);
836 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0);
837 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1);
839 DUMPREG(HDMI_V_BLANK_F2_0);
840 DUMPREG(HDMI_V_BLANK_F2_1);
841 DUMPREG(HDMI_V_BLANK_F3_0);
842 DUMPREG(HDMI_V_BLANK_F3_1);
843 DUMPREG(HDMI_V_BLANK_F4_0);
844 DUMPREG(HDMI_V_BLANK_F4_1);
845 DUMPREG(HDMI_V_BLANK_F5_0);
846 DUMPREG(HDMI_V_BLANK_F5_1);
848 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0);
849 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1);
850 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0);
851 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1);
852 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0);
853 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1);
854 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0);
855 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1);
857 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0);
858 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1);
859 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0);
860 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1);
861 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0);
862 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1);
863 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0);
864 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1);
866 DUMPREG(HDMI_VACT_SPACE_1_0);
867 DUMPREG(HDMI_VACT_SPACE_1_1);
868 DUMPREG(HDMI_VACT_SPACE_2_0);
869 DUMPREG(HDMI_VACT_SPACE_2_1);
870 DUMPREG(HDMI_VACT_SPACE_3_0);
871 DUMPREG(HDMI_VACT_SPACE_3_1);
872 DUMPREG(HDMI_VACT_SPACE_4_0);
873 DUMPREG(HDMI_VACT_SPACE_4_1);
874 DUMPREG(HDMI_VACT_SPACE_5_0);
875 DUMPREG(HDMI_VACT_SPACE_5_1);
876 DUMPREG(HDMI_VACT_SPACE_6_0);
877 DUMPREG(HDMI_VACT_SPACE_6_1);
879 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
880 DUMPREG(HDMI_TG_CMD);
881 DUMPREG(HDMI_TG_H_FSZ_L);
882 DUMPREG(HDMI_TG_H_FSZ_H);
883 DUMPREG(HDMI_TG_HACT_ST_L);
884 DUMPREG(HDMI_TG_HACT_ST_H);
885 DUMPREG(HDMI_TG_HACT_SZ_L);
886 DUMPREG(HDMI_TG_HACT_SZ_H);
887 DUMPREG(HDMI_TG_V_FSZ_L);
888 DUMPREG(HDMI_TG_V_FSZ_H);
889 DUMPREG(HDMI_TG_VSYNC_L);
890 DUMPREG(HDMI_TG_VSYNC_H);
891 DUMPREG(HDMI_TG_VSYNC2_L);
892 DUMPREG(HDMI_TG_VSYNC2_H);
893 DUMPREG(HDMI_TG_VACT_ST_L);
894 DUMPREG(HDMI_TG_VACT_ST_H);
895 DUMPREG(HDMI_TG_VACT_SZ_L);
896 DUMPREG(HDMI_TG_VACT_SZ_H);
897 DUMPREG(HDMI_TG_FIELD_CHG_L);
898 DUMPREG(HDMI_TG_FIELD_CHG_H);
899 DUMPREG(HDMI_TG_VACT_ST2_L);
900 DUMPREG(HDMI_TG_VACT_ST2_H);
901 DUMPREG(HDMI_TG_VACT_ST3_L);
902 DUMPREG(HDMI_TG_VACT_ST3_H);
903 DUMPREG(HDMI_TG_VACT_ST4_L);
904 DUMPREG(HDMI_TG_VACT_ST4_H);
905 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
906 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
907 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
908 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
909 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
910 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
911 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
912 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
913 DUMPREG(HDMI_TG_3D);
915 DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix);
916 DUMPREG(HDMI_AVI_CON);
917 DUMPREG(HDMI_AVI_HEADER0);
918 DUMPREG(HDMI_AVI_HEADER1);
919 DUMPREG(HDMI_AVI_HEADER2);
920 DUMPREG(HDMI_AVI_CHECK_SUM);
921 DUMPREG(HDMI_VSI_CON);
922 DUMPREG(HDMI_VSI_HEADER0);
923 DUMPREG(HDMI_VSI_HEADER1);
924 DUMPREG(HDMI_VSI_HEADER2);
925 for (i = 0; i < 7; ++i)
926 DUMPREG(HDMI_VSI_DATA(i));
928 #undef DUMPREG
931 static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
933 if (hdata->type == HDMI_TYPE13)
934 hdmi_v13_regs_dump(hdata, prefix);
935 else
936 hdmi_v14_regs_dump(hdata, prefix);
939 static u8 hdmi_chksum(struct hdmi_context *hdata,
940 u32 start, u8 len, u32 hdr_sum)
942 int i;
944 /* hdr_sum : header0 + header1 + header2
945 * start : start address of packet byte1
946 * len : packet bytes - 1 */
947 for (i = 0; i < len; ++i)
948 hdr_sum += 0xff & hdmi_reg_read(hdata, start + i * 4);
950 /* return 2's complement of 8 bit hdr_sum */
951 return (u8)(~(hdr_sum & 0xff) + 1);
954 static void hdmi_reg_infoframe(struct hdmi_context *hdata,
955 union hdmi_infoframe *infoframe)
957 u32 hdr_sum;
958 u8 chksum;
959 u32 mod;
960 u32 vic;
962 mod = hdmi_reg_read(hdata, HDMI_MODE_SEL);
963 if (hdata->dvi_mode) {
964 hdmi_reg_writeb(hdata, HDMI_VSI_CON,
965 HDMI_VSI_CON_DO_NOT_TRANSMIT);
966 hdmi_reg_writeb(hdata, HDMI_AVI_CON,
967 HDMI_AVI_CON_DO_NOT_TRANSMIT);
968 hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_NO_TRAN);
969 return;
972 switch (infoframe->any.type) {
973 case HDMI_INFOFRAME_TYPE_AVI:
974 hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC);
975 hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->any.type);
976 hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1,
977 infoframe->any.version);
978 hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->any.length);
979 hdr_sum = infoframe->any.type + infoframe->any.version +
980 infoframe->any.length;
982 /* Output format zero hardcoded ,RGB YBCR selection */
983 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 |
984 AVI_ACTIVE_FORMAT_VALID |
985 AVI_UNDERSCANNED_DISPLAY_VALID);
988 * Set the aspect ratio as per the mode, mentioned in
989 * Table 9 AVI InfoFrame Data Byte 2 of CEA-861-D Standard
991 switch (hdata->mode_conf.aspect_ratio) {
992 case HDMI_PICTURE_ASPECT_4_3:
993 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2),
994 hdata->mode_conf.aspect_ratio |
995 AVI_4_3_CENTER_RATIO);
996 break;
997 case HDMI_PICTURE_ASPECT_16_9:
998 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2),
999 hdata->mode_conf.aspect_ratio |
1000 AVI_16_9_CENTER_RATIO);
1001 break;
1002 case HDMI_PICTURE_ASPECT_NONE:
1003 default:
1004 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2),
1005 hdata->mode_conf.aspect_ratio |
1006 AVI_SAME_AS_PIC_ASPECT_RATIO);
1007 break;
1010 vic = hdata->mode_conf.cea_video_id;
1011 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), vic);
1013 chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1),
1014 infoframe->any.length, hdr_sum);
1015 DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum);
1016 hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum);
1017 break;
1018 case HDMI_INFOFRAME_TYPE_AUDIO:
1019 hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02);
1020 hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->any.type);
1021 hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1,
1022 infoframe->any.version);
1023 hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->any.length);
1024 hdr_sum = infoframe->any.type + infoframe->any.version +
1025 infoframe->any.length;
1026 chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1),
1027 infoframe->any.length, hdr_sum);
1028 DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum);
1029 hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum);
1030 break;
1031 default:
1032 break;
1036 static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
1037 bool force)
1039 struct hdmi_context *hdata = ctx_from_connector(connector);
1041 hdata->hpd = gpio_get_value(hdata->hpd_gpio);
1043 return hdata->hpd ? connector_status_connected :
1044 connector_status_disconnected;
1047 static void hdmi_connector_destroy(struct drm_connector *connector)
1049 drm_connector_unregister(connector);
1050 drm_connector_cleanup(connector);
1053 static struct drm_connector_funcs hdmi_connector_funcs = {
1054 .dpms = drm_atomic_helper_connector_dpms,
1055 .fill_modes = drm_helper_probe_single_connector_modes,
1056 .detect = hdmi_detect,
1057 .destroy = hdmi_connector_destroy,
1058 .reset = drm_atomic_helper_connector_reset,
1059 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1060 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1063 static int hdmi_get_modes(struct drm_connector *connector)
1065 struct hdmi_context *hdata = ctx_from_connector(connector);
1066 struct edid *edid;
1067 int ret;
1069 if (!hdata->ddc_adpt)
1070 return -ENODEV;
1072 edid = drm_get_edid(connector, hdata->ddc_adpt);
1073 if (!edid)
1074 return -ENODEV;
1076 hdata->dvi_mode = !drm_detect_hdmi_monitor(edid);
1077 DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
1078 (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
1079 edid->width_cm, edid->height_cm);
1081 drm_mode_connector_update_edid_property(connector, edid);
1083 ret = drm_add_edid_modes(connector, edid);
1085 kfree(edid);
1087 return ret;
1090 static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
1092 int i;
1094 for (i = 0; i < hdata->phy_conf_count; i++)
1095 if (hdata->phy_confs[i].pixel_clock == pixel_clock)
1096 return i;
1098 DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
1099 return -EINVAL;
1102 static int hdmi_mode_valid(struct drm_connector *connector,
1103 struct drm_display_mode *mode)
1105 struct hdmi_context *hdata = ctx_from_connector(connector);
1106 int ret;
1108 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
1109 mode->hdisplay, mode->vdisplay, mode->vrefresh,
1110 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
1111 false, mode->clock * 1000);
1113 ret = mixer_check_mode(mode);
1114 if (ret)
1115 return MODE_BAD;
1117 ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
1118 if (ret < 0)
1119 return MODE_BAD;
1121 return MODE_OK;
1124 static struct drm_encoder *hdmi_best_encoder(struct drm_connector *connector)
1126 struct hdmi_context *hdata = ctx_from_connector(connector);
1128 return hdata->encoder;
1131 static struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
1132 .get_modes = hdmi_get_modes,
1133 .mode_valid = hdmi_mode_valid,
1134 .best_encoder = hdmi_best_encoder,
1137 static int hdmi_create_connector(struct exynos_drm_display *display,
1138 struct drm_encoder *encoder)
1140 struct hdmi_context *hdata = display_to_hdmi(display);
1141 struct drm_connector *connector = &hdata->connector;
1142 int ret;
1144 hdata->encoder = encoder;
1145 connector->interlace_allowed = true;
1146 connector->polled = DRM_CONNECTOR_POLL_HPD;
1148 ret = drm_connector_init(hdata->drm_dev, connector,
1149 &hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA);
1150 if (ret) {
1151 DRM_ERROR("Failed to initialize connector with drm\n");
1152 return ret;
1155 drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
1156 drm_connector_register(connector);
1157 drm_mode_connector_attach_encoder(connector, encoder);
1159 return 0;
1162 static void hdmi_mode_fixup(struct exynos_drm_display *display,
1163 struct drm_connector *connector,
1164 const struct drm_display_mode *mode,
1165 struct drm_display_mode *adjusted_mode)
1167 struct drm_display_mode *m;
1168 int mode_ok;
1170 DRM_DEBUG_KMS("%s\n", __FILE__);
1172 drm_mode_set_crtcinfo(adjusted_mode, 0);
1174 mode_ok = hdmi_mode_valid(connector, adjusted_mode);
1176 /* just return if user desired mode exists. */
1177 if (mode_ok == MODE_OK)
1178 return;
1181 * otherwise, find the most suitable mode among modes and change it
1182 * to adjusted_mode.
1184 list_for_each_entry(m, &connector->modes, head) {
1185 mode_ok = hdmi_mode_valid(connector, m);
1187 if (mode_ok == MODE_OK) {
1188 DRM_INFO("desired mode doesn't exist so\n");
1189 DRM_INFO("use the most suitable mode among modes.\n");
1191 DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n",
1192 m->hdisplay, m->vdisplay, m->vrefresh);
1194 drm_mode_copy(adjusted_mode, m);
1195 break;
1200 static void hdmi_set_acr(u32 freq, u8 *acr)
1202 u32 n, cts;
1204 switch (freq) {
1205 case 32000:
1206 n = 4096;
1207 cts = 27000;
1208 break;
1209 case 44100:
1210 n = 6272;
1211 cts = 30000;
1212 break;
1213 case 88200:
1214 n = 12544;
1215 cts = 30000;
1216 break;
1217 case 176400:
1218 n = 25088;
1219 cts = 30000;
1220 break;
1221 case 48000:
1222 n = 6144;
1223 cts = 27000;
1224 break;
1225 case 96000:
1226 n = 12288;
1227 cts = 27000;
1228 break;
1229 case 192000:
1230 n = 24576;
1231 cts = 27000;
1232 break;
1233 default:
1234 n = 0;
1235 cts = 0;
1236 break;
1239 acr[1] = cts >> 16;
1240 acr[2] = cts >> 8 & 0xff;
1241 acr[3] = cts & 0xff;
1243 acr[4] = n >> 16;
1244 acr[5] = n >> 8 & 0xff;
1245 acr[6] = n & 0xff;
1248 static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr)
1250 hdmi_reg_writeb(hdata, HDMI_ACR_N0, acr[6]);
1251 hdmi_reg_writeb(hdata, HDMI_ACR_N1, acr[5]);
1252 hdmi_reg_writeb(hdata, HDMI_ACR_N2, acr[4]);
1253 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS0, acr[3]);
1254 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS1, acr[2]);
1255 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS2, acr[1]);
1256 hdmi_reg_writeb(hdata, HDMI_ACR_CTS0, acr[3]);
1257 hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]);
1258 hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]);
1260 if (hdata->type == HDMI_TYPE13)
1261 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4);
1262 else
1263 hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1266 static void hdmi_audio_init(struct hdmi_context *hdata)
1268 u32 sample_rate, bits_per_sample;
1269 u32 data_num, bit_ch, sample_frq;
1270 u32 val;
1271 u8 acr[7];
1273 sample_rate = 44100;
1274 bits_per_sample = 16;
1276 switch (bits_per_sample) {
1277 case 20:
1278 data_num = 2;
1279 bit_ch = 1;
1280 break;
1281 case 24:
1282 data_num = 3;
1283 bit_ch = 1;
1284 break;
1285 default:
1286 data_num = 1;
1287 bit_ch = 0;
1288 break;
1291 hdmi_set_acr(sample_rate, acr);
1292 hdmi_reg_acr(hdata, acr);
1294 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1295 | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1296 | HDMI_I2S_MUX_ENABLE);
1298 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1299 | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1301 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1303 sample_frq = (sample_rate == 44100) ? 0 :
1304 (sample_rate == 48000) ? 2 :
1305 (sample_rate == 32000) ? 3 :
1306 (sample_rate == 96000) ? 0xa : 0x0;
1308 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1309 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1311 val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1312 hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1314 /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1315 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1316 | HDMI_I2S_SEL_LRCK(6));
1317 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1318 | HDMI_I2S_SEL_SDATA2(4));
1319 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1320 | HDMI_I2S_SEL_SDATA2(2));
1321 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1323 /* I2S_CON_1 & 2 */
1324 hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1325 | HDMI_I2S_L_CH_LOW_POL);
1326 hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1327 | HDMI_I2S_SET_BIT_CH(bit_ch)
1328 | HDMI_I2S_SET_SDATA_BIT(data_num)
1329 | HDMI_I2S_BASIC_FORMAT);
1331 /* Configure register related to CUV information */
1332 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
1333 | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1334 | HDMI_I2S_COPYRIGHT
1335 | HDMI_I2S_LINEAR_PCM
1336 | HDMI_I2S_CONSUMER_FORMAT);
1337 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1338 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1339 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1340 | HDMI_I2S_SET_SMP_FREQ(sample_frq));
1341 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1342 HDMI_I2S_ORG_SMP_FREQ_44_1
1343 | HDMI_I2S_WORD_LEN_MAX24_24BITS
1344 | HDMI_I2S_WORD_LEN_MAX_24BITS);
1346 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1349 static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1351 if (hdata->dvi_mode)
1352 return;
1354 hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
1355 hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ?
1356 HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1359 static void hdmi_start(struct hdmi_context *hdata, bool start)
1361 u32 val = start ? HDMI_TG_EN : 0;
1363 if (hdata->current_mode.flags & DRM_MODE_FLAG_INTERLACE)
1364 val |= HDMI_FIELD_EN;
1366 hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN);
1367 hdmi_reg_writemask(hdata, HDMI_TG_CMD, val, HDMI_TG_EN | HDMI_FIELD_EN);
1370 static void hdmi_conf_init(struct hdmi_context *hdata)
1372 union hdmi_infoframe infoframe;
1374 /* disable HPD interrupts from HDMI IP block, use GPIO instead */
1375 hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1376 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1378 /* choose HDMI mode */
1379 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1380 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1381 /* Apply Video preable and Guard band in HDMI mode only */
1382 hdmi_reg_writeb(hdata, HDMI_CON_2, 0);
1383 /* disable bluescreen */
1384 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1386 if (hdata->dvi_mode) {
1387 /* choose DVI mode */
1388 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1389 HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1390 hdmi_reg_writeb(hdata, HDMI_CON_2,
1391 HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1394 if (hdata->type == HDMI_TYPE13) {
1395 /* choose bluescreen (fecal) color */
1396 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1397 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1398 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1400 /* enable AVI packet every vsync, fixes purple line problem */
1401 hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1402 /* force RGB, look to CEA-861-D, table 7 for more detail */
1403 hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1404 hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1406 hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1407 hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1408 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1409 } else {
1410 infoframe.any.type = HDMI_INFOFRAME_TYPE_AVI;
1411 infoframe.any.version = HDMI_AVI_VERSION;
1412 infoframe.any.length = HDMI_AVI_LENGTH;
1413 hdmi_reg_infoframe(hdata, &infoframe);
1415 infoframe.any.type = HDMI_INFOFRAME_TYPE_AUDIO;
1416 infoframe.any.version = HDMI_AUI_VERSION;
1417 infoframe.any.length = HDMI_AUI_LENGTH;
1418 hdmi_reg_infoframe(hdata, &infoframe);
1420 /* enable AVI packet every vsync, fixes purple line problem */
1421 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1425 static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1427 const struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v13_conf.tg;
1428 const struct hdmi_v13_core_regs *core =
1429 &hdata->mode_conf.conf.v13_conf.core;
1430 int tries;
1432 /* setting core registers */
1433 hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1434 hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1435 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_0, core->v_blank[0]);
1436 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_1, core->v_blank[1]);
1437 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_2, core->v_blank[2]);
1438 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_0, core->h_v_line[0]);
1439 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_1, core->h_v_line[1]);
1440 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_2, core->h_v_line[2]);
1441 hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1442 hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1443 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_0, core->v_blank_f[0]);
1444 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_1, core->v_blank_f[1]);
1445 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_2, core->v_blank_f[2]);
1446 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_0, core->h_sync_gen[0]);
1447 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_1, core->h_sync_gen[1]);
1448 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_2, core->h_sync_gen[2]);
1449 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_0, core->v_sync_gen1[0]);
1450 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_1, core->v_sync_gen1[1]);
1451 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_2, core->v_sync_gen1[2]);
1452 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_0, core->v_sync_gen2[0]);
1453 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_1, core->v_sync_gen2[1]);
1454 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_2, core->v_sync_gen2[2]);
1455 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_0, core->v_sync_gen3[0]);
1456 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]);
1457 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]);
1458 /* Timing generator registers */
1459 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz[0]);
1460 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz[1]);
1461 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st[0]);
1462 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st[1]);
1463 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz[0]);
1464 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz[1]);
1465 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz[0]);
1466 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz[1]);
1467 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync[0]);
1468 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync[1]);
1469 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2[0]);
1470 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2[1]);
1471 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st[0]);
1472 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st[1]);
1473 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz[0]);
1474 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz[1]);
1475 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg[0]);
1476 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg[1]);
1477 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2[0]);
1478 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2[1]);
1479 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi[0]);
1480 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi[1]);
1481 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi[0]);
1482 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi[1]);
1483 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi[0]);
1484 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi[1]);
1485 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi[0]);
1486 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi[1]);
1488 /* waiting for HDMIPHY's PLL to get to steady state */
1489 for (tries = 100; tries; --tries) {
1490 u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS);
1491 if (val & HDMI_PHY_STATUS_READY)
1492 break;
1493 usleep_range(1000, 2000);
1495 /* steady state not achieved */
1496 if (tries == 0) {
1497 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1498 hdmi_regs_dump(hdata, "timing apply");
1501 clk_disable_unprepare(hdata->res.sclk_hdmi);
1502 clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_hdmiphy);
1503 clk_prepare_enable(hdata->res.sclk_hdmi);
1505 /* enable HDMI and timing generator */
1506 hdmi_start(hdata, true);
1509 static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1511 const struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v14_conf.tg;
1512 const struct hdmi_v14_core_regs *core =
1513 &hdata->mode_conf.conf.v14_conf.core;
1514 int tries;
1516 /* setting core registers */
1517 hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1518 hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1519 hdmi_reg_writeb(hdata, HDMI_V2_BLANK_0, core->v2_blank[0]);
1520 hdmi_reg_writeb(hdata, HDMI_V2_BLANK_1, core->v2_blank[1]);
1521 hdmi_reg_writeb(hdata, HDMI_V1_BLANK_0, core->v1_blank[0]);
1522 hdmi_reg_writeb(hdata, HDMI_V1_BLANK_1, core->v1_blank[1]);
1523 hdmi_reg_writeb(hdata, HDMI_V_LINE_0, core->v_line[0]);
1524 hdmi_reg_writeb(hdata, HDMI_V_LINE_1, core->v_line[1]);
1525 hdmi_reg_writeb(hdata, HDMI_H_LINE_0, core->h_line[0]);
1526 hdmi_reg_writeb(hdata, HDMI_H_LINE_1, core->h_line[1]);
1527 hdmi_reg_writeb(hdata, HDMI_HSYNC_POL, core->hsync_pol[0]);
1528 hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1529 hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1530 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_0, core->v_blank_f0[0]);
1531 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_1, core->v_blank_f0[1]);
1532 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_0, core->v_blank_f1[0]);
1533 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_1, core->v_blank_f1[1]);
1534 hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_0, core->h_sync_start[0]);
1535 hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_1, core->h_sync_start[1]);
1536 hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_0, core->h_sync_end[0]);
1537 hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_1, core->h_sync_end[1]);
1538 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_0,
1539 core->v_sync_line_bef_2[0]);
1540 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_1,
1541 core->v_sync_line_bef_2[1]);
1542 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_0,
1543 core->v_sync_line_bef_1[0]);
1544 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_1,
1545 core->v_sync_line_bef_1[1]);
1546 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_0,
1547 core->v_sync_line_aft_2[0]);
1548 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_1,
1549 core->v_sync_line_aft_2[1]);
1550 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_0,
1551 core->v_sync_line_aft_1[0]);
1552 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_1,
1553 core->v_sync_line_aft_1[1]);
1554 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0,
1555 core->v_sync_line_aft_pxl_2[0]);
1556 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_1,
1557 core->v_sync_line_aft_pxl_2[1]);
1558 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0,
1559 core->v_sync_line_aft_pxl_1[0]);
1560 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_1,
1561 core->v_sync_line_aft_pxl_1[1]);
1562 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_0, core->v_blank_f2[0]);
1563 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_1, core->v_blank_f2[1]);
1564 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_0, core->v_blank_f3[0]);
1565 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_1, core->v_blank_f3[1]);
1566 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_0, core->v_blank_f4[0]);
1567 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_1, core->v_blank_f4[1]);
1568 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_0, core->v_blank_f5[0]);
1569 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_1, core->v_blank_f5[1]);
1570 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_0,
1571 core->v_sync_line_aft_3[0]);
1572 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_1,
1573 core->v_sync_line_aft_3[1]);
1574 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_0,
1575 core->v_sync_line_aft_4[0]);
1576 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_1,
1577 core->v_sync_line_aft_4[1]);
1578 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_0,
1579 core->v_sync_line_aft_5[0]);
1580 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_1,
1581 core->v_sync_line_aft_5[1]);
1582 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_0,
1583 core->v_sync_line_aft_6[0]);
1584 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_1,
1585 core->v_sync_line_aft_6[1]);
1586 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0,
1587 core->v_sync_line_aft_pxl_3[0]);
1588 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_1,
1589 core->v_sync_line_aft_pxl_3[1]);
1590 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0,
1591 core->v_sync_line_aft_pxl_4[0]);
1592 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_1,
1593 core->v_sync_line_aft_pxl_4[1]);
1594 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0,
1595 core->v_sync_line_aft_pxl_5[0]);
1596 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_1,
1597 core->v_sync_line_aft_pxl_5[1]);
1598 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0,
1599 core->v_sync_line_aft_pxl_6[0]);
1600 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_1,
1601 core->v_sync_line_aft_pxl_6[1]);
1602 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_0, core->vact_space_1[0]);
1603 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_1, core->vact_space_1[1]);
1604 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_0, core->vact_space_2[0]);
1605 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_1, core->vact_space_2[1]);
1606 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_0, core->vact_space_3[0]);
1607 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_1, core->vact_space_3[1]);
1608 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_0, core->vact_space_4[0]);
1609 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_1, core->vact_space_4[1]);
1610 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_0, core->vact_space_5[0]);
1611 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_1, core->vact_space_5[1]);
1612 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_0, core->vact_space_6[0]);
1613 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]);
1615 /* Timing generator registers */
1616 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz[0]);
1617 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz[1]);
1618 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st[0]);
1619 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st[1]);
1620 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz[0]);
1621 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz[1]);
1622 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz[0]);
1623 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz[1]);
1624 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync[0]);
1625 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync[1]);
1626 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2[0]);
1627 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2[1]);
1628 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st[0]);
1629 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st[1]);
1630 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz[0]);
1631 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz[1]);
1632 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg[0]);
1633 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg[1]);
1634 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2[0]);
1635 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2[1]);
1636 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3[0]);
1637 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3[1]);
1638 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4[0]);
1639 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4[1]);
1640 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi[0]);
1641 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi[1]);
1642 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi[0]);
1643 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi[1]);
1644 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi[0]);
1645 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi[1]);
1646 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi[0]);
1647 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi[1]);
1648 hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d[0]);
1650 /* waiting for HDMIPHY's PLL to get to steady state */
1651 for (tries = 100; tries; --tries) {
1652 u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0);
1653 if (val & HDMI_PHY_STATUS_READY)
1654 break;
1655 usleep_range(1000, 2000);
1657 /* steady state not achieved */
1658 if (tries == 0) {
1659 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1660 hdmi_regs_dump(hdata, "timing apply");
1663 clk_disable_unprepare(hdata->res.sclk_hdmi);
1664 clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_hdmiphy);
1665 clk_prepare_enable(hdata->res.sclk_hdmi);
1667 /* enable HDMI and timing generator */
1668 hdmi_start(hdata, true);
1671 static void hdmi_mode_apply(struct hdmi_context *hdata)
1673 if (hdata->type == HDMI_TYPE13)
1674 hdmi_v13_mode_apply(hdata);
1675 else
1676 hdmi_v14_mode_apply(hdata);
1679 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1681 u32 reg;
1683 clk_disable_unprepare(hdata->res.sclk_hdmi);
1684 clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_pixel);
1685 clk_prepare_enable(hdata->res.sclk_hdmi);
1687 /* operation mode */
1688 hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1689 HDMI_PHY_ENABLE_MODE_SET);
1691 if (hdata->type == HDMI_TYPE13)
1692 reg = HDMI_V13_PHY_RSTOUT;
1693 else
1694 reg = HDMI_PHY_RSTOUT;
1696 /* reset hdmiphy */
1697 hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT);
1698 usleep_range(10000, 12000);
1699 hdmi_reg_writemask(hdata, reg, 0, HDMI_PHY_SW_RSTOUT);
1700 usleep_range(10000, 12000);
1703 static void hdmiphy_poweron(struct hdmi_context *hdata)
1705 if (hdata->type != HDMI_TYPE14)
1706 return;
1708 DRM_DEBUG_KMS("\n");
1710 /* For PHY Mode Setting */
1711 hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1712 HDMI_PHY_ENABLE_MODE_SET);
1713 /* Phy Power On */
1714 hdmiphy_reg_writeb(hdata, HDMIPHY_POWER,
1715 HDMI_PHY_POWER_ON);
1716 /* For PHY Mode Setting */
1717 hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1718 HDMI_PHY_DISABLE_MODE_SET);
1719 /* PHY SW Reset */
1720 hdmiphy_conf_reset(hdata);
1723 static void hdmiphy_poweroff(struct hdmi_context *hdata)
1725 if (hdata->type != HDMI_TYPE14)
1726 return;
1728 DRM_DEBUG_KMS("\n");
1730 /* PHY SW Reset */
1731 hdmiphy_conf_reset(hdata);
1732 /* For PHY Mode Setting */
1733 hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1734 HDMI_PHY_ENABLE_MODE_SET);
1736 /* PHY Power Off */
1737 hdmiphy_reg_writeb(hdata, HDMIPHY_POWER,
1738 HDMI_PHY_POWER_OFF);
1740 /* For PHY Mode Setting */
1741 hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1742 HDMI_PHY_DISABLE_MODE_SET);
1745 static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1747 int ret;
1748 int i;
1750 /* pixel clock */
1751 i = hdmi_find_phy_conf(hdata, hdata->mode_conf.pixel_clock);
1752 if (i < 0) {
1753 DRM_ERROR("failed to find hdmiphy conf\n");
1754 return;
1757 ret = hdmiphy_reg_write_buf(hdata, 0, hdata->phy_confs[i].conf, 32);
1758 if (ret) {
1759 DRM_ERROR("failed to configure hdmiphy\n");
1760 return;
1763 usleep_range(10000, 12000);
1765 ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1766 HDMI_PHY_DISABLE_MODE_SET);
1767 if (ret) {
1768 DRM_ERROR("failed to enable hdmiphy\n");
1769 return;
1774 static void hdmi_conf_apply(struct hdmi_context *hdata)
1776 hdmiphy_conf_reset(hdata);
1777 hdmiphy_conf_apply(hdata);
1779 mutex_lock(&hdata->hdmi_mutex);
1780 hdmi_start(hdata, false);
1781 hdmi_conf_init(hdata);
1782 mutex_unlock(&hdata->hdmi_mutex);
1784 hdmi_audio_init(hdata);
1786 /* setting core registers */
1787 hdmi_mode_apply(hdata);
1788 hdmi_audio_control(hdata, true);
1790 hdmi_regs_dump(hdata, "start");
1793 static void hdmi_set_reg(u8 *reg_pair, int num_bytes, u32 value)
1795 int i;
1796 BUG_ON(num_bytes > 4);
1797 for (i = 0; i < num_bytes; i++)
1798 reg_pair[i] = (value >> (8 * i)) & 0xff;
1801 static void hdmi_v13_mode_set(struct hdmi_context *hdata,
1802 struct drm_display_mode *m)
1804 struct hdmi_v13_core_regs *core = &hdata->mode_conf.conf.v13_conf.core;
1805 struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v13_conf.tg;
1806 unsigned int val;
1808 hdata->mode_conf.cea_video_id =
1809 drm_match_cea_mode((struct drm_display_mode *)m);
1810 hdata->mode_conf.pixel_clock = m->clock * 1000;
1811 hdata->mode_conf.aspect_ratio = m->picture_aspect_ratio;
1813 hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
1814 hdmi_set_reg(core->h_v_line, 3, (m->htotal << 12) | m->vtotal);
1816 val = (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
1817 hdmi_set_reg(core->vsync_pol, 1, val);
1819 val = (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0;
1820 hdmi_set_reg(core->int_pro_mode, 1, val);
1822 val = (m->hsync_start - m->hdisplay - 2);
1823 val |= ((m->hsync_end - m->hdisplay - 2) << 10);
1824 val |= ((m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0)<<20;
1825 hdmi_set_reg(core->h_sync_gen, 3, val);
1828 * Quirk requirement for exynos HDMI IP design,
1829 * 2 pixels less than the actual calculation for hsync_start
1830 * and end.
1833 /* Following values & calculations differ for different type of modes */
1834 if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1835 /* Interlaced Mode */
1836 val = ((m->vsync_end - m->vdisplay) / 2);
1837 val |= ((m->vsync_start - m->vdisplay) / 2) << 12;
1838 hdmi_set_reg(core->v_sync_gen1, 3, val);
1840 val = m->vtotal / 2;
1841 val |= ((m->vtotal - m->vdisplay) / 2) << 11;
1842 hdmi_set_reg(core->v_blank, 3, val);
1844 val = (m->vtotal +
1845 ((m->vsync_end - m->vsync_start) * 4) + 5) / 2;
1846 val |= m->vtotal << 11;
1847 hdmi_set_reg(core->v_blank_f, 3, val);
1849 val = ((m->vtotal / 2) + 7);
1850 val |= ((m->vtotal / 2) + 2) << 12;
1851 hdmi_set_reg(core->v_sync_gen2, 3, val);
1853 val = ((m->htotal / 2) + (m->hsync_start - m->hdisplay));
1854 val |= ((m->htotal / 2) +
1855 (m->hsync_start - m->hdisplay)) << 12;
1856 hdmi_set_reg(core->v_sync_gen3, 3, val);
1858 hdmi_set_reg(tg->vact_st, 2, (m->vtotal - m->vdisplay) / 2);
1859 hdmi_set_reg(tg->vact_sz, 2, m->vdisplay / 2);
1861 hdmi_set_reg(tg->vact_st2, 2, 0x249);/* Reset value + 1*/
1862 } else {
1863 /* Progressive Mode */
1865 val = m->vtotal;
1866 val |= (m->vtotal - m->vdisplay) << 11;
1867 hdmi_set_reg(core->v_blank, 3, val);
1869 hdmi_set_reg(core->v_blank_f, 3, 0);
1871 val = (m->vsync_end - m->vdisplay);
1872 val |= ((m->vsync_start - m->vdisplay) << 12);
1873 hdmi_set_reg(core->v_sync_gen1, 3, val);
1875 hdmi_set_reg(core->v_sync_gen2, 3, 0x1001);/* Reset value */
1876 hdmi_set_reg(core->v_sync_gen3, 3, 0x1001);/* Reset value */
1877 hdmi_set_reg(tg->vact_st, 2, m->vtotal - m->vdisplay);
1878 hdmi_set_reg(tg->vact_sz, 2, m->vdisplay);
1879 hdmi_set_reg(tg->vact_st2, 2, 0x248); /* Reset value */
1882 /* Timing generator registers */
1883 hdmi_set_reg(tg->cmd, 1, 0x0);
1884 hdmi_set_reg(tg->h_fsz, 2, m->htotal);
1885 hdmi_set_reg(tg->hact_st, 2, m->htotal - m->hdisplay);
1886 hdmi_set_reg(tg->hact_sz, 2, m->hdisplay);
1887 hdmi_set_reg(tg->v_fsz, 2, m->vtotal);
1888 hdmi_set_reg(tg->vsync, 2, 0x1);
1889 hdmi_set_reg(tg->vsync2, 2, 0x233); /* Reset value */
1890 hdmi_set_reg(tg->field_chg, 2, 0x233); /* Reset value */
1891 hdmi_set_reg(tg->vsync_top_hdmi, 2, 0x1); /* Reset value */
1892 hdmi_set_reg(tg->vsync_bot_hdmi, 2, 0x233); /* Reset value */
1893 hdmi_set_reg(tg->field_top_hdmi, 2, 0x1); /* Reset value */
1894 hdmi_set_reg(tg->field_bot_hdmi, 2, 0x233); /* Reset value */
1895 hdmi_set_reg(tg->tg_3d, 1, 0x0); /* Not used */
1898 static void hdmi_v14_mode_set(struct hdmi_context *hdata,
1899 struct drm_display_mode *m)
1901 struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v14_conf.tg;
1902 struct hdmi_v14_core_regs *core =
1903 &hdata->mode_conf.conf.v14_conf.core;
1905 hdata->mode_conf.cea_video_id =
1906 drm_match_cea_mode((struct drm_display_mode *)m);
1907 hdata->mode_conf.pixel_clock = m->clock * 1000;
1908 hdata->mode_conf.aspect_ratio = m->picture_aspect_ratio;
1910 hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
1911 hdmi_set_reg(core->v_line, 2, m->vtotal);
1912 hdmi_set_reg(core->h_line, 2, m->htotal);
1913 hdmi_set_reg(core->hsync_pol, 1,
1914 (m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0);
1915 hdmi_set_reg(core->vsync_pol, 1,
1916 (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
1917 hdmi_set_reg(core->int_pro_mode, 1,
1918 (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1921 * Quirk requirement for exynos 5 HDMI IP design,
1922 * 2 pixels less than the actual calculation for hsync_start
1923 * and end.
1926 /* Following values & calculations differ for different type of modes */
1927 if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1928 /* Interlaced Mode */
1929 hdmi_set_reg(core->v_sync_line_bef_2, 2,
1930 (m->vsync_end - m->vdisplay) / 2);
1931 hdmi_set_reg(core->v_sync_line_bef_1, 2,
1932 (m->vsync_start - m->vdisplay) / 2);
1933 hdmi_set_reg(core->v2_blank, 2, m->vtotal / 2);
1934 hdmi_set_reg(core->v1_blank, 2, (m->vtotal - m->vdisplay) / 2);
1935 hdmi_set_reg(core->v_blank_f0, 2, m->vtotal - m->vdisplay / 2);
1936 hdmi_set_reg(core->v_blank_f1, 2, m->vtotal);
1937 hdmi_set_reg(core->v_sync_line_aft_2, 2, (m->vtotal / 2) + 7);
1938 hdmi_set_reg(core->v_sync_line_aft_1, 2, (m->vtotal / 2) + 2);
1939 hdmi_set_reg(core->v_sync_line_aft_pxl_2, 2,
1940 (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1941 hdmi_set_reg(core->v_sync_line_aft_pxl_1, 2,
1942 (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1943 hdmi_set_reg(tg->vact_st, 2, (m->vtotal - m->vdisplay) / 2);
1944 hdmi_set_reg(tg->vact_sz, 2, m->vdisplay / 2);
1945 hdmi_set_reg(tg->vact_st2, 2, m->vtotal - m->vdisplay / 2);
1946 hdmi_set_reg(tg->vsync2, 2, (m->vtotal / 2) + 1);
1947 hdmi_set_reg(tg->vsync_bot_hdmi, 2, (m->vtotal / 2) + 1);
1948 hdmi_set_reg(tg->field_bot_hdmi, 2, (m->vtotal / 2) + 1);
1949 hdmi_set_reg(tg->vact_st3, 2, 0x0);
1950 hdmi_set_reg(tg->vact_st4, 2, 0x0);
1951 } else {
1952 /* Progressive Mode */
1953 hdmi_set_reg(core->v_sync_line_bef_2, 2,
1954 m->vsync_end - m->vdisplay);
1955 hdmi_set_reg(core->v_sync_line_bef_1, 2,
1956 m->vsync_start - m->vdisplay);
1957 hdmi_set_reg(core->v2_blank, 2, m->vtotal);
1958 hdmi_set_reg(core->v1_blank, 2, m->vtotal - m->vdisplay);
1959 hdmi_set_reg(core->v_blank_f0, 2, 0xffff);
1960 hdmi_set_reg(core->v_blank_f1, 2, 0xffff);
1961 hdmi_set_reg(core->v_sync_line_aft_2, 2, 0xffff);
1962 hdmi_set_reg(core->v_sync_line_aft_1, 2, 0xffff);
1963 hdmi_set_reg(core->v_sync_line_aft_pxl_2, 2, 0xffff);
1964 hdmi_set_reg(core->v_sync_line_aft_pxl_1, 2, 0xffff);
1965 hdmi_set_reg(tg->vact_st, 2, m->vtotal - m->vdisplay);
1966 hdmi_set_reg(tg->vact_sz, 2, m->vdisplay);
1967 hdmi_set_reg(tg->vact_st2, 2, 0x248); /* Reset value */
1968 hdmi_set_reg(tg->vact_st3, 2, 0x47b); /* Reset value */
1969 hdmi_set_reg(tg->vact_st4, 2, 0x6ae); /* Reset value */
1970 hdmi_set_reg(tg->vsync2, 2, 0x233); /* Reset value */
1971 hdmi_set_reg(tg->vsync_bot_hdmi, 2, 0x233); /* Reset value */
1972 hdmi_set_reg(tg->field_bot_hdmi, 2, 0x233); /* Reset value */
1975 /* Following values & calculations are same irrespective of mode type */
1976 hdmi_set_reg(core->h_sync_start, 2, m->hsync_start - m->hdisplay - 2);
1977 hdmi_set_reg(core->h_sync_end, 2, m->hsync_end - m->hdisplay - 2);
1978 hdmi_set_reg(core->vact_space_1, 2, 0xffff);
1979 hdmi_set_reg(core->vact_space_2, 2, 0xffff);
1980 hdmi_set_reg(core->vact_space_3, 2, 0xffff);
1981 hdmi_set_reg(core->vact_space_4, 2, 0xffff);
1982 hdmi_set_reg(core->vact_space_5, 2, 0xffff);
1983 hdmi_set_reg(core->vact_space_6, 2, 0xffff);
1984 hdmi_set_reg(core->v_blank_f2, 2, 0xffff);
1985 hdmi_set_reg(core->v_blank_f3, 2, 0xffff);
1986 hdmi_set_reg(core->v_blank_f4, 2, 0xffff);
1987 hdmi_set_reg(core->v_blank_f5, 2, 0xffff);
1988 hdmi_set_reg(core->v_sync_line_aft_3, 2, 0xffff);
1989 hdmi_set_reg(core->v_sync_line_aft_4, 2, 0xffff);
1990 hdmi_set_reg(core->v_sync_line_aft_5, 2, 0xffff);
1991 hdmi_set_reg(core->v_sync_line_aft_6, 2, 0xffff);
1992 hdmi_set_reg(core->v_sync_line_aft_pxl_3, 2, 0xffff);
1993 hdmi_set_reg(core->v_sync_line_aft_pxl_4, 2, 0xffff);
1994 hdmi_set_reg(core->v_sync_line_aft_pxl_5, 2, 0xffff);
1995 hdmi_set_reg(core->v_sync_line_aft_pxl_6, 2, 0xffff);
1997 /* Timing generator registers */
1998 hdmi_set_reg(tg->cmd, 1, 0x0);
1999 hdmi_set_reg(tg->h_fsz, 2, m->htotal);
2000 hdmi_set_reg(tg->hact_st, 2, m->htotal - m->hdisplay);
2001 hdmi_set_reg(tg->hact_sz, 2, m->hdisplay);
2002 hdmi_set_reg(tg->v_fsz, 2, m->vtotal);
2003 hdmi_set_reg(tg->vsync, 2, 0x1);
2004 hdmi_set_reg(tg->field_chg, 2, 0x233); /* Reset value */
2005 hdmi_set_reg(tg->vsync_top_hdmi, 2, 0x1); /* Reset value */
2006 hdmi_set_reg(tg->field_top_hdmi, 2, 0x1); /* Reset value */
2007 hdmi_set_reg(tg->tg_3d, 1, 0x0);
2010 static void hdmi_mode_set(struct exynos_drm_display *display,
2011 struct drm_display_mode *mode)
2013 struct hdmi_context *hdata = display_to_hdmi(display);
2014 struct drm_display_mode *m = mode;
2016 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n",
2017 m->hdisplay, m->vdisplay,
2018 m->vrefresh, (m->flags & DRM_MODE_FLAG_INTERLACE) ?
2019 "INTERLACED" : "PROGRESSIVE");
2021 /* preserve mode information for later use. */
2022 drm_mode_copy(&hdata->current_mode, mode);
2024 if (hdata->type == HDMI_TYPE13)
2025 hdmi_v13_mode_set(hdata, mode);
2026 else
2027 hdmi_v14_mode_set(hdata, mode);
2030 static void hdmi_commit(struct exynos_drm_display *display)
2032 struct hdmi_context *hdata = display_to_hdmi(display);
2034 mutex_lock(&hdata->hdmi_mutex);
2035 if (!hdata->powered) {
2036 mutex_unlock(&hdata->hdmi_mutex);
2037 return;
2039 mutex_unlock(&hdata->hdmi_mutex);
2041 hdmi_conf_apply(hdata);
2044 static void hdmi_poweron(struct hdmi_context *hdata)
2046 struct hdmi_resources *res = &hdata->res;
2048 mutex_lock(&hdata->hdmi_mutex);
2049 if (hdata->powered) {
2050 mutex_unlock(&hdata->hdmi_mutex);
2051 return;
2054 hdata->powered = true;
2056 mutex_unlock(&hdata->hdmi_mutex);
2058 pm_runtime_get_sync(hdata->dev);
2060 if (regulator_bulk_enable(res->regul_count, res->regul_bulk))
2061 DRM_DEBUG_KMS("failed to enable regulator bulk\n");
2063 /* set pmu hdmiphy control bit to enable hdmiphy */
2064 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
2065 PMU_HDMI_PHY_ENABLE_BIT, 1);
2067 clk_prepare_enable(res->hdmi);
2068 clk_prepare_enable(res->sclk_hdmi);
2070 hdmiphy_poweron(hdata);
2071 hdmi_commit(&hdata->display);
2074 static void hdmi_poweroff(struct hdmi_context *hdata)
2076 struct hdmi_resources *res = &hdata->res;
2078 mutex_lock(&hdata->hdmi_mutex);
2079 if (!hdata->powered)
2080 goto out;
2081 mutex_unlock(&hdata->hdmi_mutex);
2083 /* HDMI System Disable */
2084 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
2086 hdmiphy_poweroff(hdata);
2088 cancel_delayed_work(&hdata->hotplug_work);
2090 clk_disable_unprepare(res->sclk_hdmi);
2091 clk_disable_unprepare(res->hdmi);
2093 /* reset pmu hdmiphy control bit to disable hdmiphy */
2094 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
2095 PMU_HDMI_PHY_ENABLE_BIT, 0);
2097 regulator_bulk_disable(res->regul_count, res->regul_bulk);
2099 pm_runtime_put_sync(hdata->dev);
2101 mutex_lock(&hdata->hdmi_mutex);
2102 hdata->powered = false;
2104 out:
2105 mutex_unlock(&hdata->hdmi_mutex);
2108 static void hdmi_dpms(struct exynos_drm_display *display, int mode)
2110 struct hdmi_context *hdata = display_to_hdmi(display);
2111 struct drm_encoder *encoder = hdata->encoder;
2112 struct drm_crtc *crtc = encoder->crtc;
2113 const struct drm_crtc_helper_funcs *funcs = NULL;
2115 DRM_DEBUG_KMS("mode %d\n", mode);
2117 switch (mode) {
2118 case DRM_MODE_DPMS_ON:
2119 hdmi_poweron(hdata);
2120 break;
2121 case DRM_MODE_DPMS_STANDBY:
2122 case DRM_MODE_DPMS_SUSPEND:
2123 case DRM_MODE_DPMS_OFF:
2125 * The SFRs of VP and Mixer are updated by Vertical Sync of
2126 * Timing generator which is a part of HDMI so the sequence
2127 * to disable TV Subsystem should be as following,
2128 * VP -> Mixer -> HDMI
2130 * Below codes will try to disable Mixer and VP(if used)
2131 * prior to disabling HDMI.
2133 if (crtc)
2134 funcs = crtc->helper_private;
2135 if (funcs && funcs->disable)
2136 (*funcs->disable)(crtc);
2138 hdmi_poweroff(hdata);
2139 break;
2140 default:
2141 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
2142 break;
2146 static struct exynos_drm_display_ops hdmi_display_ops = {
2147 .create_connector = hdmi_create_connector,
2148 .mode_fixup = hdmi_mode_fixup,
2149 .mode_set = hdmi_mode_set,
2150 .dpms = hdmi_dpms,
2151 .commit = hdmi_commit,
2154 static void hdmi_hotplug_work_func(struct work_struct *work)
2156 struct hdmi_context *hdata;
2158 hdata = container_of(work, struct hdmi_context, hotplug_work.work);
2160 mutex_lock(&hdata->hdmi_mutex);
2161 hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2162 mutex_unlock(&hdata->hdmi_mutex);
2164 if (hdata->drm_dev)
2165 drm_helper_hpd_irq_event(hdata->drm_dev);
2168 static irqreturn_t hdmi_irq_thread(int irq, void *arg)
2170 struct hdmi_context *hdata = arg;
2172 mod_delayed_work(system_wq, &hdata->hotplug_work,
2173 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
2175 return IRQ_HANDLED;
2178 static int hdmi_resources_init(struct hdmi_context *hdata)
2180 struct device *dev = hdata->dev;
2181 struct hdmi_resources *res = &hdata->res;
2182 static char *supply[] = {
2183 "vdd",
2184 "vdd_osc",
2185 "vdd_pll",
2187 int i, ret;
2189 DRM_DEBUG_KMS("HDMI resource init\n");
2191 /* get clocks, power */
2192 res->hdmi = devm_clk_get(dev, "hdmi");
2193 if (IS_ERR(res->hdmi)) {
2194 DRM_ERROR("failed to get clock 'hdmi'\n");
2195 ret = PTR_ERR(res->hdmi);
2196 goto fail;
2198 res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
2199 if (IS_ERR(res->sclk_hdmi)) {
2200 DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
2201 ret = PTR_ERR(res->sclk_hdmi);
2202 goto fail;
2204 res->sclk_pixel = devm_clk_get(dev, "sclk_pixel");
2205 if (IS_ERR(res->sclk_pixel)) {
2206 DRM_ERROR("failed to get clock 'sclk_pixel'\n");
2207 ret = PTR_ERR(res->sclk_pixel);
2208 goto fail;
2210 res->sclk_hdmiphy = devm_clk_get(dev, "sclk_hdmiphy");
2211 if (IS_ERR(res->sclk_hdmiphy)) {
2212 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
2213 ret = PTR_ERR(res->sclk_hdmiphy);
2214 goto fail;
2216 res->mout_hdmi = devm_clk_get(dev, "mout_hdmi");
2217 if (IS_ERR(res->mout_hdmi)) {
2218 DRM_ERROR("failed to get clock 'mout_hdmi'\n");
2219 ret = PTR_ERR(res->mout_hdmi);
2220 goto fail;
2223 clk_set_parent(res->mout_hdmi, res->sclk_pixel);
2225 res->regul_bulk = devm_kzalloc(dev, ARRAY_SIZE(supply) *
2226 sizeof(res->regul_bulk[0]), GFP_KERNEL);
2227 if (!res->regul_bulk) {
2228 ret = -ENOMEM;
2229 goto fail;
2231 for (i = 0; i < ARRAY_SIZE(supply); ++i) {
2232 res->regul_bulk[i].supply = supply[i];
2233 res->regul_bulk[i].consumer = NULL;
2235 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
2236 if (ret) {
2237 DRM_ERROR("failed to get regulators\n");
2238 return ret;
2240 res->regul_count = ARRAY_SIZE(supply);
2242 res->reg_hdmi_en = devm_regulator_get(dev, "hdmi-en");
2243 if (IS_ERR(res->reg_hdmi_en) && PTR_ERR(res->reg_hdmi_en) != -ENOENT) {
2244 DRM_ERROR("failed to get hdmi-en regulator\n");
2245 return PTR_ERR(res->reg_hdmi_en);
2247 if (!IS_ERR(res->reg_hdmi_en)) {
2248 ret = regulator_enable(res->reg_hdmi_en);
2249 if (ret) {
2250 DRM_ERROR("failed to enable hdmi-en regulator\n");
2251 return ret;
2253 } else
2254 res->reg_hdmi_en = NULL;
2256 return ret;
2257 fail:
2258 DRM_ERROR("HDMI resource init - failed\n");
2259 return ret;
2262 static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
2263 (struct device *dev)
2265 struct device_node *np = dev->of_node;
2266 struct s5p_hdmi_platform_data *pd;
2267 u32 value;
2269 pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
2270 if (!pd)
2271 goto err_data;
2273 if (!of_find_property(np, "hpd-gpio", &value)) {
2274 DRM_ERROR("no hpd gpio property found\n");
2275 goto err_data;
2278 pd->hpd_gpio = of_get_named_gpio(np, "hpd-gpio", 0);
2280 return pd;
2282 err_data:
2283 return NULL;
2286 static struct of_device_id hdmi_match_types[] = {
2288 .compatible = "samsung,exynos5-hdmi",
2289 .data = &exynos5_hdmi_driver_data,
2290 }, {
2291 .compatible = "samsung,exynos4210-hdmi",
2292 .data = &exynos4210_hdmi_driver_data,
2293 }, {
2294 .compatible = "samsung,exynos4212-hdmi",
2295 .data = &exynos4212_hdmi_driver_data,
2296 }, {
2297 .compatible = "samsung,exynos5420-hdmi",
2298 .data = &exynos5420_hdmi_driver_data,
2299 }, {
2300 /* end node */
2303 MODULE_DEVICE_TABLE (of, hdmi_match_types);
2305 static int hdmi_bind(struct device *dev, struct device *master, void *data)
2307 struct drm_device *drm_dev = data;
2308 struct hdmi_context *hdata = dev_get_drvdata(dev);
2310 hdata->drm_dev = drm_dev;
2312 return exynos_drm_create_enc_conn(drm_dev, &hdata->display);
2315 static void hdmi_unbind(struct device *dev, struct device *master, void *data)
2319 static const struct component_ops hdmi_component_ops = {
2320 .bind = hdmi_bind,
2321 .unbind = hdmi_unbind,
2324 static struct device_node *hdmi_legacy_ddc_dt_binding(struct device *dev)
2326 const char *compatible_str = "samsung,exynos4210-hdmiddc";
2327 struct device_node *np;
2329 np = of_find_compatible_node(NULL, NULL, compatible_str);
2330 if (np)
2331 return of_get_next_parent(np);
2333 return NULL;
2336 static struct device_node *hdmi_legacy_phy_dt_binding(struct device *dev)
2338 const char *compatible_str = "samsung,exynos4212-hdmiphy";
2340 return of_find_compatible_node(NULL, NULL, compatible_str);
2343 static int hdmi_probe(struct platform_device *pdev)
2345 struct device_node *ddc_node, *phy_node;
2346 struct s5p_hdmi_platform_data *pdata;
2347 struct hdmi_driver_data *drv_data;
2348 const struct of_device_id *match;
2349 struct device *dev = &pdev->dev;
2350 struct hdmi_context *hdata;
2351 struct resource *res;
2352 int ret;
2354 if (!dev->of_node)
2355 return -ENODEV;
2357 pdata = drm_hdmi_dt_parse_pdata(dev);
2358 if (!pdata)
2359 return -EINVAL;
2361 hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
2362 if (!hdata)
2363 return -ENOMEM;
2365 hdata->display.type = EXYNOS_DISPLAY_TYPE_HDMI;
2366 hdata->display.ops = &hdmi_display_ops;
2368 mutex_init(&hdata->hdmi_mutex);
2370 platform_set_drvdata(pdev, hdata);
2372 match = of_match_node(hdmi_match_types, dev->of_node);
2373 if (!match)
2374 return -ENODEV;
2376 drv_data = (struct hdmi_driver_data *)match->data;
2377 hdata->type = drv_data->type;
2378 hdata->phy_confs = drv_data->phy_confs;
2379 hdata->phy_conf_count = drv_data->phy_conf_count;
2381 hdata->hpd_gpio = pdata->hpd_gpio;
2382 hdata->dev = dev;
2384 ret = hdmi_resources_init(hdata);
2385 if (ret) {
2386 DRM_ERROR("hdmi_resources_init failed\n");
2387 return ret;
2390 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2391 hdata->regs = devm_ioremap_resource(dev, res);
2392 if (IS_ERR(hdata->regs)) {
2393 ret = PTR_ERR(hdata->regs);
2394 return ret;
2397 ret = devm_gpio_request(dev, hdata->hpd_gpio, "HPD");
2398 if (ret) {
2399 DRM_ERROR("failed to request HPD gpio\n");
2400 return ret;
2403 ddc_node = hdmi_legacy_ddc_dt_binding(dev);
2404 if (ddc_node)
2405 goto out_get_ddc_adpt;
2407 /* DDC i2c driver */
2408 ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
2409 if (!ddc_node) {
2410 DRM_ERROR("Failed to find ddc node in device tree\n");
2411 return -ENODEV;
2414 out_get_ddc_adpt:
2415 hdata->ddc_adpt = of_find_i2c_adapter_by_node(ddc_node);
2416 if (!hdata->ddc_adpt) {
2417 DRM_ERROR("Failed to get ddc i2c adapter by node\n");
2418 return -EPROBE_DEFER;
2421 phy_node = hdmi_legacy_phy_dt_binding(dev);
2422 if (phy_node)
2423 goto out_get_phy_port;
2425 /* hdmiphy i2c driver */
2426 phy_node = of_parse_phandle(dev->of_node, "phy", 0);
2427 if (!phy_node) {
2428 DRM_ERROR("Failed to find hdmiphy node in device tree\n");
2429 ret = -ENODEV;
2430 goto err_ddc;
2433 out_get_phy_port:
2434 if (drv_data->is_apb_phy) {
2435 hdata->regs_hdmiphy = of_iomap(phy_node, 0);
2436 if (!hdata->regs_hdmiphy) {
2437 DRM_ERROR("failed to ioremap hdmi phy\n");
2438 ret = -ENOMEM;
2439 goto err_ddc;
2441 } else {
2442 hdata->hdmiphy_port = of_find_i2c_device_by_node(phy_node);
2443 if (!hdata->hdmiphy_port) {
2444 DRM_ERROR("Failed to get hdmi phy i2c client\n");
2445 ret = -EPROBE_DEFER;
2446 goto err_ddc;
2450 hdata->irq = gpio_to_irq(hdata->hpd_gpio);
2451 if (hdata->irq < 0) {
2452 DRM_ERROR("failed to get GPIO irq\n");
2453 ret = hdata->irq;
2454 goto err_hdmiphy;
2457 hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2459 INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
2461 ret = devm_request_threaded_irq(dev, hdata->irq, NULL,
2462 hdmi_irq_thread, IRQF_TRIGGER_RISING |
2463 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
2464 "hdmi", hdata);
2465 if (ret) {
2466 DRM_ERROR("failed to register hdmi interrupt\n");
2467 goto err_hdmiphy;
2470 hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
2471 "samsung,syscon-phandle");
2472 if (IS_ERR(hdata->pmureg)) {
2473 DRM_ERROR("syscon regmap lookup failed.\n");
2474 ret = -EPROBE_DEFER;
2475 goto err_hdmiphy;
2478 pm_runtime_enable(dev);
2480 ret = component_add(&pdev->dev, &hdmi_component_ops);
2481 if (ret)
2482 goto err_disable_pm_runtime;
2484 return ret;
2486 err_disable_pm_runtime:
2487 pm_runtime_disable(dev);
2489 err_hdmiphy:
2490 if (hdata->hdmiphy_port)
2491 put_device(&hdata->hdmiphy_port->dev);
2492 err_ddc:
2493 put_device(&hdata->ddc_adpt->dev);
2495 return ret;
2498 static int hdmi_remove(struct platform_device *pdev)
2500 struct hdmi_context *hdata = platform_get_drvdata(pdev);
2502 cancel_delayed_work_sync(&hdata->hotplug_work);
2504 if (hdata->res.reg_hdmi_en)
2505 regulator_disable(hdata->res.reg_hdmi_en);
2507 if (hdata->hdmiphy_port)
2508 put_device(&hdata->hdmiphy_port->dev);
2509 put_device(&hdata->ddc_adpt->dev);
2511 pm_runtime_disable(&pdev->dev);
2512 component_del(&pdev->dev, &hdmi_component_ops);
2514 return 0;
2517 struct platform_driver hdmi_driver = {
2518 .probe = hdmi_probe,
2519 .remove = hdmi_remove,
2520 .driver = {
2521 .name = "exynos-hdmi",
2522 .owner = THIS_MODULE,
2523 .of_match_table = hdmi_match_types,