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.
19 #include "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 <drm/exynos_drm.h>
38 #include "exynos_drm_drv.h"
39 #include "exynos_drm_hdmi.h"
41 #include "exynos_hdmi.h"
43 #define HDMI_OVERLAY_NUMBER 3
44 #define MAX_WIDTH 1920
45 #define MAX_HEIGHT 1080
46 #define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev))
48 /* HDMI Version 1.3 */
49 static const u8 hdmiphy_v13_conf27
[32] = {
50 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
51 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
52 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
53 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
56 static const u8 hdmiphy_v13_conf27_027
[32] = {
57 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
58 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
59 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
60 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
63 static const u8 hdmiphy_v13_conf74_175
[32] = {
64 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
65 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
66 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
67 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
70 static const u8 hdmiphy_v13_conf74_25
[32] = {
71 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
72 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
73 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
74 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
77 static const u8 hdmiphy_v13_conf148_5
[32] = {
78 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
79 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
80 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
81 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
84 struct hdmi_v13_tg_regs
{
116 struct hdmi_v13_core_regs
{
129 struct hdmi_v13_preset_conf
{
130 struct hdmi_v13_core_regs core
;
131 struct hdmi_v13_tg_regs tg
;
134 struct hdmi_v13_conf
{
139 const u8
*hdmiphy_data
;
140 const struct hdmi_v13_preset_conf
*conf
;
143 static const struct hdmi_v13_preset_conf hdmi_v13_conf_480p
= {
145 .h_blank
= {0x8a, 0x00},
146 .v_blank
= {0x0d, 0x6a, 0x01},
147 .h_v_line
= {0x0d, 0xa2, 0x35},
149 .int_pro_mode
= {0x00},
150 .v_blank_f
= {0x00, 0x00, 0x00},
151 .h_sync_gen
= {0x0e, 0x30, 0x11},
152 .v_sync_gen1
= {0x0f, 0x90, 0x00},
153 /* other don't care */
157 0x5a, 0x03, /* h_fsz */
158 0x8a, 0x00, 0xd0, 0x02, /* hact */
159 0x0d, 0x02, /* v_fsz */
160 0x01, 0x00, 0x33, 0x02, /* vsync */
161 0x2d, 0x00, 0xe0, 0x01, /* vact */
162 0x33, 0x02, /* field_chg */
163 0x49, 0x02, /* vact_st2 */
164 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
165 0x01, 0x00, 0x33, 0x02, /* field top/bot */
169 static const struct hdmi_v13_preset_conf hdmi_v13_conf_720p60
= {
171 .h_blank
= {0x72, 0x01},
172 .v_blank
= {0xee, 0xf2, 0x00},
173 .h_v_line
= {0xee, 0x22, 0x67},
175 .int_pro_mode
= {0x00},
176 .v_blank_f
= {0x00, 0x00, 0x00}, /* don't care */
177 .h_sync_gen
= {0x6c, 0x50, 0x02},
178 .v_sync_gen1
= {0x0a, 0x50, 0x00},
179 .v_sync_gen2
= {0x01, 0x10, 0x00},
180 .v_sync_gen3
= {0x01, 0x10, 0x00},
181 /* other don't care */
185 0x72, 0x06, /* h_fsz */
186 0x71, 0x01, 0x01, 0x05, /* hact */
187 0xee, 0x02, /* v_fsz */
188 0x01, 0x00, 0x33, 0x02, /* vsync */
189 0x1e, 0x00, 0xd0, 0x02, /* vact */
190 0x33, 0x02, /* field_chg */
191 0x49, 0x02, /* vact_st2 */
192 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
193 0x01, 0x00, 0x33, 0x02, /* field top/bot */
197 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i50
= {
199 .h_blank
= {0xd0, 0x02},
200 .v_blank
= {0x32, 0xB2, 0x00},
201 .h_v_line
= {0x65, 0x04, 0xa5},
203 .int_pro_mode
= {0x01},
204 .v_blank_f
= {0x49, 0x2A, 0x23},
205 .h_sync_gen
= {0x0E, 0xEA, 0x08},
206 .v_sync_gen1
= {0x07, 0x20, 0x00},
207 .v_sync_gen2
= {0x39, 0x42, 0x23},
208 .v_sync_gen3
= {0x38, 0x87, 0x73},
209 /* other don't care */
213 0x50, 0x0A, /* h_fsz */
214 0xCF, 0x02, 0x81, 0x07, /* hact */
215 0x65, 0x04, /* v_fsz */
216 0x01, 0x00, 0x33, 0x02, /* vsync */
217 0x16, 0x00, 0x1c, 0x02, /* vact */
218 0x33, 0x02, /* field_chg */
219 0x49, 0x02, /* vact_st2 */
220 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
221 0x01, 0x00, 0x33, 0x02, /* field top/bot */
225 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p50
= {
227 .h_blank
= {0xd0, 0x02},
228 .v_blank
= {0x65, 0x6c, 0x01},
229 .h_v_line
= {0x65, 0x04, 0xa5},
231 .int_pro_mode
= {0x00},
232 .v_blank_f
= {0x00, 0x00, 0x00}, /* don't care */
233 .h_sync_gen
= {0x0e, 0xea, 0x08},
234 .v_sync_gen1
= {0x09, 0x40, 0x00},
235 .v_sync_gen2
= {0x01, 0x10, 0x00},
236 .v_sync_gen3
= {0x01, 0x10, 0x00},
237 /* other don't care */
241 0x50, 0x0A, /* h_fsz */
242 0xCF, 0x02, 0x81, 0x07, /* hact */
243 0x65, 0x04, /* v_fsz */
244 0x01, 0x00, 0x33, 0x02, /* vsync */
245 0x2d, 0x00, 0x38, 0x04, /* vact */
246 0x33, 0x02, /* field_chg */
247 0x48, 0x02, /* vact_st2 */
248 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
249 0x01, 0x00, 0x33, 0x02, /* field top/bot */
253 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i60
= {
255 .h_blank
= {0x18, 0x01},
256 .v_blank
= {0x32, 0xB2, 0x00},
257 .h_v_line
= {0x65, 0x84, 0x89},
259 .int_pro_mode
= {0x01},
260 .v_blank_f
= {0x49, 0x2A, 0x23},
261 .h_sync_gen
= {0x56, 0x08, 0x02},
262 .v_sync_gen1
= {0x07, 0x20, 0x00},
263 .v_sync_gen2
= {0x39, 0x42, 0x23},
264 .v_sync_gen3
= {0xa4, 0x44, 0x4a},
265 /* other don't care */
269 0x98, 0x08, /* h_fsz */
270 0x17, 0x01, 0x81, 0x07, /* hact */
271 0x65, 0x04, /* v_fsz */
272 0x01, 0x00, 0x33, 0x02, /* vsync */
273 0x16, 0x00, 0x1c, 0x02, /* vact */
274 0x33, 0x02, /* field_chg */
275 0x49, 0x02, /* vact_st2 */
276 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
277 0x01, 0x00, 0x33, 0x02, /* field top/bot */
281 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60
= {
283 .h_blank
= {0x18, 0x01},
284 .v_blank
= {0x65, 0x6c, 0x01},
285 .h_v_line
= {0x65, 0x84, 0x89},
287 .int_pro_mode
= {0x00},
288 .v_blank_f
= {0x00, 0x00, 0x00}, /* don't care */
289 .h_sync_gen
= {0x56, 0x08, 0x02},
290 .v_sync_gen1
= {0x09, 0x40, 0x00},
291 .v_sync_gen2
= {0x01, 0x10, 0x00},
292 .v_sync_gen3
= {0x01, 0x10, 0x00},
293 /* other don't care */
297 0x98, 0x08, /* h_fsz */
298 0x17, 0x01, 0x81, 0x07, /* hact */
299 0x65, 0x04, /* v_fsz */
300 0x01, 0x00, 0x33, 0x02, /* vsync */
301 0x2d, 0x00, 0x38, 0x04, /* vact */
302 0x33, 0x02, /* field_chg */
303 0x48, 0x02, /* vact_st2 */
304 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
305 0x01, 0x00, 0x33, 0x02, /* field top/bot */
309 static const struct hdmi_v13_conf hdmi_v13_confs
[] = {
310 { 1280, 720, 60, false, hdmiphy_v13_conf74_25
, &hdmi_v13_conf_720p60
},
311 { 1280, 720, 50, false, hdmiphy_v13_conf74_25
, &hdmi_v13_conf_720p60
},
312 { 720, 480, 60, false, hdmiphy_v13_conf27_027
, &hdmi_v13_conf_480p
},
313 { 1920, 1080, 50, true, hdmiphy_v13_conf74_25
, &hdmi_v13_conf_1080i50
},
314 { 1920, 1080, 50, false, hdmiphy_v13_conf148_5
,
315 &hdmi_v13_conf_1080p50
},
316 { 1920, 1080, 60, true, hdmiphy_v13_conf74_25
, &hdmi_v13_conf_1080i60
},
317 { 1920, 1080, 60, false, hdmiphy_v13_conf148_5
,
318 &hdmi_v13_conf_1080p60
},
321 /* HDMI Version 1.4 */
322 static const u8 hdmiphy_conf27_027
[32] = {
323 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
324 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
325 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
326 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
329 static const u8 hdmiphy_conf74_25
[32] = {
330 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
331 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
332 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
333 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
336 static const u8 hdmiphy_conf148_5
[32] = {
337 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
338 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
339 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
340 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
343 struct hdmi_tg_regs
{
380 struct hdmi_core_regs
{
393 u8 v_sync_line_bef_2
[2];
394 u8 v_sync_line_bef_1
[2];
395 u8 v_sync_line_aft_2
[2];
396 u8 v_sync_line_aft_1
[2];
397 u8 v_sync_line_aft_pxl_2
[2];
398 u8 v_sync_line_aft_pxl_1
[2];
399 u8 v_blank_f2
[2]; /* for 3D mode */
400 u8 v_blank_f3
[2]; /* for 3D mode */
401 u8 v_blank_f4
[2]; /* for 3D mode */
402 u8 v_blank_f5
[2]; /* for 3D mode */
403 u8 v_sync_line_aft_3
[2];
404 u8 v_sync_line_aft_4
[2];
405 u8 v_sync_line_aft_5
[2];
406 u8 v_sync_line_aft_6
[2];
407 u8 v_sync_line_aft_pxl_3
[2];
408 u8 v_sync_line_aft_pxl_4
[2];
409 u8 v_sync_line_aft_pxl_5
[2];
410 u8 v_sync_line_aft_pxl_6
[2];
419 struct hdmi_preset_conf
{
420 struct hdmi_core_regs core
;
421 struct hdmi_tg_regs tg
;
429 const u8
*hdmiphy_data
;
430 const struct hdmi_preset_conf
*conf
;
433 static const struct hdmi_preset_conf hdmi_conf_480p60
= {
435 .h_blank
= {0x8a, 0x00},
436 .v2_blank
= {0x0d, 0x02},
437 .v1_blank
= {0x2d, 0x00},
438 .v_line
= {0x0d, 0x02},
439 .h_line
= {0x5a, 0x03},
442 .int_pro_mode
= {0x00},
443 .v_blank_f0
= {0xff, 0xff},
444 .v_blank_f1
= {0xff, 0xff},
445 .h_sync_start
= {0x0e, 0x00},
446 .h_sync_end
= {0x4c, 0x00},
447 .v_sync_line_bef_2
= {0x0f, 0x00},
448 .v_sync_line_bef_1
= {0x09, 0x00},
449 .v_sync_line_aft_2
= {0xff, 0xff},
450 .v_sync_line_aft_1
= {0xff, 0xff},
451 .v_sync_line_aft_pxl_2
= {0xff, 0xff},
452 .v_sync_line_aft_pxl_1
= {0xff, 0xff},
453 .v_blank_f2
= {0xff, 0xff},
454 .v_blank_f3
= {0xff, 0xff},
455 .v_blank_f4
= {0xff, 0xff},
456 .v_blank_f5
= {0xff, 0xff},
457 .v_sync_line_aft_3
= {0xff, 0xff},
458 .v_sync_line_aft_4
= {0xff, 0xff},
459 .v_sync_line_aft_5
= {0xff, 0xff},
460 .v_sync_line_aft_6
= {0xff, 0xff},
461 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
462 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
463 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
464 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
465 .vact_space_1
= {0xff, 0xff},
466 .vact_space_2
= {0xff, 0xff},
467 .vact_space_3
= {0xff, 0xff},
468 .vact_space_4
= {0xff, 0xff},
469 .vact_space_5
= {0xff, 0xff},
470 .vact_space_6
= {0xff, 0xff},
471 /* other don't care */
475 0x5a, 0x03, /* h_fsz */
476 0x8a, 0x00, 0xd0, 0x02, /* hact */
477 0x0d, 0x02, /* v_fsz */
478 0x01, 0x00, 0x33, 0x02, /* vsync */
479 0x2d, 0x00, 0xe0, 0x01, /* vact */
480 0x33, 0x02, /* field_chg */
481 0x48, 0x02, /* vact_st2 */
482 0x00, 0x00, /* vact_st3 */
483 0x00, 0x00, /* vact_st4 */
484 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
485 0x01, 0x00, 0x33, 0x02, /* field top/bot */
490 static const struct hdmi_preset_conf hdmi_conf_720p50
= {
492 .h_blank
= {0xbc, 0x02},
493 .v2_blank
= {0xee, 0x02},
494 .v1_blank
= {0x1e, 0x00},
495 .v_line
= {0xee, 0x02},
496 .h_line
= {0xbc, 0x07},
499 .int_pro_mode
= {0x00},
500 .v_blank_f0
= {0xff, 0xff},
501 .v_blank_f1
= {0xff, 0xff},
502 .h_sync_start
= {0xb6, 0x01},
503 .h_sync_end
= {0xde, 0x01},
504 .v_sync_line_bef_2
= {0x0a, 0x00},
505 .v_sync_line_bef_1
= {0x05, 0x00},
506 .v_sync_line_aft_2
= {0xff, 0xff},
507 .v_sync_line_aft_1
= {0xff, 0xff},
508 .v_sync_line_aft_pxl_2
= {0xff, 0xff},
509 .v_sync_line_aft_pxl_1
= {0xff, 0xff},
510 .v_blank_f2
= {0xff, 0xff},
511 .v_blank_f3
= {0xff, 0xff},
512 .v_blank_f4
= {0xff, 0xff},
513 .v_blank_f5
= {0xff, 0xff},
514 .v_sync_line_aft_3
= {0xff, 0xff},
515 .v_sync_line_aft_4
= {0xff, 0xff},
516 .v_sync_line_aft_5
= {0xff, 0xff},
517 .v_sync_line_aft_6
= {0xff, 0xff},
518 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
519 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
520 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
521 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
522 .vact_space_1
= {0xff, 0xff},
523 .vact_space_2
= {0xff, 0xff},
524 .vact_space_3
= {0xff, 0xff},
525 .vact_space_4
= {0xff, 0xff},
526 .vact_space_5
= {0xff, 0xff},
527 .vact_space_6
= {0xff, 0xff},
528 /* other don't care */
532 0xbc, 0x07, /* h_fsz */
533 0xbc, 0x02, 0x00, 0x05, /* hact */
534 0xee, 0x02, /* v_fsz */
535 0x01, 0x00, 0x33, 0x02, /* vsync */
536 0x1e, 0x00, 0xd0, 0x02, /* vact */
537 0x33, 0x02, /* field_chg */
538 0x48, 0x02, /* vact_st2 */
539 0x00, 0x00, /* vact_st3 */
540 0x00, 0x00, /* vact_st4 */
541 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
542 0x01, 0x00, 0x33, 0x02, /* field top/bot */
547 static const struct hdmi_preset_conf hdmi_conf_720p60
= {
549 .h_blank
= {0x72, 0x01},
550 .v2_blank
= {0xee, 0x02},
551 .v1_blank
= {0x1e, 0x00},
552 .v_line
= {0xee, 0x02},
553 .h_line
= {0x72, 0x06},
556 .int_pro_mode
= {0x00},
557 .v_blank_f0
= {0xff, 0xff},
558 .v_blank_f1
= {0xff, 0xff},
559 .h_sync_start
= {0x6c, 0x00},
560 .h_sync_end
= {0x94, 0x00},
561 .v_sync_line_bef_2
= {0x0a, 0x00},
562 .v_sync_line_bef_1
= {0x05, 0x00},
563 .v_sync_line_aft_2
= {0xff, 0xff},
564 .v_sync_line_aft_1
= {0xff, 0xff},
565 .v_sync_line_aft_pxl_2
= {0xff, 0xff},
566 .v_sync_line_aft_pxl_1
= {0xff, 0xff},
567 .v_blank_f2
= {0xff, 0xff},
568 .v_blank_f3
= {0xff, 0xff},
569 .v_blank_f4
= {0xff, 0xff},
570 .v_blank_f5
= {0xff, 0xff},
571 .v_sync_line_aft_3
= {0xff, 0xff},
572 .v_sync_line_aft_4
= {0xff, 0xff},
573 .v_sync_line_aft_5
= {0xff, 0xff},
574 .v_sync_line_aft_6
= {0xff, 0xff},
575 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
576 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
577 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
578 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
579 .vact_space_1
= {0xff, 0xff},
580 .vact_space_2
= {0xff, 0xff},
581 .vact_space_3
= {0xff, 0xff},
582 .vact_space_4
= {0xff, 0xff},
583 .vact_space_5
= {0xff, 0xff},
584 .vact_space_6
= {0xff, 0xff},
585 /* other don't care */
589 0x72, 0x06, /* h_fsz */
590 0x72, 0x01, 0x00, 0x05, /* hact */
591 0xee, 0x02, /* v_fsz */
592 0x01, 0x00, 0x33, 0x02, /* vsync */
593 0x1e, 0x00, 0xd0, 0x02, /* vact */
594 0x33, 0x02, /* field_chg */
595 0x48, 0x02, /* vact_st2 */
596 0x00, 0x00, /* vact_st3 */
597 0x00, 0x00, /* vact_st4 */
598 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
599 0x01, 0x00, 0x33, 0x02, /* field top/bot */
604 static const struct hdmi_preset_conf hdmi_conf_1080i50
= {
606 .h_blank
= {0xd0, 0x02},
607 .v2_blank
= {0x32, 0x02},
608 .v1_blank
= {0x16, 0x00},
609 .v_line
= {0x65, 0x04},
610 .h_line
= {0x50, 0x0a},
613 .int_pro_mode
= {0x01},
614 .v_blank_f0
= {0x49, 0x02},
615 .v_blank_f1
= {0x65, 0x04},
616 .h_sync_start
= {0x0e, 0x02},
617 .h_sync_end
= {0x3a, 0x02},
618 .v_sync_line_bef_2
= {0x07, 0x00},
619 .v_sync_line_bef_1
= {0x02, 0x00},
620 .v_sync_line_aft_2
= {0x39, 0x02},
621 .v_sync_line_aft_1
= {0x34, 0x02},
622 .v_sync_line_aft_pxl_2
= {0x38, 0x07},
623 .v_sync_line_aft_pxl_1
= {0x38, 0x07},
624 .v_blank_f2
= {0xff, 0xff},
625 .v_blank_f3
= {0xff, 0xff},
626 .v_blank_f4
= {0xff, 0xff},
627 .v_blank_f5
= {0xff, 0xff},
628 .v_sync_line_aft_3
= {0xff, 0xff},
629 .v_sync_line_aft_4
= {0xff, 0xff},
630 .v_sync_line_aft_5
= {0xff, 0xff},
631 .v_sync_line_aft_6
= {0xff, 0xff},
632 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
633 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
634 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
635 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
636 .vact_space_1
= {0xff, 0xff},
637 .vact_space_2
= {0xff, 0xff},
638 .vact_space_3
= {0xff, 0xff},
639 .vact_space_4
= {0xff, 0xff},
640 .vact_space_5
= {0xff, 0xff},
641 .vact_space_6
= {0xff, 0xff},
642 /* other don't care */
646 0x50, 0x0a, /* h_fsz */
647 0xd0, 0x02, 0x80, 0x07, /* hact */
648 0x65, 0x04, /* v_fsz */
649 0x01, 0x00, 0x33, 0x02, /* vsync */
650 0x16, 0x00, 0x1c, 0x02, /* vact */
651 0x33, 0x02, /* field_chg */
652 0x49, 0x02, /* vact_st2 */
653 0x00, 0x00, /* vact_st3 */
654 0x00, 0x00, /* vact_st4 */
655 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
656 0x01, 0x00, 0x33, 0x02, /* field top/bot */
661 static const struct hdmi_preset_conf hdmi_conf_1080i60
= {
663 .h_blank
= {0x18, 0x01},
664 .v2_blank
= {0x32, 0x02},
665 .v1_blank
= {0x16, 0x00},
666 .v_line
= {0x65, 0x04},
667 .h_line
= {0x98, 0x08},
670 .int_pro_mode
= {0x01},
671 .v_blank_f0
= {0x49, 0x02},
672 .v_blank_f1
= {0x65, 0x04},
673 .h_sync_start
= {0x56, 0x00},
674 .h_sync_end
= {0x82, 0x00},
675 .v_sync_line_bef_2
= {0x07, 0x00},
676 .v_sync_line_bef_1
= {0x02, 0x00},
677 .v_sync_line_aft_2
= {0x39, 0x02},
678 .v_sync_line_aft_1
= {0x34, 0x02},
679 .v_sync_line_aft_pxl_2
= {0xa4, 0x04},
680 .v_sync_line_aft_pxl_1
= {0xa4, 0x04},
681 .v_blank_f2
= {0xff, 0xff},
682 .v_blank_f3
= {0xff, 0xff},
683 .v_blank_f4
= {0xff, 0xff},
684 .v_blank_f5
= {0xff, 0xff},
685 .v_sync_line_aft_3
= {0xff, 0xff},
686 .v_sync_line_aft_4
= {0xff, 0xff},
687 .v_sync_line_aft_5
= {0xff, 0xff},
688 .v_sync_line_aft_6
= {0xff, 0xff},
689 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
690 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
691 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
692 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
693 .vact_space_1
= {0xff, 0xff},
694 .vact_space_2
= {0xff, 0xff},
695 .vact_space_3
= {0xff, 0xff},
696 .vact_space_4
= {0xff, 0xff},
697 .vact_space_5
= {0xff, 0xff},
698 .vact_space_6
= {0xff, 0xff},
699 /* other don't care */
703 0x98, 0x08, /* h_fsz */
704 0x18, 0x01, 0x80, 0x07, /* hact */
705 0x65, 0x04, /* v_fsz */
706 0x01, 0x00, 0x33, 0x02, /* vsync */
707 0x16, 0x00, 0x1c, 0x02, /* vact */
708 0x33, 0x02, /* field_chg */
709 0x49, 0x02, /* vact_st2 */
710 0x00, 0x00, /* vact_st3 */
711 0x00, 0x00, /* vact_st4 */
712 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
713 0x01, 0x00, 0x33, 0x02, /* field top/bot */
718 static const struct hdmi_preset_conf hdmi_conf_1080p50
= {
720 .h_blank
= {0xd0, 0x02},
721 .v2_blank
= {0x65, 0x04},
722 .v1_blank
= {0x2d, 0x00},
723 .v_line
= {0x65, 0x04},
724 .h_line
= {0x50, 0x0a},
727 .int_pro_mode
= {0x00},
728 .v_blank_f0
= {0xff, 0xff},
729 .v_blank_f1
= {0xff, 0xff},
730 .h_sync_start
= {0x0e, 0x02},
731 .h_sync_end
= {0x3a, 0x02},
732 .v_sync_line_bef_2
= {0x09, 0x00},
733 .v_sync_line_bef_1
= {0x04, 0x00},
734 .v_sync_line_aft_2
= {0xff, 0xff},
735 .v_sync_line_aft_1
= {0xff, 0xff},
736 .v_sync_line_aft_pxl_2
= {0xff, 0xff},
737 .v_sync_line_aft_pxl_1
= {0xff, 0xff},
738 .v_blank_f2
= {0xff, 0xff},
739 .v_blank_f3
= {0xff, 0xff},
740 .v_blank_f4
= {0xff, 0xff},
741 .v_blank_f5
= {0xff, 0xff},
742 .v_sync_line_aft_3
= {0xff, 0xff},
743 .v_sync_line_aft_4
= {0xff, 0xff},
744 .v_sync_line_aft_5
= {0xff, 0xff},
745 .v_sync_line_aft_6
= {0xff, 0xff},
746 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
747 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
748 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
749 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
750 .vact_space_1
= {0xff, 0xff},
751 .vact_space_2
= {0xff, 0xff},
752 .vact_space_3
= {0xff, 0xff},
753 .vact_space_4
= {0xff, 0xff},
754 .vact_space_5
= {0xff, 0xff},
755 .vact_space_6
= {0xff, 0xff},
756 /* other don't care */
760 0x50, 0x0a, /* h_fsz */
761 0xd0, 0x02, 0x80, 0x07, /* hact */
762 0x65, 0x04, /* v_fsz */
763 0x01, 0x00, 0x33, 0x02, /* vsync */
764 0x2d, 0x00, 0x38, 0x04, /* vact */
765 0x33, 0x02, /* field_chg */
766 0x48, 0x02, /* vact_st2 */
767 0x00, 0x00, /* vact_st3 */
768 0x00, 0x00, /* vact_st4 */
769 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
770 0x01, 0x00, 0x33, 0x02, /* field top/bot */
775 static const struct hdmi_preset_conf hdmi_conf_1080p60
= {
777 .h_blank
= {0x18, 0x01},
778 .v2_blank
= {0x65, 0x04},
779 .v1_blank
= {0x2d, 0x00},
780 .v_line
= {0x65, 0x04},
781 .h_line
= {0x98, 0x08},
784 .int_pro_mode
= {0x00},
785 .v_blank_f0
= {0xff, 0xff},
786 .v_blank_f1
= {0xff, 0xff},
787 .h_sync_start
= {0x56, 0x00},
788 .h_sync_end
= {0x82, 0x00},
789 .v_sync_line_bef_2
= {0x09, 0x00},
790 .v_sync_line_bef_1
= {0x04, 0x00},
791 .v_sync_line_aft_2
= {0xff, 0xff},
792 .v_sync_line_aft_1
= {0xff, 0xff},
793 .v_sync_line_aft_pxl_2
= {0xff, 0xff},
794 .v_sync_line_aft_pxl_1
= {0xff, 0xff},
795 .v_blank_f2
= {0xff, 0xff},
796 .v_blank_f3
= {0xff, 0xff},
797 .v_blank_f4
= {0xff, 0xff},
798 .v_blank_f5
= {0xff, 0xff},
799 .v_sync_line_aft_3
= {0xff, 0xff},
800 .v_sync_line_aft_4
= {0xff, 0xff},
801 .v_sync_line_aft_5
= {0xff, 0xff},
802 .v_sync_line_aft_6
= {0xff, 0xff},
803 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
804 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
805 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
806 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
807 /* other don't care */
811 0x98, 0x08, /* h_fsz */
812 0x18, 0x01, 0x80, 0x07, /* hact */
813 0x65, 0x04, /* v_fsz */
814 0x01, 0x00, 0x33, 0x02, /* vsync */
815 0x2d, 0x00, 0x38, 0x04, /* vact */
816 0x33, 0x02, /* field_chg */
817 0x48, 0x02, /* vact_st2 */
818 0x00, 0x00, /* vact_st3 */
819 0x00, 0x00, /* vact_st4 */
820 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
821 0x01, 0x00, 0x33, 0x02, /* field top/bot */
826 static const struct hdmi_conf hdmi_confs
[] = {
827 { 720, 480, 60, false, hdmiphy_conf27_027
, &hdmi_conf_480p60
},
828 { 1280, 720, 50, false, hdmiphy_conf74_25
, &hdmi_conf_720p50
},
829 { 1280, 720, 60, false, hdmiphy_conf74_25
, &hdmi_conf_720p60
},
830 { 1920, 1080, 50, true, hdmiphy_conf74_25
, &hdmi_conf_1080i50
},
831 { 1920, 1080, 60, true, hdmiphy_conf74_25
, &hdmi_conf_1080i60
},
832 { 1920, 1080, 50, false, hdmiphy_conf148_5
, &hdmi_conf_1080p50
},
833 { 1920, 1080, 60, false, hdmiphy_conf148_5
, &hdmi_conf_1080p60
},
837 static inline u32
hdmi_reg_read(struct hdmi_context
*hdata
, u32 reg_id
)
839 return readl(hdata
->regs
+ reg_id
);
842 static inline void hdmi_reg_writeb(struct hdmi_context
*hdata
,
843 u32 reg_id
, u8 value
)
845 writeb(value
, hdata
->regs
+ reg_id
);
848 static inline void hdmi_reg_writemask(struct hdmi_context
*hdata
,
849 u32 reg_id
, u32 value
, u32 mask
)
851 u32 old
= readl(hdata
->regs
+ reg_id
);
852 value
= (value
& mask
) | (old
& ~mask
);
853 writel(value
, hdata
->regs
+ reg_id
);
856 static void hdmi_v13_regs_dump(struct hdmi_context
*hdata
, char *prefix
)
858 #define DUMPREG(reg_id) \
859 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
860 readl(hdata->regs + reg_id))
861 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix
);
862 DUMPREG(HDMI_INTC_FLAG
);
863 DUMPREG(HDMI_INTC_CON
);
864 DUMPREG(HDMI_HPD_STATUS
);
865 DUMPREG(HDMI_V13_PHY_RSTOUT
);
866 DUMPREG(HDMI_V13_PHY_VPLL
);
867 DUMPREG(HDMI_V13_PHY_CMU
);
868 DUMPREG(HDMI_V13_CORE_RSTOUT
);
870 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix
);
874 DUMPREG(HDMI_SYS_STATUS
);
875 DUMPREG(HDMI_V13_PHY_STATUS
);
876 DUMPREG(HDMI_STATUS_EN
);
878 DUMPREG(HDMI_MODE_SEL
);
879 DUMPREG(HDMI_V13_HPD_GEN
);
880 DUMPREG(HDMI_V13_DC_CONTROL
);
881 DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN
);
883 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix
);
884 DUMPREG(HDMI_H_BLANK_0
);
885 DUMPREG(HDMI_H_BLANK_1
);
886 DUMPREG(HDMI_V13_V_BLANK_0
);
887 DUMPREG(HDMI_V13_V_BLANK_1
);
888 DUMPREG(HDMI_V13_V_BLANK_2
);
889 DUMPREG(HDMI_V13_H_V_LINE_0
);
890 DUMPREG(HDMI_V13_H_V_LINE_1
);
891 DUMPREG(HDMI_V13_H_V_LINE_2
);
892 DUMPREG(HDMI_VSYNC_POL
);
893 DUMPREG(HDMI_INT_PRO_MODE
);
894 DUMPREG(HDMI_V13_V_BLANK_F_0
);
895 DUMPREG(HDMI_V13_V_BLANK_F_1
);
896 DUMPREG(HDMI_V13_V_BLANK_F_2
);
897 DUMPREG(HDMI_V13_H_SYNC_GEN_0
);
898 DUMPREG(HDMI_V13_H_SYNC_GEN_1
);
899 DUMPREG(HDMI_V13_H_SYNC_GEN_2
);
900 DUMPREG(HDMI_V13_V_SYNC_GEN_1_0
);
901 DUMPREG(HDMI_V13_V_SYNC_GEN_1_1
);
902 DUMPREG(HDMI_V13_V_SYNC_GEN_1_2
);
903 DUMPREG(HDMI_V13_V_SYNC_GEN_2_0
);
904 DUMPREG(HDMI_V13_V_SYNC_GEN_2_1
);
905 DUMPREG(HDMI_V13_V_SYNC_GEN_2_2
);
906 DUMPREG(HDMI_V13_V_SYNC_GEN_3_0
);
907 DUMPREG(HDMI_V13_V_SYNC_GEN_3_1
);
908 DUMPREG(HDMI_V13_V_SYNC_GEN_3_2
);
910 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix
);
911 DUMPREG(HDMI_TG_CMD
);
912 DUMPREG(HDMI_TG_H_FSZ_L
);
913 DUMPREG(HDMI_TG_H_FSZ_H
);
914 DUMPREG(HDMI_TG_HACT_ST_L
);
915 DUMPREG(HDMI_TG_HACT_ST_H
);
916 DUMPREG(HDMI_TG_HACT_SZ_L
);
917 DUMPREG(HDMI_TG_HACT_SZ_H
);
918 DUMPREG(HDMI_TG_V_FSZ_L
);
919 DUMPREG(HDMI_TG_V_FSZ_H
);
920 DUMPREG(HDMI_TG_VSYNC_L
);
921 DUMPREG(HDMI_TG_VSYNC_H
);
922 DUMPREG(HDMI_TG_VSYNC2_L
);
923 DUMPREG(HDMI_TG_VSYNC2_H
);
924 DUMPREG(HDMI_TG_VACT_ST_L
);
925 DUMPREG(HDMI_TG_VACT_ST_H
);
926 DUMPREG(HDMI_TG_VACT_SZ_L
);
927 DUMPREG(HDMI_TG_VACT_SZ_H
);
928 DUMPREG(HDMI_TG_FIELD_CHG_L
);
929 DUMPREG(HDMI_TG_FIELD_CHG_H
);
930 DUMPREG(HDMI_TG_VACT_ST2_L
);
931 DUMPREG(HDMI_TG_VACT_ST2_H
);
932 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L
);
933 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H
);
934 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L
);
935 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H
);
936 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L
);
937 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H
);
938 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L
);
939 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H
);
943 static void hdmi_v14_regs_dump(struct hdmi_context
*hdata
, char *prefix
)
947 #define DUMPREG(reg_id) \
948 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
949 readl(hdata->regs + reg_id))
951 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix
);
952 DUMPREG(HDMI_INTC_CON
);
953 DUMPREG(HDMI_INTC_FLAG
);
954 DUMPREG(HDMI_HPD_STATUS
);
955 DUMPREG(HDMI_INTC_CON_1
);
956 DUMPREG(HDMI_INTC_FLAG_1
);
957 DUMPREG(HDMI_PHY_STATUS_0
);
958 DUMPREG(HDMI_PHY_STATUS_PLL
);
959 DUMPREG(HDMI_PHY_CON_0
);
960 DUMPREG(HDMI_PHY_RSTOUT
);
961 DUMPREG(HDMI_PHY_VPLL
);
962 DUMPREG(HDMI_PHY_CMU
);
963 DUMPREG(HDMI_CORE_RSTOUT
);
965 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix
);
969 DUMPREG(HDMI_SYS_STATUS
);
970 DUMPREG(HDMI_PHY_STATUS_0
);
971 DUMPREG(HDMI_STATUS_EN
);
973 DUMPREG(HDMI_MODE_SEL
);
974 DUMPREG(HDMI_ENC_EN
);
975 DUMPREG(HDMI_DC_CONTROL
);
976 DUMPREG(HDMI_VIDEO_PATTERN_GEN
);
978 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix
);
979 DUMPREG(HDMI_H_BLANK_0
);
980 DUMPREG(HDMI_H_BLANK_1
);
981 DUMPREG(HDMI_V2_BLANK_0
);
982 DUMPREG(HDMI_V2_BLANK_1
);
983 DUMPREG(HDMI_V1_BLANK_0
);
984 DUMPREG(HDMI_V1_BLANK_1
);
985 DUMPREG(HDMI_V_LINE_0
);
986 DUMPREG(HDMI_V_LINE_1
);
987 DUMPREG(HDMI_H_LINE_0
);
988 DUMPREG(HDMI_H_LINE_1
);
989 DUMPREG(HDMI_HSYNC_POL
);
991 DUMPREG(HDMI_VSYNC_POL
);
992 DUMPREG(HDMI_INT_PRO_MODE
);
993 DUMPREG(HDMI_V_BLANK_F0_0
);
994 DUMPREG(HDMI_V_BLANK_F0_1
);
995 DUMPREG(HDMI_V_BLANK_F1_0
);
996 DUMPREG(HDMI_V_BLANK_F1_1
);
998 DUMPREG(HDMI_H_SYNC_START_0
);
999 DUMPREG(HDMI_H_SYNC_START_1
);
1000 DUMPREG(HDMI_H_SYNC_END_0
);
1001 DUMPREG(HDMI_H_SYNC_END_1
);
1003 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0
);
1004 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1
);
1005 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0
);
1006 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1
);
1008 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0
);
1009 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1
);
1010 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0
);
1011 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1
);
1013 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0
);
1014 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1
);
1015 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0
);
1016 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1
);
1018 DUMPREG(HDMI_V_BLANK_F2_0
);
1019 DUMPREG(HDMI_V_BLANK_F2_1
);
1020 DUMPREG(HDMI_V_BLANK_F3_0
);
1021 DUMPREG(HDMI_V_BLANK_F3_1
);
1022 DUMPREG(HDMI_V_BLANK_F4_0
);
1023 DUMPREG(HDMI_V_BLANK_F4_1
);
1024 DUMPREG(HDMI_V_BLANK_F5_0
);
1025 DUMPREG(HDMI_V_BLANK_F5_1
);
1027 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0
);
1028 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1
);
1029 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0
);
1030 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1
);
1031 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0
);
1032 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1
);
1033 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0
);
1034 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1
);
1036 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0
);
1037 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1
);
1038 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0
);
1039 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1
);
1040 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0
);
1041 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1
);
1042 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0
);
1043 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1
);
1045 DUMPREG(HDMI_VACT_SPACE_1_0
);
1046 DUMPREG(HDMI_VACT_SPACE_1_1
);
1047 DUMPREG(HDMI_VACT_SPACE_2_0
);
1048 DUMPREG(HDMI_VACT_SPACE_2_1
);
1049 DUMPREG(HDMI_VACT_SPACE_3_0
);
1050 DUMPREG(HDMI_VACT_SPACE_3_1
);
1051 DUMPREG(HDMI_VACT_SPACE_4_0
);
1052 DUMPREG(HDMI_VACT_SPACE_4_1
);
1053 DUMPREG(HDMI_VACT_SPACE_5_0
);
1054 DUMPREG(HDMI_VACT_SPACE_5_1
);
1055 DUMPREG(HDMI_VACT_SPACE_6_0
);
1056 DUMPREG(HDMI_VACT_SPACE_6_1
);
1058 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix
);
1059 DUMPREG(HDMI_TG_CMD
);
1060 DUMPREG(HDMI_TG_H_FSZ_L
);
1061 DUMPREG(HDMI_TG_H_FSZ_H
);
1062 DUMPREG(HDMI_TG_HACT_ST_L
);
1063 DUMPREG(HDMI_TG_HACT_ST_H
);
1064 DUMPREG(HDMI_TG_HACT_SZ_L
);
1065 DUMPREG(HDMI_TG_HACT_SZ_H
);
1066 DUMPREG(HDMI_TG_V_FSZ_L
);
1067 DUMPREG(HDMI_TG_V_FSZ_H
);
1068 DUMPREG(HDMI_TG_VSYNC_L
);
1069 DUMPREG(HDMI_TG_VSYNC_H
);
1070 DUMPREG(HDMI_TG_VSYNC2_L
);
1071 DUMPREG(HDMI_TG_VSYNC2_H
);
1072 DUMPREG(HDMI_TG_VACT_ST_L
);
1073 DUMPREG(HDMI_TG_VACT_ST_H
);
1074 DUMPREG(HDMI_TG_VACT_SZ_L
);
1075 DUMPREG(HDMI_TG_VACT_SZ_H
);
1076 DUMPREG(HDMI_TG_FIELD_CHG_L
);
1077 DUMPREG(HDMI_TG_FIELD_CHG_H
);
1078 DUMPREG(HDMI_TG_VACT_ST2_L
);
1079 DUMPREG(HDMI_TG_VACT_ST2_H
);
1080 DUMPREG(HDMI_TG_VACT_ST3_L
);
1081 DUMPREG(HDMI_TG_VACT_ST3_H
);
1082 DUMPREG(HDMI_TG_VACT_ST4_L
);
1083 DUMPREG(HDMI_TG_VACT_ST4_H
);
1084 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L
);
1085 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H
);
1086 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L
);
1087 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H
);
1088 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L
);
1089 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H
);
1090 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L
);
1091 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H
);
1092 DUMPREG(HDMI_TG_3D
);
1094 DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix
);
1095 DUMPREG(HDMI_AVI_CON
);
1096 DUMPREG(HDMI_AVI_HEADER0
);
1097 DUMPREG(HDMI_AVI_HEADER1
);
1098 DUMPREG(HDMI_AVI_HEADER2
);
1099 DUMPREG(HDMI_AVI_CHECK_SUM
);
1100 DUMPREG(HDMI_VSI_CON
);
1101 DUMPREG(HDMI_VSI_HEADER0
);
1102 DUMPREG(HDMI_VSI_HEADER1
);
1103 DUMPREG(HDMI_VSI_HEADER2
);
1104 for (i
= 0; i
< 7; ++i
)
1105 DUMPREG(HDMI_VSI_DATA(i
));
1110 static void hdmi_regs_dump(struct hdmi_context
*hdata
, char *prefix
)
1113 hdmi_v13_regs_dump(hdata
, prefix
);
1115 hdmi_v14_regs_dump(hdata
, prefix
);
1118 static int hdmi_v13_conf_index(struct drm_display_mode
*mode
)
1122 for (i
= 0; i
< ARRAY_SIZE(hdmi_v13_confs
); ++i
)
1123 if (hdmi_v13_confs
[i
].width
== mode
->hdisplay
&&
1124 hdmi_v13_confs
[i
].height
== mode
->vdisplay
&&
1125 hdmi_v13_confs
[i
].vrefresh
== mode
->vrefresh
&&
1126 hdmi_v13_confs
[i
].interlace
==
1127 ((mode
->flags
& DRM_MODE_FLAG_INTERLACE
) ?
1134 static int hdmi_v14_conf_index(struct drm_display_mode
*mode
)
1138 for (i
= 0; i
< ARRAY_SIZE(hdmi_confs
); ++i
)
1139 if (hdmi_confs
[i
].width
== mode
->hdisplay
&&
1140 hdmi_confs
[i
].height
== mode
->vdisplay
&&
1141 hdmi_confs
[i
].vrefresh
== mode
->vrefresh
&&
1142 hdmi_confs
[i
].interlace
==
1143 ((mode
->flags
& DRM_MODE_FLAG_INTERLACE
) ?
1150 static int hdmi_conf_index(struct hdmi_context
*hdata
,
1151 struct drm_display_mode
*mode
)
1154 return hdmi_v13_conf_index(mode
);
1156 return hdmi_v14_conf_index(mode
);
1159 static bool hdmi_is_connected(void *ctx
)
1161 struct hdmi_context
*hdata
= (struct hdmi_context
*)ctx
;
1162 u32 val
= hdmi_reg_read(hdata
, HDMI_HPD_STATUS
);
1170 static int hdmi_get_edid(void *ctx
, struct drm_connector
*connector
,
1173 struct edid
*raw_edid
;
1174 struct hdmi_context
*hdata
= (struct hdmi_context
*)ctx
;
1176 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1178 if (!hdata
->ddc_port
)
1181 raw_edid
= drm_get_edid(connector
, hdata
->ddc_port
->adapter
);
1183 memcpy(edid
, raw_edid
, min((1 + raw_edid
->extensions
)
1184 * EDID_LENGTH
, len
));
1185 DRM_DEBUG_KMS("width[%d] x height[%d]\n",
1186 raw_edid
->width_cm
, raw_edid
->height_cm
);
1194 static int hdmi_v13_check_timing(struct fb_videomode
*check_timing
)
1198 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1199 check_timing
->xres
, check_timing
->yres
,
1200 check_timing
->refresh
, (check_timing
->vmode
&
1201 FB_VMODE_INTERLACED
) ? true : false);
1203 for (i
= 0; i
< ARRAY_SIZE(hdmi_v13_confs
); ++i
)
1204 if (hdmi_v13_confs
[i
].width
== check_timing
->xres
&&
1205 hdmi_v13_confs
[i
].height
== check_timing
->yres
&&
1206 hdmi_v13_confs
[i
].vrefresh
== check_timing
->refresh
&&
1207 hdmi_v13_confs
[i
].interlace
==
1208 ((check_timing
->vmode
& FB_VMODE_INTERLACED
) ?
1217 static int hdmi_v14_check_timing(struct fb_videomode
*check_timing
)
1221 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1222 check_timing
->xres
, check_timing
->yres
,
1223 check_timing
->refresh
, (check_timing
->vmode
&
1224 FB_VMODE_INTERLACED
) ? true : false);
1226 for (i
= 0; i
< ARRAY_SIZE(hdmi_confs
); i
++)
1227 if (hdmi_confs
[i
].width
== check_timing
->xres
&&
1228 hdmi_confs
[i
].height
== check_timing
->yres
&&
1229 hdmi_confs
[i
].vrefresh
== check_timing
->refresh
&&
1230 hdmi_confs
[i
].interlace
==
1231 ((check_timing
->vmode
& FB_VMODE_INTERLACED
) ?
1240 static int hdmi_check_timing(void *ctx
, void *timing
)
1242 struct hdmi_context
*hdata
= (struct hdmi_context
*)ctx
;
1243 struct fb_videomode
*check_timing
= timing
;
1245 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1247 DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing
->xres
,
1248 check_timing
->yres
, check_timing
->refresh
,
1249 check_timing
->vmode
);
1252 return hdmi_v13_check_timing(check_timing
);
1254 return hdmi_v14_check_timing(check_timing
);
1257 static int hdmi_display_power_on(void *ctx
, int mode
)
1259 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1262 case DRM_MODE_DPMS_ON
:
1263 DRM_DEBUG_KMS("hdmi [on]\n");
1265 case DRM_MODE_DPMS_STANDBY
:
1267 case DRM_MODE_DPMS_SUSPEND
:
1269 case DRM_MODE_DPMS_OFF
:
1270 DRM_DEBUG_KMS("hdmi [off]\n");
1279 static struct exynos_hdmi_display_ops display_ops
= {
1280 .is_connected
= hdmi_is_connected
,
1281 .get_edid
= hdmi_get_edid
,
1282 .check_timing
= hdmi_check_timing
,
1283 .power_on
= hdmi_display_power_on
,
1286 static void hdmi_conf_reset(struct hdmi_context
*hdata
)
1290 /* disable hpd handle for drm */
1291 hdata
->hpd_handle
= false;
1294 reg
= HDMI_V13_CORE_RSTOUT
;
1296 reg
= HDMI_CORE_RSTOUT
;
1298 /* resetting HDMI core */
1299 hdmi_reg_writemask(hdata
, reg
, 0, HDMI_CORE_SW_RSTOUT
);
1301 hdmi_reg_writemask(hdata
, reg
, ~0, HDMI_CORE_SW_RSTOUT
);
1304 /* enable hpd handle for drm */
1305 hdata
->hpd_handle
= true;
1308 static void hdmi_conf_init(struct hdmi_context
*hdata
)
1310 /* disable hpd handle for drm */
1311 hdata
->hpd_handle
= false;
1313 /* enable HPD interrupts */
1314 hdmi_reg_writemask(hdata
, HDMI_INTC_CON
, 0, HDMI_INTC_EN_GLOBAL
|
1315 HDMI_INTC_EN_HPD_PLUG
| HDMI_INTC_EN_HPD_UNPLUG
);
1317 hdmi_reg_writemask(hdata
, HDMI_INTC_CON
, ~0, HDMI_INTC_EN_GLOBAL
|
1318 HDMI_INTC_EN_HPD_PLUG
| HDMI_INTC_EN_HPD_UNPLUG
);
1320 /* choose HDMI mode */
1321 hdmi_reg_writemask(hdata
, HDMI_MODE_SEL
,
1322 HDMI_MODE_HDMI_EN
, HDMI_MODE_MASK
);
1323 /* disable bluescreen */
1324 hdmi_reg_writemask(hdata
, HDMI_CON_0
, 0, HDMI_BLUE_SCR_EN
);
1326 if (hdata
->is_v13
) {
1327 /* choose bluescreen (fecal) color */
1328 hdmi_reg_writeb(hdata
, HDMI_V13_BLUE_SCREEN_0
, 0x12);
1329 hdmi_reg_writeb(hdata
, HDMI_V13_BLUE_SCREEN_1
, 0x34);
1330 hdmi_reg_writeb(hdata
, HDMI_V13_BLUE_SCREEN_2
, 0x56);
1332 /* enable AVI packet every vsync, fixes purple line problem */
1333 hdmi_reg_writeb(hdata
, HDMI_V13_AVI_CON
, 0x02);
1334 /* force RGB, look to CEA-861-D, table 7 for more detail */
1335 hdmi_reg_writeb(hdata
, HDMI_V13_AVI_BYTE(0), 0 << 5);
1336 hdmi_reg_writemask(hdata
, HDMI_CON_1
, 0x10 << 5, 0x11 << 5);
1338 hdmi_reg_writeb(hdata
, HDMI_V13_SPD_CON
, 0x02);
1339 hdmi_reg_writeb(hdata
, HDMI_V13_AUI_CON
, 0x02);
1340 hdmi_reg_writeb(hdata
, HDMI_V13_ACR_CON
, 0x04);
1342 /* enable AVI packet every vsync, fixes purple line problem */
1343 hdmi_reg_writeb(hdata
, HDMI_AVI_CON
, 0x02);
1344 hdmi_reg_writeb(hdata
, HDMI_AVI_BYTE(1), 2 << 5);
1345 hdmi_reg_writemask(hdata
, HDMI_CON_1
, 2, 3 << 5);
1348 /* enable hpd handle for drm */
1349 hdata
->hpd_handle
= true;
1352 static void hdmi_v13_timing_apply(struct hdmi_context
*hdata
)
1354 const struct hdmi_v13_preset_conf
*conf
=
1355 hdmi_v13_confs
[hdata
->cur_conf
].conf
;
1356 const struct hdmi_v13_core_regs
*core
= &conf
->core
;
1357 const struct hdmi_v13_tg_regs
*tg
= &conf
->tg
;
1360 /* setting core registers */
1361 hdmi_reg_writeb(hdata
, HDMI_H_BLANK_0
, core
->h_blank
[0]);
1362 hdmi_reg_writeb(hdata
, HDMI_H_BLANK_1
, core
->h_blank
[1]);
1363 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_0
, core
->v_blank
[0]);
1364 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_1
, core
->v_blank
[1]);
1365 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_2
, core
->v_blank
[2]);
1366 hdmi_reg_writeb(hdata
, HDMI_V13_H_V_LINE_0
, core
->h_v_line
[0]);
1367 hdmi_reg_writeb(hdata
, HDMI_V13_H_V_LINE_1
, core
->h_v_line
[1]);
1368 hdmi_reg_writeb(hdata
, HDMI_V13_H_V_LINE_2
, core
->h_v_line
[2]);
1369 hdmi_reg_writeb(hdata
, HDMI_VSYNC_POL
, core
->vsync_pol
[0]);
1370 hdmi_reg_writeb(hdata
, HDMI_INT_PRO_MODE
, core
->int_pro_mode
[0]);
1371 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_F_0
, core
->v_blank_f
[0]);
1372 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_F_1
, core
->v_blank_f
[1]);
1373 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_F_2
, core
->v_blank_f
[2]);
1374 hdmi_reg_writeb(hdata
, HDMI_V13_H_SYNC_GEN_0
, core
->h_sync_gen
[0]);
1375 hdmi_reg_writeb(hdata
, HDMI_V13_H_SYNC_GEN_1
, core
->h_sync_gen
[1]);
1376 hdmi_reg_writeb(hdata
, HDMI_V13_H_SYNC_GEN_2
, core
->h_sync_gen
[2]);
1377 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_1_0
, core
->v_sync_gen1
[0]);
1378 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_1_1
, core
->v_sync_gen1
[1]);
1379 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_1_2
, core
->v_sync_gen1
[2]);
1380 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_2_0
, core
->v_sync_gen2
[0]);
1381 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_2_1
, core
->v_sync_gen2
[1]);
1382 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_2_2
, core
->v_sync_gen2
[2]);
1383 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_3_0
, core
->v_sync_gen3
[0]);
1384 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_3_1
, core
->v_sync_gen3
[1]);
1385 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_3_2
, core
->v_sync_gen3
[2]);
1386 /* Timing generator registers */
1387 hdmi_reg_writeb(hdata
, HDMI_TG_H_FSZ_L
, tg
->h_fsz_l
);
1388 hdmi_reg_writeb(hdata
, HDMI_TG_H_FSZ_H
, tg
->h_fsz_h
);
1389 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_ST_L
, tg
->hact_st_l
);
1390 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_ST_H
, tg
->hact_st_h
);
1391 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_SZ_L
, tg
->hact_sz_l
);
1392 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_SZ_H
, tg
->hact_sz_h
);
1393 hdmi_reg_writeb(hdata
, HDMI_TG_V_FSZ_L
, tg
->v_fsz_l
);
1394 hdmi_reg_writeb(hdata
, HDMI_TG_V_FSZ_H
, tg
->v_fsz_h
);
1395 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_L
, tg
->vsync_l
);
1396 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_H
, tg
->vsync_h
);
1397 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC2_L
, tg
->vsync2_l
);
1398 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC2_H
, tg
->vsync2_h
);
1399 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST_L
, tg
->vact_st_l
);
1400 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST_H
, tg
->vact_st_h
);
1401 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_SZ_L
, tg
->vact_sz_l
);
1402 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_SZ_H
, tg
->vact_sz_h
);
1403 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_CHG_L
, tg
->field_chg_l
);
1404 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_CHG_H
, tg
->field_chg_h
);
1405 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST2_L
, tg
->vact_st2_l
);
1406 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST2_H
, tg
->vact_st2_h
);
1407 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_TOP_HDMI_L
, tg
->vsync_top_hdmi_l
);
1408 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_TOP_HDMI_H
, tg
->vsync_top_hdmi_h
);
1409 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_BOT_HDMI_L
, tg
->vsync_bot_hdmi_l
);
1410 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_BOT_HDMI_H
, tg
->vsync_bot_hdmi_h
);
1411 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_TOP_HDMI_L
, tg
->field_top_hdmi_l
);
1412 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_TOP_HDMI_H
, tg
->field_top_hdmi_h
);
1413 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_BOT_HDMI_L
, tg
->field_bot_hdmi_l
);
1414 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_BOT_HDMI_H
, tg
->field_bot_hdmi_h
);
1416 /* waiting for HDMIPHY's PLL to get to steady state */
1417 for (tries
= 100; tries
; --tries
) {
1418 u32 val
= hdmi_reg_read(hdata
, HDMI_V13_PHY_STATUS
);
1419 if (val
& HDMI_PHY_STATUS_READY
)
1423 /* steady state not achieved */
1425 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1426 hdmi_regs_dump(hdata
, "timing apply");
1429 clk_disable(hdata
->res
.sclk_hdmi
);
1430 clk_set_parent(hdata
->res
.sclk_hdmi
, hdata
->res
.sclk_hdmiphy
);
1431 clk_enable(hdata
->res
.sclk_hdmi
);
1433 /* enable HDMI and timing generator */
1434 hdmi_reg_writemask(hdata
, HDMI_CON_0
, ~0, HDMI_EN
);
1435 if (core
->int_pro_mode
[0])
1436 hdmi_reg_writemask(hdata
, HDMI_TG_CMD
, ~0, HDMI_TG_EN
|
1439 hdmi_reg_writemask(hdata
, HDMI_TG_CMD
, ~0, HDMI_TG_EN
);
1442 static void hdmi_v14_timing_apply(struct hdmi_context
*hdata
)
1444 const struct hdmi_preset_conf
*conf
= hdmi_confs
[hdata
->cur_conf
].conf
;
1445 const struct hdmi_core_regs
*core
= &conf
->core
;
1446 const struct hdmi_tg_regs
*tg
= &conf
->tg
;
1449 /* setting core registers */
1450 hdmi_reg_writeb(hdata
, HDMI_H_BLANK_0
, core
->h_blank
[0]);
1451 hdmi_reg_writeb(hdata
, HDMI_H_BLANK_1
, core
->h_blank
[1]);
1452 hdmi_reg_writeb(hdata
, HDMI_V2_BLANK_0
, core
->v2_blank
[0]);
1453 hdmi_reg_writeb(hdata
, HDMI_V2_BLANK_1
, core
->v2_blank
[1]);
1454 hdmi_reg_writeb(hdata
, HDMI_V1_BLANK_0
, core
->v1_blank
[0]);
1455 hdmi_reg_writeb(hdata
, HDMI_V1_BLANK_1
, core
->v1_blank
[1]);
1456 hdmi_reg_writeb(hdata
, HDMI_V_LINE_0
, core
->v_line
[0]);
1457 hdmi_reg_writeb(hdata
, HDMI_V_LINE_1
, core
->v_line
[1]);
1458 hdmi_reg_writeb(hdata
, HDMI_H_LINE_0
, core
->h_line
[0]);
1459 hdmi_reg_writeb(hdata
, HDMI_H_LINE_1
, core
->h_line
[1]);
1460 hdmi_reg_writeb(hdata
, HDMI_HSYNC_POL
, core
->hsync_pol
[0]);
1461 hdmi_reg_writeb(hdata
, HDMI_VSYNC_POL
, core
->vsync_pol
[0]);
1462 hdmi_reg_writeb(hdata
, HDMI_INT_PRO_MODE
, core
->int_pro_mode
[0]);
1463 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F0_0
, core
->v_blank_f0
[0]);
1464 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F0_1
, core
->v_blank_f0
[1]);
1465 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F1_0
, core
->v_blank_f1
[0]);
1466 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F1_1
, core
->v_blank_f1
[1]);
1467 hdmi_reg_writeb(hdata
, HDMI_H_SYNC_START_0
, core
->h_sync_start
[0]);
1468 hdmi_reg_writeb(hdata
, HDMI_H_SYNC_START_1
, core
->h_sync_start
[1]);
1469 hdmi_reg_writeb(hdata
, HDMI_H_SYNC_END_0
, core
->h_sync_end
[0]);
1470 hdmi_reg_writeb(hdata
, HDMI_H_SYNC_END_1
, core
->h_sync_end
[1]);
1471 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_BEF_2_0
,
1472 core
->v_sync_line_bef_2
[0]);
1473 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_BEF_2_1
,
1474 core
->v_sync_line_bef_2
[1]);
1475 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_BEF_1_0
,
1476 core
->v_sync_line_bef_1
[0]);
1477 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_BEF_1_1
,
1478 core
->v_sync_line_bef_1
[1]);
1479 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_2_0
,
1480 core
->v_sync_line_aft_2
[0]);
1481 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_2_1
,
1482 core
->v_sync_line_aft_2
[1]);
1483 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_1_0
,
1484 core
->v_sync_line_aft_1
[0]);
1485 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_1_1
,
1486 core
->v_sync_line_aft_1
[1]);
1487 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_2_0
,
1488 core
->v_sync_line_aft_pxl_2
[0]);
1489 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_2_1
,
1490 core
->v_sync_line_aft_pxl_2
[1]);
1491 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_1_0
,
1492 core
->v_sync_line_aft_pxl_1
[0]);
1493 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_1_1
,
1494 core
->v_sync_line_aft_pxl_1
[1]);
1495 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F2_0
, core
->v_blank_f2
[0]);
1496 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F2_1
, core
->v_blank_f2
[1]);
1497 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F3_0
, core
->v_blank_f3
[0]);
1498 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F3_1
, core
->v_blank_f3
[1]);
1499 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F4_0
, core
->v_blank_f4
[0]);
1500 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F4_1
, core
->v_blank_f4
[1]);
1501 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F5_0
, core
->v_blank_f5
[0]);
1502 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F5_1
, core
->v_blank_f5
[1]);
1503 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_3_0
,
1504 core
->v_sync_line_aft_3
[0]);
1505 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_3_1
,
1506 core
->v_sync_line_aft_3
[1]);
1507 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_4_0
,
1508 core
->v_sync_line_aft_4
[0]);
1509 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_4_1
,
1510 core
->v_sync_line_aft_4
[1]);
1511 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_5_0
,
1512 core
->v_sync_line_aft_5
[0]);
1513 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_5_1
,
1514 core
->v_sync_line_aft_5
[1]);
1515 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_6_0
,
1516 core
->v_sync_line_aft_6
[0]);
1517 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_6_1
,
1518 core
->v_sync_line_aft_6
[1]);
1519 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_3_0
,
1520 core
->v_sync_line_aft_pxl_3
[0]);
1521 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_3_1
,
1522 core
->v_sync_line_aft_pxl_3
[1]);
1523 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_4_0
,
1524 core
->v_sync_line_aft_pxl_4
[0]);
1525 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_4_1
,
1526 core
->v_sync_line_aft_pxl_4
[1]);
1527 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_5_0
,
1528 core
->v_sync_line_aft_pxl_5
[0]);
1529 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_5_1
,
1530 core
->v_sync_line_aft_pxl_5
[1]);
1531 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_6_0
,
1532 core
->v_sync_line_aft_pxl_6
[0]);
1533 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_6_1
,
1534 core
->v_sync_line_aft_pxl_6
[1]);
1535 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_1_0
, core
->vact_space_1
[0]);
1536 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_1_1
, core
->vact_space_1
[1]);
1537 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_2_0
, core
->vact_space_2
[0]);
1538 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_2_1
, core
->vact_space_2
[1]);
1539 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_3_0
, core
->vact_space_3
[0]);
1540 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_3_1
, core
->vact_space_3
[1]);
1541 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_4_0
, core
->vact_space_4
[0]);
1542 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_4_1
, core
->vact_space_4
[1]);
1543 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_5_0
, core
->vact_space_5
[0]);
1544 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_5_1
, core
->vact_space_5
[1]);
1545 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_6_0
, core
->vact_space_6
[0]);
1546 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_6_1
, core
->vact_space_6
[1]);
1548 /* Timing generator registers */
1549 hdmi_reg_writeb(hdata
, HDMI_TG_H_FSZ_L
, tg
->h_fsz_l
);
1550 hdmi_reg_writeb(hdata
, HDMI_TG_H_FSZ_H
, tg
->h_fsz_h
);
1551 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_ST_L
, tg
->hact_st_l
);
1552 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_ST_H
, tg
->hact_st_h
);
1553 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_SZ_L
, tg
->hact_sz_l
);
1554 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_SZ_H
, tg
->hact_sz_h
);
1555 hdmi_reg_writeb(hdata
, HDMI_TG_V_FSZ_L
, tg
->v_fsz_l
);
1556 hdmi_reg_writeb(hdata
, HDMI_TG_V_FSZ_H
, tg
->v_fsz_h
);
1557 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_L
, tg
->vsync_l
);
1558 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_H
, tg
->vsync_h
);
1559 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC2_L
, tg
->vsync2_l
);
1560 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC2_H
, tg
->vsync2_h
);
1561 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST_L
, tg
->vact_st_l
);
1562 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST_H
, tg
->vact_st_h
);
1563 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_SZ_L
, tg
->vact_sz_l
);
1564 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_SZ_H
, tg
->vact_sz_h
);
1565 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_CHG_L
, tg
->field_chg_l
);
1566 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_CHG_H
, tg
->field_chg_h
);
1567 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST2_L
, tg
->vact_st2_l
);
1568 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST2_H
, tg
->vact_st2_h
);
1569 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST3_L
, tg
->vact_st3_l
);
1570 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST3_H
, tg
->vact_st3_h
);
1571 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST4_L
, tg
->vact_st4_l
);
1572 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST4_H
, tg
->vact_st4_h
);
1573 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_TOP_HDMI_L
, tg
->vsync_top_hdmi_l
);
1574 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_TOP_HDMI_H
, tg
->vsync_top_hdmi_h
);
1575 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_BOT_HDMI_L
, tg
->vsync_bot_hdmi_l
);
1576 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_BOT_HDMI_H
, tg
->vsync_bot_hdmi_h
);
1577 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_TOP_HDMI_L
, tg
->field_top_hdmi_l
);
1578 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_TOP_HDMI_H
, tg
->field_top_hdmi_h
);
1579 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_BOT_HDMI_L
, tg
->field_bot_hdmi_l
);
1580 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_BOT_HDMI_H
, tg
->field_bot_hdmi_h
);
1581 hdmi_reg_writeb(hdata
, HDMI_TG_3D
, tg
->tg_3d
);
1583 /* waiting for HDMIPHY's PLL to get to steady state */
1584 for (tries
= 100; tries
; --tries
) {
1585 u32 val
= hdmi_reg_read(hdata
, HDMI_PHY_STATUS_0
);
1586 if (val
& HDMI_PHY_STATUS_READY
)
1590 /* steady state not achieved */
1592 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1593 hdmi_regs_dump(hdata
, "timing apply");
1596 clk_disable(hdata
->res
.sclk_hdmi
);
1597 clk_set_parent(hdata
->res
.sclk_hdmi
, hdata
->res
.sclk_hdmiphy
);
1598 clk_enable(hdata
->res
.sclk_hdmi
);
1600 /* enable HDMI and timing generator */
1601 hdmi_reg_writemask(hdata
, HDMI_CON_0
, ~0, HDMI_EN
);
1602 if (core
->int_pro_mode
[0])
1603 hdmi_reg_writemask(hdata
, HDMI_TG_CMD
, ~0, HDMI_TG_EN
|
1606 hdmi_reg_writemask(hdata
, HDMI_TG_CMD
, ~0, HDMI_TG_EN
);
1609 static void hdmi_timing_apply(struct hdmi_context
*hdata
)
1612 hdmi_v13_timing_apply(hdata
);
1614 hdmi_v14_timing_apply(hdata
);
1617 static void hdmiphy_conf_reset(struct hdmi_context
*hdata
)
1622 clk_disable(hdata
->res
.sclk_hdmi
);
1623 clk_set_parent(hdata
->res
.sclk_hdmi
, hdata
->res
.sclk_pixel
);
1624 clk_enable(hdata
->res
.sclk_hdmi
);
1626 /* operation mode */
1630 if (hdata
->hdmiphy_port
)
1631 i2c_master_send(hdata
->hdmiphy_port
, buffer
, 2);
1634 reg
= HDMI_V13_PHY_RSTOUT
;
1636 reg
= HDMI_PHY_RSTOUT
;
1639 hdmi_reg_writemask(hdata
, reg
, ~0, HDMI_PHY_SW_RSTOUT
);
1641 hdmi_reg_writemask(hdata
, reg
, 0, HDMI_PHY_SW_RSTOUT
);
1645 static void hdmiphy_conf_apply(struct hdmi_context
*hdata
)
1647 const u8
*hdmiphy_data
;
1650 u8 read_buffer
[32] = {0, };
1654 if (!hdata
->hdmiphy_port
) {
1655 DRM_ERROR("hdmiphy is not attached\n");
1661 hdmiphy_data
= hdmi_v13_confs
[hdata
->cur_conf
].hdmiphy_data
;
1663 hdmiphy_data
= hdmi_confs
[hdata
->cur_conf
].hdmiphy_data
;
1665 memcpy(buffer
, hdmiphy_data
, 32);
1666 ret
= i2c_master_send(hdata
->hdmiphy_port
, buffer
, 32);
1668 DRM_ERROR("failed to configure HDMIPHY via I2C\n");
1674 /* operation mode */
1675 operation
[0] = 0x1f;
1676 operation
[1] = 0x80;
1678 ret
= i2c_master_send(hdata
->hdmiphy_port
, operation
, 2);
1680 DRM_ERROR("failed to enable hdmiphy\n");
1684 ret
= i2c_master_recv(hdata
->hdmiphy_port
, read_buffer
, 32);
1686 DRM_ERROR("failed to read hdmiphy config\n");
1690 for (i
= 0; i
< ret
; i
++)
1691 DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
1692 "recv [0x%02x]\n", i
, buffer
[i
], read_buffer
[i
]);
1695 static void hdmi_conf_apply(struct hdmi_context
*hdata
)
1697 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1699 hdmiphy_conf_reset(hdata
);
1700 hdmiphy_conf_apply(hdata
);
1702 hdmi_conf_reset(hdata
);
1703 hdmi_conf_init(hdata
);
1705 /* setting core registers */
1706 hdmi_timing_apply(hdata
);
1708 hdmi_regs_dump(hdata
, "start");
1711 static void hdmi_mode_fixup(void *ctx
, struct drm_connector
*connector
,
1712 struct drm_display_mode
*mode
,
1713 struct drm_display_mode
*adjusted_mode
)
1715 struct drm_display_mode
*m
;
1716 struct hdmi_context
*hdata
= (struct hdmi_context
*)ctx
;
1719 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1721 drm_mode_set_crtcinfo(adjusted_mode
, 0);
1724 index
= hdmi_v13_conf_index(adjusted_mode
);
1726 index
= hdmi_v14_conf_index(adjusted_mode
);
1728 /* just return if user desired mode exists. */
1733 * otherwise, find the most suitable mode among modes and change it
1736 list_for_each_entry(m
, &connector
->modes
, head
) {
1738 index
= hdmi_v13_conf_index(m
);
1740 index
= hdmi_v14_conf_index(m
);
1743 DRM_INFO("desired mode doesn't exist so\n");
1744 DRM_INFO("use the most suitable mode among modes.\n");
1745 memcpy(adjusted_mode
, m
, sizeof(*m
));
1751 static void hdmi_mode_set(void *ctx
, void *mode
)
1753 struct hdmi_context
*hdata
= (struct hdmi_context
*)ctx
;
1756 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1758 conf_idx
= hdmi_conf_index(hdata
, mode
);
1760 hdata
->cur_conf
= conf_idx
;
1762 DRM_DEBUG_KMS("not supported mode\n");
1765 static void hdmi_get_max_resol(void *ctx
, unsigned int *width
,
1766 unsigned int *height
)
1768 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1771 *height
= MAX_HEIGHT
;
1774 static void hdmi_commit(void *ctx
)
1776 struct hdmi_context
*hdata
= (struct hdmi_context
*)ctx
;
1778 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1780 hdmi_conf_apply(hdata
);
1782 hdata
->enabled
= true;
1785 static void hdmi_disable(void *ctx
)
1787 struct hdmi_context
*hdata
= (struct hdmi_context
*)ctx
;
1789 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1791 if (hdata
->enabled
) {
1792 hdmiphy_conf_reset(hdata
);
1793 hdmi_conf_reset(hdata
);
1797 static struct exynos_hdmi_manager_ops manager_ops
= {
1798 .mode_fixup
= hdmi_mode_fixup
,
1799 .mode_set
= hdmi_mode_set
,
1800 .get_max_resol
= hdmi_get_max_resol
,
1801 .commit
= hdmi_commit
,
1802 .disable
= hdmi_disable
,
1806 * Handle hotplug events outside the interrupt handler proper.
1808 static void hdmi_hotplug_func(struct work_struct
*work
)
1810 struct hdmi_context
*hdata
=
1811 container_of(work
, struct hdmi_context
, hotplug_work
);
1812 struct exynos_drm_hdmi_context
*ctx
=
1813 (struct exynos_drm_hdmi_context
*)hdata
->parent_ctx
;
1815 drm_helper_hpd_irq_event(ctx
->drm_dev
);
1818 static irqreturn_t
hdmi_irq_handler(int irq
, void *arg
)
1820 struct exynos_drm_hdmi_context
*ctx
= arg
;
1821 struct hdmi_context
*hdata
= (struct hdmi_context
*)ctx
->ctx
;
1824 intc_flag
= hdmi_reg_read(hdata
, HDMI_INTC_FLAG
);
1825 /* clearing flags for HPD plug/unplug */
1826 if (intc_flag
& HDMI_INTC_FLAG_HPD_UNPLUG
) {
1827 DRM_DEBUG_KMS("unplugged, handling:%d\n", hdata
->hpd_handle
);
1828 hdmi_reg_writemask(hdata
, HDMI_INTC_FLAG
, ~0,
1829 HDMI_INTC_FLAG_HPD_UNPLUG
);
1831 if (intc_flag
& HDMI_INTC_FLAG_HPD_PLUG
) {
1832 DRM_DEBUG_KMS("plugged, handling:%d\n", hdata
->hpd_handle
);
1833 hdmi_reg_writemask(hdata
, HDMI_INTC_FLAG
, ~0,
1834 HDMI_INTC_FLAG_HPD_PLUG
);
1837 if (ctx
->drm_dev
&& hdata
->hpd_handle
)
1838 queue_work(hdata
->wq
, &hdata
->hotplug_work
);
1843 static int __devinit
hdmi_resources_init(struct hdmi_context
*hdata
)
1845 struct device
*dev
= hdata
->dev
;
1846 struct hdmi_resources
*res
= &hdata
->res
;
1847 static char *supply
[] = {
1855 DRM_DEBUG_KMS("HDMI resource init\n");
1857 memset(res
, 0, sizeof *res
);
1859 /* get clocks, power */
1860 res
->hdmi
= clk_get(dev
, "hdmi");
1861 if (IS_ERR_OR_NULL(res
->hdmi
)) {
1862 DRM_ERROR("failed to get clock 'hdmi'\n");
1865 res
->sclk_hdmi
= clk_get(dev
, "sclk_hdmi");
1866 if (IS_ERR_OR_NULL(res
->sclk_hdmi
)) {
1867 DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
1870 res
->sclk_pixel
= clk_get(dev
, "sclk_pixel");
1871 if (IS_ERR_OR_NULL(res
->sclk_pixel
)) {
1872 DRM_ERROR("failed to get clock 'sclk_pixel'\n");
1875 res
->sclk_hdmiphy
= clk_get(dev
, "sclk_hdmiphy");
1876 if (IS_ERR_OR_NULL(res
->sclk_hdmiphy
)) {
1877 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
1880 res
->hdmiphy
= clk_get(dev
, "hdmiphy");
1881 if (IS_ERR_OR_NULL(res
->hdmiphy
)) {
1882 DRM_ERROR("failed to get clock 'hdmiphy'\n");
1886 clk_set_parent(res
->sclk_hdmi
, res
->sclk_pixel
);
1888 res
->regul_bulk
= kzalloc(ARRAY_SIZE(supply
) *
1889 sizeof res
->regul_bulk
[0], GFP_KERNEL
);
1890 if (!res
->regul_bulk
) {
1891 DRM_ERROR("failed to get memory for regulators\n");
1894 for (i
= 0; i
< ARRAY_SIZE(supply
); ++i
) {
1895 res
->regul_bulk
[i
].supply
= supply
[i
];
1896 res
->regul_bulk
[i
].consumer
= NULL
;
1898 ret
= regulator_bulk_get(dev
, ARRAY_SIZE(supply
), res
->regul_bulk
);
1900 DRM_ERROR("failed to get regulators\n");
1903 res
->regul_count
= ARRAY_SIZE(supply
);
1907 DRM_ERROR("HDMI resource init - failed\n");
1911 static int hdmi_resources_cleanup(struct hdmi_context
*hdata
)
1913 struct hdmi_resources
*res
= &hdata
->res
;
1915 regulator_bulk_free(res
->regul_count
, res
->regul_bulk
);
1916 /* kfree is NULL-safe */
1917 kfree(res
->regul_bulk
);
1918 if (!IS_ERR_OR_NULL(res
->hdmiphy
))
1919 clk_put(res
->hdmiphy
);
1920 if (!IS_ERR_OR_NULL(res
->sclk_hdmiphy
))
1921 clk_put(res
->sclk_hdmiphy
);
1922 if (!IS_ERR_OR_NULL(res
->sclk_pixel
))
1923 clk_put(res
->sclk_pixel
);
1924 if (!IS_ERR_OR_NULL(res
->sclk_hdmi
))
1925 clk_put(res
->sclk_hdmi
);
1926 if (!IS_ERR_OR_NULL(res
->hdmi
))
1928 memset(res
, 0, sizeof *res
);
1933 static void hdmi_resource_poweron(struct hdmi_context
*hdata
)
1935 struct hdmi_resources
*res
= &hdata
->res
;
1937 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1939 /* turn HDMI power on */
1940 regulator_bulk_enable(res
->regul_count
, res
->regul_bulk
);
1941 /* power-on hdmi physical interface */
1942 clk_enable(res
->hdmiphy
);
1943 /* turn clocks on */
1944 clk_enable(res
->hdmi
);
1945 clk_enable(res
->sclk_hdmi
);
1947 hdmiphy_conf_reset(hdata
);
1948 hdmi_conf_reset(hdata
);
1949 hdmi_conf_init(hdata
);
1952 static void hdmi_resource_poweroff(struct hdmi_context
*hdata
)
1954 struct hdmi_resources
*res
= &hdata
->res
;
1956 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1958 /* turn clocks off */
1959 clk_disable(res
->sclk_hdmi
);
1960 clk_disable(res
->hdmi
);
1961 /* power-off hdmiphy */
1962 clk_disable(res
->hdmiphy
);
1963 /* turn HDMI power off */
1964 regulator_bulk_disable(res
->regul_count
, res
->regul_bulk
);
1967 static int hdmi_runtime_suspend(struct device
*dev
)
1969 struct exynos_drm_hdmi_context
*ctx
= get_hdmi_context(dev
);
1971 DRM_DEBUG_KMS("%s\n", __func__
);
1973 hdmi_resource_poweroff((struct hdmi_context
*)ctx
->ctx
);
1978 static int hdmi_runtime_resume(struct device
*dev
)
1980 struct exynos_drm_hdmi_context
*ctx
= get_hdmi_context(dev
);
1982 DRM_DEBUG_KMS("%s\n", __func__
);
1984 hdmi_resource_poweron((struct hdmi_context
*)ctx
->ctx
);
1989 static const struct dev_pm_ops hdmi_pm_ops
= {
1990 .runtime_suspend
= hdmi_runtime_suspend
,
1991 .runtime_resume
= hdmi_runtime_resume
,
1994 static struct i2c_client
*hdmi_ddc
, *hdmi_hdmiphy
;
1996 void hdmi_attach_ddc_client(struct i2c_client
*ddc
)
2002 void hdmi_attach_hdmiphy_client(struct i2c_client
*hdmiphy
)
2005 hdmi_hdmiphy
= hdmiphy
;
2008 static int __devinit
hdmi_probe(struct platform_device
*pdev
)
2010 struct device
*dev
= &pdev
->dev
;
2011 struct exynos_drm_hdmi_context
*drm_hdmi_ctx
;
2012 struct hdmi_context
*hdata
;
2013 struct exynos_drm_hdmi_pdata
*pdata
;
2014 struct resource
*res
;
2017 DRM_DEBUG_KMS("[%d]\n", __LINE__
);
2019 pdata
= pdev
->dev
.platform_data
;
2021 DRM_ERROR("no platform data specified\n");
2025 drm_hdmi_ctx
= kzalloc(sizeof(*drm_hdmi_ctx
), GFP_KERNEL
);
2026 if (!drm_hdmi_ctx
) {
2027 DRM_ERROR("failed to allocate common hdmi context.\n");
2031 hdata
= kzalloc(sizeof(struct hdmi_context
), GFP_KERNEL
);
2033 DRM_ERROR("out of memory\n");
2034 kfree(drm_hdmi_ctx
);
2038 drm_hdmi_ctx
->ctx
= (void *)hdata
;
2039 hdata
->parent_ctx
= (void *)drm_hdmi_ctx
;
2041 platform_set_drvdata(pdev
, drm_hdmi_ctx
);
2043 hdata
->is_v13
= pdata
->is_v13
;
2044 hdata
->default_win
= pdata
->default_win
;
2045 hdata
->default_timing
= &pdata
->timing
;
2046 hdata
->default_bpp
= pdata
->bpp
;
2049 ret
= hdmi_resources_init(hdata
);
2055 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
2057 DRM_ERROR("failed to find registers\n");
2062 hdata
->regs_res
= request_mem_region(res
->start
, resource_size(res
),
2064 if (!hdata
->regs_res
) {
2065 DRM_ERROR("failed to claim register region\n");
2070 hdata
->regs
= ioremap(res
->start
, resource_size(res
));
2072 DRM_ERROR("failed to map registers\n");
2074 goto err_req_region
;
2077 /* DDC i2c driver */
2078 if (i2c_add_driver(&ddc_driver
)) {
2079 DRM_ERROR("failed to register ddc i2c driver\n");
2084 hdata
->ddc_port
= hdmi_ddc
;
2086 /* hdmiphy i2c driver */
2087 if (i2c_add_driver(&hdmiphy_driver
)) {
2088 DRM_ERROR("failed to register hdmiphy i2c driver\n");
2093 hdata
->hdmiphy_port
= hdmi_hdmiphy
;
2095 res
= platform_get_resource(pdev
, IORESOURCE_IRQ
, 0);
2097 DRM_ERROR("get interrupt resource failed.\n");
2102 /* create workqueue and hotplug work */
2103 hdata
->wq
= alloc_workqueue("exynos-drm-hdmi",
2104 WQ_UNBOUND
| WQ_NON_REENTRANT
, 1);
2105 if (hdata
->wq
== NULL
) {
2106 DRM_ERROR("Failed to create workqueue.\n");
2110 INIT_WORK(&hdata
->hotplug_work
, hdmi_hotplug_func
);
2112 /* register hpd interrupt */
2113 ret
= request_irq(res
->start
, hdmi_irq_handler
, 0, "drm_hdmi",
2116 DRM_ERROR("request interrupt failed.\n");
2119 hdata
->irq
= res
->start
;
2121 /* register specific callbacks to common hdmi. */
2122 exynos_drm_display_ops_register(&display_ops
);
2123 exynos_drm_manager_ops_register(&manager_ops
);
2125 hdmi_resource_poweron(hdata
);
2130 destroy_workqueue(hdata
->wq
);
2132 i2c_del_driver(&hdmiphy_driver
);
2134 i2c_del_driver(&ddc_driver
);
2136 iounmap(hdata
->regs
);
2138 release_mem_region(hdata
->regs_res
->start
,
2139 resource_size(hdata
->regs_res
));
2141 hdmi_resources_cleanup(hdata
);
2144 kfree(drm_hdmi_ctx
);
2148 static int __devexit
hdmi_remove(struct platform_device
*pdev
)
2150 struct exynos_drm_hdmi_context
*ctx
= platform_get_drvdata(pdev
);
2151 struct hdmi_context
*hdata
= (struct hdmi_context
*)ctx
->ctx
;
2153 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
2155 hdmi_resource_poweroff(hdata
);
2157 disable_irq(hdata
->irq
);
2158 free_irq(hdata
->irq
, hdata
);
2160 cancel_work_sync(&hdata
->hotplug_work
);
2161 destroy_workqueue(hdata
->wq
);
2163 hdmi_resources_cleanup(hdata
);
2165 iounmap(hdata
->regs
);
2167 release_mem_region(hdata
->regs_res
->start
,
2168 resource_size(hdata
->regs_res
));
2170 /* hdmiphy i2c driver */
2171 i2c_del_driver(&hdmiphy_driver
);
2172 /* DDC i2c driver */
2173 i2c_del_driver(&ddc_driver
);
2180 struct platform_driver hdmi_driver
= {
2181 .probe
= hdmi_probe
,
2182 .remove
= __devexit_p(hdmi_remove
),
2184 .name
= "exynos4-hdmi",
2185 .owner
= THIS_MODULE
,