2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
4 * Seung-Woo Kim <sw0312.kim@samsung.com>
5 * Inki Dae <inki.dae@samsung.com>
6 * Joonyoung Shim <jy0922.shim@samsung.com>
8 * Based on drivers/media/video/s5p-tv/hdmi_drv.c
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
18 #include <drm/drm_edid.h>
19 #include <drm/drm_crtc_helper.h>
20 #include <drm/drm_atomic_helper.h>
22 #include "regs-hdmi.h"
24 #include <linux/kernel.h>
25 #include <linux/wait.h>
26 #include <linux/i2c.h>
27 #include <linux/platform_device.h>
28 #include <linux/interrupt.h>
29 #include <linux/irq.h>
30 #include <linux/delay.h>
31 #include <linux/pm_runtime.h>
32 #include <linux/clk.h>
33 #include <linux/regulator/consumer.h>
35 #include <linux/of_address.h>
36 #include <linux/of_device.h>
37 #include <linux/of_gpio.h>
38 #include <linux/hdmi.h>
39 #include <linux/component.h>
40 #include <linux/mfd/syscon.h>
41 #include <linux/regmap.h>
43 #include <drm/exynos_drm.h>
45 #include "exynos_drm_drv.h"
46 #include "exynos_drm_crtc.h"
47 #include "exynos_mixer.h"
49 #include <linux/gpio.h>
51 #define ctx_from_connector(c) container_of(c, struct hdmi_context, connector)
53 #define HOTPLUG_DEBOUNCE_MS 1100
55 /* AVI header and aspect ratio */
56 #define HDMI_AVI_VERSION 0x02
57 #define HDMI_AVI_LENGTH 0x0D
60 #define HDMI_AUI_VERSION 0x01
61 #define HDMI_AUI_LENGTH 0x0A
62 #define AVI_SAME_AS_PIC_ASPECT_RATIO 0x8
63 #define AVI_4_3_CENTER_RATIO 0x9
64 #define AVI_16_9_CENTER_RATIO 0xa
72 #define HDMI_MAPPED_BASE 0xffff0000
74 enum hdmi_mapped_regs
{
75 HDMI_PHY_STATUS
= HDMI_MAPPED_BASE
,
80 static const u32 hdmi_reg_map
[][HDMI_TYPE_COUNT
] = {
81 { HDMI_V13_PHY_STATUS
, HDMI_PHY_STATUS_0
},
82 { HDMI_V13_PHY_RSTOUT
, HDMI_V14_PHY_RSTOUT
},
83 { HDMI_V13_ACR_CON
, HDMI_V14_ACR_CON
},
86 struct hdmi_driver_data
{
88 const struct hdmiphy_config
*phy_confs
;
89 unsigned int phy_conf_count
;
90 unsigned int is_apb_phy
:1;
93 struct hdmi_resources
{
95 struct clk
*sclk_hdmi
;
96 struct clk
*sclk_pixel
;
97 struct clk
*sclk_hdmiphy
;
98 struct clk
*mout_hdmi
;
99 struct regulator_bulk_data
*regul_bulk
;
100 struct regulator
*reg_hdmi_en
;
104 struct hdmi_context
{
105 struct drm_encoder encoder
;
107 struct drm_device
*drm_dev
;
108 struct drm_connector connector
;
115 struct delayed_work hotplug_work
;
117 struct i2c_adapter
*ddc_adpt
;
118 struct i2c_client
*hdmiphy_port
;
120 /* current hdmiphy conf regs */
121 struct drm_display_mode current_mode
;
124 struct hdmi_resources res
;
125 const struct hdmi_driver_data
*drv_data
;
128 void __iomem
*regs_hdmiphy
;
130 struct regmap
*pmureg
;
133 static inline struct hdmi_context
*encoder_to_hdmi(struct drm_encoder
*e
)
135 return container_of(e
, struct hdmi_context
, encoder
);
138 struct hdmiphy_config
{
143 /* list of phy config settings */
144 static const struct hdmiphy_config hdmiphy_v13_configs
[] = {
146 .pixel_clock
= 27000000,
148 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
149 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
150 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
151 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x80,
155 .pixel_clock
= 27027000,
157 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
158 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
159 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
160 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x80,
164 .pixel_clock
= 74176000,
166 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
167 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
168 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
169 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x80,
173 .pixel_clock
= 74250000,
175 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
176 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
177 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
178 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x80,
182 .pixel_clock
= 148500000,
184 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
185 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
186 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
187 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x80,
192 static const struct hdmiphy_config hdmiphy_v14_configs
[] = {
194 .pixel_clock
= 25200000,
196 0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
197 0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
198 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
199 0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
203 .pixel_clock
= 27000000,
205 0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
206 0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
207 0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
208 0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
212 .pixel_clock
= 27027000,
214 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
215 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
216 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
217 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
221 .pixel_clock
= 36000000,
223 0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
224 0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
225 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
226 0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
230 .pixel_clock
= 40000000,
232 0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
233 0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
234 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
235 0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
239 .pixel_clock
= 65000000,
241 0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
242 0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
243 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
244 0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
248 .pixel_clock
= 71000000,
250 0x01, 0xd1, 0x3b, 0x35, 0x40, 0x0c, 0x04, 0x08,
251 0x85, 0xa0, 0x63, 0xd9, 0x45, 0xa0, 0xac, 0x80,
252 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
253 0x54, 0xad, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
257 .pixel_clock
= 73250000,
259 0x01, 0xd1, 0x3d, 0x35, 0x40, 0x18, 0x02, 0x08,
260 0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
261 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
262 0x54, 0xa8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
266 .pixel_clock
= 74176000,
268 0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
269 0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
270 0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
271 0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
275 .pixel_clock
= 74250000,
277 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
278 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
279 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
280 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
284 .pixel_clock
= 83500000,
286 0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
287 0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
288 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
289 0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
293 .pixel_clock
= 106500000,
295 0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
296 0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
297 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
298 0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
302 .pixel_clock
= 108000000,
304 0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
305 0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
306 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
307 0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
311 .pixel_clock
= 115500000,
313 0x01, 0xd1, 0x30, 0x12, 0x40, 0x40, 0x10, 0x08,
314 0x80, 0x80, 0x21, 0xd9, 0x45, 0xa0, 0xac, 0x80,
315 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
316 0x54, 0xaa, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
320 .pixel_clock
= 119000000,
322 0x01, 0xd1, 0x32, 0x1a, 0x40, 0x30, 0xd8, 0x08,
323 0x04, 0xa0, 0x2a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
324 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
325 0x54, 0x9d, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
329 .pixel_clock
= 146250000,
331 0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
332 0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
333 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
334 0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
338 .pixel_clock
= 148500000,
340 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
341 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
342 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
343 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
348 static const struct hdmiphy_config hdmiphy_5420_configs
[] = {
350 .pixel_clock
= 25200000,
352 0x01, 0x52, 0x3F, 0x55, 0x40, 0x01, 0x00, 0xC8,
353 0x82, 0xC8, 0xBD, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
354 0x06, 0x80, 0x01, 0x84, 0x05, 0x02, 0x24, 0x66,
355 0x54, 0xF4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
359 .pixel_clock
= 27000000,
361 0x01, 0xD1, 0x22, 0x51, 0x40, 0x08, 0xFC, 0xE0,
362 0x98, 0xE8, 0xCB, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
363 0x06, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
364 0x54, 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
368 .pixel_clock
= 27027000,
370 0x01, 0xD1, 0x2D, 0x72, 0x40, 0x64, 0x12, 0xC8,
371 0x43, 0xE8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
372 0x26, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
373 0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
377 .pixel_clock
= 36000000,
379 0x01, 0x51, 0x2D, 0x55, 0x40, 0x40, 0x00, 0xC8,
380 0x02, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
381 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
382 0x54, 0xAB, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
386 .pixel_clock
= 40000000,
388 0x01, 0xD1, 0x21, 0x31, 0x40, 0x3C, 0x28, 0xC8,
389 0x87, 0xE8, 0xC8, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
390 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
391 0x54, 0x9A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
395 .pixel_clock
= 65000000,
397 0x01, 0xD1, 0x36, 0x34, 0x40, 0x0C, 0x04, 0xC8,
398 0x82, 0xE8, 0x45, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
399 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
400 0x54, 0xBD, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
404 .pixel_clock
= 71000000,
406 0x01, 0xD1, 0x3B, 0x35, 0x40, 0x0C, 0x04, 0xC8,
407 0x85, 0xE8, 0x63, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
408 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
409 0x54, 0x57, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
413 .pixel_clock
= 73250000,
415 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x78, 0x8D, 0xC8,
416 0x81, 0xE8, 0xB7, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
417 0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
418 0x54, 0xA8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
422 .pixel_clock
= 74176000,
424 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0xC8,
425 0x81, 0xE8, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
426 0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
427 0x54, 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
431 .pixel_clock
= 74250000,
433 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0x08,
434 0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
435 0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
436 0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
440 .pixel_clock
= 83500000,
442 0x01, 0xD1, 0x23, 0x11, 0x40, 0x0C, 0xFB, 0xC8,
443 0x85, 0xE8, 0xD1, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
444 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
445 0x54, 0x4A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
449 .pixel_clock
= 88750000,
451 0x01, 0xD1, 0x25, 0x11, 0x40, 0x18, 0xFF, 0xC8,
452 0x83, 0xE8, 0xDE, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
453 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
454 0x54, 0x45, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
458 .pixel_clock
= 106500000,
460 0x01, 0xD1, 0x2C, 0x12, 0x40, 0x0C, 0x09, 0xC8,
461 0x84, 0xE8, 0x0A, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
462 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
463 0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
467 .pixel_clock
= 108000000,
469 0x01, 0x51, 0x2D, 0x15, 0x40, 0x01, 0x00, 0xC8,
470 0x82, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
471 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
472 0x54, 0xC7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
476 .pixel_clock
= 115500000,
478 0x01, 0xD1, 0x30, 0x14, 0x40, 0x0C, 0x03, 0xC8,
479 0x88, 0xE8, 0x21, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
480 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
481 0x54, 0x6A, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
485 .pixel_clock
= 146250000,
487 0x01, 0xD1, 0x3D, 0x15, 0x40, 0x18, 0xFD, 0xC8,
488 0x83, 0xE8, 0x6E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
489 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
490 0x54, 0x54, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
494 .pixel_clock
= 148500000,
496 0x01, 0xD1, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0x08,
497 0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
498 0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
499 0x54, 0x4B, 0x25, 0x03, 0x00, 0x80, 0x01, 0x80,
504 static struct hdmi_driver_data exynos5420_hdmi_driver_data
= {
506 .phy_confs
= hdmiphy_5420_configs
,
507 .phy_conf_count
= ARRAY_SIZE(hdmiphy_5420_configs
),
511 static struct hdmi_driver_data exynos4212_hdmi_driver_data
= {
513 .phy_confs
= hdmiphy_v14_configs
,
514 .phy_conf_count
= ARRAY_SIZE(hdmiphy_v14_configs
),
518 static struct hdmi_driver_data exynos4210_hdmi_driver_data
= {
520 .phy_confs
= hdmiphy_v13_configs
,
521 .phy_conf_count
= ARRAY_SIZE(hdmiphy_v13_configs
),
525 static inline u32
hdmi_map_reg(struct hdmi_context
*hdata
, u32 reg_id
)
527 if ((reg_id
& 0xffff0000) == HDMI_MAPPED_BASE
)
528 return hdmi_reg_map
[reg_id
& 0xffff][hdata
->drv_data
->type
];
532 static inline u32
hdmi_reg_read(struct hdmi_context
*hdata
, u32 reg_id
)
534 return readl(hdata
->regs
+ hdmi_map_reg(hdata
, reg_id
));
537 static inline void hdmi_reg_writeb(struct hdmi_context
*hdata
,
538 u32 reg_id
, u8 value
)
540 writel(value
, hdata
->regs
+ hdmi_map_reg(hdata
, reg_id
));
543 static inline void hdmi_reg_writev(struct hdmi_context
*hdata
, u32 reg_id
,
546 reg_id
= hdmi_map_reg(hdata
, reg_id
);
548 while (--bytes
>= 0) {
549 writel(val
& 0xff, hdata
->regs
+ reg_id
);
555 static inline void hdmi_reg_writemask(struct hdmi_context
*hdata
,
556 u32 reg_id
, u32 value
, u32 mask
)
560 reg_id
= hdmi_map_reg(hdata
, reg_id
);
561 old
= readl(hdata
->regs
+ reg_id
);
562 value
= (value
& mask
) | (old
& ~mask
);
563 writel(value
, hdata
->regs
+ reg_id
);
566 static int hdmiphy_reg_write_buf(struct hdmi_context
*hdata
,
567 u32 reg_offset
, const u8
*buf
, u32 len
)
569 if ((reg_offset
+ len
) > 32)
572 if (hdata
->hdmiphy_port
) {
575 ret
= i2c_master_send(hdata
->hdmiphy_port
, buf
, len
);
581 for (i
= 0; i
< len
; i
++)
582 writel(buf
[i
], hdata
->regs_hdmiphy
+
583 ((reg_offset
+ i
)<<2));
588 static void hdmi_v13_regs_dump(struct hdmi_context
*hdata
, char *prefix
)
590 #define DUMPREG(reg_id) \
591 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
592 readl(hdata->regs + reg_id))
593 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix
);
594 DUMPREG(HDMI_INTC_FLAG
);
595 DUMPREG(HDMI_INTC_CON
);
596 DUMPREG(HDMI_HPD_STATUS
);
597 DUMPREG(HDMI_V13_PHY_RSTOUT
);
598 DUMPREG(HDMI_V13_PHY_VPLL
);
599 DUMPREG(HDMI_V13_PHY_CMU
);
600 DUMPREG(HDMI_V13_CORE_RSTOUT
);
602 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix
);
606 DUMPREG(HDMI_SYS_STATUS
);
607 DUMPREG(HDMI_V13_PHY_STATUS
);
608 DUMPREG(HDMI_STATUS_EN
);
610 DUMPREG(HDMI_MODE_SEL
);
611 DUMPREG(HDMI_V13_HPD_GEN
);
612 DUMPREG(HDMI_V13_DC_CONTROL
);
613 DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN
);
615 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix
);
616 DUMPREG(HDMI_H_BLANK_0
);
617 DUMPREG(HDMI_H_BLANK_1
);
618 DUMPREG(HDMI_V13_V_BLANK_0
);
619 DUMPREG(HDMI_V13_V_BLANK_1
);
620 DUMPREG(HDMI_V13_V_BLANK_2
);
621 DUMPREG(HDMI_V13_H_V_LINE_0
);
622 DUMPREG(HDMI_V13_H_V_LINE_1
);
623 DUMPREG(HDMI_V13_H_V_LINE_2
);
624 DUMPREG(HDMI_VSYNC_POL
);
625 DUMPREG(HDMI_INT_PRO_MODE
);
626 DUMPREG(HDMI_V13_V_BLANK_F_0
);
627 DUMPREG(HDMI_V13_V_BLANK_F_1
);
628 DUMPREG(HDMI_V13_V_BLANK_F_2
);
629 DUMPREG(HDMI_V13_H_SYNC_GEN_0
);
630 DUMPREG(HDMI_V13_H_SYNC_GEN_1
);
631 DUMPREG(HDMI_V13_H_SYNC_GEN_2
);
632 DUMPREG(HDMI_V13_V_SYNC_GEN_1_0
);
633 DUMPREG(HDMI_V13_V_SYNC_GEN_1_1
);
634 DUMPREG(HDMI_V13_V_SYNC_GEN_1_2
);
635 DUMPREG(HDMI_V13_V_SYNC_GEN_2_0
);
636 DUMPREG(HDMI_V13_V_SYNC_GEN_2_1
);
637 DUMPREG(HDMI_V13_V_SYNC_GEN_2_2
);
638 DUMPREG(HDMI_V13_V_SYNC_GEN_3_0
);
639 DUMPREG(HDMI_V13_V_SYNC_GEN_3_1
);
640 DUMPREG(HDMI_V13_V_SYNC_GEN_3_2
);
642 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix
);
643 DUMPREG(HDMI_TG_CMD
);
644 DUMPREG(HDMI_TG_H_FSZ_L
);
645 DUMPREG(HDMI_TG_H_FSZ_H
);
646 DUMPREG(HDMI_TG_HACT_ST_L
);
647 DUMPREG(HDMI_TG_HACT_ST_H
);
648 DUMPREG(HDMI_TG_HACT_SZ_L
);
649 DUMPREG(HDMI_TG_HACT_SZ_H
);
650 DUMPREG(HDMI_TG_V_FSZ_L
);
651 DUMPREG(HDMI_TG_V_FSZ_H
);
652 DUMPREG(HDMI_TG_VSYNC_L
);
653 DUMPREG(HDMI_TG_VSYNC_H
);
654 DUMPREG(HDMI_TG_VSYNC2_L
);
655 DUMPREG(HDMI_TG_VSYNC2_H
);
656 DUMPREG(HDMI_TG_VACT_ST_L
);
657 DUMPREG(HDMI_TG_VACT_ST_H
);
658 DUMPREG(HDMI_TG_VACT_SZ_L
);
659 DUMPREG(HDMI_TG_VACT_SZ_H
);
660 DUMPREG(HDMI_TG_FIELD_CHG_L
);
661 DUMPREG(HDMI_TG_FIELD_CHG_H
);
662 DUMPREG(HDMI_TG_VACT_ST2_L
);
663 DUMPREG(HDMI_TG_VACT_ST2_H
);
664 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L
);
665 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H
);
666 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L
);
667 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H
);
668 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L
);
669 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H
);
670 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L
);
671 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H
);
675 static void hdmi_v14_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))
683 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix
);
684 DUMPREG(HDMI_INTC_CON
);
685 DUMPREG(HDMI_INTC_FLAG
);
686 DUMPREG(HDMI_HPD_STATUS
);
687 DUMPREG(HDMI_INTC_CON_1
);
688 DUMPREG(HDMI_INTC_FLAG_1
);
689 DUMPREG(HDMI_PHY_STATUS_0
);
690 DUMPREG(HDMI_PHY_STATUS_PLL
);
691 DUMPREG(HDMI_PHY_CON_0
);
692 DUMPREG(HDMI_V14_PHY_RSTOUT
);
693 DUMPREG(HDMI_PHY_VPLL
);
694 DUMPREG(HDMI_PHY_CMU
);
695 DUMPREG(HDMI_CORE_RSTOUT
);
697 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix
);
701 DUMPREG(HDMI_SYS_STATUS
);
702 DUMPREG(HDMI_PHY_STATUS_0
);
703 DUMPREG(HDMI_STATUS_EN
);
705 DUMPREG(HDMI_MODE_SEL
);
706 DUMPREG(HDMI_ENC_EN
);
707 DUMPREG(HDMI_DC_CONTROL
);
708 DUMPREG(HDMI_VIDEO_PATTERN_GEN
);
710 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix
);
711 DUMPREG(HDMI_H_BLANK_0
);
712 DUMPREG(HDMI_H_BLANK_1
);
713 DUMPREG(HDMI_V2_BLANK_0
);
714 DUMPREG(HDMI_V2_BLANK_1
);
715 DUMPREG(HDMI_V1_BLANK_0
);
716 DUMPREG(HDMI_V1_BLANK_1
);
717 DUMPREG(HDMI_V_LINE_0
);
718 DUMPREG(HDMI_V_LINE_1
);
719 DUMPREG(HDMI_H_LINE_0
);
720 DUMPREG(HDMI_H_LINE_1
);
721 DUMPREG(HDMI_HSYNC_POL
);
723 DUMPREG(HDMI_VSYNC_POL
);
724 DUMPREG(HDMI_INT_PRO_MODE
);
725 DUMPREG(HDMI_V_BLANK_F0_0
);
726 DUMPREG(HDMI_V_BLANK_F0_1
);
727 DUMPREG(HDMI_V_BLANK_F1_0
);
728 DUMPREG(HDMI_V_BLANK_F1_1
);
730 DUMPREG(HDMI_H_SYNC_START_0
);
731 DUMPREG(HDMI_H_SYNC_START_1
);
732 DUMPREG(HDMI_H_SYNC_END_0
);
733 DUMPREG(HDMI_H_SYNC_END_1
);
735 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0
);
736 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1
);
737 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0
);
738 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1
);
740 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0
);
741 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1
);
742 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0
);
743 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1
);
745 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0
);
746 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1
);
747 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0
);
748 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1
);
750 DUMPREG(HDMI_V_BLANK_F2_0
);
751 DUMPREG(HDMI_V_BLANK_F2_1
);
752 DUMPREG(HDMI_V_BLANK_F3_0
);
753 DUMPREG(HDMI_V_BLANK_F3_1
);
754 DUMPREG(HDMI_V_BLANK_F4_0
);
755 DUMPREG(HDMI_V_BLANK_F4_1
);
756 DUMPREG(HDMI_V_BLANK_F5_0
);
757 DUMPREG(HDMI_V_BLANK_F5_1
);
759 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0
);
760 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1
);
761 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0
);
762 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1
);
763 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0
);
764 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1
);
765 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0
);
766 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1
);
768 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0
);
769 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1
);
770 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0
);
771 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1
);
772 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0
);
773 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1
);
774 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0
);
775 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1
);
777 DUMPREG(HDMI_VACT_SPACE_1_0
);
778 DUMPREG(HDMI_VACT_SPACE_1_1
);
779 DUMPREG(HDMI_VACT_SPACE_2_0
);
780 DUMPREG(HDMI_VACT_SPACE_2_1
);
781 DUMPREG(HDMI_VACT_SPACE_3_0
);
782 DUMPREG(HDMI_VACT_SPACE_3_1
);
783 DUMPREG(HDMI_VACT_SPACE_4_0
);
784 DUMPREG(HDMI_VACT_SPACE_4_1
);
785 DUMPREG(HDMI_VACT_SPACE_5_0
);
786 DUMPREG(HDMI_VACT_SPACE_5_1
);
787 DUMPREG(HDMI_VACT_SPACE_6_0
);
788 DUMPREG(HDMI_VACT_SPACE_6_1
);
790 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix
);
791 DUMPREG(HDMI_TG_CMD
);
792 DUMPREG(HDMI_TG_H_FSZ_L
);
793 DUMPREG(HDMI_TG_H_FSZ_H
);
794 DUMPREG(HDMI_TG_HACT_ST_L
);
795 DUMPREG(HDMI_TG_HACT_ST_H
);
796 DUMPREG(HDMI_TG_HACT_SZ_L
);
797 DUMPREG(HDMI_TG_HACT_SZ_H
);
798 DUMPREG(HDMI_TG_V_FSZ_L
);
799 DUMPREG(HDMI_TG_V_FSZ_H
);
800 DUMPREG(HDMI_TG_VSYNC_L
);
801 DUMPREG(HDMI_TG_VSYNC_H
);
802 DUMPREG(HDMI_TG_VSYNC2_L
);
803 DUMPREG(HDMI_TG_VSYNC2_H
);
804 DUMPREG(HDMI_TG_VACT_ST_L
);
805 DUMPREG(HDMI_TG_VACT_ST_H
);
806 DUMPREG(HDMI_TG_VACT_SZ_L
);
807 DUMPREG(HDMI_TG_VACT_SZ_H
);
808 DUMPREG(HDMI_TG_FIELD_CHG_L
);
809 DUMPREG(HDMI_TG_FIELD_CHG_H
);
810 DUMPREG(HDMI_TG_VACT_ST2_L
);
811 DUMPREG(HDMI_TG_VACT_ST2_H
);
812 DUMPREG(HDMI_TG_VACT_ST3_L
);
813 DUMPREG(HDMI_TG_VACT_ST3_H
);
814 DUMPREG(HDMI_TG_VACT_ST4_L
);
815 DUMPREG(HDMI_TG_VACT_ST4_H
);
816 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L
);
817 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H
);
818 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L
);
819 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H
);
820 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L
);
821 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H
);
822 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L
);
823 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H
);
826 DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix
);
827 DUMPREG(HDMI_AVI_CON
);
828 DUMPREG(HDMI_AVI_HEADER0
);
829 DUMPREG(HDMI_AVI_HEADER1
);
830 DUMPREG(HDMI_AVI_HEADER2
);
831 DUMPREG(HDMI_AVI_CHECK_SUM
);
832 DUMPREG(HDMI_VSI_CON
);
833 DUMPREG(HDMI_VSI_HEADER0
);
834 DUMPREG(HDMI_VSI_HEADER1
);
835 DUMPREG(HDMI_VSI_HEADER2
);
836 for (i
= 0; i
< 7; ++i
)
837 DUMPREG(HDMI_VSI_DATA(i
));
842 static void hdmi_regs_dump(struct hdmi_context
*hdata
, char *prefix
)
844 if (hdata
->drv_data
->type
== HDMI_TYPE13
)
845 hdmi_v13_regs_dump(hdata
, prefix
);
847 hdmi_v14_regs_dump(hdata
, prefix
);
850 static u8
hdmi_chksum(struct hdmi_context
*hdata
,
851 u32 start
, u8 len
, u32 hdr_sum
)
855 /* hdr_sum : header0 + header1 + header2
856 * start : start address of packet byte1
857 * len : packet bytes - 1 */
858 for (i
= 0; i
< len
; ++i
)
859 hdr_sum
+= 0xff & hdmi_reg_read(hdata
, start
+ i
* 4);
861 /* return 2's complement of 8 bit hdr_sum */
862 return (u8
)(~(hdr_sum
& 0xff) + 1);
865 static void hdmi_reg_infoframe(struct hdmi_context
*hdata
,
866 union hdmi_infoframe
*infoframe
)
873 mod
= hdmi_reg_read(hdata
, HDMI_MODE_SEL
);
874 if (hdata
->dvi_mode
) {
875 hdmi_reg_writeb(hdata
, HDMI_VSI_CON
,
876 HDMI_VSI_CON_DO_NOT_TRANSMIT
);
877 hdmi_reg_writeb(hdata
, HDMI_AVI_CON
,
878 HDMI_AVI_CON_DO_NOT_TRANSMIT
);
879 hdmi_reg_writeb(hdata
, HDMI_AUI_CON
, HDMI_AUI_CON_NO_TRAN
);
883 switch (infoframe
->any
.type
) {
884 case HDMI_INFOFRAME_TYPE_AVI
:
885 hdmi_reg_writeb(hdata
, HDMI_AVI_CON
, HDMI_AVI_CON_EVERY_VSYNC
);
886 hdmi_reg_writeb(hdata
, HDMI_AVI_HEADER0
, infoframe
->any
.type
);
887 hdmi_reg_writeb(hdata
, HDMI_AVI_HEADER1
,
888 infoframe
->any
.version
);
889 hdmi_reg_writeb(hdata
, HDMI_AVI_HEADER2
, infoframe
->any
.length
);
890 hdr_sum
= infoframe
->any
.type
+ infoframe
->any
.version
+
891 infoframe
->any
.length
;
893 /* Output format zero hardcoded ,RGB YBCR selection */
894 hdmi_reg_writeb(hdata
, HDMI_AVI_BYTE(1), 0 << 5 |
895 AVI_ACTIVE_FORMAT_VALID
|
896 AVI_UNDERSCANNED_DISPLAY_VALID
);
899 * Set the aspect ratio as per the mode, mentioned in
900 * Table 9 AVI InfoFrame Data Byte 2 of CEA-861-D Standard
902 ar
= hdata
->current_mode
.picture_aspect_ratio
;
904 case HDMI_PICTURE_ASPECT_4_3
:
905 ar
|= AVI_4_3_CENTER_RATIO
;
907 case HDMI_PICTURE_ASPECT_16_9
:
908 ar
|= AVI_16_9_CENTER_RATIO
;
910 case HDMI_PICTURE_ASPECT_NONE
:
912 ar
|= AVI_SAME_AS_PIC_ASPECT_RATIO
;
915 hdmi_reg_writeb(hdata
, HDMI_AVI_BYTE(2), ar
);
917 hdmi_reg_writeb(hdata
, HDMI_AVI_BYTE(4), hdata
->cea_video_id
);
919 chksum
= hdmi_chksum(hdata
, HDMI_AVI_BYTE(1),
920 infoframe
->any
.length
, hdr_sum
);
921 DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum
);
922 hdmi_reg_writeb(hdata
, HDMI_AVI_CHECK_SUM
, chksum
);
924 case HDMI_INFOFRAME_TYPE_AUDIO
:
925 hdmi_reg_writeb(hdata
, HDMI_AUI_CON
, 0x02);
926 hdmi_reg_writeb(hdata
, HDMI_AUI_HEADER0
, infoframe
->any
.type
);
927 hdmi_reg_writeb(hdata
, HDMI_AUI_HEADER1
,
928 infoframe
->any
.version
);
929 hdmi_reg_writeb(hdata
, HDMI_AUI_HEADER2
, infoframe
->any
.length
);
930 hdr_sum
= infoframe
->any
.type
+ infoframe
->any
.version
+
931 infoframe
->any
.length
;
932 chksum
= hdmi_chksum(hdata
, HDMI_AUI_BYTE(1),
933 infoframe
->any
.length
, hdr_sum
);
934 DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum
);
935 hdmi_reg_writeb(hdata
, HDMI_AUI_CHECK_SUM
, chksum
);
942 static enum drm_connector_status
hdmi_detect(struct drm_connector
*connector
,
945 struct hdmi_context
*hdata
= ctx_from_connector(connector
);
947 if (gpio_get_value(hdata
->hpd_gpio
))
948 return connector_status_connected
;
950 return connector_status_disconnected
;
953 static void hdmi_connector_destroy(struct drm_connector
*connector
)
955 drm_connector_unregister(connector
);
956 drm_connector_cleanup(connector
);
959 static struct drm_connector_funcs hdmi_connector_funcs
= {
960 .dpms
= drm_atomic_helper_connector_dpms
,
961 .fill_modes
= drm_helper_probe_single_connector_modes
,
962 .detect
= hdmi_detect
,
963 .destroy
= hdmi_connector_destroy
,
964 .reset
= drm_atomic_helper_connector_reset
,
965 .atomic_duplicate_state
= drm_atomic_helper_connector_duplicate_state
,
966 .atomic_destroy_state
= drm_atomic_helper_connector_destroy_state
,
969 static int hdmi_get_modes(struct drm_connector
*connector
)
971 struct hdmi_context
*hdata
= ctx_from_connector(connector
);
975 if (!hdata
->ddc_adpt
)
978 edid
= drm_get_edid(connector
, hdata
->ddc_adpt
);
982 hdata
->dvi_mode
= !drm_detect_hdmi_monitor(edid
);
983 DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
984 (hdata
->dvi_mode
? "dvi monitor" : "hdmi monitor"),
985 edid
->width_cm
, edid
->height_cm
);
987 drm_mode_connector_update_edid_property(connector
, edid
);
989 ret
= drm_add_edid_modes(connector
, edid
);
996 static int hdmi_find_phy_conf(struct hdmi_context
*hdata
, u32 pixel_clock
)
1000 for (i
= 0; i
< hdata
->drv_data
->phy_conf_count
; i
++)
1001 if (hdata
->drv_data
->phy_confs
[i
].pixel_clock
== pixel_clock
)
1004 DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock
);
1008 static int hdmi_mode_valid(struct drm_connector
*connector
,
1009 struct drm_display_mode
*mode
)
1011 struct hdmi_context
*hdata
= ctx_from_connector(connector
);
1014 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
1015 mode
->hdisplay
, mode
->vdisplay
, mode
->vrefresh
,
1016 (mode
->flags
& DRM_MODE_FLAG_INTERLACE
) ? true :
1017 false, mode
->clock
* 1000);
1019 ret
= mixer_check_mode(mode
);
1023 ret
= hdmi_find_phy_conf(hdata
, mode
->clock
* 1000);
1030 static struct drm_encoder
*hdmi_best_encoder(struct drm_connector
*connector
)
1032 struct hdmi_context
*hdata
= ctx_from_connector(connector
);
1034 return &hdata
->encoder
;
1037 static struct drm_connector_helper_funcs hdmi_connector_helper_funcs
= {
1038 .get_modes
= hdmi_get_modes
,
1039 .mode_valid
= hdmi_mode_valid
,
1040 .best_encoder
= hdmi_best_encoder
,
1043 static int hdmi_create_connector(struct drm_encoder
*encoder
)
1045 struct hdmi_context
*hdata
= encoder_to_hdmi(encoder
);
1046 struct drm_connector
*connector
= &hdata
->connector
;
1049 connector
->interlace_allowed
= true;
1050 connector
->polled
= DRM_CONNECTOR_POLL_HPD
;
1052 ret
= drm_connector_init(hdata
->drm_dev
, connector
,
1053 &hdmi_connector_funcs
, DRM_MODE_CONNECTOR_HDMIA
);
1055 DRM_ERROR("Failed to initialize connector with drm\n");
1059 drm_connector_helper_add(connector
, &hdmi_connector_helper_funcs
);
1060 drm_connector_register(connector
);
1061 drm_mode_connector_attach_encoder(connector
, encoder
);
1066 static bool hdmi_mode_fixup(struct drm_encoder
*encoder
,
1067 const struct drm_display_mode
*mode
,
1068 struct drm_display_mode
*adjusted_mode
)
1070 struct drm_device
*dev
= encoder
->dev
;
1071 struct drm_connector
*connector
;
1072 struct drm_display_mode
*m
;
1075 drm_mode_set_crtcinfo(adjusted_mode
, 0);
1077 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
1078 if (connector
->encoder
== encoder
)
1082 if (connector
->encoder
!= encoder
)
1085 mode_ok
= hdmi_mode_valid(connector
, adjusted_mode
);
1087 /* just return if user desired mode exists. */
1088 if (mode_ok
== MODE_OK
)
1092 * otherwise, find the most suitable mode among modes and change it
1095 list_for_each_entry(m
, &connector
->modes
, head
) {
1096 mode_ok
= hdmi_mode_valid(connector
, m
);
1098 if (mode_ok
== MODE_OK
) {
1099 DRM_INFO("desired mode doesn't exist so\n");
1100 DRM_INFO("use the most suitable mode among modes.\n");
1102 DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n",
1103 m
->hdisplay
, m
->vdisplay
, m
->vrefresh
);
1105 drm_mode_copy(adjusted_mode
, m
);
1113 static void hdmi_set_acr(u32 freq
, u8
*acr
)
1153 acr
[2] = cts
>> 8 & 0xff;
1154 acr
[3] = cts
& 0xff;
1157 acr
[5] = n
>> 8 & 0xff;
1161 static void hdmi_reg_acr(struct hdmi_context
*hdata
, u8
*acr
)
1163 hdmi_reg_writeb(hdata
, HDMI_ACR_N0
, acr
[6]);
1164 hdmi_reg_writeb(hdata
, HDMI_ACR_N1
, acr
[5]);
1165 hdmi_reg_writeb(hdata
, HDMI_ACR_N2
, acr
[4]);
1166 hdmi_reg_writeb(hdata
, HDMI_ACR_MCTS0
, acr
[3]);
1167 hdmi_reg_writeb(hdata
, HDMI_ACR_MCTS1
, acr
[2]);
1168 hdmi_reg_writeb(hdata
, HDMI_ACR_MCTS2
, acr
[1]);
1169 hdmi_reg_writeb(hdata
, HDMI_ACR_CTS0
, acr
[3]);
1170 hdmi_reg_writeb(hdata
, HDMI_ACR_CTS1
, acr
[2]);
1171 hdmi_reg_writeb(hdata
, HDMI_ACR_CTS2
, acr
[1]);
1172 hdmi_reg_writeb(hdata
, HDMI_ACR_CON
, 4);
1175 static void hdmi_audio_init(struct hdmi_context
*hdata
)
1177 u32 sample_rate
, bits_per_sample
;
1178 u32 data_num
, bit_ch
, sample_frq
;
1182 sample_rate
= 44100;
1183 bits_per_sample
= 16;
1185 switch (bits_per_sample
) {
1200 hdmi_set_acr(sample_rate
, acr
);
1201 hdmi_reg_acr(hdata
, acr
);
1203 hdmi_reg_writeb(hdata
, HDMI_I2S_MUX_CON
, HDMI_I2S_IN_DISABLE
1204 | HDMI_I2S_AUD_I2S
| HDMI_I2S_CUV_I2S_ENABLE
1205 | HDMI_I2S_MUX_ENABLE
);
1207 hdmi_reg_writeb(hdata
, HDMI_I2S_MUX_CH
, HDMI_I2S_CH0_EN
1208 | HDMI_I2S_CH1_EN
| HDMI_I2S_CH2_EN
);
1210 hdmi_reg_writeb(hdata
, HDMI_I2S_MUX_CUV
, HDMI_I2S_CUV_RL_EN
);
1212 sample_frq
= (sample_rate
== 44100) ? 0 :
1213 (sample_rate
== 48000) ? 2 :
1214 (sample_rate
== 32000) ? 3 :
1215 (sample_rate
== 96000) ? 0xa : 0x0;
1217 hdmi_reg_writeb(hdata
, HDMI_I2S_CLK_CON
, HDMI_I2S_CLK_DIS
);
1218 hdmi_reg_writeb(hdata
, HDMI_I2S_CLK_CON
, HDMI_I2S_CLK_EN
);
1220 val
= hdmi_reg_read(hdata
, HDMI_I2S_DSD_CON
) | 0x01;
1221 hdmi_reg_writeb(hdata
, HDMI_I2S_DSD_CON
, val
);
1223 /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1224 hdmi_reg_writeb(hdata
, HDMI_I2S_PIN_SEL_0
, HDMI_I2S_SEL_SCLK(5)
1225 | HDMI_I2S_SEL_LRCK(6));
1226 hdmi_reg_writeb(hdata
, HDMI_I2S_PIN_SEL_1
, HDMI_I2S_SEL_SDATA1(1)
1227 | HDMI_I2S_SEL_SDATA2(4));
1228 hdmi_reg_writeb(hdata
, HDMI_I2S_PIN_SEL_2
, HDMI_I2S_SEL_SDATA3(1)
1229 | HDMI_I2S_SEL_SDATA2(2));
1230 hdmi_reg_writeb(hdata
, HDMI_I2S_PIN_SEL_3
, HDMI_I2S_SEL_DSD(0));
1233 hdmi_reg_writeb(hdata
, HDMI_I2S_CON_1
, HDMI_I2S_SCLK_FALLING_EDGE
1234 | HDMI_I2S_L_CH_LOW_POL
);
1235 hdmi_reg_writeb(hdata
, HDMI_I2S_CON_2
, HDMI_I2S_MSB_FIRST_MODE
1236 | HDMI_I2S_SET_BIT_CH(bit_ch
)
1237 | HDMI_I2S_SET_SDATA_BIT(data_num
)
1238 | HDMI_I2S_BASIC_FORMAT
);
1240 /* Configure register related to CUV information */
1241 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_0
, HDMI_I2S_CH_STATUS_MODE_0
1242 | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1243 | HDMI_I2S_COPYRIGHT
1244 | HDMI_I2S_LINEAR_PCM
1245 | HDMI_I2S_CONSUMER_FORMAT
);
1246 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_1
, HDMI_I2S_CD_PLAYER
);
1247 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_2
, HDMI_I2S_SET_SOURCE_NUM(0));
1248 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_3
, HDMI_I2S_CLK_ACCUR_LEVEL_2
1249 | HDMI_I2S_SET_SMP_FREQ(sample_frq
));
1250 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_4
,
1251 HDMI_I2S_ORG_SMP_FREQ_44_1
1252 | HDMI_I2S_WORD_LEN_MAX24_24BITS
1253 | HDMI_I2S_WORD_LEN_MAX_24BITS
);
1255 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_CON
, HDMI_I2S_CH_STATUS_RELOAD
);
1258 static void hdmi_audio_control(struct hdmi_context
*hdata
, bool onoff
)
1260 if (hdata
->dvi_mode
)
1263 hdmi_reg_writeb(hdata
, HDMI_AUI_CON
, onoff
? 2 : 0);
1264 hdmi_reg_writemask(hdata
, HDMI_CON_0
, onoff
?
1265 HDMI_ASP_EN
: HDMI_ASP_DIS
, HDMI_ASP_MASK
);
1268 static void hdmi_start(struct hdmi_context
*hdata
, bool start
)
1270 u32 val
= start
? HDMI_TG_EN
: 0;
1272 if (hdata
->current_mode
.flags
& DRM_MODE_FLAG_INTERLACE
)
1273 val
|= HDMI_FIELD_EN
;
1275 hdmi_reg_writemask(hdata
, HDMI_CON_0
, val
, HDMI_EN
);
1276 hdmi_reg_writemask(hdata
, HDMI_TG_CMD
, val
, HDMI_TG_EN
| HDMI_FIELD_EN
);
1279 static void hdmi_conf_init(struct hdmi_context
*hdata
)
1281 union hdmi_infoframe infoframe
;
1283 /* disable HPD interrupts from HDMI IP block, use GPIO instead */
1284 hdmi_reg_writemask(hdata
, HDMI_INTC_CON
, 0, HDMI_INTC_EN_GLOBAL
|
1285 HDMI_INTC_EN_HPD_PLUG
| HDMI_INTC_EN_HPD_UNPLUG
);
1287 /* choose HDMI mode */
1288 hdmi_reg_writemask(hdata
, HDMI_MODE_SEL
,
1289 HDMI_MODE_HDMI_EN
, HDMI_MODE_MASK
);
1290 /* Apply Video preable and Guard band in HDMI mode only */
1291 hdmi_reg_writeb(hdata
, HDMI_CON_2
, 0);
1292 /* disable bluescreen */
1293 hdmi_reg_writemask(hdata
, HDMI_CON_0
, 0, HDMI_BLUE_SCR_EN
);
1295 if (hdata
->dvi_mode
) {
1296 /* choose DVI mode */
1297 hdmi_reg_writemask(hdata
, HDMI_MODE_SEL
,
1298 HDMI_MODE_DVI_EN
, HDMI_MODE_MASK
);
1299 hdmi_reg_writeb(hdata
, HDMI_CON_2
,
1300 HDMI_VID_PREAMBLE_DIS
| HDMI_GUARD_BAND_DIS
);
1303 if (hdata
->drv_data
->type
== HDMI_TYPE13
) {
1304 /* choose bluescreen (fecal) color */
1305 hdmi_reg_writeb(hdata
, HDMI_V13_BLUE_SCREEN_0
, 0x12);
1306 hdmi_reg_writeb(hdata
, HDMI_V13_BLUE_SCREEN_1
, 0x34);
1307 hdmi_reg_writeb(hdata
, HDMI_V13_BLUE_SCREEN_2
, 0x56);
1309 /* enable AVI packet every vsync, fixes purple line problem */
1310 hdmi_reg_writeb(hdata
, HDMI_V13_AVI_CON
, 0x02);
1311 /* force RGB, look to CEA-861-D, table 7 for more detail */
1312 hdmi_reg_writeb(hdata
, HDMI_V13_AVI_BYTE(0), 0 << 5);
1313 hdmi_reg_writemask(hdata
, HDMI_CON_1
, 0x10 << 5, 0x11 << 5);
1315 hdmi_reg_writeb(hdata
, HDMI_V13_SPD_CON
, 0x02);
1316 hdmi_reg_writeb(hdata
, HDMI_V13_AUI_CON
, 0x02);
1317 hdmi_reg_writeb(hdata
, HDMI_V13_ACR_CON
, 0x04);
1319 infoframe
.any
.type
= HDMI_INFOFRAME_TYPE_AVI
;
1320 infoframe
.any
.version
= HDMI_AVI_VERSION
;
1321 infoframe
.any
.length
= HDMI_AVI_LENGTH
;
1322 hdmi_reg_infoframe(hdata
, &infoframe
);
1324 infoframe
.any
.type
= HDMI_INFOFRAME_TYPE_AUDIO
;
1325 infoframe
.any
.version
= HDMI_AUI_VERSION
;
1326 infoframe
.any
.length
= HDMI_AUI_LENGTH
;
1327 hdmi_reg_infoframe(hdata
, &infoframe
);
1329 /* enable AVI packet every vsync, fixes purple line problem */
1330 hdmi_reg_writemask(hdata
, HDMI_CON_1
, 2, 3 << 5);
1334 static void hdmiphy_wait_for_pll(struct hdmi_context
*hdata
)
1338 for (tries
= 0; tries
< 10; ++tries
) {
1339 u32 val
= hdmi_reg_read(hdata
, HDMI_PHY_STATUS
);
1341 if (val
& HDMI_PHY_STATUS_READY
) {
1342 DRM_DEBUG_KMS("PLL stabilized after %d tries\n", tries
);
1345 usleep_range(10, 20);
1348 DRM_ERROR("PLL could not reach steady state\n");
1351 static void hdmi_v13_mode_apply(struct hdmi_context
*hdata
)
1353 struct drm_display_mode
*m
= &hdata
->current_mode
;
1356 hdmi_reg_writev(hdata
, HDMI_H_BLANK_0
, 2, m
->htotal
- m
->hdisplay
);
1357 hdmi_reg_writev(hdata
, HDMI_V13_H_V_LINE_0
, 3,
1358 (m
->htotal
<< 12) | m
->vtotal
);
1360 val
= (m
->flags
& DRM_MODE_FLAG_NVSYNC
) ? 1 : 0;
1361 hdmi_reg_writev(hdata
, HDMI_VSYNC_POL
, 1, val
);
1363 val
= (m
->flags
& DRM_MODE_FLAG_INTERLACE
) ? 1 : 0;
1364 hdmi_reg_writev(hdata
, HDMI_INT_PRO_MODE
, 1, val
);
1366 val
= (m
->hsync_start
- m
->hdisplay
- 2);
1367 val
|= ((m
->hsync_end
- m
->hdisplay
- 2) << 10);
1368 val
|= ((m
->flags
& DRM_MODE_FLAG_NHSYNC
) ? 1 : 0)<<20;
1369 hdmi_reg_writev(hdata
, HDMI_V13_H_SYNC_GEN_0
, 3, val
);
1372 * Quirk requirement for exynos HDMI IP design,
1373 * 2 pixels less than the actual calculation for hsync_start
1377 /* Following values & calculations differ for different type of modes */
1378 if (m
->flags
& DRM_MODE_FLAG_INTERLACE
) {
1379 /* Interlaced Mode */
1380 val
= ((m
->vsync_end
- m
->vdisplay
) / 2);
1381 val
|= ((m
->vsync_start
- m
->vdisplay
) / 2) << 12;
1382 hdmi_reg_writev(hdata
, HDMI_V13_V_SYNC_GEN_1_0
, 3, val
);
1384 val
= m
->vtotal
/ 2;
1385 val
|= ((m
->vtotal
- m
->vdisplay
) / 2) << 11;
1386 hdmi_reg_writev(hdata
, HDMI_V13_V_BLANK_0
, 3, val
);
1389 ((m
->vsync_end
- m
->vsync_start
) * 4) + 5) / 2;
1390 val
|= m
->vtotal
<< 11;
1391 hdmi_reg_writev(hdata
, HDMI_V13_V_BLANK_F_0
, 3, val
);
1393 val
= ((m
->vtotal
/ 2) + 7);
1394 val
|= ((m
->vtotal
/ 2) + 2) << 12;
1395 hdmi_reg_writev(hdata
, HDMI_V13_V_SYNC_GEN_2_0
, 3, val
);
1397 val
= ((m
->htotal
/ 2) + (m
->hsync_start
- m
->hdisplay
));
1398 val
|= ((m
->htotal
/ 2) +
1399 (m
->hsync_start
- m
->hdisplay
)) << 12;
1400 hdmi_reg_writev(hdata
, HDMI_V13_V_SYNC_GEN_3_0
, 3, val
);
1402 hdmi_reg_writev(hdata
, HDMI_TG_VACT_ST_L
, 2,
1403 (m
->vtotal
- m
->vdisplay
) / 2);
1404 hdmi_reg_writev(hdata
, HDMI_TG_VACT_SZ_L
, 2, m
->vdisplay
/ 2);
1406 hdmi_reg_writev(hdata
, HDMI_TG_VACT_ST2_L
, 2, 0x249);
1408 /* Progressive Mode */
1411 val
|= (m
->vtotal
- m
->vdisplay
) << 11;
1412 hdmi_reg_writev(hdata
, HDMI_V13_V_BLANK_0
, 3, val
);
1414 hdmi_reg_writev(hdata
, HDMI_V13_V_BLANK_F_0
, 3, 0);
1416 val
= (m
->vsync_end
- m
->vdisplay
);
1417 val
|= ((m
->vsync_start
- m
->vdisplay
) << 12);
1418 hdmi_reg_writev(hdata
, HDMI_V13_V_SYNC_GEN_1_0
, 3, val
);
1420 hdmi_reg_writev(hdata
, HDMI_V13_V_SYNC_GEN_2_0
, 3, 0x1001);
1421 hdmi_reg_writev(hdata
, HDMI_V13_V_SYNC_GEN_3_0
, 3, 0x1001);
1422 hdmi_reg_writev(hdata
, HDMI_TG_VACT_ST_L
, 2,
1423 m
->vtotal
- m
->vdisplay
);
1424 hdmi_reg_writev(hdata
, HDMI_TG_VACT_SZ_L
, 2, m
->vdisplay
);
1425 hdmi_reg_writev(hdata
, HDMI_TG_VACT_ST2_L
, 2, 0x248);
1428 /* Timing generator registers */
1429 hdmi_reg_writev(hdata
, HDMI_TG_H_FSZ_L
, 2, m
->htotal
);
1430 hdmi_reg_writev(hdata
, HDMI_TG_HACT_ST_L
, 2, m
->htotal
- m
->hdisplay
);
1431 hdmi_reg_writev(hdata
, HDMI_TG_HACT_SZ_L
, 2, m
->hdisplay
);
1432 hdmi_reg_writev(hdata
, HDMI_TG_V_FSZ_L
, 2, m
->vtotal
);
1433 hdmi_reg_writev(hdata
, HDMI_TG_VSYNC_L
, 2, 0x1);
1434 hdmi_reg_writev(hdata
, HDMI_TG_VSYNC2_L
, 2, 0x233);
1435 hdmi_reg_writev(hdata
, HDMI_TG_FIELD_CHG_L
, 2, 0x233);
1436 hdmi_reg_writev(hdata
, HDMI_TG_VSYNC_TOP_HDMI_L
, 2, 0x1);
1437 hdmi_reg_writev(hdata
, HDMI_TG_VSYNC_BOT_HDMI_L
, 2, 0x233);
1438 hdmi_reg_writev(hdata
, HDMI_TG_FIELD_TOP_HDMI_L
, 2, 0x1);
1439 hdmi_reg_writev(hdata
, HDMI_TG_FIELD_BOT_HDMI_L
, 2, 0x233);
1442 static void hdmi_v14_mode_apply(struct hdmi_context
*hdata
)
1444 struct drm_display_mode
*m
= &hdata
->current_mode
;
1446 hdmi_reg_writev(hdata
, HDMI_H_BLANK_0
, 2, m
->htotal
- m
->hdisplay
);
1447 hdmi_reg_writev(hdata
, HDMI_V_LINE_0
, 2, m
->vtotal
);
1448 hdmi_reg_writev(hdata
, HDMI_H_LINE_0
, 2, m
->htotal
);
1449 hdmi_reg_writev(hdata
, HDMI_HSYNC_POL
, 1,
1450 (m
->flags
& DRM_MODE_FLAG_NHSYNC
) ? 1 : 0);
1451 hdmi_reg_writev(hdata
, HDMI_VSYNC_POL
, 1,
1452 (m
->flags
& DRM_MODE_FLAG_NVSYNC
) ? 1 : 0);
1453 hdmi_reg_writev(hdata
, HDMI_INT_PRO_MODE
, 1,
1454 (m
->flags
& DRM_MODE_FLAG_INTERLACE
) ? 1 : 0);
1457 * Quirk requirement for exynos 5 HDMI IP design,
1458 * 2 pixels less than the actual calculation for hsync_start
1462 /* Following values & calculations differ for different type of modes */
1463 if (m
->flags
& DRM_MODE_FLAG_INTERLACE
) {
1464 /* Interlaced Mode */
1465 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_BEF_2_0
, 2,
1466 (m
->vsync_end
- m
->vdisplay
) / 2);
1467 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_BEF_1_0
, 2,
1468 (m
->vsync_start
- m
->vdisplay
) / 2);
1469 hdmi_reg_writev(hdata
, HDMI_V2_BLANK_0
, 2, m
->vtotal
/ 2);
1470 hdmi_reg_writev(hdata
, HDMI_V1_BLANK_0
, 2,
1471 (m
->vtotal
- m
->vdisplay
) / 2);
1472 hdmi_reg_writev(hdata
, HDMI_V_BLANK_F0_0
, 2,
1473 m
->vtotal
- m
->vdisplay
/ 2);
1474 hdmi_reg_writev(hdata
, HDMI_V_BLANK_F1_0
, 2, m
->vtotal
);
1475 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_AFT_2_0
, 2,
1476 (m
->vtotal
/ 2) + 7);
1477 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_AFT_1_0
, 2,
1478 (m
->vtotal
/ 2) + 2);
1479 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_2_0
, 2,
1480 (m
->htotal
/ 2) + (m
->hsync_start
- m
->hdisplay
));
1481 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_1_0
, 2,
1482 (m
->htotal
/ 2) + (m
->hsync_start
- m
->hdisplay
));
1483 hdmi_reg_writev(hdata
, HDMI_TG_VACT_ST_L
, 2,
1484 (m
->vtotal
- m
->vdisplay
) / 2);
1485 hdmi_reg_writev(hdata
, HDMI_TG_VACT_SZ_L
, 2, m
->vdisplay
/ 2);
1486 hdmi_reg_writev(hdata
, HDMI_TG_VACT_ST2_L
, 2,
1487 m
->vtotal
- m
->vdisplay
/ 2);
1488 hdmi_reg_writev(hdata
, HDMI_TG_VSYNC2_L
, 2,
1489 (m
->vtotal
/ 2) + 1);
1490 hdmi_reg_writev(hdata
, HDMI_TG_VSYNC_BOT_HDMI_L
, 2,
1491 (m
->vtotal
/ 2) + 1);
1492 hdmi_reg_writev(hdata
, HDMI_TG_FIELD_BOT_HDMI_L
, 2,
1493 (m
->vtotal
/ 2) + 1);
1494 hdmi_reg_writev(hdata
, HDMI_TG_VACT_ST3_L
, 2, 0x0);
1495 hdmi_reg_writev(hdata
, HDMI_TG_VACT_ST4_L
, 2, 0x0);
1497 /* Progressive Mode */
1498 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_BEF_2_0
, 2,
1499 m
->vsync_end
- m
->vdisplay
);
1500 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_BEF_1_0
, 2,
1501 m
->vsync_start
- m
->vdisplay
);
1502 hdmi_reg_writev(hdata
, HDMI_V2_BLANK_0
, 2, m
->vtotal
);
1503 hdmi_reg_writev(hdata
, HDMI_V1_BLANK_0
, 2,
1504 m
->vtotal
- m
->vdisplay
);
1505 hdmi_reg_writev(hdata
, HDMI_V_BLANK_F0_0
, 2, 0xffff);
1506 hdmi_reg_writev(hdata
, HDMI_V_BLANK_F1_0
, 2, 0xffff);
1507 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_AFT_2_0
, 2, 0xffff);
1508 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_AFT_1_0
, 2, 0xffff);
1509 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_2_0
, 2, 0xffff);
1510 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_1_0
, 2, 0xffff);
1511 hdmi_reg_writev(hdata
, HDMI_TG_VACT_ST_L
, 2,
1512 m
->vtotal
- m
->vdisplay
);
1513 hdmi_reg_writev(hdata
, HDMI_TG_VACT_SZ_L
, 2, m
->vdisplay
);
1514 hdmi_reg_writev(hdata
, HDMI_TG_VACT_ST2_L
, 2, 0x248);
1515 hdmi_reg_writev(hdata
, HDMI_TG_VACT_ST3_L
, 2, 0x47b);
1516 hdmi_reg_writev(hdata
, HDMI_TG_VACT_ST4_L
, 2, 0x6ae);
1517 hdmi_reg_writev(hdata
, HDMI_TG_VSYNC2_L
, 2, 0x233);
1518 hdmi_reg_writev(hdata
, HDMI_TG_VSYNC_BOT_HDMI_L
, 2, 0x233);
1519 hdmi_reg_writev(hdata
, HDMI_TG_FIELD_BOT_HDMI_L
, 2, 0x233);
1522 /* Following values & calculations are same irrespective of mode type */
1523 hdmi_reg_writev(hdata
, HDMI_H_SYNC_START_0
, 2,
1524 m
->hsync_start
- m
->hdisplay
- 2);
1525 hdmi_reg_writev(hdata
, HDMI_H_SYNC_END_0
, 2,
1526 m
->hsync_end
- m
->hdisplay
- 2);
1527 hdmi_reg_writev(hdata
, HDMI_VACT_SPACE_1_0
, 2, 0xffff);
1528 hdmi_reg_writev(hdata
, HDMI_VACT_SPACE_2_0
, 2, 0xffff);
1529 hdmi_reg_writev(hdata
, HDMI_VACT_SPACE_3_0
, 2, 0xffff);
1530 hdmi_reg_writev(hdata
, HDMI_VACT_SPACE_4_0
, 2, 0xffff);
1531 hdmi_reg_writev(hdata
, HDMI_VACT_SPACE_5_0
, 2, 0xffff);
1532 hdmi_reg_writev(hdata
, HDMI_VACT_SPACE_6_0
, 2, 0xffff);
1533 hdmi_reg_writev(hdata
, HDMI_V_BLANK_F2_0
, 2, 0xffff);
1534 hdmi_reg_writev(hdata
, HDMI_V_BLANK_F3_0
, 2, 0xffff);
1535 hdmi_reg_writev(hdata
, HDMI_V_BLANK_F4_0
, 2, 0xffff);
1536 hdmi_reg_writev(hdata
, HDMI_V_BLANK_F5_0
, 2, 0xffff);
1537 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_AFT_3_0
, 2, 0xffff);
1538 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_AFT_4_0
, 2, 0xffff);
1539 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_AFT_5_0
, 2, 0xffff);
1540 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_AFT_6_0
, 2, 0xffff);
1541 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_3_0
, 2, 0xffff);
1542 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_4_0
, 2, 0xffff);
1543 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_5_0
, 2, 0xffff);
1544 hdmi_reg_writev(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_6_0
, 2, 0xffff);
1546 /* Timing generator registers */
1547 hdmi_reg_writev(hdata
, HDMI_TG_H_FSZ_L
, 2, m
->htotal
);
1548 hdmi_reg_writev(hdata
, HDMI_TG_HACT_ST_L
, 2, m
->htotal
- m
->hdisplay
);
1549 hdmi_reg_writev(hdata
, HDMI_TG_HACT_SZ_L
, 2, m
->hdisplay
);
1550 hdmi_reg_writev(hdata
, HDMI_TG_V_FSZ_L
, 2, m
->vtotal
);
1551 hdmi_reg_writev(hdata
, HDMI_TG_VSYNC_L
, 2, 0x1);
1552 hdmi_reg_writev(hdata
, HDMI_TG_FIELD_CHG_L
, 2, 0x233);
1553 hdmi_reg_writev(hdata
, HDMI_TG_VSYNC_TOP_HDMI_L
, 2, 0x1);
1554 hdmi_reg_writev(hdata
, HDMI_TG_FIELD_TOP_HDMI_L
, 2, 0x1);
1555 hdmi_reg_writev(hdata
, HDMI_TG_3D
, 1, 0x0);
1558 static void hdmi_mode_apply(struct hdmi_context
*hdata
)
1560 if (hdata
->drv_data
->type
== HDMI_TYPE13
)
1561 hdmi_v13_mode_apply(hdata
);
1563 hdmi_v14_mode_apply(hdata
);
1565 hdmiphy_wait_for_pll(hdata
);
1567 clk_disable_unprepare(hdata
->res
.sclk_hdmi
);
1568 clk_set_parent(hdata
->res
.mout_hdmi
, hdata
->res
.sclk_hdmiphy
);
1569 clk_prepare_enable(hdata
->res
.sclk_hdmi
);
1571 /* enable HDMI and timing generator */
1572 hdmi_start(hdata
, true);
1575 static void hdmiphy_conf_reset(struct hdmi_context
*hdata
)
1577 clk_disable_unprepare(hdata
->res
.sclk_hdmi
);
1578 clk_set_parent(hdata
->res
.mout_hdmi
, hdata
->res
.sclk_pixel
);
1579 clk_prepare_enable(hdata
->res
.sclk_hdmi
);
1582 hdmi_reg_writemask(hdata
, HDMI_PHY_RSTOUT
, ~0, HDMI_PHY_SW_RSTOUT
);
1583 usleep_range(10000, 12000);
1584 hdmi_reg_writemask(hdata
, HDMI_PHY_RSTOUT
, 0, HDMI_PHY_SW_RSTOUT
);
1585 usleep_range(10000, 12000);
1588 static void hdmiphy_conf_apply(struct hdmi_context
*hdata
)
1594 i
= hdmi_find_phy_conf(hdata
, hdata
->current_mode
.clock
* 1000);
1596 DRM_ERROR("failed to find hdmiphy conf\n");
1600 ret
= hdmiphy_reg_write_buf(hdata
, 0,
1601 hdata
->drv_data
->phy_confs
[i
].conf
, 32);
1603 DRM_ERROR("failed to configure hdmiphy\n");
1607 usleep_range(10000, 12000);
1610 static void hdmi_conf_apply(struct hdmi_context
*hdata
)
1612 hdmiphy_conf_reset(hdata
);
1613 hdmiphy_conf_apply(hdata
);
1615 hdmi_start(hdata
, false);
1616 hdmi_conf_init(hdata
);
1618 hdmi_audio_init(hdata
);
1620 /* setting core registers */
1621 hdmi_mode_apply(hdata
);
1622 hdmi_audio_control(hdata
, true);
1624 hdmi_regs_dump(hdata
, "start");
1627 static void hdmi_mode_set(struct drm_encoder
*encoder
,
1628 struct drm_display_mode
*mode
,
1629 struct drm_display_mode
*adjusted_mode
)
1631 struct hdmi_context
*hdata
= encoder_to_hdmi(encoder
);
1632 struct drm_display_mode
*m
= adjusted_mode
;
1634 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n",
1635 m
->hdisplay
, m
->vdisplay
,
1636 m
->vrefresh
, (m
->flags
& DRM_MODE_FLAG_INTERLACE
) ?
1637 "INTERLACED" : "PROGRESSIVE");
1639 drm_mode_copy(&hdata
->current_mode
, m
);
1640 hdata
->cea_video_id
= drm_match_cea_mode(mode
);
1643 static void hdmi_enable(struct drm_encoder
*encoder
)
1645 struct hdmi_context
*hdata
= encoder_to_hdmi(encoder
);
1646 struct hdmi_resources
*res
= &hdata
->res
;
1651 hdata
->powered
= true;
1653 pm_runtime_get_sync(hdata
->dev
);
1655 if (regulator_bulk_enable(res
->regul_count
, res
->regul_bulk
))
1656 DRM_DEBUG_KMS("failed to enable regulator bulk\n");
1658 /* set pmu hdmiphy control bit to enable hdmiphy */
1659 regmap_update_bits(hdata
->pmureg
, PMU_HDMI_PHY_CONTROL
,
1660 PMU_HDMI_PHY_ENABLE_BIT
, 1);
1662 clk_prepare_enable(res
->hdmi
);
1663 clk_prepare_enable(res
->sclk_hdmi
);
1665 hdmi_conf_apply(hdata
);
1668 static void hdmi_disable(struct drm_encoder
*encoder
)
1670 struct hdmi_context
*hdata
= encoder_to_hdmi(encoder
);
1671 struct hdmi_resources
*res
= &hdata
->res
;
1672 struct drm_crtc
*crtc
= encoder
->crtc
;
1673 const struct drm_crtc_helper_funcs
*funcs
= NULL
;
1675 if (!hdata
->powered
)
1679 * The SFRs of VP and Mixer are updated by Vertical Sync of
1680 * Timing generator which is a part of HDMI so the sequence
1681 * to disable TV Subsystem should be as following,
1682 * VP -> Mixer -> HDMI
1684 * Below codes will try to disable Mixer and VP(if used)
1685 * prior to disabling HDMI.
1688 funcs
= crtc
->helper_private
;
1689 if (funcs
&& funcs
->disable
)
1690 (*funcs
->disable
)(crtc
);
1692 /* HDMI System Disable */
1693 hdmi_reg_writemask(hdata
, HDMI_CON_0
, 0, HDMI_EN
);
1695 cancel_delayed_work(&hdata
->hotplug_work
);
1697 clk_disable_unprepare(res
->sclk_hdmi
);
1698 clk_disable_unprepare(res
->hdmi
);
1700 /* reset pmu hdmiphy control bit to disable hdmiphy */
1701 regmap_update_bits(hdata
->pmureg
, PMU_HDMI_PHY_CONTROL
,
1702 PMU_HDMI_PHY_ENABLE_BIT
, 0);
1704 regulator_bulk_disable(res
->regul_count
, res
->regul_bulk
);
1706 pm_runtime_put_sync(hdata
->dev
);
1708 hdata
->powered
= false;
1711 static struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs
= {
1712 .mode_fixup
= hdmi_mode_fixup
,
1713 .mode_set
= hdmi_mode_set
,
1714 .enable
= hdmi_enable
,
1715 .disable
= hdmi_disable
,
1718 static struct drm_encoder_funcs exynos_hdmi_encoder_funcs
= {
1719 .destroy
= drm_encoder_cleanup
,
1722 static void hdmi_hotplug_work_func(struct work_struct
*work
)
1724 struct hdmi_context
*hdata
;
1726 hdata
= container_of(work
, struct hdmi_context
, hotplug_work
.work
);
1729 drm_helper_hpd_irq_event(hdata
->drm_dev
);
1732 static irqreturn_t
hdmi_irq_thread(int irq
, void *arg
)
1734 struct hdmi_context
*hdata
= arg
;
1736 mod_delayed_work(system_wq
, &hdata
->hotplug_work
,
1737 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS
));
1742 static int hdmi_resources_init(struct hdmi_context
*hdata
)
1744 struct device
*dev
= hdata
->dev
;
1745 struct hdmi_resources
*res
= &hdata
->res
;
1746 static char *supply
[] = {
1753 DRM_DEBUG_KMS("HDMI resource init\n");
1755 /* get clocks, power */
1756 res
->hdmi
= devm_clk_get(dev
, "hdmi");
1757 if (IS_ERR(res
->hdmi
)) {
1758 DRM_ERROR("failed to get clock 'hdmi'\n");
1759 ret
= PTR_ERR(res
->hdmi
);
1762 res
->sclk_hdmi
= devm_clk_get(dev
, "sclk_hdmi");
1763 if (IS_ERR(res
->sclk_hdmi
)) {
1764 DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
1765 ret
= PTR_ERR(res
->sclk_hdmi
);
1768 res
->sclk_pixel
= devm_clk_get(dev
, "sclk_pixel");
1769 if (IS_ERR(res
->sclk_pixel
)) {
1770 DRM_ERROR("failed to get clock 'sclk_pixel'\n");
1771 ret
= PTR_ERR(res
->sclk_pixel
);
1774 res
->sclk_hdmiphy
= devm_clk_get(dev
, "sclk_hdmiphy");
1775 if (IS_ERR(res
->sclk_hdmiphy
)) {
1776 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
1777 ret
= PTR_ERR(res
->sclk_hdmiphy
);
1780 res
->mout_hdmi
= devm_clk_get(dev
, "mout_hdmi");
1781 if (IS_ERR(res
->mout_hdmi
)) {
1782 DRM_ERROR("failed to get clock 'mout_hdmi'\n");
1783 ret
= PTR_ERR(res
->mout_hdmi
);
1787 clk_set_parent(res
->mout_hdmi
, res
->sclk_pixel
);
1789 res
->regul_bulk
= devm_kzalloc(dev
, ARRAY_SIZE(supply
) *
1790 sizeof(res
->regul_bulk
[0]), GFP_KERNEL
);
1791 if (!res
->regul_bulk
) {
1795 for (i
= 0; i
< ARRAY_SIZE(supply
); ++i
) {
1796 res
->regul_bulk
[i
].supply
= supply
[i
];
1797 res
->regul_bulk
[i
].consumer
= NULL
;
1799 ret
= devm_regulator_bulk_get(dev
, ARRAY_SIZE(supply
), res
->regul_bulk
);
1801 DRM_ERROR("failed to get regulators\n");
1804 res
->regul_count
= ARRAY_SIZE(supply
);
1806 res
->reg_hdmi_en
= devm_regulator_get_optional(dev
, "hdmi-en");
1808 if (PTR_ERR(res
->reg_hdmi_en
) == -ENODEV
)
1811 if (IS_ERR(res
->reg_hdmi_en
))
1812 return PTR_ERR(res
->reg_hdmi_en
);
1814 ret
= regulator_enable(res
->reg_hdmi_en
);
1816 DRM_ERROR("failed to enable hdmi-en regulator\n");
1820 DRM_ERROR("HDMI resource init - failed\n");
1824 static struct of_device_id hdmi_match_types
[] = {
1826 .compatible
= "samsung,exynos4210-hdmi",
1827 .data
= &exynos4210_hdmi_driver_data
,
1829 .compatible
= "samsung,exynos4212-hdmi",
1830 .data
= &exynos4212_hdmi_driver_data
,
1832 .compatible
= "samsung,exynos5420-hdmi",
1833 .data
= &exynos5420_hdmi_driver_data
,
1838 MODULE_DEVICE_TABLE (of
, hdmi_match_types
);
1840 static int hdmi_bind(struct device
*dev
, struct device
*master
, void *data
)
1842 struct drm_device
*drm_dev
= data
;
1843 struct hdmi_context
*hdata
= dev_get_drvdata(dev
);
1844 struct drm_encoder
*encoder
= &hdata
->encoder
;
1847 hdata
->drm_dev
= drm_dev
;
1849 pipe
= exynos_drm_crtc_get_pipe_from_type(drm_dev
,
1850 EXYNOS_DISPLAY_TYPE_HDMI
);
1854 encoder
->possible_crtcs
= 1 << pipe
;
1856 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder
->possible_crtcs
);
1858 drm_encoder_init(drm_dev
, encoder
, &exynos_hdmi_encoder_funcs
,
1859 DRM_MODE_ENCODER_TMDS
);
1861 drm_encoder_helper_add(encoder
, &exynos_hdmi_encoder_helper_funcs
);
1863 ret
= hdmi_create_connector(encoder
);
1865 DRM_ERROR("failed to create connector ret = %d\n", ret
);
1866 drm_encoder_cleanup(encoder
);
1873 static void hdmi_unbind(struct device
*dev
, struct device
*master
, void *data
)
1877 static const struct component_ops hdmi_component_ops
= {
1879 .unbind
= hdmi_unbind
,
1882 static struct device_node
*hdmi_legacy_ddc_dt_binding(struct device
*dev
)
1884 const char *compatible_str
= "samsung,exynos4210-hdmiddc";
1885 struct device_node
*np
;
1887 np
= of_find_compatible_node(NULL
, NULL
, compatible_str
);
1889 return of_get_next_parent(np
);
1894 static struct device_node
*hdmi_legacy_phy_dt_binding(struct device
*dev
)
1896 const char *compatible_str
= "samsung,exynos4212-hdmiphy";
1898 return of_find_compatible_node(NULL
, NULL
, compatible_str
);
1901 static int hdmi_probe(struct platform_device
*pdev
)
1903 struct device_node
*ddc_node
, *phy_node
;
1904 const struct of_device_id
*match
;
1905 struct device
*dev
= &pdev
->dev
;
1906 struct hdmi_context
*hdata
;
1907 struct resource
*res
;
1910 hdata
= devm_kzalloc(dev
, sizeof(struct hdmi_context
), GFP_KERNEL
);
1914 match
= of_match_device(hdmi_match_types
, dev
);
1918 hdata
->drv_data
= match
->data
;
1920 platform_set_drvdata(pdev
, hdata
);
1923 hdata
->hpd_gpio
= of_get_named_gpio(dev
->of_node
, "hpd-gpio", 0);
1924 if (hdata
->hpd_gpio
< 0) {
1925 DRM_ERROR("cannot get hpd gpio property\n");
1926 return hdata
->hpd_gpio
;
1929 ret
= hdmi_resources_init(hdata
);
1931 DRM_ERROR("hdmi_resources_init failed\n");
1935 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1936 hdata
->regs
= devm_ioremap_resource(dev
, res
);
1937 if (IS_ERR(hdata
->regs
)) {
1938 ret
= PTR_ERR(hdata
->regs
);
1942 ret
= devm_gpio_request(dev
, hdata
->hpd_gpio
, "HPD");
1944 DRM_ERROR("failed to request HPD gpio\n");
1948 ddc_node
= hdmi_legacy_ddc_dt_binding(dev
);
1950 goto out_get_ddc_adpt
;
1952 /* DDC i2c driver */
1953 ddc_node
= of_parse_phandle(dev
->of_node
, "ddc", 0);
1955 DRM_ERROR("Failed to find ddc node in device tree\n");
1960 hdata
->ddc_adpt
= of_find_i2c_adapter_by_node(ddc_node
);
1961 if (!hdata
->ddc_adpt
) {
1962 DRM_ERROR("Failed to get ddc i2c adapter by node\n");
1963 return -EPROBE_DEFER
;
1966 phy_node
= hdmi_legacy_phy_dt_binding(dev
);
1968 goto out_get_phy_port
;
1970 /* hdmiphy i2c driver */
1971 phy_node
= of_parse_phandle(dev
->of_node
, "phy", 0);
1973 DRM_ERROR("Failed to find hdmiphy node in device tree\n");
1979 if (hdata
->drv_data
->is_apb_phy
) {
1980 hdata
->regs_hdmiphy
= of_iomap(phy_node
, 0);
1981 if (!hdata
->regs_hdmiphy
) {
1982 DRM_ERROR("failed to ioremap hdmi phy\n");
1987 hdata
->hdmiphy_port
= of_find_i2c_device_by_node(phy_node
);
1988 if (!hdata
->hdmiphy_port
) {
1989 DRM_ERROR("Failed to get hdmi phy i2c client\n");
1990 ret
= -EPROBE_DEFER
;
1995 hdata
->irq
= gpio_to_irq(hdata
->hpd_gpio
);
1996 if (hdata
->irq
< 0) {
1997 DRM_ERROR("failed to get GPIO irq\n");
2002 INIT_DELAYED_WORK(&hdata
->hotplug_work
, hdmi_hotplug_work_func
);
2004 ret
= devm_request_threaded_irq(dev
, hdata
->irq
, NULL
,
2005 hdmi_irq_thread
, IRQF_TRIGGER_RISING
|
2006 IRQF_TRIGGER_FALLING
| IRQF_ONESHOT
,
2009 DRM_ERROR("failed to register hdmi interrupt\n");
2013 hdata
->pmureg
= syscon_regmap_lookup_by_phandle(dev
->of_node
,
2014 "samsung,syscon-phandle");
2015 if (IS_ERR(hdata
->pmureg
)) {
2016 DRM_ERROR("syscon regmap lookup failed.\n");
2017 ret
= -EPROBE_DEFER
;
2021 pm_runtime_enable(dev
);
2023 ret
= component_add(&pdev
->dev
, &hdmi_component_ops
);
2025 goto err_disable_pm_runtime
;
2029 err_disable_pm_runtime
:
2030 pm_runtime_disable(dev
);
2033 if (hdata
->hdmiphy_port
)
2034 put_device(&hdata
->hdmiphy_port
->dev
);
2036 put_device(&hdata
->ddc_adpt
->dev
);
2041 static int hdmi_remove(struct platform_device
*pdev
)
2043 struct hdmi_context
*hdata
= platform_get_drvdata(pdev
);
2045 cancel_delayed_work_sync(&hdata
->hotplug_work
);
2047 component_del(&pdev
->dev
, &hdmi_component_ops
);
2049 pm_runtime_disable(&pdev
->dev
);
2051 if (!IS_ERR(hdata
->res
.reg_hdmi_en
))
2052 regulator_disable(hdata
->res
.reg_hdmi_en
);
2054 if (hdata
->hdmiphy_port
)
2055 put_device(&hdata
->hdmiphy_port
->dev
);
2057 put_device(&hdata
->ddc_adpt
->dev
);
2062 struct platform_driver hdmi_driver
= {
2063 .probe
= hdmi_probe
,
2064 .remove
= hdmi_remove
,
2066 .name
= "exynos-hdmi",
2067 .owner
= THIS_MODULE
,
2068 .of_match_table
= hdmi_match_types
,