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>
21 #include "regs-hdmi.h"
23 #include <linux/kernel.h>
24 #include <linux/spinlock.h>
25 #include <linux/wait.h>
26 #include <linux/i2c.h>
27 #include <linux/module.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>
36 #include <linux/of_gpio.h>
37 #include <plat/gpio-cfg.h>
39 #include <drm/exynos_drm.h>
41 #include "exynos_drm_drv.h"
42 #include "exynos_drm_hdmi.h"
44 #include "exynos_hdmi.h"
46 #include <linux/gpio.h>
47 #include <media/s5p_hdmi.h>
49 #define MAX_WIDTH 1920
50 #define MAX_HEIGHT 1080
51 #define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev))
53 /* AVI header and aspect ratio */
54 #define HDMI_AVI_VERSION 0x02
55 #define HDMI_AVI_LENGTH 0x0D
56 #define AVI_PIC_ASPECT_RATIO_16_9 (2 << 4)
57 #define AVI_SAME_AS_PIC_ASPECT_RATIO 8
60 #define HDMI_AUI_VERSION 0x01
61 #define HDMI_AUI_LENGTH 0x0A
63 /* HDMI infoframe to configure HDMI out packet header, AUI and AVI */
64 enum HDMI_PACKET_TYPE {
65 /* refer to Table 5-8 Packet Type in HDMI specification v1.4a */
66 /* InfoFrame packet type */
67 HDMI_PACKET_TYPE_INFOFRAME = 0x80,
68 /* Vendor-Specific InfoFrame */
69 HDMI_PACKET_TYPE_VSI = HDMI_PACKET_TYPE_INFOFRAME + 1,
70 /* Auxiliary Video information InfoFrame */
71 HDMI_PACKET_TYPE_AVI = HDMI_PACKET_TYPE_INFOFRAME + 2,
72 /* Audio information InfoFrame */
73 HDMI_PACKET_TYPE_AUI = HDMI_PACKET_TYPE_INFOFRAME + 4
81 struct hdmi_resources {
83 struct clk *sclk_hdmi;
84 struct clk *sclk_pixel;
85 struct clk *sclk_hdmiphy;
87 struct regulator_bulk_data *regul_bulk;
93 struct drm_device *drm_dev;
97 struct mutex hdmi_mutex;
104 struct i2c_client *ddc_port;
105 struct i2c_client *hdmiphy_port;
107 /* current hdmiphy conf index */
110 struct hdmi_resources res;
117 /* HDMI Version 1.3 */
118 static const u8 hdmiphy_v13_conf27[32] = {
119 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
120 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
121 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
122 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
125 static const u8 hdmiphy_v13_conf27_027[32] = {
126 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
127 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
128 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
129 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
132 static const u8 hdmiphy_v13_conf74_175[32] = {
133 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
134 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
135 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
136 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
139 static const u8 hdmiphy_v13_conf74_25[32] = {
140 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
141 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
142 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
143 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
146 static const u8 hdmiphy_v13_conf148_5[32] = {
147 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
148 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
149 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
150 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
153 struct hdmi_v13_tg_regs {
185 struct hdmi_v13_core_regs {
198 struct hdmi_v13_preset_conf {
199 struct hdmi_v13_core_regs core;
200 struct hdmi_v13_tg_regs tg;
203 struct hdmi_v13_conf {
209 const u8 *hdmiphy_data;
210 const struct hdmi_v13_preset_conf *conf;
213 static const struct hdmi_v13_preset_conf hdmi_v13_conf_480p = {
215 .h_blank = {0x8a, 0x00},
216 .v_blank = {0x0d, 0x6a, 0x01},
217 .h_v_line = {0x0d, 0xa2, 0x35},
219 .int_pro_mode = {0x00},
220 .v_blank_f = {0x00, 0x00, 0x00},
221 .h_sync_gen = {0x0e, 0x30, 0x11},
222 .v_sync_gen1 = {0x0f, 0x90, 0x00},
223 /* other don't care */
227 0x5a, 0x03, /* h_fsz */
228 0x8a, 0x00, 0xd0, 0x02, /* hact */
229 0x0d, 0x02, /* v_fsz */
230 0x01, 0x00, 0x33, 0x02, /* vsync */
231 0x2d, 0x00, 0xe0, 0x01, /* vact */
232 0x33, 0x02, /* field_chg */
233 0x49, 0x02, /* vact_st2 */
234 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
235 0x01, 0x00, 0x33, 0x02, /* field top/bot */
239 static const struct hdmi_v13_preset_conf hdmi_v13_conf_720p60 = {
241 .h_blank = {0x72, 0x01},
242 .v_blank = {0xee, 0xf2, 0x00},
243 .h_v_line = {0xee, 0x22, 0x67},
245 .int_pro_mode = {0x00},
246 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
247 .h_sync_gen = {0x6c, 0x50, 0x02},
248 .v_sync_gen1 = {0x0a, 0x50, 0x00},
249 .v_sync_gen2 = {0x01, 0x10, 0x00},
250 .v_sync_gen3 = {0x01, 0x10, 0x00},
251 /* other don't care */
255 0x72, 0x06, /* h_fsz */
256 0x71, 0x01, 0x01, 0x05, /* hact */
257 0xee, 0x02, /* v_fsz */
258 0x01, 0x00, 0x33, 0x02, /* vsync */
259 0x1e, 0x00, 0xd0, 0x02, /* vact */
260 0x33, 0x02, /* field_chg */
261 0x49, 0x02, /* vact_st2 */
262 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
263 0x01, 0x00, 0x33, 0x02, /* field top/bot */
267 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i50 = {
269 .h_blank = {0xd0, 0x02},
270 .v_blank = {0x32, 0xB2, 0x00},
271 .h_v_line = {0x65, 0x04, 0xa5},
273 .int_pro_mode = {0x01},
274 .v_blank_f = {0x49, 0x2A, 0x23},
275 .h_sync_gen = {0x0E, 0xEA, 0x08},
276 .v_sync_gen1 = {0x07, 0x20, 0x00},
277 .v_sync_gen2 = {0x39, 0x42, 0x23},
278 .v_sync_gen3 = {0x38, 0x87, 0x73},
279 /* other don't care */
283 0x50, 0x0A, /* h_fsz */
284 0xCF, 0x02, 0x81, 0x07, /* hact */
285 0x65, 0x04, /* v_fsz */
286 0x01, 0x00, 0x33, 0x02, /* vsync */
287 0x16, 0x00, 0x1c, 0x02, /* vact */
288 0x33, 0x02, /* field_chg */
289 0x49, 0x02, /* vact_st2 */
290 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
291 0x01, 0x00, 0x33, 0x02, /* field top/bot */
295 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p50 = {
297 .h_blank = {0xd0, 0x02},
298 .v_blank = {0x65, 0x6c, 0x01},
299 .h_v_line = {0x65, 0x04, 0xa5},
301 .int_pro_mode = {0x00},
302 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
303 .h_sync_gen = {0x0e, 0xea, 0x08},
304 .v_sync_gen1 = {0x09, 0x40, 0x00},
305 .v_sync_gen2 = {0x01, 0x10, 0x00},
306 .v_sync_gen3 = {0x01, 0x10, 0x00},
307 /* other don't care */
311 0x50, 0x0A, /* h_fsz */
312 0xCF, 0x02, 0x81, 0x07, /* hact */
313 0x65, 0x04, /* v_fsz */
314 0x01, 0x00, 0x33, 0x02, /* vsync */
315 0x2d, 0x00, 0x38, 0x04, /* vact */
316 0x33, 0x02, /* field_chg */
317 0x48, 0x02, /* vact_st2 */
318 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
319 0x01, 0x00, 0x33, 0x02, /* field top/bot */
323 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i60 = {
325 .h_blank = {0x18, 0x01},
326 .v_blank = {0x32, 0xB2, 0x00},
327 .h_v_line = {0x65, 0x84, 0x89},
329 .int_pro_mode = {0x01},
330 .v_blank_f = {0x49, 0x2A, 0x23},
331 .h_sync_gen = {0x56, 0x08, 0x02},
332 .v_sync_gen1 = {0x07, 0x20, 0x00},
333 .v_sync_gen2 = {0x39, 0x42, 0x23},
334 .v_sync_gen3 = {0xa4, 0x44, 0x4a},
335 /* other don't care */
339 0x98, 0x08, /* h_fsz */
340 0x17, 0x01, 0x81, 0x07, /* hact */
341 0x65, 0x04, /* v_fsz */
342 0x01, 0x00, 0x33, 0x02, /* vsync */
343 0x16, 0x00, 0x1c, 0x02, /* vact */
344 0x33, 0x02, /* field_chg */
345 0x49, 0x02, /* vact_st2 */
346 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
347 0x01, 0x00, 0x33, 0x02, /* field top/bot */
351 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60 = {
353 .h_blank = {0x18, 0x01},
354 .v_blank = {0x65, 0x6c, 0x01},
355 .h_v_line = {0x65, 0x84, 0x89},
357 .int_pro_mode = {0x00},
358 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
359 .h_sync_gen = {0x56, 0x08, 0x02},
360 .v_sync_gen1 = {0x09, 0x40, 0x00},
361 .v_sync_gen2 = {0x01, 0x10, 0x00},
362 .v_sync_gen3 = {0x01, 0x10, 0x00},
363 /* other don't care */
367 0x98, 0x08, /* h_fsz */
368 0x17, 0x01, 0x81, 0x07, /* hact */
369 0x65, 0x04, /* v_fsz */
370 0x01, 0x00, 0x33, 0x02, /* vsync */
371 0x2d, 0x00, 0x38, 0x04, /* vact */
372 0x33, 0x02, /* field_chg */
373 0x48, 0x02, /* vact_st2 */
374 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
375 0x01, 0x00, 0x33, 0x02, /* field top/bot */
379 static const struct hdmi_v13_conf hdmi_v13_confs[] = {
380 { 1280, 720, 60, false, 4, hdmiphy_v13_conf74_25,
381 &hdmi_v13_conf_720p60 },
382 { 1280, 720, 50, false, 19, hdmiphy_v13_conf74_25,
383 &hdmi_v13_conf_720p60 },
384 { 720, 480, 60, false, 3, hdmiphy_v13_conf27_027,
385 &hdmi_v13_conf_480p },
386 { 1920, 1080, 50, true, 20, hdmiphy_v13_conf74_25,
387 &hdmi_v13_conf_1080i50 },
388 { 1920, 1080, 50, false, 31, hdmiphy_v13_conf148_5,
389 &hdmi_v13_conf_1080p50 },
390 { 1920, 1080, 60, true, 5, hdmiphy_v13_conf74_25,
391 &hdmi_v13_conf_1080i60 },
392 { 1920, 1080, 60, false, 16, hdmiphy_v13_conf148_5,
393 &hdmi_v13_conf_1080p60 },
396 /* HDMI Version 1.4 */
397 static const u8 hdmiphy_conf27_027[32] = {
398 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
399 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
400 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
401 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
404 static const u8 hdmiphy_conf74_176[32] = {
405 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x5b, 0xef, 0x08,
406 0x81, 0xa0, 0xb9, 0xd8, 0x45, 0xa0, 0xac, 0x80,
407 0x5a, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
408 0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
411 static const u8 hdmiphy_conf74_25[32] = {
412 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
413 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
414 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
415 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
418 static const u8 hdmiphy_conf148_5[32] = {
419 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
420 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
421 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
422 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
425 struct hdmi_tg_regs {
462 struct hdmi_core_regs {
475 u8 v_sync_line_bef_2[2];
476 u8 v_sync_line_bef_1[2];
477 u8 v_sync_line_aft_2[2];
478 u8 v_sync_line_aft_1[2];
479 u8 v_sync_line_aft_pxl_2[2];
480 u8 v_sync_line_aft_pxl_1[2];
481 u8 v_blank_f2[2]; /* for 3D mode */
482 u8 v_blank_f3[2]; /* for 3D mode */
483 u8 v_blank_f4[2]; /* for 3D mode */
484 u8 v_blank_f5[2]; /* for 3D mode */
485 u8 v_sync_line_aft_3[2];
486 u8 v_sync_line_aft_4[2];
487 u8 v_sync_line_aft_5[2];
488 u8 v_sync_line_aft_6[2];
489 u8 v_sync_line_aft_pxl_3[2];
490 u8 v_sync_line_aft_pxl_4[2];
491 u8 v_sync_line_aft_pxl_5[2];
492 u8 v_sync_line_aft_pxl_6[2];
501 struct hdmi_preset_conf {
502 struct hdmi_core_regs core;
503 struct hdmi_tg_regs tg;
512 const u8 *hdmiphy_data;
513 const struct hdmi_preset_conf *conf;
516 static const struct hdmi_preset_conf hdmi_conf_480p60 = {
518 .h_blank = {0x8a, 0x00},
519 .v2_blank = {0x0d, 0x02},
520 .v1_blank = {0x2d, 0x00},
521 .v_line = {0x0d, 0x02},
522 .h_line = {0x5a, 0x03},
525 .int_pro_mode = {0x00},
526 .v_blank_f0 = {0xff, 0xff},
527 .v_blank_f1 = {0xff, 0xff},
528 .h_sync_start = {0x0e, 0x00},
529 .h_sync_end = {0x4c, 0x00},
530 .v_sync_line_bef_2 = {0x0f, 0x00},
531 .v_sync_line_bef_1 = {0x09, 0x00},
532 .v_sync_line_aft_2 = {0xff, 0xff},
533 .v_sync_line_aft_1 = {0xff, 0xff},
534 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
535 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
536 .v_blank_f2 = {0xff, 0xff},
537 .v_blank_f3 = {0xff, 0xff},
538 .v_blank_f4 = {0xff, 0xff},
539 .v_blank_f5 = {0xff, 0xff},
540 .v_sync_line_aft_3 = {0xff, 0xff},
541 .v_sync_line_aft_4 = {0xff, 0xff},
542 .v_sync_line_aft_5 = {0xff, 0xff},
543 .v_sync_line_aft_6 = {0xff, 0xff},
544 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
545 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
546 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
547 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
548 .vact_space_1 = {0xff, 0xff},
549 .vact_space_2 = {0xff, 0xff},
550 .vact_space_3 = {0xff, 0xff},
551 .vact_space_4 = {0xff, 0xff},
552 .vact_space_5 = {0xff, 0xff},
553 .vact_space_6 = {0xff, 0xff},
554 /* other don't care */
558 0x5a, 0x03, /* h_fsz */
559 0x8a, 0x00, 0xd0, 0x02, /* hact */
560 0x0d, 0x02, /* v_fsz */
561 0x01, 0x00, 0x33, 0x02, /* vsync */
562 0x2d, 0x00, 0xe0, 0x01, /* vact */
563 0x33, 0x02, /* field_chg */
564 0x48, 0x02, /* vact_st2 */
565 0x00, 0x00, /* vact_st3 */
566 0x00, 0x00, /* vact_st4 */
567 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
568 0x01, 0x00, 0x33, 0x02, /* field top/bot */
573 static const struct hdmi_preset_conf hdmi_conf_720p50 = {
575 .h_blank = {0xbc, 0x02},
576 .v2_blank = {0xee, 0x02},
577 .v1_blank = {0x1e, 0x00},
578 .v_line = {0xee, 0x02},
579 .h_line = {0xbc, 0x07},
582 .int_pro_mode = {0x00},
583 .v_blank_f0 = {0xff, 0xff},
584 .v_blank_f1 = {0xff, 0xff},
585 .h_sync_start = {0xb6, 0x01},
586 .h_sync_end = {0xde, 0x01},
587 .v_sync_line_bef_2 = {0x0a, 0x00},
588 .v_sync_line_bef_1 = {0x05, 0x00},
589 .v_sync_line_aft_2 = {0xff, 0xff},
590 .v_sync_line_aft_1 = {0xff, 0xff},
591 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
592 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
593 .v_blank_f2 = {0xff, 0xff},
594 .v_blank_f3 = {0xff, 0xff},
595 .v_blank_f4 = {0xff, 0xff},
596 .v_blank_f5 = {0xff, 0xff},
597 .v_sync_line_aft_3 = {0xff, 0xff},
598 .v_sync_line_aft_4 = {0xff, 0xff},
599 .v_sync_line_aft_5 = {0xff, 0xff},
600 .v_sync_line_aft_6 = {0xff, 0xff},
601 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
602 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
603 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
604 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
605 .vact_space_1 = {0xff, 0xff},
606 .vact_space_2 = {0xff, 0xff},
607 .vact_space_3 = {0xff, 0xff},
608 .vact_space_4 = {0xff, 0xff},
609 .vact_space_5 = {0xff, 0xff},
610 .vact_space_6 = {0xff, 0xff},
611 /* other don't care */
615 0xbc, 0x07, /* h_fsz */
616 0xbc, 0x02, 0x00, 0x05, /* hact */
617 0xee, 0x02, /* v_fsz */
618 0x01, 0x00, 0x33, 0x02, /* vsync */
619 0x1e, 0x00, 0xd0, 0x02, /* vact */
620 0x33, 0x02, /* field_chg */
621 0x48, 0x02, /* vact_st2 */
622 0x00, 0x00, /* vact_st3 */
623 0x00, 0x00, /* vact_st4 */
624 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
625 0x01, 0x00, 0x33, 0x02, /* field top/bot */
630 static const struct hdmi_preset_conf hdmi_conf_720p60 = {
632 .h_blank = {0x72, 0x01},
633 .v2_blank = {0xee, 0x02},
634 .v1_blank = {0x1e, 0x00},
635 .v_line = {0xee, 0x02},
636 .h_line = {0x72, 0x06},
639 .int_pro_mode = {0x00},
640 .v_blank_f0 = {0xff, 0xff},
641 .v_blank_f1 = {0xff, 0xff},
642 .h_sync_start = {0x6c, 0x00},
643 .h_sync_end = {0x94, 0x00},
644 .v_sync_line_bef_2 = {0x0a, 0x00},
645 .v_sync_line_bef_1 = {0x05, 0x00},
646 .v_sync_line_aft_2 = {0xff, 0xff},
647 .v_sync_line_aft_1 = {0xff, 0xff},
648 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
649 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
650 .v_blank_f2 = {0xff, 0xff},
651 .v_blank_f3 = {0xff, 0xff},
652 .v_blank_f4 = {0xff, 0xff},
653 .v_blank_f5 = {0xff, 0xff},
654 .v_sync_line_aft_3 = {0xff, 0xff},
655 .v_sync_line_aft_4 = {0xff, 0xff},
656 .v_sync_line_aft_5 = {0xff, 0xff},
657 .v_sync_line_aft_6 = {0xff, 0xff},
658 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
659 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
660 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
661 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
662 .vact_space_1 = {0xff, 0xff},
663 .vact_space_2 = {0xff, 0xff},
664 .vact_space_3 = {0xff, 0xff},
665 .vact_space_4 = {0xff, 0xff},
666 .vact_space_5 = {0xff, 0xff},
667 .vact_space_6 = {0xff, 0xff},
668 /* other don't care */
672 0x72, 0x06, /* h_fsz */
673 0x72, 0x01, 0x00, 0x05, /* hact */
674 0xee, 0x02, /* v_fsz */
675 0x01, 0x00, 0x33, 0x02, /* vsync */
676 0x1e, 0x00, 0xd0, 0x02, /* vact */
677 0x33, 0x02, /* field_chg */
678 0x48, 0x02, /* vact_st2 */
679 0x00, 0x00, /* vact_st3 */
680 0x00, 0x00, /* vact_st4 */
681 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
682 0x01, 0x00, 0x33, 0x02, /* field top/bot */
687 static const struct hdmi_preset_conf hdmi_conf_1080i50 = {
689 .h_blank = {0xd0, 0x02},
690 .v2_blank = {0x32, 0x02},
691 .v1_blank = {0x16, 0x00},
692 .v_line = {0x65, 0x04},
693 .h_line = {0x50, 0x0a},
696 .int_pro_mode = {0x01},
697 .v_blank_f0 = {0x49, 0x02},
698 .v_blank_f1 = {0x65, 0x04},
699 .h_sync_start = {0x0e, 0x02},
700 .h_sync_end = {0x3a, 0x02},
701 .v_sync_line_bef_2 = {0x07, 0x00},
702 .v_sync_line_bef_1 = {0x02, 0x00},
703 .v_sync_line_aft_2 = {0x39, 0x02},
704 .v_sync_line_aft_1 = {0x34, 0x02},
705 .v_sync_line_aft_pxl_2 = {0x38, 0x07},
706 .v_sync_line_aft_pxl_1 = {0x38, 0x07},
707 .v_blank_f2 = {0xff, 0xff},
708 .v_blank_f3 = {0xff, 0xff},
709 .v_blank_f4 = {0xff, 0xff},
710 .v_blank_f5 = {0xff, 0xff},
711 .v_sync_line_aft_3 = {0xff, 0xff},
712 .v_sync_line_aft_4 = {0xff, 0xff},
713 .v_sync_line_aft_5 = {0xff, 0xff},
714 .v_sync_line_aft_6 = {0xff, 0xff},
715 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
716 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
717 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
718 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
719 .vact_space_1 = {0xff, 0xff},
720 .vact_space_2 = {0xff, 0xff},
721 .vact_space_3 = {0xff, 0xff},
722 .vact_space_4 = {0xff, 0xff},
723 .vact_space_5 = {0xff, 0xff},
724 .vact_space_6 = {0xff, 0xff},
725 /* other don't care */
729 0x50, 0x0a, /* h_fsz */
730 0xd0, 0x02, 0x80, 0x07, /* hact */
731 0x65, 0x04, /* v_fsz */
732 0x01, 0x00, 0x33, 0x02, /* vsync */
733 0x16, 0x00, 0x1c, 0x02, /* vact */
734 0x33, 0x02, /* field_chg */
735 0x49, 0x02, /* vact_st2 */
736 0x00, 0x00, /* vact_st3 */
737 0x00, 0x00, /* vact_st4 */
738 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
739 0x01, 0x00, 0x33, 0x02, /* field top/bot */
744 static const struct hdmi_preset_conf hdmi_conf_1080i60 = {
746 .h_blank = {0x18, 0x01},
747 .v2_blank = {0x32, 0x02},
748 .v1_blank = {0x16, 0x00},
749 .v_line = {0x65, 0x04},
750 .h_line = {0x98, 0x08},
753 .int_pro_mode = {0x01},
754 .v_blank_f0 = {0x49, 0x02},
755 .v_blank_f1 = {0x65, 0x04},
756 .h_sync_start = {0x56, 0x00},
757 .h_sync_end = {0x82, 0x00},
758 .v_sync_line_bef_2 = {0x07, 0x00},
759 .v_sync_line_bef_1 = {0x02, 0x00},
760 .v_sync_line_aft_2 = {0x39, 0x02},
761 .v_sync_line_aft_1 = {0x34, 0x02},
762 .v_sync_line_aft_pxl_2 = {0xa4, 0x04},
763 .v_sync_line_aft_pxl_1 = {0xa4, 0x04},
764 .v_blank_f2 = {0xff, 0xff},
765 .v_blank_f3 = {0xff, 0xff},
766 .v_blank_f4 = {0xff, 0xff},
767 .v_blank_f5 = {0xff, 0xff},
768 .v_sync_line_aft_3 = {0xff, 0xff},
769 .v_sync_line_aft_4 = {0xff, 0xff},
770 .v_sync_line_aft_5 = {0xff, 0xff},
771 .v_sync_line_aft_6 = {0xff, 0xff},
772 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
773 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
774 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
775 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
776 .vact_space_1 = {0xff, 0xff},
777 .vact_space_2 = {0xff, 0xff},
778 .vact_space_3 = {0xff, 0xff},
779 .vact_space_4 = {0xff, 0xff},
780 .vact_space_5 = {0xff, 0xff},
781 .vact_space_6 = {0xff, 0xff},
782 /* other don't care */
786 0x98, 0x08, /* h_fsz */
787 0x18, 0x01, 0x80, 0x07, /* hact */
788 0x65, 0x04, /* v_fsz */
789 0x01, 0x00, 0x33, 0x02, /* vsync */
790 0x16, 0x00, 0x1c, 0x02, /* vact */
791 0x33, 0x02, /* field_chg */
792 0x49, 0x02, /* vact_st2 */
793 0x00, 0x00, /* vact_st3 */
794 0x00, 0x00, /* vact_st4 */
795 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
796 0x01, 0x00, 0x33, 0x02, /* field top/bot */
801 static const struct hdmi_preset_conf hdmi_conf_1080p30 = {
803 .h_blank = {0x18, 0x01},
804 .v2_blank = {0x65, 0x04},
805 .v1_blank = {0x2d, 0x00},
806 .v_line = {0x65, 0x04},
807 .h_line = {0x98, 0x08},
810 .int_pro_mode = {0x00},
811 .v_blank_f0 = {0xff, 0xff},
812 .v_blank_f1 = {0xff, 0xff},
813 .h_sync_start = {0x56, 0x00},
814 .h_sync_end = {0x82, 0x00},
815 .v_sync_line_bef_2 = {0x09, 0x00},
816 .v_sync_line_bef_1 = {0x04, 0x00},
817 .v_sync_line_aft_2 = {0xff, 0xff},
818 .v_sync_line_aft_1 = {0xff, 0xff},
819 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
820 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
821 .v_blank_f2 = {0xff, 0xff},
822 .v_blank_f3 = {0xff, 0xff},
823 .v_blank_f4 = {0xff, 0xff},
824 .v_blank_f5 = {0xff, 0xff},
825 .v_sync_line_aft_3 = {0xff, 0xff},
826 .v_sync_line_aft_4 = {0xff, 0xff},
827 .v_sync_line_aft_5 = {0xff, 0xff},
828 .v_sync_line_aft_6 = {0xff, 0xff},
829 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
830 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
831 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
832 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
833 .vact_space_1 = {0xff, 0xff},
834 .vact_space_2 = {0xff, 0xff},
835 .vact_space_3 = {0xff, 0xff},
836 .vact_space_4 = {0xff, 0xff},
837 .vact_space_5 = {0xff, 0xff},
838 .vact_space_6 = {0xff, 0xff},
839 /* other don't care */
843 0x98, 0x08, /* h_fsz */
844 0x18, 0x01, 0x80, 0x07, /* hact */
845 0x65, 0x04, /* v_fsz */
846 0x01, 0x00, 0x33, 0x02, /* vsync */
847 0x2d, 0x00, 0x38, 0x04, /* vact */
848 0x33, 0x02, /* field_chg */
849 0x48, 0x02, /* vact_st2 */
850 0x00, 0x00, /* vact_st3 */
851 0x00, 0x00, /* vact_st4 */
852 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
853 0x01, 0x00, 0x33, 0x02, /* field top/bot */
858 static const struct hdmi_preset_conf hdmi_conf_1080p50 = {
860 .h_blank = {0xd0, 0x02},
861 .v2_blank = {0x65, 0x04},
862 .v1_blank = {0x2d, 0x00},
863 .v_line = {0x65, 0x04},
864 .h_line = {0x50, 0x0a},
867 .int_pro_mode = {0x00},
868 .v_blank_f0 = {0xff, 0xff},
869 .v_blank_f1 = {0xff, 0xff},
870 .h_sync_start = {0x0e, 0x02},
871 .h_sync_end = {0x3a, 0x02},
872 .v_sync_line_bef_2 = {0x09, 0x00},
873 .v_sync_line_bef_1 = {0x04, 0x00},
874 .v_sync_line_aft_2 = {0xff, 0xff},
875 .v_sync_line_aft_1 = {0xff, 0xff},
876 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
877 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
878 .v_blank_f2 = {0xff, 0xff},
879 .v_blank_f3 = {0xff, 0xff},
880 .v_blank_f4 = {0xff, 0xff},
881 .v_blank_f5 = {0xff, 0xff},
882 .v_sync_line_aft_3 = {0xff, 0xff},
883 .v_sync_line_aft_4 = {0xff, 0xff},
884 .v_sync_line_aft_5 = {0xff, 0xff},
885 .v_sync_line_aft_6 = {0xff, 0xff},
886 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
887 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
888 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
889 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
890 .vact_space_1 = {0xff, 0xff},
891 .vact_space_2 = {0xff, 0xff},
892 .vact_space_3 = {0xff, 0xff},
893 .vact_space_4 = {0xff, 0xff},
894 .vact_space_5 = {0xff, 0xff},
895 .vact_space_6 = {0xff, 0xff},
896 /* other don't care */
900 0x50, 0x0a, /* h_fsz */
901 0xd0, 0x02, 0x80, 0x07, /* hact */
902 0x65, 0x04, /* v_fsz */
903 0x01, 0x00, 0x33, 0x02, /* vsync */
904 0x2d, 0x00, 0x38, 0x04, /* vact */
905 0x33, 0x02, /* field_chg */
906 0x48, 0x02, /* vact_st2 */
907 0x00, 0x00, /* vact_st3 */
908 0x00, 0x00, /* vact_st4 */
909 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
910 0x01, 0x00, 0x33, 0x02, /* field top/bot */
915 static const struct hdmi_preset_conf hdmi_conf_1080p60 = {
917 .h_blank = {0x18, 0x01},
918 .v2_blank = {0x65, 0x04},
919 .v1_blank = {0x2d, 0x00},
920 .v_line = {0x65, 0x04},
921 .h_line = {0x98, 0x08},
924 .int_pro_mode = {0x00},
925 .v_blank_f0 = {0xff, 0xff},
926 .v_blank_f1 = {0xff, 0xff},
927 .h_sync_start = {0x56, 0x00},
928 .h_sync_end = {0x82, 0x00},
929 .v_sync_line_bef_2 = {0x09, 0x00},
930 .v_sync_line_bef_1 = {0x04, 0x00},
931 .v_sync_line_aft_2 = {0xff, 0xff},
932 .v_sync_line_aft_1 = {0xff, 0xff},
933 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
934 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
935 .v_blank_f2 = {0xff, 0xff},
936 .v_blank_f3 = {0xff, 0xff},
937 .v_blank_f4 = {0xff, 0xff},
938 .v_blank_f5 = {0xff, 0xff},
939 .v_sync_line_aft_3 = {0xff, 0xff},
940 .v_sync_line_aft_4 = {0xff, 0xff},
941 .v_sync_line_aft_5 = {0xff, 0xff},
942 .v_sync_line_aft_6 = {0xff, 0xff},
943 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
944 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
945 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
946 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
947 /* other don't care */
951 0x98, 0x08, /* h_fsz */
952 0x18, 0x01, 0x80, 0x07, /* hact */
953 0x65, 0x04, /* v_fsz */
954 0x01, 0x00, 0x33, 0x02, /* vsync */
955 0x2d, 0x00, 0x38, 0x04, /* vact */
956 0x33, 0x02, /* field_chg */
957 0x48, 0x02, /* vact_st2 */
958 0x00, 0x00, /* vact_st3 */
959 0x00, 0x00, /* vact_st4 */
960 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
961 0x01, 0x00, 0x33, 0x02, /* field top/bot */
966 static const struct hdmi_conf hdmi_confs[] = {
967 { 720, 480, 60, false, 3, hdmiphy_conf27_027, &hdmi_conf_480p60 },
968 { 1280, 720, 50, false, 19, hdmiphy_conf74_25, &hdmi_conf_720p50 },
969 { 1280, 720, 60, false, 4, hdmiphy_conf74_25, &hdmi_conf_720p60 },
970 { 1920, 1080, 50, true, 20, hdmiphy_conf74_25, &hdmi_conf_1080i50 },
971 { 1920, 1080, 60, true, 5, hdmiphy_conf74_25, &hdmi_conf_1080i60 },
972 { 1920, 1080, 30, false, 34, hdmiphy_conf74_176, &hdmi_conf_1080p30 },
973 { 1920, 1080, 50, false, 31, hdmiphy_conf148_5, &hdmi_conf_1080p50 },
974 { 1920, 1080, 60, false, 16, hdmiphy_conf148_5, &hdmi_conf_1080p60 },
977 struct hdmi_infoframe {
978 enum HDMI_PACKET_TYPE type;
983 static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
985 return readl(hdata->regs + reg_id);
988 static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
989 u32 reg_id, u8 value)
991 writeb(value, hdata->regs + reg_id);
994 static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
995 u32 reg_id, u32 value, u32 mask)
997 u32 old = readl(hdata->regs + reg_id);
998 value = (value & mask) | (old & ~mask);
999 writel(value, hdata->regs + reg_id);
1002 static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix)
1004 #define DUMPREG(reg_id) \
1005 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
1006 readl(hdata->regs + reg_id))
1007 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
1008 DUMPREG(HDMI_INTC_FLAG);
1009 DUMPREG(HDMI_INTC_CON);
1010 DUMPREG(HDMI_HPD_STATUS);
1011 DUMPREG(HDMI_V13_PHY_RSTOUT);
1012 DUMPREG(HDMI_V13_PHY_VPLL);
1013 DUMPREG(HDMI_V13_PHY_CMU);
1014 DUMPREG(HDMI_V13_CORE_RSTOUT);
1016 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
1017 DUMPREG(HDMI_CON_0);
1018 DUMPREG(HDMI_CON_1);
1019 DUMPREG(HDMI_CON_2);
1020 DUMPREG(HDMI_SYS_STATUS);
1021 DUMPREG(HDMI_V13_PHY_STATUS);
1022 DUMPREG(HDMI_STATUS_EN);
1024 DUMPREG(HDMI_MODE_SEL);
1025 DUMPREG(HDMI_V13_HPD_GEN);
1026 DUMPREG(HDMI_V13_DC_CONTROL);
1027 DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN);
1029 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
1030 DUMPREG(HDMI_H_BLANK_0);
1031 DUMPREG(HDMI_H_BLANK_1);
1032 DUMPREG(HDMI_V13_V_BLANK_0);
1033 DUMPREG(HDMI_V13_V_BLANK_1);
1034 DUMPREG(HDMI_V13_V_BLANK_2);
1035 DUMPREG(HDMI_V13_H_V_LINE_0);
1036 DUMPREG(HDMI_V13_H_V_LINE_1);
1037 DUMPREG(HDMI_V13_H_V_LINE_2);
1038 DUMPREG(HDMI_VSYNC_POL);
1039 DUMPREG(HDMI_INT_PRO_MODE);
1040 DUMPREG(HDMI_V13_V_BLANK_F_0);
1041 DUMPREG(HDMI_V13_V_BLANK_F_1);
1042 DUMPREG(HDMI_V13_V_BLANK_F_2);
1043 DUMPREG(HDMI_V13_H_SYNC_GEN_0);
1044 DUMPREG(HDMI_V13_H_SYNC_GEN_1);
1045 DUMPREG(HDMI_V13_H_SYNC_GEN_2);
1046 DUMPREG(HDMI_V13_V_SYNC_GEN_1_0);
1047 DUMPREG(HDMI_V13_V_SYNC_GEN_1_1);
1048 DUMPREG(HDMI_V13_V_SYNC_GEN_1_2);
1049 DUMPREG(HDMI_V13_V_SYNC_GEN_2_0);
1050 DUMPREG(HDMI_V13_V_SYNC_GEN_2_1);
1051 DUMPREG(HDMI_V13_V_SYNC_GEN_2_2);
1052 DUMPREG(HDMI_V13_V_SYNC_GEN_3_0);
1053 DUMPREG(HDMI_V13_V_SYNC_GEN_3_1);
1054 DUMPREG(HDMI_V13_V_SYNC_GEN_3_2);
1056 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
1057 DUMPREG(HDMI_TG_CMD);
1058 DUMPREG(HDMI_TG_H_FSZ_L);
1059 DUMPREG(HDMI_TG_H_FSZ_H);
1060 DUMPREG(HDMI_TG_HACT_ST_L);
1061 DUMPREG(HDMI_TG_HACT_ST_H);
1062 DUMPREG(HDMI_TG_HACT_SZ_L);
1063 DUMPREG(HDMI_TG_HACT_SZ_H);
1064 DUMPREG(HDMI_TG_V_FSZ_L);
1065 DUMPREG(HDMI_TG_V_FSZ_H);
1066 DUMPREG(HDMI_TG_VSYNC_L);
1067 DUMPREG(HDMI_TG_VSYNC_H);
1068 DUMPREG(HDMI_TG_VSYNC2_L);
1069 DUMPREG(HDMI_TG_VSYNC2_H);
1070 DUMPREG(HDMI_TG_VACT_ST_L);
1071 DUMPREG(HDMI_TG_VACT_ST_H);
1072 DUMPREG(HDMI_TG_VACT_SZ_L);
1073 DUMPREG(HDMI_TG_VACT_SZ_H);
1074 DUMPREG(HDMI_TG_FIELD_CHG_L);
1075 DUMPREG(HDMI_TG_FIELD_CHG_H);
1076 DUMPREG(HDMI_TG_VACT_ST2_L);
1077 DUMPREG(HDMI_TG_VACT_ST2_H);
1078 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
1079 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
1080 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
1081 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
1082 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
1083 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
1084 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
1085 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
1089 static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix)
1093 #define DUMPREG(reg_id) \
1094 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
1095 readl(hdata->regs + reg_id))
1097 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
1098 DUMPREG(HDMI_INTC_CON);
1099 DUMPREG(HDMI_INTC_FLAG);
1100 DUMPREG(HDMI_HPD_STATUS);
1101 DUMPREG(HDMI_INTC_CON_1);
1102 DUMPREG(HDMI_INTC_FLAG_1);
1103 DUMPREG(HDMI_PHY_STATUS_0);
1104 DUMPREG(HDMI_PHY_STATUS_PLL);
1105 DUMPREG(HDMI_PHY_CON_0);
1106 DUMPREG(HDMI_PHY_RSTOUT);
1107 DUMPREG(HDMI_PHY_VPLL);
1108 DUMPREG(HDMI_PHY_CMU);
1109 DUMPREG(HDMI_CORE_RSTOUT);
1111 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
1112 DUMPREG(HDMI_CON_0);
1113 DUMPREG(HDMI_CON_1);
1114 DUMPREG(HDMI_CON_2);
1115 DUMPREG(HDMI_SYS_STATUS);
1116 DUMPREG(HDMI_PHY_STATUS_0);
1117 DUMPREG(HDMI_STATUS_EN);
1119 DUMPREG(HDMI_MODE_SEL);
1120 DUMPREG(HDMI_ENC_EN);
1121 DUMPREG(HDMI_DC_CONTROL);
1122 DUMPREG(HDMI_VIDEO_PATTERN_GEN);
1124 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
1125 DUMPREG(HDMI_H_BLANK_0);
1126 DUMPREG(HDMI_H_BLANK_1);
1127 DUMPREG(HDMI_V2_BLANK_0);
1128 DUMPREG(HDMI_V2_BLANK_1);
1129 DUMPREG(HDMI_V1_BLANK_0);
1130 DUMPREG(HDMI_V1_BLANK_1);
1131 DUMPREG(HDMI_V_LINE_0);
1132 DUMPREG(HDMI_V_LINE_1);
1133 DUMPREG(HDMI_H_LINE_0);
1134 DUMPREG(HDMI_H_LINE_1);
1135 DUMPREG(HDMI_HSYNC_POL);
1137 DUMPREG(HDMI_VSYNC_POL);
1138 DUMPREG(HDMI_INT_PRO_MODE);
1139 DUMPREG(HDMI_V_BLANK_F0_0);
1140 DUMPREG(HDMI_V_BLANK_F0_1);
1141 DUMPREG(HDMI_V_BLANK_F1_0);
1142 DUMPREG(HDMI_V_BLANK_F1_1);
1144 DUMPREG(HDMI_H_SYNC_START_0);
1145 DUMPREG(HDMI_H_SYNC_START_1);
1146 DUMPREG(HDMI_H_SYNC_END_0);
1147 DUMPREG(HDMI_H_SYNC_END_1);
1149 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0);
1150 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1);
1151 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0);
1152 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1);
1154 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0);
1155 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1);
1156 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0);
1157 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1);
1159 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0);
1160 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1);
1161 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0);
1162 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1);
1164 DUMPREG(HDMI_V_BLANK_F2_0);
1165 DUMPREG(HDMI_V_BLANK_F2_1);
1166 DUMPREG(HDMI_V_BLANK_F3_0);
1167 DUMPREG(HDMI_V_BLANK_F3_1);
1168 DUMPREG(HDMI_V_BLANK_F4_0);
1169 DUMPREG(HDMI_V_BLANK_F4_1);
1170 DUMPREG(HDMI_V_BLANK_F5_0);
1171 DUMPREG(HDMI_V_BLANK_F5_1);
1173 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0);
1174 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1);
1175 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0);
1176 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1);
1177 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0);
1178 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1);
1179 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0);
1180 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1);
1182 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0);
1183 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1);
1184 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0);
1185 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1);
1186 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0);
1187 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1);
1188 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0);
1189 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1);
1191 DUMPREG(HDMI_VACT_SPACE_1_0);
1192 DUMPREG(HDMI_VACT_SPACE_1_1);
1193 DUMPREG(HDMI_VACT_SPACE_2_0);
1194 DUMPREG(HDMI_VACT_SPACE_2_1);
1195 DUMPREG(HDMI_VACT_SPACE_3_0);
1196 DUMPREG(HDMI_VACT_SPACE_3_1);
1197 DUMPREG(HDMI_VACT_SPACE_4_0);
1198 DUMPREG(HDMI_VACT_SPACE_4_1);
1199 DUMPREG(HDMI_VACT_SPACE_5_0);
1200 DUMPREG(HDMI_VACT_SPACE_5_1);
1201 DUMPREG(HDMI_VACT_SPACE_6_0);
1202 DUMPREG(HDMI_VACT_SPACE_6_1);
1204 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
1205 DUMPREG(HDMI_TG_CMD);
1206 DUMPREG(HDMI_TG_H_FSZ_L);
1207 DUMPREG(HDMI_TG_H_FSZ_H);
1208 DUMPREG(HDMI_TG_HACT_ST_L);
1209 DUMPREG(HDMI_TG_HACT_ST_H);
1210 DUMPREG(HDMI_TG_HACT_SZ_L);
1211 DUMPREG(HDMI_TG_HACT_SZ_H);
1212 DUMPREG(HDMI_TG_V_FSZ_L);
1213 DUMPREG(HDMI_TG_V_FSZ_H);
1214 DUMPREG(HDMI_TG_VSYNC_L);
1215 DUMPREG(HDMI_TG_VSYNC_H);
1216 DUMPREG(HDMI_TG_VSYNC2_L);
1217 DUMPREG(HDMI_TG_VSYNC2_H);
1218 DUMPREG(HDMI_TG_VACT_ST_L);
1219 DUMPREG(HDMI_TG_VACT_ST_H);
1220 DUMPREG(HDMI_TG_VACT_SZ_L);
1221 DUMPREG(HDMI_TG_VACT_SZ_H);
1222 DUMPREG(HDMI_TG_FIELD_CHG_L);
1223 DUMPREG(HDMI_TG_FIELD_CHG_H);
1224 DUMPREG(HDMI_TG_VACT_ST2_L);
1225 DUMPREG(HDMI_TG_VACT_ST2_H);
1226 DUMPREG(HDMI_TG_VACT_ST3_L);
1227 DUMPREG(HDMI_TG_VACT_ST3_H);
1228 DUMPREG(HDMI_TG_VACT_ST4_L);
1229 DUMPREG(HDMI_TG_VACT_ST4_H);
1230 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
1231 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
1232 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
1233 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
1234 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
1235 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
1236 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
1237 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
1238 DUMPREG(HDMI_TG_3D);
1240 DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix);
1241 DUMPREG(HDMI_AVI_CON);
1242 DUMPREG(HDMI_AVI_HEADER0);
1243 DUMPREG(HDMI_AVI_HEADER1);
1244 DUMPREG(HDMI_AVI_HEADER2);
1245 DUMPREG(HDMI_AVI_CHECK_SUM);
1246 DUMPREG(HDMI_VSI_CON);
1247 DUMPREG(HDMI_VSI_HEADER0);
1248 DUMPREG(HDMI_VSI_HEADER1);
1249 DUMPREG(HDMI_VSI_HEADER2);
1250 for (i = 0; i < 7; ++i)
1251 DUMPREG(HDMI_VSI_DATA(i));
1256 static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
1258 if (hdata->type == HDMI_TYPE13)
1259 hdmi_v13_regs_dump(hdata, prefix);
1261 hdmi_v14_regs_dump(hdata, prefix);
1264 static int hdmi_v13_conf_index(struct drm_display_mode *mode)
1268 for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1269 if (hdmi_v13_confs[i].width == mode->hdisplay &&
1270 hdmi_v13_confs[i].height == mode->vdisplay &&
1271 hdmi_v13_confs[i].vrefresh == mode->vrefresh &&
1272 hdmi_v13_confs[i].interlace ==
1273 ((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1280 static int hdmi_v14_conf_index(struct drm_display_mode *mode)
1284 for (i = 0; i < ARRAY_SIZE(hdmi_confs); ++i)
1285 if (hdmi_confs[i].width == mode->hdisplay &&
1286 hdmi_confs[i].height == mode->vdisplay &&
1287 hdmi_confs[i].vrefresh == mode->vrefresh &&
1288 hdmi_confs[i].interlace ==
1289 ((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1296 static int hdmi_conf_index(struct hdmi_context *hdata,
1297 struct drm_display_mode *mode)
1299 if (hdata->type == HDMI_TYPE13)
1300 return hdmi_v13_conf_index(mode);
1302 return hdmi_v14_conf_index(mode);
1305 static u8 hdmi_chksum(struct hdmi_context *hdata,
1306 u32 start, u8 len, u32 hdr_sum)
1310 /* hdr_sum : header0 + header1 + header2
1311 * start : start address of packet byte1
1312 * len : packet bytes - 1 */
1313 for (i = 0; i < len; ++i)
1314 hdr_sum += 0xff & hdmi_reg_read(hdata, start + i * 4);
1316 /* return 2's complement of 8 bit hdr_sum */
1317 return (u8)(~(hdr_sum & 0xff) + 1);
1320 static void hdmi_reg_infoframe(struct hdmi_context *hdata,
1321 struct hdmi_infoframe *infoframe)
1329 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1331 mod = hdmi_reg_read(hdata, HDMI_MODE_SEL);
1332 if (hdata->dvi_mode) {
1333 hdmi_reg_writeb(hdata, HDMI_VSI_CON,
1334 HDMI_VSI_CON_DO_NOT_TRANSMIT);
1335 hdmi_reg_writeb(hdata, HDMI_AVI_CON,
1336 HDMI_AVI_CON_DO_NOT_TRANSMIT);
1337 hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_NO_TRAN);
1341 switch (infoframe->type) {
1342 case HDMI_PACKET_TYPE_AVI:
1343 hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC);
1344 hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->type);
1345 hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1, infoframe->ver);
1346 hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->len);
1347 hdr_sum = infoframe->type + infoframe->ver + infoframe->len;
1349 /* Output format zero hardcoded ,RGB YBCR selection */
1350 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 |
1351 AVI_ACTIVE_FORMAT_VALID |
1352 AVI_UNDERSCANNED_DISPLAY_VALID);
1354 aspect_ratio = AVI_PIC_ASPECT_RATIO_16_9;
1356 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2), aspect_ratio |
1357 AVI_SAME_AS_PIC_ASPECT_RATIO);
1359 if (hdata->type == HDMI_TYPE13)
1360 vic = hdmi_v13_confs[hdata->cur_conf].cea_video_id;
1362 vic = hdmi_confs[hdata->cur_conf].cea_video_id;
1364 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), vic);
1366 chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1),
1367 infoframe->len, hdr_sum);
1368 DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum);
1369 hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum);
1371 case HDMI_PACKET_TYPE_AUI:
1372 hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02);
1373 hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->type);
1374 hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1, infoframe->ver);
1375 hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->len);
1376 hdr_sum = infoframe->type + infoframe->ver + infoframe->len;
1377 chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1),
1378 infoframe->len, hdr_sum);
1379 DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum);
1380 hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum);
1387 static bool hdmi_is_connected(void *ctx)
1389 struct hdmi_context *hdata = ctx;
1394 static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
1397 struct edid *raw_edid;
1398 struct hdmi_context *hdata = ctx;
1400 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1402 if (!hdata->ddc_port)
1405 raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter);
1407 hdata->dvi_mode = !drm_detect_hdmi_monitor(raw_edid);
1408 memcpy(edid, raw_edid, min((1 + raw_edid->extensions)
1409 * EDID_LENGTH, len));
1410 DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
1411 (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
1412 raw_edid->width_cm, raw_edid->height_cm);
1421 static int hdmi_v13_check_timing(struct fb_videomode *check_timing)
1425 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1426 check_timing->xres, check_timing->yres,
1427 check_timing->refresh, (check_timing->vmode &
1428 FB_VMODE_INTERLACED) ? true : false);
1430 for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1431 if (hdmi_v13_confs[i].width == check_timing->xres &&
1432 hdmi_v13_confs[i].height == check_timing->yres &&
1433 hdmi_v13_confs[i].vrefresh == check_timing->refresh &&
1434 hdmi_v13_confs[i].interlace ==
1435 ((check_timing->vmode & FB_VMODE_INTERLACED) ?
1444 static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
1448 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1449 check_timing->xres, check_timing->yres,
1450 check_timing->refresh, (check_timing->vmode &
1451 FB_VMODE_INTERLACED) ? true : false);
1453 for (i = 0; i < ARRAY_SIZE(hdmi_confs); i++)
1454 if (hdmi_confs[i].width == check_timing->xres &&
1455 hdmi_confs[i].height == check_timing->yres &&
1456 hdmi_confs[i].vrefresh == check_timing->refresh &&
1457 hdmi_confs[i].interlace ==
1458 ((check_timing->vmode & FB_VMODE_INTERLACED) ?
1467 static int hdmi_check_timing(void *ctx, void *timing)
1469 struct hdmi_context *hdata = ctx;
1470 struct fb_videomode *check_timing = timing;
1472 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1474 DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres,
1475 check_timing->yres, check_timing->refresh,
1476 check_timing->vmode);
1478 if (hdata->type == HDMI_TYPE13)
1479 return hdmi_v13_check_timing(check_timing);
1481 return hdmi_v14_check_timing(check_timing);
1484 static void hdmi_set_acr(u32 freq, u8 *acr)
1524 acr[2] = cts >> 8 & 0xff;
1525 acr[3] = cts & 0xff;
1528 acr[5] = n >> 8 & 0xff;
1532 static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr)
1534 hdmi_reg_writeb(hdata, HDMI_ACR_N0, acr[6]);
1535 hdmi_reg_writeb(hdata, HDMI_ACR_N1, acr[5]);
1536 hdmi_reg_writeb(hdata, HDMI_ACR_N2, acr[4]);
1537 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS0, acr[3]);
1538 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS1, acr[2]);
1539 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS2, acr[1]);
1540 hdmi_reg_writeb(hdata, HDMI_ACR_CTS0, acr[3]);
1541 hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]);
1542 hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]);
1544 if (hdata->type == HDMI_TYPE13)
1545 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4);
1547 hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1550 static void hdmi_audio_init(struct hdmi_context *hdata)
1552 u32 sample_rate, bits_per_sample, frame_size_code;
1553 u32 data_num, bit_ch, sample_frq;
1557 sample_rate = 44100;
1558 bits_per_sample = 16;
1559 frame_size_code = 0;
1561 switch (bits_per_sample) {
1576 hdmi_set_acr(sample_rate, acr);
1577 hdmi_reg_acr(hdata, acr);
1579 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1580 | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1581 | HDMI_I2S_MUX_ENABLE);
1583 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1584 | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1586 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1588 sample_frq = (sample_rate == 44100) ? 0 :
1589 (sample_rate == 48000) ? 2 :
1590 (sample_rate == 32000) ? 3 :
1591 (sample_rate == 96000) ? 0xa : 0x0;
1593 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1594 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1596 val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1597 hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1599 /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1600 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1601 | HDMI_I2S_SEL_LRCK(6));
1602 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1603 | HDMI_I2S_SEL_SDATA2(4));
1604 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1605 | HDMI_I2S_SEL_SDATA2(2));
1606 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1609 hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1610 | HDMI_I2S_L_CH_LOW_POL);
1611 hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1612 | HDMI_I2S_SET_BIT_CH(bit_ch)
1613 | HDMI_I2S_SET_SDATA_BIT(data_num)
1614 | HDMI_I2S_BASIC_FORMAT);
1616 /* Configure register related to CUV information */
1617 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
1618 | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1619 | HDMI_I2S_COPYRIGHT
1620 | HDMI_I2S_LINEAR_PCM
1621 | HDMI_I2S_CONSUMER_FORMAT);
1622 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1623 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1624 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1625 | HDMI_I2S_SET_SMP_FREQ(sample_frq));
1626 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1627 HDMI_I2S_ORG_SMP_FREQ_44_1
1628 | HDMI_I2S_WORD_LEN_MAX24_24BITS
1629 | HDMI_I2S_WORD_LEN_MAX_24BITS);
1631 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1634 static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1636 if (hdata->dvi_mode)
1639 hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
1640 hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ?
1641 HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1644 static void hdmi_conf_reset(struct hdmi_context *hdata)
1648 if (hdata->type == HDMI_TYPE13)
1649 reg = HDMI_V13_CORE_RSTOUT;
1651 reg = HDMI_CORE_RSTOUT;
1653 /* resetting HDMI core */
1654 hdmi_reg_writemask(hdata, reg, 0, HDMI_CORE_SW_RSTOUT);
1656 hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT);
1660 static void hdmi_conf_init(struct hdmi_context *hdata)
1662 struct hdmi_infoframe infoframe;
1664 /* disable HPD interrupts */
1665 hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1666 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1668 /* choose HDMI mode */
1669 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1670 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1671 /* disable bluescreen */
1672 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1674 if (hdata->dvi_mode) {
1675 /* choose DVI mode */
1676 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1677 HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1678 hdmi_reg_writeb(hdata, HDMI_CON_2,
1679 HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1682 if (hdata->type == HDMI_TYPE13) {
1683 /* choose bluescreen (fecal) color */
1684 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1685 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1686 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1688 /* enable AVI packet every vsync, fixes purple line problem */
1689 hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1690 /* force RGB, look to CEA-861-D, table 7 for more detail */
1691 hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1692 hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1694 hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1695 hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1696 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1698 infoframe.type = HDMI_PACKET_TYPE_AVI;
1699 infoframe.ver = HDMI_AVI_VERSION;
1700 infoframe.len = HDMI_AVI_LENGTH;
1701 hdmi_reg_infoframe(hdata, &infoframe);
1703 infoframe.type = HDMI_PACKET_TYPE_AUI;
1704 infoframe.ver = HDMI_AUI_VERSION;
1705 infoframe.len = HDMI_AUI_LENGTH;
1706 hdmi_reg_infoframe(hdata, &infoframe);
1708 /* enable AVI packet every vsync, fixes purple line problem */
1709 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1713 static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
1715 const struct hdmi_v13_preset_conf *conf =
1716 hdmi_v13_confs[hdata->cur_conf].conf;
1717 const struct hdmi_v13_core_regs *core = &conf->core;
1718 const struct hdmi_v13_tg_regs *tg = &conf->tg;
1721 /* setting core registers */
1722 hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1723 hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1724 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_0, core->v_blank[0]);
1725 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_1, core->v_blank[1]);
1726 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_2, core->v_blank[2]);
1727 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_0, core->h_v_line[0]);
1728 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_1, core->h_v_line[1]);
1729 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_2, core->h_v_line[2]);
1730 hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1731 hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1732 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_0, core->v_blank_f[0]);
1733 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_1, core->v_blank_f[1]);
1734 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_2, core->v_blank_f[2]);
1735 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_0, core->h_sync_gen[0]);
1736 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_1, core->h_sync_gen[1]);
1737 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_2, core->h_sync_gen[2]);
1738 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_0, core->v_sync_gen1[0]);
1739 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_1, core->v_sync_gen1[1]);
1740 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_2, core->v_sync_gen1[2]);
1741 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_0, core->v_sync_gen2[0]);
1742 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_1, core->v_sync_gen2[1]);
1743 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_2, core->v_sync_gen2[2]);
1744 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_0, core->v_sync_gen3[0]);
1745 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]);
1746 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]);
1747 /* Timing generator registers */
1748 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1749 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1750 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1751 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1752 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1753 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1754 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1755 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1756 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1757 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1758 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1759 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1760 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1761 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1762 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1763 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1764 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1765 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1766 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1767 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1768 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1769 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1770 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1771 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1772 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1773 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1774 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1775 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1777 /* waiting for HDMIPHY's PLL to get to steady state */
1778 for (tries = 100; tries; --tries) {
1779 u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS);
1780 if (val & HDMI_PHY_STATUS_READY)
1784 /* steady state not achieved */
1786 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1787 hdmi_regs_dump(hdata, "timing apply");
1790 clk_disable(hdata->res.sclk_hdmi);
1791 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1792 clk_enable(hdata->res.sclk_hdmi);
1794 /* enable HDMI and timing generator */
1795 hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1796 if (core->int_pro_mode[0])
1797 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1800 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1803 static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
1805 const struct hdmi_preset_conf *conf = hdmi_confs[hdata->cur_conf].conf;
1806 const struct hdmi_core_regs *core = &conf->core;
1807 const struct hdmi_tg_regs *tg = &conf->tg;
1810 /* setting core registers */
1811 hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1812 hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1813 hdmi_reg_writeb(hdata, HDMI_V2_BLANK_0, core->v2_blank[0]);
1814 hdmi_reg_writeb(hdata, HDMI_V2_BLANK_1, core->v2_blank[1]);
1815 hdmi_reg_writeb(hdata, HDMI_V1_BLANK_0, core->v1_blank[0]);
1816 hdmi_reg_writeb(hdata, HDMI_V1_BLANK_1, core->v1_blank[1]);
1817 hdmi_reg_writeb(hdata, HDMI_V_LINE_0, core->v_line[0]);
1818 hdmi_reg_writeb(hdata, HDMI_V_LINE_1, core->v_line[1]);
1819 hdmi_reg_writeb(hdata, HDMI_H_LINE_0, core->h_line[0]);
1820 hdmi_reg_writeb(hdata, HDMI_H_LINE_1, core->h_line[1]);
1821 hdmi_reg_writeb(hdata, HDMI_HSYNC_POL, core->hsync_pol[0]);
1822 hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1823 hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1824 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_0, core->v_blank_f0[0]);
1825 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_1, core->v_blank_f0[1]);
1826 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_0, core->v_blank_f1[0]);
1827 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_1, core->v_blank_f1[1]);
1828 hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_0, core->h_sync_start[0]);
1829 hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_1, core->h_sync_start[1]);
1830 hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_0, core->h_sync_end[0]);
1831 hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_1, core->h_sync_end[1]);
1832 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_0,
1833 core->v_sync_line_bef_2[0]);
1834 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_1,
1835 core->v_sync_line_bef_2[1]);
1836 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_0,
1837 core->v_sync_line_bef_1[0]);
1838 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_1,
1839 core->v_sync_line_bef_1[1]);
1840 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_0,
1841 core->v_sync_line_aft_2[0]);
1842 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_1,
1843 core->v_sync_line_aft_2[1]);
1844 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_0,
1845 core->v_sync_line_aft_1[0]);
1846 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_1,
1847 core->v_sync_line_aft_1[1]);
1848 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0,
1849 core->v_sync_line_aft_pxl_2[0]);
1850 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_1,
1851 core->v_sync_line_aft_pxl_2[1]);
1852 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0,
1853 core->v_sync_line_aft_pxl_1[0]);
1854 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_1,
1855 core->v_sync_line_aft_pxl_1[1]);
1856 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_0, core->v_blank_f2[0]);
1857 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_1, core->v_blank_f2[1]);
1858 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_0, core->v_blank_f3[0]);
1859 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_1, core->v_blank_f3[1]);
1860 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_0, core->v_blank_f4[0]);
1861 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_1, core->v_blank_f4[1]);
1862 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_0, core->v_blank_f5[0]);
1863 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_1, core->v_blank_f5[1]);
1864 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_0,
1865 core->v_sync_line_aft_3[0]);
1866 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_1,
1867 core->v_sync_line_aft_3[1]);
1868 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_0,
1869 core->v_sync_line_aft_4[0]);
1870 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_1,
1871 core->v_sync_line_aft_4[1]);
1872 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_0,
1873 core->v_sync_line_aft_5[0]);
1874 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_1,
1875 core->v_sync_line_aft_5[1]);
1876 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_0,
1877 core->v_sync_line_aft_6[0]);
1878 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_1,
1879 core->v_sync_line_aft_6[1]);
1880 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0,
1881 core->v_sync_line_aft_pxl_3[0]);
1882 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_1,
1883 core->v_sync_line_aft_pxl_3[1]);
1884 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0,
1885 core->v_sync_line_aft_pxl_4[0]);
1886 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_1,
1887 core->v_sync_line_aft_pxl_4[1]);
1888 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0,
1889 core->v_sync_line_aft_pxl_5[0]);
1890 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_1,
1891 core->v_sync_line_aft_pxl_5[1]);
1892 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0,
1893 core->v_sync_line_aft_pxl_6[0]);
1894 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_1,
1895 core->v_sync_line_aft_pxl_6[1]);
1896 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_0, core->vact_space_1[0]);
1897 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_1, core->vact_space_1[1]);
1898 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_0, core->vact_space_2[0]);
1899 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_1, core->vact_space_2[1]);
1900 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_0, core->vact_space_3[0]);
1901 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_1, core->vact_space_3[1]);
1902 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_0, core->vact_space_4[0]);
1903 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_1, core->vact_space_4[1]);
1904 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_0, core->vact_space_5[0]);
1905 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_1, core->vact_space_5[1]);
1906 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_0, core->vact_space_6[0]);
1907 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]);
1909 /* Timing generator registers */
1910 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1911 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1912 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1913 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1914 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1915 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1916 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1917 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1918 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1919 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1920 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1921 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1922 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1923 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1924 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1925 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1926 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1927 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1928 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1929 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1930 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3_l);
1931 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3_h);
1932 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4_l);
1933 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4_h);
1934 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1935 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1936 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1937 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1938 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1939 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1940 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1941 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1942 hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d);
1944 /* waiting for HDMIPHY's PLL to get to steady state */
1945 for (tries = 100; tries; --tries) {
1946 u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0);
1947 if (val & HDMI_PHY_STATUS_READY)
1951 /* steady state not achieved */
1953 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1954 hdmi_regs_dump(hdata, "timing apply");
1957 clk_disable(hdata->res.sclk_hdmi);
1958 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1959 clk_enable(hdata->res.sclk_hdmi);
1961 /* enable HDMI and timing generator */
1962 hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1963 if (core->int_pro_mode[0])
1964 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1967 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1970 static void hdmi_timing_apply(struct hdmi_context *hdata)
1972 if (hdata->type == HDMI_TYPE13)
1973 hdmi_v13_timing_apply(hdata);
1975 hdmi_v14_timing_apply(hdata);
1978 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1983 clk_disable(hdata->res.sclk_hdmi);
1984 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel);
1985 clk_enable(hdata->res.sclk_hdmi);
1987 /* operation mode */
1991 if (hdata->hdmiphy_port)
1992 i2c_master_send(hdata->hdmiphy_port, buffer, 2);
1994 if (hdata->type == HDMI_TYPE13)
1995 reg = HDMI_V13_PHY_RSTOUT;
1997 reg = HDMI_PHY_RSTOUT;
2000 hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT);
2002 hdmi_reg_writemask(hdata, reg, 0, HDMI_PHY_SW_RSTOUT);
2006 static void hdmiphy_poweron(struct hdmi_context *hdata)
2008 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2010 if (hdata->type == HDMI_TYPE14)
2011 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0,
2012 HDMI_PHY_POWER_OFF_EN);
2015 static void hdmiphy_poweroff(struct hdmi_context *hdata)
2017 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2019 if (hdata->type == HDMI_TYPE14)
2020 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0,
2021 HDMI_PHY_POWER_OFF_EN);
2024 static void hdmiphy_conf_apply(struct hdmi_context *hdata)
2026 const u8 *hdmiphy_data;
2029 u8 read_buffer[32] = {0, };
2033 if (!hdata->hdmiphy_port) {
2034 DRM_ERROR("hdmiphy is not attached\n");
2039 if (hdata->type == HDMI_TYPE13)
2040 hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data;
2042 hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data;
2044 memcpy(buffer, hdmiphy_data, 32);
2045 ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
2047 DRM_ERROR("failed to configure HDMIPHY via I2C\n");
2053 /* operation mode */
2054 operation[0] = 0x1f;
2055 operation[1] = 0x80;
2057 ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
2059 DRM_ERROR("failed to enable hdmiphy\n");
2063 ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
2065 DRM_ERROR("failed to read hdmiphy config\n");
2069 for (i = 0; i < ret; i++)
2070 DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
2071 "recv [0x%02x]\n", i, buffer[i], read_buffer[i]);
2074 static void hdmi_conf_apply(struct hdmi_context *hdata)
2076 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2078 hdmiphy_conf_reset(hdata);
2079 hdmiphy_conf_apply(hdata);
2081 mutex_lock(&hdata->hdmi_mutex);
2082 hdmi_conf_reset(hdata);
2083 hdmi_conf_init(hdata);
2084 mutex_unlock(&hdata->hdmi_mutex);
2086 hdmi_audio_init(hdata);
2088 /* setting core registers */
2089 hdmi_timing_apply(hdata);
2090 hdmi_audio_control(hdata, true);
2092 hdmi_regs_dump(hdata, "start");
2095 static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
2096 const struct drm_display_mode *mode,
2097 struct drm_display_mode *adjusted_mode)
2099 struct drm_display_mode *m;
2100 struct hdmi_context *hdata = ctx;
2103 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2105 drm_mode_set_crtcinfo(adjusted_mode, 0);
2107 if (hdata->type == HDMI_TYPE13)
2108 index = hdmi_v13_conf_index(adjusted_mode);
2110 index = hdmi_v14_conf_index(adjusted_mode);
2112 /* just return if user desired mode exists. */
2117 * otherwise, find the most suitable mode among modes and change it
2120 list_for_each_entry(m, &connector->modes, head) {
2121 if (hdata->type == HDMI_TYPE13)
2122 index = hdmi_v13_conf_index(m);
2124 index = hdmi_v14_conf_index(m);
2127 struct drm_mode_object base;
2128 struct list_head head;
2130 DRM_INFO("desired mode doesn't exist so\n");
2131 DRM_INFO("use the most suitable mode among modes.\n");
2133 /* preserve display mode header while copying. */
2134 head = adjusted_mode->head;
2135 base = adjusted_mode->base;
2136 memcpy(adjusted_mode, m, sizeof(*m));
2137 adjusted_mode->head = head;
2138 adjusted_mode->base = base;
2144 static void hdmi_mode_set(void *ctx, void *mode)
2146 struct hdmi_context *hdata = ctx;
2149 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2151 conf_idx = hdmi_conf_index(hdata, mode);
2153 hdata->cur_conf = conf_idx;
2155 DRM_DEBUG_KMS("not supported mode\n");
2158 static void hdmi_get_max_resol(void *ctx, unsigned int *width,
2159 unsigned int *height)
2161 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2164 *height = MAX_HEIGHT;
2167 static void hdmi_commit(void *ctx)
2169 struct hdmi_context *hdata = ctx;
2171 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2173 hdmi_conf_apply(hdata);
2176 static void hdmi_poweron(struct hdmi_context *hdata)
2178 struct hdmi_resources *res = &hdata->res;
2180 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2182 mutex_lock(&hdata->hdmi_mutex);
2183 if (hdata->powered) {
2184 mutex_unlock(&hdata->hdmi_mutex);
2188 hdata->powered = true;
2190 mutex_unlock(&hdata->hdmi_mutex);
2192 regulator_bulk_enable(res->regul_count, res->regul_bulk);
2193 clk_enable(res->hdmiphy);
2194 clk_enable(res->hdmi);
2195 clk_enable(res->sclk_hdmi);
2197 hdmiphy_poweron(hdata);
2200 static void hdmi_poweroff(struct hdmi_context *hdata)
2202 struct hdmi_resources *res = &hdata->res;
2204 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2206 mutex_lock(&hdata->hdmi_mutex);
2207 if (!hdata->powered)
2209 mutex_unlock(&hdata->hdmi_mutex);
2212 * The TV power domain needs any condition of hdmiphy to turn off and
2213 * its reset state seems to meet the condition.
2215 hdmiphy_conf_reset(hdata);
2216 hdmiphy_poweroff(hdata);
2218 clk_disable(res->sclk_hdmi);
2219 clk_disable(res->hdmi);
2220 clk_disable(res->hdmiphy);
2221 regulator_bulk_disable(res->regul_count, res->regul_bulk);
2223 mutex_lock(&hdata->hdmi_mutex);
2225 hdata->powered = false;
2228 mutex_unlock(&hdata->hdmi_mutex);
2231 static void hdmi_dpms(void *ctx, int mode)
2233 struct hdmi_context *hdata = ctx;
2235 DRM_DEBUG_KMS("[%d] %s mode %d\n", __LINE__, __func__, mode);
2238 case DRM_MODE_DPMS_ON:
2239 if (pm_runtime_suspended(hdata->dev))
2240 pm_runtime_get_sync(hdata->dev);
2242 case DRM_MODE_DPMS_STANDBY:
2243 case DRM_MODE_DPMS_SUSPEND:
2244 case DRM_MODE_DPMS_OFF:
2245 if (!pm_runtime_suspended(hdata->dev))
2246 pm_runtime_put_sync(hdata->dev);
2249 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
2254 static struct exynos_hdmi_ops hdmi_ops = {
2256 .is_connected = hdmi_is_connected,
2257 .get_edid = hdmi_get_edid,
2258 .check_timing = hdmi_check_timing,
2261 .mode_fixup = hdmi_mode_fixup,
2262 .mode_set = hdmi_mode_set,
2263 .get_max_resol = hdmi_get_max_resol,
2264 .commit = hdmi_commit,
2268 static irqreturn_t hdmi_external_irq_thread(int irq, void *arg)
2270 struct exynos_drm_hdmi_context *ctx = arg;
2271 struct hdmi_context *hdata = ctx->ctx;
2273 mutex_lock(&hdata->hdmi_mutex);
2274 hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2275 mutex_unlock(&hdata->hdmi_mutex);
2278 drm_helper_hpd_irq_event(ctx->drm_dev);
2283 static irqreturn_t hdmi_internal_irq_thread(int irq, void *arg)
2285 struct exynos_drm_hdmi_context *ctx = arg;
2286 struct hdmi_context *hdata = ctx->ctx;
2289 intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG);
2290 /* clearing flags for HPD plug/unplug */
2291 if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) {
2292 DRM_DEBUG_KMS("unplugged\n");
2293 hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
2294 HDMI_INTC_FLAG_HPD_UNPLUG);
2296 if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) {
2297 DRM_DEBUG_KMS("plugged\n");
2298 hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
2299 HDMI_INTC_FLAG_HPD_PLUG);
2303 drm_helper_hpd_irq_event(ctx->drm_dev);
2308 static int hdmi_resources_init(struct hdmi_context *hdata)
2310 struct device *dev = hdata->dev;
2311 struct hdmi_resources *res = &hdata->res;
2312 static char *supply[] = {
2320 DRM_DEBUG_KMS("HDMI resource init\n");
2322 memset(res, 0, sizeof(*res));
2324 /* get clocks, power */
2325 res->hdmi = devm_clk_get(dev, "hdmi");
2326 if (IS_ERR_OR_NULL(res->hdmi)) {
2327 DRM_ERROR("failed to get clock 'hdmi'\n");
2330 res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
2331 if (IS_ERR_OR_NULL(res->sclk_hdmi)) {
2332 DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
2335 res->sclk_pixel = devm_clk_get(dev, "sclk_pixel");
2336 if (IS_ERR_OR_NULL(res->sclk_pixel)) {
2337 DRM_ERROR("failed to get clock 'sclk_pixel'\n");
2340 res->sclk_hdmiphy = devm_clk_get(dev, "sclk_hdmiphy");
2341 if (IS_ERR_OR_NULL(res->sclk_hdmiphy)) {
2342 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
2345 res->hdmiphy = devm_clk_get(dev, "hdmiphy");
2346 if (IS_ERR_OR_NULL(res->hdmiphy)) {
2347 DRM_ERROR("failed to get clock 'hdmiphy'\n");
2351 clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
2353 res->regul_bulk = devm_kzalloc(dev, ARRAY_SIZE(supply) *
2354 sizeof(res->regul_bulk[0]), GFP_KERNEL);
2355 if (!res->regul_bulk) {
2356 DRM_ERROR("failed to get memory for regulators\n");
2359 for (i = 0; i < ARRAY_SIZE(supply); ++i) {
2360 res->regul_bulk[i].supply = supply[i];
2361 res->regul_bulk[i].consumer = NULL;
2363 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
2365 DRM_ERROR("failed to get regulators\n");
2368 res->regul_count = ARRAY_SIZE(supply);
2372 DRM_ERROR("HDMI resource init - failed\n");
2376 static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
2378 void hdmi_attach_ddc_client(struct i2c_client *ddc)
2384 void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
2387 hdmi_hdmiphy = hdmiphy;
2391 static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
2392 (struct device *dev)
2394 struct device_node *np = dev->of_node;
2395 struct s5p_hdmi_platform_data *pd;
2396 enum of_gpio_flags flags;
2399 pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
2401 DRM_ERROR("memory allocation for pdata failed\n");
2405 if (!of_find_property(np, "hpd-gpio", &value)) {
2406 DRM_ERROR("no hpd gpio property found\n");
2410 pd->hpd_gpio = of_get_named_gpio_flags(np, "hpd-gpio", 0, &flags);
2418 static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
2419 (struct device *dev)
2425 static struct platform_device_id hdmi_driver_types[] = {
2427 .name = "s5pv210-hdmi",
2428 .driver_data = HDMI_TYPE13,
2430 .name = "exynos4-hdmi",
2431 .driver_data = HDMI_TYPE13,
2433 .name = "exynos4-hdmi14",
2434 .driver_data = HDMI_TYPE14,
2436 .name = "exynos5-hdmi",
2437 .driver_data = HDMI_TYPE14,
2444 static struct of_device_id hdmi_match_types[] = {
2446 .compatible = "samsung,exynos5-hdmi",
2447 .data = (void *)HDMI_TYPE14,
2454 static int hdmi_probe(struct platform_device *pdev)
2456 struct device *dev = &pdev->dev;
2457 struct exynos_drm_hdmi_context *drm_hdmi_ctx;
2458 struct hdmi_context *hdata;
2459 struct s5p_hdmi_platform_data *pdata;
2460 struct resource *res;
2463 DRM_DEBUG_KMS("[%d]\n", __LINE__);
2465 if (pdev->dev.of_node) {
2466 pdata = drm_hdmi_dt_parse_pdata(dev);
2467 if (IS_ERR(pdata)) {
2468 DRM_ERROR("failed to parse dt\n");
2469 return PTR_ERR(pdata);
2472 pdata = pdev->dev.platform_data;
2476 DRM_ERROR("no platform data specified\n");
2480 drm_hdmi_ctx = devm_kzalloc(&pdev->dev, sizeof(*drm_hdmi_ctx),
2482 if (!drm_hdmi_ctx) {
2483 DRM_ERROR("failed to allocate common hdmi context.\n");
2487 hdata = devm_kzalloc(&pdev->dev, sizeof(struct hdmi_context),
2490 DRM_ERROR("out of memory\n");
2494 mutex_init(&hdata->hdmi_mutex);
2496 drm_hdmi_ctx->ctx = (void *)hdata;
2497 hdata->parent_ctx = (void *)drm_hdmi_ctx;
2499 platform_set_drvdata(pdev, drm_hdmi_ctx);
2502 const struct of_device_id *match;
2503 match = of_match_node(of_match_ptr(hdmi_match_types),
2507 hdata->type = (enum hdmi_type)match->data;
2509 hdata->type = (enum hdmi_type)platform_get_device_id
2510 (pdev)->driver_data;
2513 hdata->hpd_gpio = pdata->hpd_gpio;
2516 ret = hdmi_resources_init(hdata);
2519 DRM_ERROR("hdmi_resources_init failed\n");
2523 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2525 DRM_ERROR("failed to find registers\n");
2529 hdata->regs = devm_request_and_ioremap(&pdev->dev, res);
2531 DRM_ERROR("failed to map registers\n");
2535 ret = devm_gpio_request(&pdev->dev, hdata->hpd_gpio, "HPD");
2537 DRM_ERROR("failed to request HPD gpio\n");
2541 /* DDC i2c driver */
2542 if (i2c_add_driver(&ddc_driver)) {
2543 DRM_ERROR("failed to register ddc i2c driver\n");
2547 hdata->ddc_port = hdmi_ddc;
2549 /* hdmiphy i2c driver */
2550 if (i2c_add_driver(&hdmiphy_driver)) {
2551 DRM_ERROR("failed to register hdmiphy i2c driver\n");
2556 hdata->hdmiphy_port = hdmi_hdmiphy;
2558 hdata->external_irq = gpio_to_irq(hdata->hpd_gpio);
2559 if (hdata->external_irq < 0) {
2560 DRM_ERROR("failed to get GPIO external irq\n");
2561 ret = hdata->external_irq;
2565 hdata->internal_irq = platform_get_irq(pdev, 0);
2566 if (hdata->internal_irq < 0) {
2567 DRM_ERROR("failed to get platform internal irq\n");
2568 ret = hdata->internal_irq;
2572 hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2574 ret = request_threaded_irq(hdata->external_irq, NULL,
2575 hdmi_external_irq_thread, IRQF_TRIGGER_RISING |
2576 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
2577 "hdmi_external", drm_hdmi_ctx);
2579 DRM_ERROR("failed to register hdmi external interrupt\n");
2583 ret = request_threaded_irq(hdata->internal_irq, NULL,
2584 hdmi_internal_irq_thread, IRQF_ONESHOT,
2585 "hdmi_internal", drm_hdmi_ctx);
2587 DRM_ERROR("failed to register hdmi internal interrupt\n");
2591 /* Attach HDMI Driver to common hdmi. */
2592 exynos_hdmi_drv_attach(drm_hdmi_ctx);
2594 /* register specific callbacks to common hdmi. */
2595 exynos_hdmi_ops_register(&hdmi_ops);
2597 pm_runtime_enable(dev);
2602 free_irq(hdata->external_irq, drm_hdmi_ctx);
2604 i2c_del_driver(&hdmiphy_driver);
2606 i2c_del_driver(&ddc_driver);
2610 static int hdmi_remove(struct platform_device *pdev)
2612 struct device *dev = &pdev->dev;
2613 struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev);
2614 struct hdmi_context *hdata = ctx->ctx;
2616 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2618 pm_runtime_disable(dev);
2620 free_irq(hdata->internal_irq, hdata);
2621 free_irq(hdata->external_irq, hdata);
2624 /* hdmiphy i2c driver */
2625 i2c_del_driver(&hdmiphy_driver);
2626 /* DDC i2c driver */
2627 i2c_del_driver(&ddc_driver);
2632 #ifdef CONFIG_PM_SLEEP
2633 static int hdmi_suspend(struct device *dev)
2635 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2636 struct hdmi_context *hdata = ctx->ctx;
2638 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2640 disable_irq(hdata->internal_irq);
2641 disable_irq(hdata->external_irq);
2645 drm_helper_hpd_irq_event(ctx->drm_dev);
2647 if (pm_runtime_suspended(dev)) {
2648 DRM_DEBUG_KMS("%s : Already suspended\n", __func__);
2652 hdmi_poweroff(hdata);
2657 static int hdmi_resume(struct device *dev)
2659 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2660 struct hdmi_context *hdata = ctx->ctx;
2662 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2664 hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2666 enable_irq(hdata->external_irq);
2667 enable_irq(hdata->internal_irq);
2669 if (!pm_runtime_suspended(dev)) {
2670 DRM_DEBUG_KMS("%s : Already resumed\n", __func__);
2674 hdmi_poweron(hdata);
2680 #ifdef CONFIG_PM_RUNTIME
2681 static int hdmi_runtime_suspend(struct device *dev)
2683 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2684 struct hdmi_context *hdata = ctx->ctx;
2685 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2687 hdmi_poweroff(hdata);
2692 static int hdmi_runtime_resume(struct device *dev)
2694 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2695 struct hdmi_context *hdata = ctx->ctx;
2696 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2698 hdmi_poweron(hdata);
2704 static const struct dev_pm_ops hdmi_pm_ops = {
2705 SET_SYSTEM_SLEEP_PM_OPS(hdmi_suspend, hdmi_resume)
2706 SET_RUNTIME_PM_OPS(hdmi_runtime_suspend, hdmi_runtime_resume, NULL)
2709 struct platform_driver hdmi_driver = {
2710 .probe = hdmi_probe,
2711 .remove = hdmi_remove,
2712 .id_table = hdmi_driver_types,
2714 .name = "exynos-hdmi",
2715 .owner = THIS_MODULE,
2717 .of_match_table = of_match_ptr(hdmi_match_types),