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 MAX_WIDTH 1920
44 #define MAX_HEIGHT 1080
45 #define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev))
47 struct hdmi_resources
{
49 struct clk
*sclk_hdmi
;
50 struct clk
*sclk_pixel
;
51 struct clk
*sclk_hdmiphy
;
53 struct regulator_bulk_data
*regul_bulk
;
59 struct drm_device
*drm_dev
;
64 struct mutex hdmi_mutex
;
66 struct resource
*regs_res
;
68 unsigned int external_irq
;
69 unsigned int internal_irq
;
71 struct i2c_client
*ddc_port
;
72 struct i2c_client
*hdmiphy_port
;
74 /* current hdmiphy conf index */
77 struct hdmi_resources res
;
80 void (*cfg_hpd
)(bool external
);
84 /* HDMI Version 1.3 */
85 static const u8 hdmiphy_v13_conf27
[32] = {
86 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
87 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
88 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
89 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
92 static const u8 hdmiphy_v13_conf27_027
[32] = {
93 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
94 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
95 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
96 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
99 static const u8 hdmiphy_v13_conf74_175
[32] = {
100 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
101 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
102 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
103 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
106 static const u8 hdmiphy_v13_conf74_25
[32] = {
107 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
108 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
109 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
110 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
113 static const u8 hdmiphy_v13_conf148_5
[32] = {
114 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
115 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
116 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
117 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
120 struct hdmi_v13_tg_regs
{
152 struct hdmi_v13_core_regs
{
165 struct hdmi_v13_preset_conf
{
166 struct hdmi_v13_core_regs core
;
167 struct hdmi_v13_tg_regs tg
;
170 struct hdmi_v13_conf
{
175 const u8
*hdmiphy_data
;
176 const struct hdmi_v13_preset_conf
*conf
;
179 static const struct hdmi_v13_preset_conf hdmi_v13_conf_480p
= {
181 .h_blank
= {0x8a, 0x00},
182 .v_blank
= {0x0d, 0x6a, 0x01},
183 .h_v_line
= {0x0d, 0xa2, 0x35},
185 .int_pro_mode
= {0x00},
186 .v_blank_f
= {0x00, 0x00, 0x00},
187 .h_sync_gen
= {0x0e, 0x30, 0x11},
188 .v_sync_gen1
= {0x0f, 0x90, 0x00},
189 /* other don't care */
193 0x5a, 0x03, /* h_fsz */
194 0x8a, 0x00, 0xd0, 0x02, /* hact */
195 0x0d, 0x02, /* v_fsz */
196 0x01, 0x00, 0x33, 0x02, /* vsync */
197 0x2d, 0x00, 0xe0, 0x01, /* vact */
198 0x33, 0x02, /* field_chg */
199 0x49, 0x02, /* vact_st2 */
200 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
201 0x01, 0x00, 0x33, 0x02, /* field top/bot */
205 static const struct hdmi_v13_preset_conf hdmi_v13_conf_720p60
= {
207 .h_blank
= {0x72, 0x01},
208 .v_blank
= {0xee, 0xf2, 0x00},
209 .h_v_line
= {0xee, 0x22, 0x67},
211 .int_pro_mode
= {0x00},
212 .v_blank_f
= {0x00, 0x00, 0x00}, /* don't care */
213 .h_sync_gen
= {0x6c, 0x50, 0x02},
214 .v_sync_gen1
= {0x0a, 0x50, 0x00},
215 .v_sync_gen2
= {0x01, 0x10, 0x00},
216 .v_sync_gen3
= {0x01, 0x10, 0x00},
217 /* other don't care */
221 0x72, 0x06, /* h_fsz */
222 0x71, 0x01, 0x01, 0x05, /* hact */
223 0xee, 0x02, /* v_fsz */
224 0x01, 0x00, 0x33, 0x02, /* vsync */
225 0x1e, 0x00, 0xd0, 0x02, /* vact */
226 0x33, 0x02, /* field_chg */
227 0x49, 0x02, /* vact_st2 */
228 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
229 0x01, 0x00, 0x33, 0x02, /* field top/bot */
233 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i50
= {
235 .h_blank
= {0xd0, 0x02},
236 .v_blank
= {0x32, 0xB2, 0x00},
237 .h_v_line
= {0x65, 0x04, 0xa5},
239 .int_pro_mode
= {0x01},
240 .v_blank_f
= {0x49, 0x2A, 0x23},
241 .h_sync_gen
= {0x0E, 0xEA, 0x08},
242 .v_sync_gen1
= {0x07, 0x20, 0x00},
243 .v_sync_gen2
= {0x39, 0x42, 0x23},
244 .v_sync_gen3
= {0x38, 0x87, 0x73},
245 /* other don't care */
249 0x50, 0x0A, /* h_fsz */
250 0xCF, 0x02, 0x81, 0x07, /* hact */
251 0x65, 0x04, /* v_fsz */
252 0x01, 0x00, 0x33, 0x02, /* vsync */
253 0x16, 0x00, 0x1c, 0x02, /* vact */
254 0x33, 0x02, /* field_chg */
255 0x49, 0x02, /* vact_st2 */
256 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
257 0x01, 0x00, 0x33, 0x02, /* field top/bot */
261 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p50
= {
263 .h_blank
= {0xd0, 0x02},
264 .v_blank
= {0x65, 0x6c, 0x01},
265 .h_v_line
= {0x65, 0x04, 0xa5},
267 .int_pro_mode
= {0x00},
268 .v_blank_f
= {0x00, 0x00, 0x00}, /* don't care */
269 .h_sync_gen
= {0x0e, 0xea, 0x08},
270 .v_sync_gen1
= {0x09, 0x40, 0x00},
271 .v_sync_gen2
= {0x01, 0x10, 0x00},
272 .v_sync_gen3
= {0x01, 0x10, 0x00},
273 /* other don't care */
277 0x50, 0x0A, /* h_fsz */
278 0xCF, 0x02, 0x81, 0x07, /* hact */
279 0x65, 0x04, /* v_fsz */
280 0x01, 0x00, 0x33, 0x02, /* vsync */
281 0x2d, 0x00, 0x38, 0x04, /* vact */
282 0x33, 0x02, /* field_chg */
283 0x48, 0x02, /* vact_st2 */
284 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
285 0x01, 0x00, 0x33, 0x02, /* field top/bot */
289 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i60
= {
291 .h_blank
= {0x18, 0x01},
292 .v_blank
= {0x32, 0xB2, 0x00},
293 .h_v_line
= {0x65, 0x84, 0x89},
295 .int_pro_mode
= {0x01},
296 .v_blank_f
= {0x49, 0x2A, 0x23},
297 .h_sync_gen
= {0x56, 0x08, 0x02},
298 .v_sync_gen1
= {0x07, 0x20, 0x00},
299 .v_sync_gen2
= {0x39, 0x42, 0x23},
300 .v_sync_gen3
= {0xa4, 0x44, 0x4a},
301 /* other don't care */
305 0x98, 0x08, /* h_fsz */
306 0x17, 0x01, 0x81, 0x07, /* hact */
307 0x65, 0x04, /* v_fsz */
308 0x01, 0x00, 0x33, 0x02, /* vsync */
309 0x16, 0x00, 0x1c, 0x02, /* vact */
310 0x33, 0x02, /* field_chg */
311 0x49, 0x02, /* vact_st2 */
312 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
313 0x01, 0x00, 0x33, 0x02, /* field top/bot */
317 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60
= {
319 .h_blank
= {0x18, 0x01},
320 .v_blank
= {0x65, 0x6c, 0x01},
321 .h_v_line
= {0x65, 0x84, 0x89},
323 .int_pro_mode
= {0x00},
324 .v_blank_f
= {0x00, 0x00, 0x00}, /* don't care */
325 .h_sync_gen
= {0x56, 0x08, 0x02},
326 .v_sync_gen1
= {0x09, 0x40, 0x00},
327 .v_sync_gen2
= {0x01, 0x10, 0x00},
328 .v_sync_gen3
= {0x01, 0x10, 0x00},
329 /* other don't care */
333 0x98, 0x08, /* h_fsz */
334 0x17, 0x01, 0x81, 0x07, /* hact */
335 0x65, 0x04, /* v_fsz */
336 0x01, 0x00, 0x33, 0x02, /* vsync */
337 0x2d, 0x00, 0x38, 0x04, /* vact */
338 0x33, 0x02, /* field_chg */
339 0x48, 0x02, /* vact_st2 */
340 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
341 0x01, 0x00, 0x33, 0x02, /* field top/bot */
345 static const struct hdmi_v13_conf hdmi_v13_confs
[] = {
346 { 1280, 720, 60, false, hdmiphy_v13_conf74_25
, &hdmi_v13_conf_720p60
},
347 { 1280, 720, 50, false, hdmiphy_v13_conf74_25
, &hdmi_v13_conf_720p60
},
348 { 720, 480, 60, false, hdmiphy_v13_conf27_027
, &hdmi_v13_conf_480p
},
349 { 1920, 1080, 50, true, hdmiphy_v13_conf74_25
, &hdmi_v13_conf_1080i50
},
350 { 1920, 1080, 50, false, hdmiphy_v13_conf148_5
,
351 &hdmi_v13_conf_1080p50
},
352 { 1920, 1080, 60, true, hdmiphy_v13_conf74_25
, &hdmi_v13_conf_1080i60
},
353 { 1920, 1080, 60, false, hdmiphy_v13_conf148_5
,
354 &hdmi_v13_conf_1080p60
},
357 /* HDMI Version 1.4 */
358 static const u8 hdmiphy_conf27_027
[32] = {
359 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
360 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
361 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
362 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
365 static const u8 hdmiphy_conf74_25
[32] = {
366 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
367 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
368 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
369 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
372 static const u8 hdmiphy_conf148_5
[32] = {
373 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
374 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
375 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
376 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
379 struct hdmi_tg_regs
{
416 struct hdmi_core_regs
{
429 u8 v_sync_line_bef_2
[2];
430 u8 v_sync_line_bef_1
[2];
431 u8 v_sync_line_aft_2
[2];
432 u8 v_sync_line_aft_1
[2];
433 u8 v_sync_line_aft_pxl_2
[2];
434 u8 v_sync_line_aft_pxl_1
[2];
435 u8 v_blank_f2
[2]; /* for 3D mode */
436 u8 v_blank_f3
[2]; /* for 3D mode */
437 u8 v_blank_f4
[2]; /* for 3D mode */
438 u8 v_blank_f5
[2]; /* for 3D mode */
439 u8 v_sync_line_aft_3
[2];
440 u8 v_sync_line_aft_4
[2];
441 u8 v_sync_line_aft_5
[2];
442 u8 v_sync_line_aft_6
[2];
443 u8 v_sync_line_aft_pxl_3
[2];
444 u8 v_sync_line_aft_pxl_4
[2];
445 u8 v_sync_line_aft_pxl_5
[2];
446 u8 v_sync_line_aft_pxl_6
[2];
455 struct hdmi_preset_conf
{
456 struct hdmi_core_regs core
;
457 struct hdmi_tg_regs tg
;
465 const u8
*hdmiphy_data
;
466 const struct hdmi_preset_conf
*conf
;
469 static const struct hdmi_preset_conf hdmi_conf_480p60
= {
471 .h_blank
= {0x8a, 0x00},
472 .v2_blank
= {0x0d, 0x02},
473 .v1_blank
= {0x2d, 0x00},
474 .v_line
= {0x0d, 0x02},
475 .h_line
= {0x5a, 0x03},
478 .int_pro_mode
= {0x00},
479 .v_blank_f0
= {0xff, 0xff},
480 .v_blank_f1
= {0xff, 0xff},
481 .h_sync_start
= {0x0e, 0x00},
482 .h_sync_end
= {0x4c, 0x00},
483 .v_sync_line_bef_2
= {0x0f, 0x00},
484 .v_sync_line_bef_1
= {0x09, 0x00},
485 .v_sync_line_aft_2
= {0xff, 0xff},
486 .v_sync_line_aft_1
= {0xff, 0xff},
487 .v_sync_line_aft_pxl_2
= {0xff, 0xff},
488 .v_sync_line_aft_pxl_1
= {0xff, 0xff},
489 .v_blank_f2
= {0xff, 0xff},
490 .v_blank_f3
= {0xff, 0xff},
491 .v_blank_f4
= {0xff, 0xff},
492 .v_blank_f5
= {0xff, 0xff},
493 .v_sync_line_aft_3
= {0xff, 0xff},
494 .v_sync_line_aft_4
= {0xff, 0xff},
495 .v_sync_line_aft_5
= {0xff, 0xff},
496 .v_sync_line_aft_6
= {0xff, 0xff},
497 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
498 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
499 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
500 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
501 .vact_space_1
= {0xff, 0xff},
502 .vact_space_2
= {0xff, 0xff},
503 .vact_space_3
= {0xff, 0xff},
504 .vact_space_4
= {0xff, 0xff},
505 .vact_space_5
= {0xff, 0xff},
506 .vact_space_6
= {0xff, 0xff},
507 /* other don't care */
511 0x5a, 0x03, /* h_fsz */
512 0x8a, 0x00, 0xd0, 0x02, /* hact */
513 0x0d, 0x02, /* v_fsz */
514 0x01, 0x00, 0x33, 0x02, /* vsync */
515 0x2d, 0x00, 0xe0, 0x01, /* vact */
516 0x33, 0x02, /* field_chg */
517 0x48, 0x02, /* vact_st2 */
518 0x00, 0x00, /* vact_st3 */
519 0x00, 0x00, /* vact_st4 */
520 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
521 0x01, 0x00, 0x33, 0x02, /* field top/bot */
526 static const struct hdmi_preset_conf hdmi_conf_720p50
= {
528 .h_blank
= {0xbc, 0x02},
529 .v2_blank
= {0xee, 0x02},
530 .v1_blank
= {0x1e, 0x00},
531 .v_line
= {0xee, 0x02},
532 .h_line
= {0xbc, 0x07},
535 .int_pro_mode
= {0x00},
536 .v_blank_f0
= {0xff, 0xff},
537 .v_blank_f1
= {0xff, 0xff},
538 .h_sync_start
= {0xb6, 0x01},
539 .h_sync_end
= {0xde, 0x01},
540 .v_sync_line_bef_2
= {0x0a, 0x00},
541 .v_sync_line_bef_1
= {0x05, 0x00},
542 .v_sync_line_aft_2
= {0xff, 0xff},
543 .v_sync_line_aft_1
= {0xff, 0xff},
544 .v_sync_line_aft_pxl_2
= {0xff, 0xff},
545 .v_sync_line_aft_pxl_1
= {0xff, 0xff},
546 .v_blank_f2
= {0xff, 0xff},
547 .v_blank_f3
= {0xff, 0xff},
548 .v_blank_f4
= {0xff, 0xff},
549 .v_blank_f5
= {0xff, 0xff},
550 .v_sync_line_aft_3
= {0xff, 0xff},
551 .v_sync_line_aft_4
= {0xff, 0xff},
552 .v_sync_line_aft_5
= {0xff, 0xff},
553 .v_sync_line_aft_6
= {0xff, 0xff},
554 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
555 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
556 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
557 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
558 .vact_space_1
= {0xff, 0xff},
559 .vact_space_2
= {0xff, 0xff},
560 .vact_space_3
= {0xff, 0xff},
561 .vact_space_4
= {0xff, 0xff},
562 .vact_space_5
= {0xff, 0xff},
563 .vact_space_6
= {0xff, 0xff},
564 /* other don't care */
568 0xbc, 0x07, /* h_fsz */
569 0xbc, 0x02, 0x00, 0x05, /* hact */
570 0xee, 0x02, /* v_fsz */
571 0x01, 0x00, 0x33, 0x02, /* vsync */
572 0x1e, 0x00, 0xd0, 0x02, /* vact */
573 0x33, 0x02, /* field_chg */
574 0x48, 0x02, /* vact_st2 */
575 0x00, 0x00, /* vact_st3 */
576 0x00, 0x00, /* vact_st4 */
577 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
578 0x01, 0x00, 0x33, 0x02, /* field top/bot */
583 static const struct hdmi_preset_conf hdmi_conf_720p60
= {
585 .h_blank
= {0x72, 0x01},
586 .v2_blank
= {0xee, 0x02},
587 .v1_blank
= {0x1e, 0x00},
588 .v_line
= {0xee, 0x02},
589 .h_line
= {0x72, 0x06},
592 .int_pro_mode
= {0x00},
593 .v_blank_f0
= {0xff, 0xff},
594 .v_blank_f1
= {0xff, 0xff},
595 .h_sync_start
= {0x6c, 0x00},
596 .h_sync_end
= {0x94, 0x00},
597 .v_sync_line_bef_2
= {0x0a, 0x00},
598 .v_sync_line_bef_1
= {0x05, 0x00},
599 .v_sync_line_aft_2
= {0xff, 0xff},
600 .v_sync_line_aft_1
= {0xff, 0xff},
601 .v_sync_line_aft_pxl_2
= {0xff, 0xff},
602 .v_sync_line_aft_pxl_1
= {0xff, 0xff},
603 .v_blank_f2
= {0xff, 0xff},
604 .v_blank_f3
= {0xff, 0xff},
605 .v_blank_f4
= {0xff, 0xff},
606 .v_blank_f5
= {0xff, 0xff},
607 .v_sync_line_aft_3
= {0xff, 0xff},
608 .v_sync_line_aft_4
= {0xff, 0xff},
609 .v_sync_line_aft_5
= {0xff, 0xff},
610 .v_sync_line_aft_6
= {0xff, 0xff},
611 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
612 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
613 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
614 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
615 .vact_space_1
= {0xff, 0xff},
616 .vact_space_2
= {0xff, 0xff},
617 .vact_space_3
= {0xff, 0xff},
618 .vact_space_4
= {0xff, 0xff},
619 .vact_space_5
= {0xff, 0xff},
620 .vact_space_6
= {0xff, 0xff},
621 /* other don't care */
625 0x72, 0x06, /* h_fsz */
626 0x72, 0x01, 0x00, 0x05, /* hact */
627 0xee, 0x02, /* v_fsz */
628 0x01, 0x00, 0x33, 0x02, /* vsync */
629 0x1e, 0x00, 0xd0, 0x02, /* vact */
630 0x33, 0x02, /* field_chg */
631 0x48, 0x02, /* vact_st2 */
632 0x00, 0x00, /* vact_st3 */
633 0x00, 0x00, /* vact_st4 */
634 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
635 0x01, 0x00, 0x33, 0x02, /* field top/bot */
640 static const struct hdmi_preset_conf hdmi_conf_1080i50
= {
642 .h_blank
= {0xd0, 0x02},
643 .v2_blank
= {0x32, 0x02},
644 .v1_blank
= {0x16, 0x00},
645 .v_line
= {0x65, 0x04},
646 .h_line
= {0x50, 0x0a},
649 .int_pro_mode
= {0x01},
650 .v_blank_f0
= {0x49, 0x02},
651 .v_blank_f1
= {0x65, 0x04},
652 .h_sync_start
= {0x0e, 0x02},
653 .h_sync_end
= {0x3a, 0x02},
654 .v_sync_line_bef_2
= {0x07, 0x00},
655 .v_sync_line_bef_1
= {0x02, 0x00},
656 .v_sync_line_aft_2
= {0x39, 0x02},
657 .v_sync_line_aft_1
= {0x34, 0x02},
658 .v_sync_line_aft_pxl_2
= {0x38, 0x07},
659 .v_sync_line_aft_pxl_1
= {0x38, 0x07},
660 .v_blank_f2
= {0xff, 0xff},
661 .v_blank_f3
= {0xff, 0xff},
662 .v_blank_f4
= {0xff, 0xff},
663 .v_blank_f5
= {0xff, 0xff},
664 .v_sync_line_aft_3
= {0xff, 0xff},
665 .v_sync_line_aft_4
= {0xff, 0xff},
666 .v_sync_line_aft_5
= {0xff, 0xff},
667 .v_sync_line_aft_6
= {0xff, 0xff},
668 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
669 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
670 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
671 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
672 .vact_space_1
= {0xff, 0xff},
673 .vact_space_2
= {0xff, 0xff},
674 .vact_space_3
= {0xff, 0xff},
675 .vact_space_4
= {0xff, 0xff},
676 .vact_space_5
= {0xff, 0xff},
677 .vact_space_6
= {0xff, 0xff},
678 /* other don't care */
682 0x50, 0x0a, /* h_fsz */
683 0xd0, 0x02, 0x80, 0x07, /* hact */
684 0x65, 0x04, /* v_fsz */
685 0x01, 0x00, 0x33, 0x02, /* vsync */
686 0x16, 0x00, 0x1c, 0x02, /* vact */
687 0x33, 0x02, /* field_chg */
688 0x49, 0x02, /* vact_st2 */
689 0x00, 0x00, /* vact_st3 */
690 0x00, 0x00, /* vact_st4 */
691 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
692 0x01, 0x00, 0x33, 0x02, /* field top/bot */
697 static const struct hdmi_preset_conf hdmi_conf_1080i60
= {
699 .h_blank
= {0x18, 0x01},
700 .v2_blank
= {0x32, 0x02},
701 .v1_blank
= {0x16, 0x00},
702 .v_line
= {0x65, 0x04},
703 .h_line
= {0x98, 0x08},
706 .int_pro_mode
= {0x01},
707 .v_blank_f0
= {0x49, 0x02},
708 .v_blank_f1
= {0x65, 0x04},
709 .h_sync_start
= {0x56, 0x00},
710 .h_sync_end
= {0x82, 0x00},
711 .v_sync_line_bef_2
= {0x07, 0x00},
712 .v_sync_line_bef_1
= {0x02, 0x00},
713 .v_sync_line_aft_2
= {0x39, 0x02},
714 .v_sync_line_aft_1
= {0x34, 0x02},
715 .v_sync_line_aft_pxl_2
= {0xa4, 0x04},
716 .v_sync_line_aft_pxl_1
= {0xa4, 0x04},
717 .v_blank_f2
= {0xff, 0xff},
718 .v_blank_f3
= {0xff, 0xff},
719 .v_blank_f4
= {0xff, 0xff},
720 .v_blank_f5
= {0xff, 0xff},
721 .v_sync_line_aft_3
= {0xff, 0xff},
722 .v_sync_line_aft_4
= {0xff, 0xff},
723 .v_sync_line_aft_5
= {0xff, 0xff},
724 .v_sync_line_aft_6
= {0xff, 0xff},
725 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
726 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
727 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
728 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
729 .vact_space_1
= {0xff, 0xff},
730 .vact_space_2
= {0xff, 0xff},
731 .vact_space_3
= {0xff, 0xff},
732 .vact_space_4
= {0xff, 0xff},
733 .vact_space_5
= {0xff, 0xff},
734 .vact_space_6
= {0xff, 0xff},
735 /* other don't care */
739 0x98, 0x08, /* h_fsz */
740 0x18, 0x01, 0x80, 0x07, /* hact */
741 0x65, 0x04, /* v_fsz */
742 0x01, 0x00, 0x33, 0x02, /* vsync */
743 0x16, 0x00, 0x1c, 0x02, /* vact */
744 0x33, 0x02, /* field_chg */
745 0x49, 0x02, /* vact_st2 */
746 0x00, 0x00, /* vact_st3 */
747 0x00, 0x00, /* vact_st4 */
748 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
749 0x01, 0x00, 0x33, 0x02, /* field top/bot */
754 static const struct hdmi_preset_conf hdmi_conf_1080p50
= {
756 .h_blank
= {0xd0, 0x02},
757 .v2_blank
= {0x65, 0x04},
758 .v1_blank
= {0x2d, 0x00},
759 .v_line
= {0x65, 0x04},
760 .h_line
= {0x50, 0x0a},
763 .int_pro_mode
= {0x00},
764 .v_blank_f0
= {0xff, 0xff},
765 .v_blank_f1
= {0xff, 0xff},
766 .h_sync_start
= {0x0e, 0x02},
767 .h_sync_end
= {0x3a, 0x02},
768 .v_sync_line_bef_2
= {0x09, 0x00},
769 .v_sync_line_bef_1
= {0x04, 0x00},
770 .v_sync_line_aft_2
= {0xff, 0xff},
771 .v_sync_line_aft_1
= {0xff, 0xff},
772 .v_sync_line_aft_pxl_2
= {0xff, 0xff},
773 .v_sync_line_aft_pxl_1
= {0xff, 0xff},
774 .v_blank_f2
= {0xff, 0xff},
775 .v_blank_f3
= {0xff, 0xff},
776 .v_blank_f4
= {0xff, 0xff},
777 .v_blank_f5
= {0xff, 0xff},
778 .v_sync_line_aft_3
= {0xff, 0xff},
779 .v_sync_line_aft_4
= {0xff, 0xff},
780 .v_sync_line_aft_5
= {0xff, 0xff},
781 .v_sync_line_aft_6
= {0xff, 0xff},
782 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
783 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
784 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
785 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
786 .vact_space_1
= {0xff, 0xff},
787 .vact_space_2
= {0xff, 0xff},
788 .vact_space_3
= {0xff, 0xff},
789 .vact_space_4
= {0xff, 0xff},
790 .vact_space_5
= {0xff, 0xff},
791 .vact_space_6
= {0xff, 0xff},
792 /* other don't care */
796 0x50, 0x0a, /* h_fsz */
797 0xd0, 0x02, 0x80, 0x07, /* hact */
798 0x65, 0x04, /* v_fsz */
799 0x01, 0x00, 0x33, 0x02, /* vsync */
800 0x2d, 0x00, 0x38, 0x04, /* vact */
801 0x33, 0x02, /* field_chg */
802 0x48, 0x02, /* vact_st2 */
803 0x00, 0x00, /* vact_st3 */
804 0x00, 0x00, /* vact_st4 */
805 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
806 0x01, 0x00, 0x33, 0x02, /* field top/bot */
811 static const struct hdmi_preset_conf hdmi_conf_1080p60
= {
813 .h_blank
= {0x18, 0x01},
814 .v2_blank
= {0x65, 0x04},
815 .v1_blank
= {0x2d, 0x00},
816 .v_line
= {0x65, 0x04},
817 .h_line
= {0x98, 0x08},
820 .int_pro_mode
= {0x00},
821 .v_blank_f0
= {0xff, 0xff},
822 .v_blank_f1
= {0xff, 0xff},
823 .h_sync_start
= {0x56, 0x00},
824 .h_sync_end
= {0x82, 0x00},
825 .v_sync_line_bef_2
= {0x09, 0x00},
826 .v_sync_line_bef_1
= {0x04, 0x00},
827 .v_sync_line_aft_2
= {0xff, 0xff},
828 .v_sync_line_aft_1
= {0xff, 0xff},
829 .v_sync_line_aft_pxl_2
= {0xff, 0xff},
830 .v_sync_line_aft_pxl_1
= {0xff, 0xff},
831 .v_blank_f2
= {0xff, 0xff},
832 .v_blank_f3
= {0xff, 0xff},
833 .v_blank_f4
= {0xff, 0xff},
834 .v_blank_f5
= {0xff, 0xff},
835 .v_sync_line_aft_3
= {0xff, 0xff},
836 .v_sync_line_aft_4
= {0xff, 0xff},
837 .v_sync_line_aft_5
= {0xff, 0xff},
838 .v_sync_line_aft_6
= {0xff, 0xff},
839 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
840 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
841 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
842 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
843 /* other don't care */
847 0x98, 0x08, /* h_fsz */
848 0x18, 0x01, 0x80, 0x07, /* hact */
849 0x65, 0x04, /* v_fsz */
850 0x01, 0x00, 0x33, 0x02, /* vsync */
851 0x2d, 0x00, 0x38, 0x04, /* vact */
852 0x33, 0x02, /* field_chg */
853 0x48, 0x02, /* vact_st2 */
854 0x00, 0x00, /* vact_st3 */
855 0x00, 0x00, /* vact_st4 */
856 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
857 0x01, 0x00, 0x33, 0x02, /* field top/bot */
862 static const struct hdmi_conf hdmi_confs
[] = {
863 { 720, 480, 60, false, hdmiphy_conf27_027
, &hdmi_conf_480p60
},
864 { 1280, 720, 50, false, hdmiphy_conf74_25
, &hdmi_conf_720p50
},
865 { 1280, 720, 60, false, hdmiphy_conf74_25
, &hdmi_conf_720p60
},
866 { 1920, 1080, 50, true, hdmiphy_conf74_25
, &hdmi_conf_1080i50
},
867 { 1920, 1080, 60, true, hdmiphy_conf74_25
, &hdmi_conf_1080i60
},
868 { 1920, 1080, 50, false, hdmiphy_conf148_5
, &hdmi_conf_1080p50
},
869 { 1920, 1080, 60, false, hdmiphy_conf148_5
, &hdmi_conf_1080p60
},
873 static inline u32
hdmi_reg_read(struct hdmi_context
*hdata
, u32 reg_id
)
875 return readl(hdata
->regs
+ reg_id
);
878 static inline void hdmi_reg_writeb(struct hdmi_context
*hdata
,
879 u32 reg_id
, u8 value
)
881 writeb(value
, hdata
->regs
+ reg_id
);
884 static inline void hdmi_reg_writemask(struct hdmi_context
*hdata
,
885 u32 reg_id
, u32 value
, u32 mask
)
887 u32 old
= readl(hdata
->regs
+ reg_id
);
888 value
= (value
& mask
) | (old
& ~mask
);
889 writel(value
, hdata
->regs
+ reg_id
);
892 static void hdmi_v13_regs_dump(struct hdmi_context
*hdata
, char *prefix
)
894 #define DUMPREG(reg_id) \
895 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
896 readl(hdata->regs + reg_id))
897 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix
);
898 DUMPREG(HDMI_INTC_FLAG
);
899 DUMPREG(HDMI_INTC_CON
);
900 DUMPREG(HDMI_HPD_STATUS
);
901 DUMPREG(HDMI_V13_PHY_RSTOUT
);
902 DUMPREG(HDMI_V13_PHY_VPLL
);
903 DUMPREG(HDMI_V13_PHY_CMU
);
904 DUMPREG(HDMI_V13_CORE_RSTOUT
);
906 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix
);
910 DUMPREG(HDMI_SYS_STATUS
);
911 DUMPREG(HDMI_V13_PHY_STATUS
);
912 DUMPREG(HDMI_STATUS_EN
);
914 DUMPREG(HDMI_MODE_SEL
);
915 DUMPREG(HDMI_V13_HPD_GEN
);
916 DUMPREG(HDMI_V13_DC_CONTROL
);
917 DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN
);
919 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix
);
920 DUMPREG(HDMI_H_BLANK_0
);
921 DUMPREG(HDMI_H_BLANK_1
);
922 DUMPREG(HDMI_V13_V_BLANK_0
);
923 DUMPREG(HDMI_V13_V_BLANK_1
);
924 DUMPREG(HDMI_V13_V_BLANK_2
);
925 DUMPREG(HDMI_V13_H_V_LINE_0
);
926 DUMPREG(HDMI_V13_H_V_LINE_1
);
927 DUMPREG(HDMI_V13_H_V_LINE_2
);
928 DUMPREG(HDMI_VSYNC_POL
);
929 DUMPREG(HDMI_INT_PRO_MODE
);
930 DUMPREG(HDMI_V13_V_BLANK_F_0
);
931 DUMPREG(HDMI_V13_V_BLANK_F_1
);
932 DUMPREG(HDMI_V13_V_BLANK_F_2
);
933 DUMPREG(HDMI_V13_H_SYNC_GEN_0
);
934 DUMPREG(HDMI_V13_H_SYNC_GEN_1
);
935 DUMPREG(HDMI_V13_H_SYNC_GEN_2
);
936 DUMPREG(HDMI_V13_V_SYNC_GEN_1_0
);
937 DUMPREG(HDMI_V13_V_SYNC_GEN_1_1
);
938 DUMPREG(HDMI_V13_V_SYNC_GEN_1_2
);
939 DUMPREG(HDMI_V13_V_SYNC_GEN_2_0
);
940 DUMPREG(HDMI_V13_V_SYNC_GEN_2_1
);
941 DUMPREG(HDMI_V13_V_SYNC_GEN_2_2
);
942 DUMPREG(HDMI_V13_V_SYNC_GEN_3_0
);
943 DUMPREG(HDMI_V13_V_SYNC_GEN_3_1
);
944 DUMPREG(HDMI_V13_V_SYNC_GEN_3_2
);
946 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix
);
947 DUMPREG(HDMI_TG_CMD
);
948 DUMPREG(HDMI_TG_H_FSZ_L
);
949 DUMPREG(HDMI_TG_H_FSZ_H
);
950 DUMPREG(HDMI_TG_HACT_ST_L
);
951 DUMPREG(HDMI_TG_HACT_ST_H
);
952 DUMPREG(HDMI_TG_HACT_SZ_L
);
953 DUMPREG(HDMI_TG_HACT_SZ_H
);
954 DUMPREG(HDMI_TG_V_FSZ_L
);
955 DUMPREG(HDMI_TG_V_FSZ_H
);
956 DUMPREG(HDMI_TG_VSYNC_L
);
957 DUMPREG(HDMI_TG_VSYNC_H
);
958 DUMPREG(HDMI_TG_VSYNC2_L
);
959 DUMPREG(HDMI_TG_VSYNC2_H
);
960 DUMPREG(HDMI_TG_VACT_ST_L
);
961 DUMPREG(HDMI_TG_VACT_ST_H
);
962 DUMPREG(HDMI_TG_VACT_SZ_L
);
963 DUMPREG(HDMI_TG_VACT_SZ_H
);
964 DUMPREG(HDMI_TG_FIELD_CHG_L
);
965 DUMPREG(HDMI_TG_FIELD_CHG_H
);
966 DUMPREG(HDMI_TG_VACT_ST2_L
);
967 DUMPREG(HDMI_TG_VACT_ST2_H
);
968 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L
);
969 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H
);
970 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L
);
971 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H
);
972 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L
);
973 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H
);
974 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L
);
975 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H
);
979 static void hdmi_v14_regs_dump(struct hdmi_context
*hdata
, char *prefix
)
983 #define DUMPREG(reg_id) \
984 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
985 readl(hdata->regs + reg_id))
987 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix
);
988 DUMPREG(HDMI_INTC_CON
);
989 DUMPREG(HDMI_INTC_FLAG
);
990 DUMPREG(HDMI_HPD_STATUS
);
991 DUMPREG(HDMI_INTC_CON_1
);
992 DUMPREG(HDMI_INTC_FLAG_1
);
993 DUMPREG(HDMI_PHY_STATUS_0
);
994 DUMPREG(HDMI_PHY_STATUS_PLL
);
995 DUMPREG(HDMI_PHY_CON_0
);
996 DUMPREG(HDMI_PHY_RSTOUT
);
997 DUMPREG(HDMI_PHY_VPLL
);
998 DUMPREG(HDMI_PHY_CMU
);
999 DUMPREG(HDMI_CORE_RSTOUT
);
1001 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix
);
1002 DUMPREG(HDMI_CON_0
);
1003 DUMPREG(HDMI_CON_1
);
1004 DUMPREG(HDMI_CON_2
);
1005 DUMPREG(HDMI_SYS_STATUS
);
1006 DUMPREG(HDMI_PHY_STATUS_0
);
1007 DUMPREG(HDMI_STATUS_EN
);
1009 DUMPREG(HDMI_MODE_SEL
);
1010 DUMPREG(HDMI_ENC_EN
);
1011 DUMPREG(HDMI_DC_CONTROL
);
1012 DUMPREG(HDMI_VIDEO_PATTERN_GEN
);
1014 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix
);
1015 DUMPREG(HDMI_H_BLANK_0
);
1016 DUMPREG(HDMI_H_BLANK_1
);
1017 DUMPREG(HDMI_V2_BLANK_0
);
1018 DUMPREG(HDMI_V2_BLANK_1
);
1019 DUMPREG(HDMI_V1_BLANK_0
);
1020 DUMPREG(HDMI_V1_BLANK_1
);
1021 DUMPREG(HDMI_V_LINE_0
);
1022 DUMPREG(HDMI_V_LINE_1
);
1023 DUMPREG(HDMI_H_LINE_0
);
1024 DUMPREG(HDMI_H_LINE_1
);
1025 DUMPREG(HDMI_HSYNC_POL
);
1027 DUMPREG(HDMI_VSYNC_POL
);
1028 DUMPREG(HDMI_INT_PRO_MODE
);
1029 DUMPREG(HDMI_V_BLANK_F0_0
);
1030 DUMPREG(HDMI_V_BLANK_F0_1
);
1031 DUMPREG(HDMI_V_BLANK_F1_0
);
1032 DUMPREG(HDMI_V_BLANK_F1_1
);
1034 DUMPREG(HDMI_H_SYNC_START_0
);
1035 DUMPREG(HDMI_H_SYNC_START_1
);
1036 DUMPREG(HDMI_H_SYNC_END_0
);
1037 DUMPREG(HDMI_H_SYNC_END_1
);
1039 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0
);
1040 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1
);
1041 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0
);
1042 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1
);
1044 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0
);
1045 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1
);
1046 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0
);
1047 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1
);
1049 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0
);
1050 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1
);
1051 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0
);
1052 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1
);
1054 DUMPREG(HDMI_V_BLANK_F2_0
);
1055 DUMPREG(HDMI_V_BLANK_F2_1
);
1056 DUMPREG(HDMI_V_BLANK_F3_0
);
1057 DUMPREG(HDMI_V_BLANK_F3_1
);
1058 DUMPREG(HDMI_V_BLANK_F4_0
);
1059 DUMPREG(HDMI_V_BLANK_F4_1
);
1060 DUMPREG(HDMI_V_BLANK_F5_0
);
1061 DUMPREG(HDMI_V_BLANK_F5_1
);
1063 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0
);
1064 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1
);
1065 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0
);
1066 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1
);
1067 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0
);
1068 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1
);
1069 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0
);
1070 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1
);
1072 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0
);
1073 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1
);
1074 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0
);
1075 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1
);
1076 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0
);
1077 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1
);
1078 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0
);
1079 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1
);
1081 DUMPREG(HDMI_VACT_SPACE_1_0
);
1082 DUMPREG(HDMI_VACT_SPACE_1_1
);
1083 DUMPREG(HDMI_VACT_SPACE_2_0
);
1084 DUMPREG(HDMI_VACT_SPACE_2_1
);
1085 DUMPREG(HDMI_VACT_SPACE_3_0
);
1086 DUMPREG(HDMI_VACT_SPACE_3_1
);
1087 DUMPREG(HDMI_VACT_SPACE_4_0
);
1088 DUMPREG(HDMI_VACT_SPACE_4_1
);
1089 DUMPREG(HDMI_VACT_SPACE_5_0
);
1090 DUMPREG(HDMI_VACT_SPACE_5_1
);
1091 DUMPREG(HDMI_VACT_SPACE_6_0
);
1092 DUMPREG(HDMI_VACT_SPACE_6_1
);
1094 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix
);
1095 DUMPREG(HDMI_TG_CMD
);
1096 DUMPREG(HDMI_TG_H_FSZ_L
);
1097 DUMPREG(HDMI_TG_H_FSZ_H
);
1098 DUMPREG(HDMI_TG_HACT_ST_L
);
1099 DUMPREG(HDMI_TG_HACT_ST_H
);
1100 DUMPREG(HDMI_TG_HACT_SZ_L
);
1101 DUMPREG(HDMI_TG_HACT_SZ_H
);
1102 DUMPREG(HDMI_TG_V_FSZ_L
);
1103 DUMPREG(HDMI_TG_V_FSZ_H
);
1104 DUMPREG(HDMI_TG_VSYNC_L
);
1105 DUMPREG(HDMI_TG_VSYNC_H
);
1106 DUMPREG(HDMI_TG_VSYNC2_L
);
1107 DUMPREG(HDMI_TG_VSYNC2_H
);
1108 DUMPREG(HDMI_TG_VACT_ST_L
);
1109 DUMPREG(HDMI_TG_VACT_ST_H
);
1110 DUMPREG(HDMI_TG_VACT_SZ_L
);
1111 DUMPREG(HDMI_TG_VACT_SZ_H
);
1112 DUMPREG(HDMI_TG_FIELD_CHG_L
);
1113 DUMPREG(HDMI_TG_FIELD_CHG_H
);
1114 DUMPREG(HDMI_TG_VACT_ST2_L
);
1115 DUMPREG(HDMI_TG_VACT_ST2_H
);
1116 DUMPREG(HDMI_TG_VACT_ST3_L
);
1117 DUMPREG(HDMI_TG_VACT_ST3_H
);
1118 DUMPREG(HDMI_TG_VACT_ST4_L
);
1119 DUMPREG(HDMI_TG_VACT_ST4_H
);
1120 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L
);
1121 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H
);
1122 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L
);
1123 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H
);
1124 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L
);
1125 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H
);
1126 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L
);
1127 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H
);
1128 DUMPREG(HDMI_TG_3D
);
1130 DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix
);
1131 DUMPREG(HDMI_AVI_CON
);
1132 DUMPREG(HDMI_AVI_HEADER0
);
1133 DUMPREG(HDMI_AVI_HEADER1
);
1134 DUMPREG(HDMI_AVI_HEADER2
);
1135 DUMPREG(HDMI_AVI_CHECK_SUM
);
1136 DUMPREG(HDMI_VSI_CON
);
1137 DUMPREG(HDMI_VSI_HEADER0
);
1138 DUMPREG(HDMI_VSI_HEADER1
);
1139 DUMPREG(HDMI_VSI_HEADER2
);
1140 for (i
= 0; i
< 7; ++i
)
1141 DUMPREG(HDMI_VSI_DATA(i
));
1146 static void hdmi_regs_dump(struct hdmi_context
*hdata
, char *prefix
)
1149 hdmi_v13_regs_dump(hdata
, prefix
);
1151 hdmi_v14_regs_dump(hdata
, prefix
);
1154 static int hdmi_v13_conf_index(struct drm_display_mode
*mode
)
1158 for (i
= 0; i
< ARRAY_SIZE(hdmi_v13_confs
); ++i
)
1159 if (hdmi_v13_confs
[i
].width
== mode
->hdisplay
&&
1160 hdmi_v13_confs
[i
].height
== mode
->vdisplay
&&
1161 hdmi_v13_confs
[i
].vrefresh
== mode
->vrefresh
&&
1162 hdmi_v13_confs
[i
].interlace
==
1163 ((mode
->flags
& DRM_MODE_FLAG_INTERLACE
) ?
1170 static int hdmi_v14_conf_index(struct drm_display_mode
*mode
)
1174 for (i
= 0; i
< ARRAY_SIZE(hdmi_confs
); ++i
)
1175 if (hdmi_confs
[i
].width
== mode
->hdisplay
&&
1176 hdmi_confs
[i
].height
== mode
->vdisplay
&&
1177 hdmi_confs
[i
].vrefresh
== mode
->vrefresh
&&
1178 hdmi_confs
[i
].interlace
==
1179 ((mode
->flags
& DRM_MODE_FLAG_INTERLACE
) ?
1186 static int hdmi_conf_index(struct hdmi_context
*hdata
,
1187 struct drm_display_mode
*mode
)
1190 return hdmi_v13_conf_index(mode
);
1192 return hdmi_v14_conf_index(mode
);
1195 static bool hdmi_is_connected(void *ctx
)
1197 struct hdmi_context
*hdata
= ctx
;
1202 static int hdmi_get_edid(void *ctx
, struct drm_connector
*connector
,
1205 struct edid
*raw_edid
;
1206 struct hdmi_context
*hdata
= ctx
;
1208 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1210 if (!hdata
->ddc_port
)
1213 raw_edid
= drm_get_edid(connector
, hdata
->ddc_port
->adapter
);
1215 hdata
->dvi_mode
= !drm_detect_hdmi_monitor(raw_edid
);
1216 memcpy(edid
, raw_edid
, min((1 + raw_edid
->extensions
)
1217 * EDID_LENGTH
, len
));
1218 DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
1219 (hdata
->dvi_mode
? "dvi monitor" : "hdmi monitor"),
1220 raw_edid
->width_cm
, raw_edid
->height_cm
);
1228 static int hdmi_v13_check_timing(struct fb_videomode
*check_timing
)
1232 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1233 check_timing
->xres
, check_timing
->yres
,
1234 check_timing
->refresh
, (check_timing
->vmode
&
1235 FB_VMODE_INTERLACED
) ? true : false);
1237 for (i
= 0; i
< ARRAY_SIZE(hdmi_v13_confs
); ++i
)
1238 if (hdmi_v13_confs
[i
].width
== check_timing
->xres
&&
1239 hdmi_v13_confs
[i
].height
== check_timing
->yres
&&
1240 hdmi_v13_confs
[i
].vrefresh
== check_timing
->refresh
&&
1241 hdmi_v13_confs
[i
].interlace
==
1242 ((check_timing
->vmode
& FB_VMODE_INTERLACED
) ?
1251 static int hdmi_v14_check_timing(struct fb_videomode
*check_timing
)
1255 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1256 check_timing
->xres
, check_timing
->yres
,
1257 check_timing
->refresh
, (check_timing
->vmode
&
1258 FB_VMODE_INTERLACED
) ? true : false);
1260 for (i
= 0; i
< ARRAY_SIZE(hdmi_confs
); i
++)
1261 if (hdmi_confs
[i
].width
== check_timing
->xres
&&
1262 hdmi_confs
[i
].height
== check_timing
->yres
&&
1263 hdmi_confs
[i
].vrefresh
== check_timing
->refresh
&&
1264 hdmi_confs
[i
].interlace
==
1265 ((check_timing
->vmode
& FB_VMODE_INTERLACED
) ?
1274 static int hdmi_check_timing(void *ctx
, void *timing
)
1276 struct hdmi_context
*hdata
= ctx
;
1277 struct fb_videomode
*check_timing
= timing
;
1279 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1281 DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing
->xres
,
1282 check_timing
->yres
, check_timing
->refresh
,
1283 check_timing
->vmode
);
1286 return hdmi_v13_check_timing(check_timing
);
1288 return hdmi_v14_check_timing(check_timing
);
1291 static void hdmi_set_acr(u32 freq
, u8
*acr
)
1331 acr
[2] = cts
>> 8 & 0xff;
1332 acr
[3] = cts
& 0xff;
1335 acr
[5] = n
>> 8 & 0xff;
1339 static void hdmi_reg_acr(struct hdmi_context
*hdata
, u8
*acr
)
1341 hdmi_reg_writeb(hdata
, HDMI_ACR_N0
, acr
[6]);
1342 hdmi_reg_writeb(hdata
, HDMI_ACR_N1
, acr
[5]);
1343 hdmi_reg_writeb(hdata
, HDMI_ACR_N2
, acr
[4]);
1344 hdmi_reg_writeb(hdata
, HDMI_ACR_MCTS0
, acr
[3]);
1345 hdmi_reg_writeb(hdata
, HDMI_ACR_MCTS1
, acr
[2]);
1346 hdmi_reg_writeb(hdata
, HDMI_ACR_MCTS2
, acr
[1]);
1347 hdmi_reg_writeb(hdata
, HDMI_ACR_CTS0
, acr
[3]);
1348 hdmi_reg_writeb(hdata
, HDMI_ACR_CTS1
, acr
[2]);
1349 hdmi_reg_writeb(hdata
, HDMI_ACR_CTS2
, acr
[1]);
1352 hdmi_reg_writeb(hdata
, HDMI_V13_ACR_CON
, 4);
1354 hdmi_reg_writeb(hdata
, HDMI_ACR_CON
, 4);
1357 static void hdmi_audio_init(struct hdmi_context
*hdata
)
1359 u32 sample_rate
, bits_per_sample
, frame_size_code
;
1360 u32 data_num
, bit_ch
, sample_frq
;
1364 sample_rate
= 44100;
1365 bits_per_sample
= 16;
1366 frame_size_code
= 0;
1368 switch (bits_per_sample
) {
1383 hdmi_set_acr(sample_rate
, acr
);
1384 hdmi_reg_acr(hdata
, acr
);
1386 hdmi_reg_writeb(hdata
, HDMI_I2S_MUX_CON
, HDMI_I2S_IN_DISABLE
1387 | HDMI_I2S_AUD_I2S
| HDMI_I2S_CUV_I2S_ENABLE
1388 | HDMI_I2S_MUX_ENABLE
);
1390 hdmi_reg_writeb(hdata
, HDMI_I2S_MUX_CH
, HDMI_I2S_CH0_EN
1391 | HDMI_I2S_CH1_EN
| HDMI_I2S_CH2_EN
);
1393 hdmi_reg_writeb(hdata
, HDMI_I2S_MUX_CUV
, HDMI_I2S_CUV_RL_EN
);
1395 sample_frq
= (sample_rate
== 44100) ? 0 :
1396 (sample_rate
== 48000) ? 2 :
1397 (sample_rate
== 32000) ? 3 :
1398 (sample_rate
== 96000) ? 0xa : 0x0;
1400 hdmi_reg_writeb(hdata
, HDMI_I2S_CLK_CON
, HDMI_I2S_CLK_DIS
);
1401 hdmi_reg_writeb(hdata
, HDMI_I2S_CLK_CON
, HDMI_I2S_CLK_EN
);
1403 val
= hdmi_reg_read(hdata
, HDMI_I2S_DSD_CON
) | 0x01;
1404 hdmi_reg_writeb(hdata
, HDMI_I2S_DSD_CON
, val
);
1406 /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1407 hdmi_reg_writeb(hdata
, HDMI_I2S_PIN_SEL_0
, HDMI_I2S_SEL_SCLK(5)
1408 | HDMI_I2S_SEL_LRCK(6));
1409 hdmi_reg_writeb(hdata
, HDMI_I2S_PIN_SEL_1
, HDMI_I2S_SEL_SDATA1(1)
1410 | HDMI_I2S_SEL_SDATA2(4));
1411 hdmi_reg_writeb(hdata
, HDMI_I2S_PIN_SEL_2
, HDMI_I2S_SEL_SDATA3(1)
1412 | HDMI_I2S_SEL_SDATA2(2));
1413 hdmi_reg_writeb(hdata
, HDMI_I2S_PIN_SEL_3
, HDMI_I2S_SEL_DSD(0));
1416 hdmi_reg_writeb(hdata
, HDMI_I2S_CON_1
, HDMI_I2S_SCLK_FALLING_EDGE
1417 | HDMI_I2S_L_CH_LOW_POL
);
1418 hdmi_reg_writeb(hdata
, HDMI_I2S_CON_2
, HDMI_I2S_MSB_FIRST_MODE
1419 | HDMI_I2S_SET_BIT_CH(bit_ch
)
1420 | HDMI_I2S_SET_SDATA_BIT(data_num
)
1421 | HDMI_I2S_BASIC_FORMAT
);
1423 /* Configure register related to CUV information */
1424 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_0
, HDMI_I2S_CH_STATUS_MODE_0
1425 | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1426 | HDMI_I2S_COPYRIGHT
1427 | HDMI_I2S_LINEAR_PCM
1428 | HDMI_I2S_CONSUMER_FORMAT
);
1429 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_1
, HDMI_I2S_CD_PLAYER
);
1430 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_2
, HDMI_I2S_SET_SOURCE_NUM(0));
1431 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_3
, HDMI_I2S_CLK_ACCUR_LEVEL_2
1432 | HDMI_I2S_SET_SMP_FREQ(sample_frq
));
1433 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_4
,
1434 HDMI_I2S_ORG_SMP_FREQ_44_1
1435 | HDMI_I2S_WORD_LEN_MAX24_24BITS
1436 | HDMI_I2S_WORD_LEN_MAX_24BITS
);
1438 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_CON
, HDMI_I2S_CH_STATUS_RELOAD
);
1441 static void hdmi_audio_control(struct hdmi_context
*hdata
, bool onoff
)
1443 if (hdata
->dvi_mode
)
1446 hdmi_reg_writeb(hdata
, HDMI_AUI_CON
, onoff
? 2 : 0);
1447 hdmi_reg_writemask(hdata
, HDMI_CON_0
, onoff
?
1448 HDMI_ASP_EN
: HDMI_ASP_DIS
, HDMI_ASP_MASK
);
1451 static void hdmi_conf_reset(struct hdmi_context
*hdata
)
1456 reg
= HDMI_V13_CORE_RSTOUT
;
1458 reg
= HDMI_CORE_RSTOUT
;
1460 /* resetting HDMI core */
1461 hdmi_reg_writemask(hdata
, reg
, 0, HDMI_CORE_SW_RSTOUT
);
1463 hdmi_reg_writemask(hdata
, reg
, ~0, HDMI_CORE_SW_RSTOUT
);
1467 static void hdmi_conf_init(struct hdmi_context
*hdata
)
1469 /* enable HPD interrupts */
1470 hdmi_reg_writemask(hdata
, HDMI_INTC_CON
, 0, HDMI_INTC_EN_GLOBAL
|
1471 HDMI_INTC_EN_HPD_PLUG
| HDMI_INTC_EN_HPD_UNPLUG
);
1473 hdmi_reg_writemask(hdata
, HDMI_INTC_CON
, ~0, HDMI_INTC_EN_GLOBAL
|
1474 HDMI_INTC_EN_HPD_PLUG
| HDMI_INTC_EN_HPD_UNPLUG
);
1476 /* choose HDMI mode */
1477 hdmi_reg_writemask(hdata
, HDMI_MODE_SEL
,
1478 HDMI_MODE_HDMI_EN
, HDMI_MODE_MASK
);
1479 /* disable bluescreen */
1480 hdmi_reg_writemask(hdata
, HDMI_CON_0
, 0, HDMI_BLUE_SCR_EN
);
1482 if (hdata
->dvi_mode
) {
1483 /* choose DVI mode */
1484 hdmi_reg_writemask(hdata
, HDMI_MODE_SEL
,
1485 HDMI_MODE_DVI_EN
, HDMI_MODE_MASK
);
1486 hdmi_reg_writeb(hdata
, HDMI_CON_2
,
1487 HDMI_VID_PREAMBLE_DIS
| HDMI_GUARD_BAND_DIS
);
1490 if (hdata
->is_v13
) {
1491 /* choose bluescreen (fecal) color */
1492 hdmi_reg_writeb(hdata
, HDMI_V13_BLUE_SCREEN_0
, 0x12);
1493 hdmi_reg_writeb(hdata
, HDMI_V13_BLUE_SCREEN_1
, 0x34);
1494 hdmi_reg_writeb(hdata
, HDMI_V13_BLUE_SCREEN_2
, 0x56);
1496 /* enable AVI packet every vsync, fixes purple line problem */
1497 hdmi_reg_writeb(hdata
, HDMI_V13_AVI_CON
, 0x02);
1498 /* force RGB, look to CEA-861-D, table 7 for more detail */
1499 hdmi_reg_writeb(hdata
, HDMI_V13_AVI_BYTE(0), 0 << 5);
1500 hdmi_reg_writemask(hdata
, HDMI_CON_1
, 0x10 << 5, 0x11 << 5);
1502 hdmi_reg_writeb(hdata
, HDMI_V13_SPD_CON
, 0x02);
1503 hdmi_reg_writeb(hdata
, HDMI_V13_AUI_CON
, 0x02);
1504 hdmi_reg_writeb(hdata
, HDMI_V13_ACR_CON
, 0x04);
1506 /* enable AVI packet every vsync, fixes purple line problem */
1507 hdmi_reg_writeb(hdata
, HDMI_AVI_CON
, 0x02);
1508 hdmi_reg_writeb(hdata
, HDMI_AVI_BYTE(1), 2 << 5);
1509 hdmi_reg_writemask(hdata
, HDMI_CON_1
, 2, 3 << 5);
1513 static void hdmi_v13_timing_apply(struct hdmi_context
*hdata
)
1515 const struct hdmi_v13_preset_conf
*conf
=
1516 hdmi_v13_confs
[hdata
->cur_conf
].conf
;
1517 const struct hdmi_v13_core_regs
*core
= &conf
->core
;
1518 const struct hdmi_v13_tg_regs
*tg
= &conf
->tg
;
1521 /* setting core registers */
1522 hdmi_reg_writeb(hdata
, HDMI_H_BLANK_0
, core
->h_blank
[0]);
1523 hdmi_reg_writeb(hdata
, HDMI_H_BLANK_1
, core
->h_blank
[1]);
1524 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_0
, core
->v_blank
[0]);
1525 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_1
, core
->v_blank
[1]);
1526 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_2
, core
->v_blank
[2]);
1527 hdmi_reg_writeb(hdata
, HDMI_V13_H_V_LINE_0
, core
->h_v_line
[0]);
1528 hdmi_reg_writeb(hdata
, HDMI_V13_H_V_LINE_1
, core
->h_v_line
[1]);
1529 hdmi_reg_writeb(hdata
, HDMI_V13_H_V_LINE_2
, core
->h_v_line
[2]);
1530 hdmi_reg_writeb(hdata
, HDMI_VSYNC_POL
, core
->vsync_pol
[0]);
1531 hdmi_reg_writeb(hdata
, HDMI_INT_PRO_MODE
, core
->int_pro_mode
[0]);
1532 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_F_0
, core
->v_blank_f
[0]);
1533 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_F_1
, core
->v_blank_f
[1]);
1534 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_F_2
, core
->v_blank_f
[2]);
1535 hdmi_reg_writeb(hdata
, HDMI_V13_H_SYNC_GEN_0
, core
->h_sync_gen
[0]);
1536 hdmi_reg_writeb(hdata
, HDMI_V13_H_SYNC_GEN_1
, core
->h_sync_gen
[1]);
1537 hdmi_reg_writeb(hdata
, HDMI_V13_H_SYNC_GEN_2
, core
->h_sync_gen
[2]);
1538 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_1_0
, core
->v_sync_gen1
[0]);
1539 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_1_1
, core
->v_sync_gen1
[1]);
1540 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_1_2
, core
->v_sync_gen1
[2]);
1541 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_2_0
, core
->v_sync_gen2
[0]);
1542 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_2_1
, core
->v_sync_gen2
[1]);
1543 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_2_2
, core
->v_sync_gen2
[2]);
1544 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_3_0
, core
->v_sync_gen3
[0]);
1545 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_3_1
, core
->v_sync_gen3
[1]);
1546 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_3_2
, core
->v_sync_gen3
[2]);
1547 /* Timing generator registers */
1548 hdmi_reg_writeb(hdata
, HDMI_TG_H_FSZ_L
, tg
->h_fsz_l
);
1549 hdmi_reg_writeb(hdata
, HDMI_TG_H_FSZ_H
, tg
->h_fsz_h
);
1550 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_ST_L
, tg
->hact_st_l
);
1551 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_ST_H
, tg
->hact_st_h
);
1552 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_SZ_L
, tg
->hact_sz_l
);
1553 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_SZ_H
, tg
->hact_sz_h
);
1554 hdmi_reg_writeb(hdata
, HDMI_TG_V_FSZ_L
, tg
->v_fsz_l
);
1555 hdmi_reg_writeb(hdata
, HDMI_TG_V_FSZ_H
, tg
->v_fsz_h
);
1556 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_L
, tg
->vsync_l
);
1557 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_H
, tg
->vsync_h
);
1558 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC2_L
, tg
->vsync2_l
);
1559 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC2_H
, tg
->vsync2_h
);
1560 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST_L
, tg
->vact_st_l
);
1561 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST_H
, tg
->vact_st_h
);
1562 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_SZ_L
, tg
->vact_sz_l
);
1563 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_SZ_H
, tg
->vact_sz_h
);
1564 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_CHG_L
, tg
->field_chg_l
);
1565 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_CHG_H
, tg
->field_chg_h
);
1566 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST2_L
, tg
->vact_st2_l
);
1567 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST2_H
, tg
->vact_st2_h
);
1568 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_TOP_HDMI_L
, tg
->vsync_top_hdmi_l
);
1569 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_TOP_HDMI_H
, tg
->vsync_top_hdmi_h
);
1570 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_BOT_HDMI_L
, tg
->vsync_bot_hdmi_l
);
1571 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_BOT_HDMI_H
, tg
->vsync_bot_hdmi_h
);
1572 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_TOP_HDMI_L
, tg
->field_top_hdmi_l
);
1573 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_TOP_HDMI_H
, tg
->field_top_hdmi_h
);
1574 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_BOT_HDMI_L
, tg
->field_bot_hdmi_l
);
1575 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_BOT_HDMI_H
, tg
->field_bot_hdmi_h
);
1577 /* waiting for HDMIPHY's PLL to get to steady state */
1578 for (tries
= 100; tries
; --tries
) {
1579 u32 val
= hdmi_reg_read(hdata
, HDMI_V13_PHY_STATUS
);
1580 if (val
& HDMI_PHY_STATUS_READY
)
1584 /* steady state not achieved */
1586 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1587 hdmi_regs_dump(hdata
, "timing apply");
1590 clk_disable(hdata
->res
.sclk_hdmi
);
1591 clk_set_parent(hdata
->res
.sclk_hdmi
, hdata
->res
.sclk_hdmiphy
);
1592 clk_enable(hdata
->res
.sclk_hdmi
);
1594 /* enable HDMI and timing generator */
1595 hdmi_reg_writemask(hdata
, HDMI_CON_0
, ~0, HDMI_EN
);
1596 if (core
->int_pro_mode
[0])
1597 hdmi_reg_writemask(hdata
, HDMI_TG_CMD
, ~0, HDMI_TG_EN
|
1600 hdmi_reg_writemask(hdata
, HDMI_TG_CMD
, ~0, HDMI_TG_EN
);
1603 static void hdmi_v14_timing_apply(struct hdmi_context
*hdata
)
1605 const struct hdmi_preset_conf
*conf
= hdmi_confs
[hdata
->cur_conf
].conf
;
1606 const struct hdmi_core_regs
*core
= &conf
->core
;
1607 const struct hdmi_tg_regs
*tg
= &conf
->tg
;
1610 /* setting core registers */
1611 hdmi_reg_writeb(hdata
, HDMI_H_BLANK_0
, core
->h_blank
[0]);
1612 hdmi_reg_writeb(hdata
, HDMI_H_BLANK_1
, core
->h_blank
[1]);
1613 hdmi_reg_writeb(hdata
, HDMI_V2_BLANK_0
, core
->v2_blank
[0]);
1614 hdmi_reg_writeb(hdata
, HDMI_V2_BLANK_1
, core
->v2_blank
[1]);
1615 hdmi_reg_writeb(hdata
, HDMI_V1_BLANK_0
, core
->v1_blank
[0]);
1616 hdmi_reg_writeb(hdata
, HDMI_V1_BLANK_1
, core
->v1_blank
[1]);
1617 hdmi_reg_writeb(hdata
, HDMI_V_LINE_0
, core
->v_line
[0]);
1618 hdmi_reg_writeb(hdata
, HDMI_V_LINE_1
, core
->v_line
[1]);
1619 hdmi_reg_writeb(hdata
, HDMI_H_LINE_0
, core
->h_line
[0]);
1620 hdmi_reg_writeb(hdata
, HDMI_H_LINE_1
, core
->h_line
[1]);
1621 hdmi_reg_writeb(hdata
, HDMI_HSYNC_POL
, core
->hsync_pol
[0]);
1622 hdmi_reg_writeb(hdata
, HDMI_VSYNC_POL
, core
->vsync_pol
[0]);
1623 hdmi_reg_writeb(hdata
, HDMI_INT_PRO_MODE
, core
->int_pro_mode
[0]);
1624 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F0_0
, core
->v_blank_f0
[0]);
1625 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F0_1
, core
->v_blank_f0
[1]);
1626 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F1_0
, core
->v_blank_f1
[0]);
1627 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F1_1
, core
->v_blank_f1
[1]);
1628 hdmi_reg_writeb(hdata
, HDMI_H_SYNC_START_0
, core
->h_sync_start
[0]);
1629 hdmi_reg_writeb(hdata
, HDMI_H_SYNC_START_1
, core
->h_sync_start
[1]);
1630 hdmi_reg_writeb(hdata
, HDMI_H_SYNC_END_0
, core
->h_sync_end
[0]);
1631 hdmi_reg_writeb(hdata
, HDMI_H_SYNC_END_1
, core
->h_sync_end
[1]);
1632 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_BEF_2_0
,
1633 core
->v_sync_line_bef_2
[0]);
1634 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_BEF_2_1
,
1635 core
->v_sync_line_bef_2
[1]);
1636 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_BEF_1_0
,
1637 core
->v_sync_line_bef_1
[0]);
1638 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_BEF_1_1
,
1639 core
->v_sync_line_bef_1
[1]);
1640 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_2_0
,
1641 core
->v_sync_line_aft_2
[0]);
1642 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_2_1
,
1643 core
->v_sync_line_aft_2
[1]);
1644 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_1_0
,
1645 core
->v_sync_line_aft_1
[0]);
1646 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_1_1
,
1647 core
->v_sync_line_aft_1
[1]);
1648 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_2_0
,
1649 core
->v_sync_line_aft_pxl_2
[0]);
1650 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_2_1
,
1651 core
->v_sync_line_aft_pxl_2
[1]);
1652 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_1_0
,
1653 core
->v_sync_line_aft_pxl_1
[0]);
1654 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_1_1
,
1655 core
->v_sync_line_aft_pxl_1
[1]);
1656 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F2_0
, core
->v_blank_f2
[0]);
1657 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F2_1
, core
->v_blank_f2
[1]);
1658 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F3_0
, core
->v_blank_f3
[0]);
1659 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F3_1
, core
->v_blank_f3
[1]);
1660 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F4_0
, core
->v_blank_f4
[0]);
1661 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F4_1
, core
->v_blank_f4
[1]);
1662 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F5_0
, core
->v_blank_f5
[0]);
1663 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F5_1
, core
->v_blank_f5
[1]);
1664 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_3_0
,
1665 core
->v_sync_line_aft_3
[0]);
1666 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_3_1
,
1667 core
->v_sync_line_aft_3
[1]);
1668 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_4_0
,
1669 core
->v_sync_line_aft_4
[0]);
1670 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_4_1
,
1671 core
->v_sync_line_aft_4
[1]);
1672 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_5_0
,
1673 core
->v_sync_line_aft_5
[0]);
1674 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_5_1
,
1675 core
->v_sync_line_aft_5
[1]);
1676 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_6_0
,
1677 core
->v_sync_line_aft_6
[0]);
1678 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_6_1
,
1679 core
->v_sync_line_aft_6
[1]);
1680 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_3_0
,
1681 core
->v_sync_line_aft_pxl_3
[0]);
1682 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_3_1
,
1683 core
->v_sync_line_aft_pxl_3
[1]);
1684 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_4_0
,
1685 core
->v_sync_line_aft_pxl_4
[0]);
1686 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_4_1
,
1687 core
->v_sync_line_aft_pxl_4
[1]);
1688 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_5_0
,
1689 core
->v_sync_line_aft_pxl_5
[0]);
1690 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_5_1
,
1691 core
->v_sync_line_aft_pxl_5
[1]);
1692 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_6_0
,
1693 core
->v_sync_line_aft_pxl_6
[0]);
1694 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_6_1
,
1695 core
->v_sync_line_aft_pxl_6
[1]);
1696 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_1_0
, core
->vact_space_1
[0]);
1697 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_1_1
, core
->vact_space_1
[1]);
1698 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_2_0
, core
->vact_space_2
[0]);
1699 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_2_1
, core
->vact_space_2
[1]);
1700 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_3_0
, core
->vact_space_3
[0]);
1701 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_3_1
, core
->vact_space_3
[1]);
1702 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_4_0
, core
->vact_space_4
[0]);
1703 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_4_1
, core
->vact_space_4
[1]);
1704 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_5_0
, core
->vact_space_5
[0]);
1705 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_5_1
, core
->vact_space_5
[1]);
1706 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_6_0
, core
->vact_space_6
[0]);
1707 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_6_1
, core
->vact_space_6
[1]);
1709 /* Timing generator registers */
1710 hdmi_reg_writeb(hdata
, HDMI_TG_H_FSZ_L
, tg
->h_fsz_l
);
1711 hdmi_reg_writeb(hdata
, HDMI_TG_H_FSZ_H
, tg
->h_fsz_h
);
1712 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_ST_L
, tg
->hact_st_l
);
1713 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_ST_H
, tg
->hact_st_h
);
1714 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_SZ_L
, tg
->hact_sz_l
);
1715 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_SZ_H
, tg
->hact_sz_h
);
1716 hdmi_reg_writeb(hdata
, HDMI_TG_V_FSZ_L
, tg
->v_fsz_l
);
1717 hdmi_reg_writeb(hdata
, HDMI_TG_V_FSZ_H
, tg
->v_fsz_h
);
1718 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_L
, tg
->vsync_l
);
1719 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_H
, tg
->vsync_h
);
1720 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC2_L
, tg
->vsync2_l
);
1721 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC2_H
, tg
->vsync2_h
);
1722 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST_L
, tg
->vact_st_l
);
1723 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST_H
, tg
->vact_st_h
);
1724 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_SZ_L
, tg
->vact_sz_l
);
1725 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_SZ_H
, tg
->vact_sz_h
);
1726 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_CHG_L
, tg
->field_chg_l
);
1727 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_CHG_H
, tg
->field_chg_h
);
1728 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST2_L
, tg
->vact_st2_l
);
1729 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST2_H
, tg
->vact_st2_h
);
1730 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST3_L
, tg
->vact_st3_l
);
1731 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST3_H
, tg
->vact_st3_h
);
1732 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST4_L
, tg
->vact_st4_l
);
1733 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST4_H
, tg
->vact_st4_h
);
1734 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_TOP_HDMI_L
, tg
->vsync_top_hdmi_l
);
1735 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_TOP_HDMI_H
, tg
->vsync_top_hdmi_h
);
1736 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_BOT_HDMI_L
, tg
->vsync_bot_hdmi_l
);
1737 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_BOT_HDMI_H
, tg
->vsync_bot_hdmi_h
);
1738 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_TOP_HDMI_L
, tg
->field_top_hdmi_l
);
1739 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_TOP_HDMI_H
, tg
->field_top_hdmi_h
);
1740 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_BOT_HDMI_L
, tg
->field_bot_hdmi_l
);
1741 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_BOT_HDMI_H
, tg
->field_bot_hdmi_h
);
1742 hdmi_reg_writeb(hdata
, HDMI_TG_3D
, tg
->tg_3d
);
1744 /* waiting for HDMIPHY's PLL to get to steady state */
1745 for (tries
= 100; tries
; --tries
) {
1746 u32 val
= hdmi_reg_read(hdata
, HDMI_PHY_STATUS_0
);
1747 if (val
& HDMI_PHY_STATUS_READY
)
1751 /* steady state not achieved */
1753 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1754 hdmi_regs_dump(hdata
, "timing apply");
1757 clk_disable(hdata
->res
.sclk_hdmi
);
1758 clk_set_parent(hdata
->res
.sclk_hdmi
, hdata
->res
.sclk_hdmiphy
);
1759 clk_enable(hdata
->res
.sclk_hdmi
);
1761 /* enable HDMI and timing generator */
1762 hdmi_reg_writemask(hdata
, HDMI_CON_0
, ~0, HDMI_EN
);
1763 if (core
->int_pro_mode
[0])
1764 hdmi_reg_writemask(hdata
, HDMI_TG_CMD
, ~0, HDMI_TG_EN
|
1767 hdmi_reg_writemask(hdata
, HDMI_TG_CMD
, ~0, HDMI_TG_EN
);
1770 static void hdmi_timing_apply(struct hdmi_context
*hdata
)
1773 hdmi_v13_timing_apply(hdata
);
1775 hdmi_v14_timing_apply(hdata
);
1778 static void hdmiphy_conf_reset(struct hdmi_context
*hdata
)
1783 clk_disable(hdata
->res
.sclk_hdmi
);
1784 clk_set_parent(hdata
->res
.sclk_hdmi
, hdata
->res
.sclk_pixel
);
1785 clk_enable(hdata
->res
.sclk_hdmi
);
1787 /* operation mode */
1791 if (hdata
->hdmiphy_port
)
1792 i2c_master_send(hdata
->hdmiphy_port
, buffer
, 2);
1795 reg
= HDMI_V13_PHY_RSTOUT
;
1797 reg
= HDMI_PHY_RSTOUT
;
1800 hdmi_reg_writemask(hdata
, reg
, ~0, HDMI_PHY_SW_RSTOUT
);
1802 hdmi_reg_writemask(hdata
, reg
, 0, HDMI_PHY_SW_RSTOUT
);
1806 static void hdmiphy_conf_apply(struct hdmi_context
*hdata
)
1808 const u8
*hdmiphy_data
;
1811 u8 read_buffer
[32] = {0, };
1815 if (!hdata
->hdmiphy_port
) {
1816 DRM_ERROR("hdmiphy is not attached\n");
1822 hdmiphy_data
= hdmi_v13_confs
[hdata
->cur_conf
].hdmiphy_data
;
1824 hdmiphy_data
= hdmi_confs
[hdata
->cur_conf
].hdmiphy_data
;
1826 memcpy(buffer
, hdmiphy_data
, 32);
1827 ret
= i2c_master_send(hdata
->hdmiphy_port
, buffer
, 32);
1829 DRM_ERROR("failed to configure HDMIPHY via I2C\n");
1835 /* operation mode */
1836 operation
[0] = 0x1f;
1837 operation
[1] = 0x80;
1839 ret
= i2c_master_send(hdata
->hdmiphy_port
, operation
, 2);
1841 DRM_ERROR("failed to enable hdmiphy\n");
1845 ret
= i2c_master_recv(hdata
->hdmiphy_port
, read_buffer
, 32);
1847 DRM_ERROR("failed to read hdmiphy config\n");
1851 for (i
= 0; i
< ret
; i
++)
1852 DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
1853 "recv [0x%02x]\n", i
, buffer
[i
], read_buffer
[i
]);
1856 static void hdmi_conf_apply(struct hdmi_context
*hdata
)
1858 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1860 hdmiphy_conf_reset(hdata
);
1861 hdmiphy_conf_apply(hdata
);
1863 mutex_lock(&hdata
->hdmi_mutex
);
1864 hdmi_conf_reset(hdata
);
1865 hdmi_conf_init(hdata
);
1866 mutex_unlock(&hdata
->hdmi_mutex
);
1868 hdmi_audio_init(hdata
);
1870 /* setting core registers */
1871 hdmi_timing_apply(hdata
);
1872 hdmi_audio_control(hdata
, true);
1874 hdmi_regs_dump(hdata
, "start");
1877 static void hdmi_mode_fixup(void *ctx
, struct drm_connector
*connector
,
1878 struct drm_display_mode
*mode
,
1879 struct drm_display_mode
*adjusted_mode
)
1881 struct drm_display_mode
*m
;
1882 struct hdmi_context
*hdata
= ctx
;
1885 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1887 drm_mode_set_crtcinfo(adjusted_mode
, 0);
1890 index
= hdmi_v13_conf_index(adjusted_mode
);
1892 index
= hdmi_v14_conf_index(adjusted_mode
);
1894 /* just return if user desired mode exists. */
1899 * otherwise, find the most suitable mode among modes and change it
1902 list_for_each_entry(m
, &connector
->modes
, head
) {
1904 index
= hdmi_v13_conf_index(m
);
1906 index
= hdmi_v14_conf_index(m
);
1909 DRM_INFO("desired mode doesn't exist so\n");
1910 DRM_INFO("use the most suitable mode among modes.\n");
1911 memcpy(adjusted_mode
, m
, sizeof(*m
));
1917 static void hdmi_mode_set(void *ctx
, void *mode
)
1919 struct hdmi_context
*hdata
= ctx
;
1922 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1924 conf_idx
= hdmi_conf_index(hdata
, mode
);
1926 hdata
->cur_conf
= conf_idx
;
1928 DRM_DEBUG_KMS("not supported mode\n");
1931 static void hdmi_get_max_resol(void *ctx
, unsigned int *width
,
1932 unsigned int *height
)
1934 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1937 *height
= MAX_HEIGHT
;
1940 static void hdmi_commit(void *ctx
)
1942 struct hdmi_context
*hdata
= ctx
;
1944 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1946 hdmi_conf_apply(hdata
);
1949 static void hdmi_poweron(struct hdmi_context
*hdata
)
1951 struct hdmi_resources
*res
= &hdata
->res
;
1953 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1955 mutex_lock(&hdata
->hdmi_mutex
);
1956 if (hdata
->powered
) {
1957 mutex_unlock(&hdata
->hdmi_mutex
);
1961 hdata
->powered
= true;
1964 hdata
->cfg_hpd(true);
1965 mutex_unlock(&hdata
->hdmi_mutex
);
1967 pm_runtime_get_sync(hdata
->dev
);
1969 regulator_bulk_enable(res
->regul_count
, res
->regul_bulk
);
1970 clk_enable(res
->hdmiphy
);
1971 clk_enable(res
->hdmi
);
1972 clk_enable(res
->sclk_hdmi
);
1975 static void hdmi_poweroff(struct hdmi_context
*hdata
)
1977 struct hdmi_resources
*res
= &hdata
->res
;
1979 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1981 mutex_lock(&hdata
->hdmi_mutex
);
1982 if (!hdata
->powered
)
1984 mutex_unlock(&hdata
->hdmi_mutex
);
1987 * The TV power domain needs any condition of hdmiphy to turn off and
1988 * its reset state seems to meet the condition.
1990 hdmiphy_conf_reset(hdata
);
1992 clk_disable(res
->sclk_hdmi
);
1993 clk_disable(res
->hdmi
);
1994 clk_disable(res
->hdmiphy
);
1995 regulator_bulk_disable(res
->regul_count
, res
->regul_bulk
);
1997 pm_runtime_put_sync(hdata
->dev
);
1999 mutex_lock(&hdata
->hdmi_mutex
);
2001 hdata
->cfg_hpd(false);
2003 hdata
->powered
= false;
2006 mutex_unlock(&hdata
->hdmi_mutex
);
2009 static void hdmi_dpms(void *ctx
, int mode
)
2011 struct hdmi_context
*hdata
= ctx
;
2013 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
2016 case DRM_MODE_DPMS_ON
:
2017 hdmi_poweron(hdata
);
2019 case DRM_MODE_DPMS_STANDBY
:
2020 case DRM_MODE_DPMS_SUSPEND
:
2021 case DRM_MODE_DPMS_OFF
:
2022 hdmi_poweroff(hdata
);
2025 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode
);
2030 static struct exynos_hdmi_ops hdmi_ops
= {
2032 .is_connected
= hdmi_is_connected
,
2033 .get_edid
= hdmi_get_edid
,
2034 .check_timing
= hdmi_check_timing
,
2037 .mode_fixup
= hdmi_mode_fixup
,
2038 .mode_set
= hdmi_mode_set
,
2039 .get_max_resol
= hdmi_get_max_resol
,
2040 .commit
= hdmi_commit
,
2044 static irqreturn_t
hdmi_external_irq_thread(int irq
, void *arg
)
2046 struct exynos_drm_hdmi_context
*ctx
= arg
;
2047 struct hdmi_context
*hdata
= ctx
->ctx
;
2049 if (!hdata
->get_hpd
)
2052 mutex_lock(&hdata
->hdmi_mutex
);
2053 hdata
->hpd
= hdata
->get_hpd();
2054 mutex_unlock(&hdata
->hdmi_mutex
);
2057 drm_helper_hpd_irq_event(ctx
->drm_dev
);
2063 static irqreturn_t
hdmi_internal_irq_thread(int irq
, void *arg
)
2065 struct exynos_drm_hdmi_context
*ctx
= arg
;
2066 struct hdmi_context
*hdata
= ctx
->ctx
;
2069 intc_flag
= hdmi_reg_read(hdata
, HDMI_INTC_FLAG
);
2070 /* clearing flags for HPD plug/unplug */
2071 if (intc_flag
& HDMI_INTC_FLAG_HPD_UNPLUG
) {
2072 DRM_DEBUG_KMS("unplugged\n");
2073 hdmi_reg_writemask(hdata
, HDMI_INTC_FLAG
, ~0,
2074 HDMI_INTC_FLAG_HPD_UNPLUG
);
2076 if (intc_flag
& HDMI_INTC_FLAG_HPD_PLUG
) {
2077 DRM_DEBUG_KMS("plugged\n");
2078 hdmi_reg_writemask(hdata
, HDMI_INTC_FLAG
, ~0,
2079 HDMI_INTC_FLAG_HPD_PLUG
);
2082 mutex_lock(&hdata
->hdmi_mutex
);
2083 hdata
->hpd
= hdmi_reg_read(hdata
, HDMI_HPD_STATUS
);
2084 if (hdata
->powered
&& hdata
->hpd
) {
2085 mutex_unlock(&hdata
->hdmi_mutex
);
2088 mutex_unlock(&hdata
->hdmi_mutex
);
2091 drm_helper_hpd_irq_event(ctx
->drm_dev
);
2097 static int __devinit
hdmi_resources_init(struct hdmi_context
*hdata
)
2099 struct device
*dev
= hdata
->dev
;
2100 struct hdmi_resources
*res
= &hdata
->res
;
2101 static char *supply
[] = {
2109 DRM_DEBUG_KMS("HDMI resource init\n");
2111 memset(res
, 0, sizeof *res
);
2113 /* get clocks, power */
2114 res
->hdmi
= clk_get(dev
, "hdmi");
2115 if (IS_ERR_OR_NULL(res
->hdmi
)) {
2116 DRM_ERROR("failed to get clock 'hdmi'\n");
2119 res
->sclk_hdmi
= clk_get(dev
, "sclk_hdmi");
2120 if (IS_ERR_OR_NULL(res
->sclk_hdmi
)) {
2121 DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
2124 res
->sclk_pixel
= clk_get(dev
, "sclk_pixel");
2125 if (IS_ERR_OR_NULL(res
->sclk_pixel
)) {
2126 DRM_ERROR("failed to get clock 'sclk_pixel'\n");
2129 res
->sclk_hdmiphy
= clk_get(dev
, "sclk_hdmiphy");
2130 if (IS_ERR_OR_NULL(res
->sclk_hdmiphy
)) {
2131 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
2134 res
->hdmiphy
= clk_get(dev
, "hdmiphy");
2135 if (IS_ERR_OR_NULL(res
->hdmiphy
)) {
2136 DRM_ERROR("failed to get clock 'hdmiphy'\n");
2140 clk_set_parent(res
->sclk_hdmi
, res
->sclk_pixel
);
2142 res
->regul_bulk
= kzalloc(ARRAY_SIZE(supply
) *
2143 sizeof res
->regul_bulk
[0], GFP_KERNEL
);
2144 if (!res
->regul_bulk
) {
2145 DRM_ERROR("failed to get memory for regulators\n");
2148 for (i
= 0; i
< ARRAY_SIZE(supply
); ++i
) {
2149 res
->regul_bulk
[i
].supply
= supply
[i
];
2150 res
->regul_bulk
[i
].consumer
= NULL
;
2152 ret
= regulator_bulk_get(dev
, ARRAY_SIZE(supply
), res
->regul_bulk
);
2154 DRM_ERROR("failed to get regulators\n");
2157 res
->regul_count
= ARRAY_SIZE(supply
);
2161 DRM_ERROR("HDMI resource init - failed\n");
2165 static int hdmi_resources_cleanup(struct hdmi_context
*hdata
)
2167 struct hdmi_resources
*res
= &hdata
->res
;
2169 regulator_bulk_free(res
->regul_count
, res
->regul_bulk
);
2170 /* kfree is NULL-safe */
2171 kfree(res
->regul_bulk
);
2172 if (!IS_ERR_OR_NULL(res
->hdmiphy
))
2173 clk_put(res
->hdmiphy
);
2174 if (!IS_ERR_OR_NULL(res
->sclk_hdmiphy
))
2175 clk_put(res
->sclk_hdmiphy
);
2176 if (!IS_ERR_OR_NULL(res
->sclk_pixel
))
2177 clk_put(res
->sclk_pixel
);
2178 if (!IS_ERR_OR_NULL(res
->sclk_hdmi
))
2179 clk_put(res
->sclk_hdmi
);
2180 if (!IS_ERR_OR_NULL(res
->hdmi
))
2182 memset(res
, 0, sizeof *res
);
2187 static struct i2c_client
*hdmi_ddc
, *hdmi_hdmiphy
;
2189 void hdmi_attach_ddc_client(struct i2c_client
*ddc
)
2195 void hdmi_attach_hdmiphy_client(struct i2c_client
*hdmiphy
)
2198 hdmi_hdmiphy
= hdmiphy
;
2201 static int __devinit
hdmi_probe(struct platform_device
*pdev
)
2203 struct device
*dev
= &pdev
->dev
;
2204 struct exynos_drm_hdmi_context
*drm_hdmi_ctx
;
2205 struct hdmi_context
*hdata
;
2206 struct exynos_drm_hdmi_pdata
*pdata
;
2207 struct resource
*res
;
2210 DRM_DEBUG_KMS("[%d]\n", __LINE__
);
2212 pdata
= pdev
->dev
.platform_data
;
2214 DRM_ERROR("no platform data specified\n");
2218 drm_hdmi_ctx
= kzalloc(sizeof(*drm_hdmi_ctx
), GFP_KERNEL
);
2219 if (!drm_hdmi_ctx
) {
2220 DRM_ERROR("failed to allocate common hdmi context.\n");
2224 hdata
= kzalloc(sizeof(struct hdmi_context
), GFP_KERNEL
);
2226 DRM_ERROR("out of memory\n");
2227 kfree(drm_hdmi_ctx
);
2231 mutex_init(&hdata
->hdmi_mutex
);
2233 drm_hdmi_ctx
->ctx
= (void *)hdata
;
2234 hdata
->parent_ctx
= (void *)drm_hdmi_ctx
;
2236 platform_set_drvdata(pdev
, drm_hdmi_ctx
);
2238 hdata
->is_v13
= pdata
->is_v13
;
2239 hdata
->cfg_hpd
= pdata
->cfg_hpd
;
2240 hdata
->get_hpd
= pdata
->get_hpd
;
2243 ret
= hdmi_resources_init(hdata
);
2249 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
2251 DRM_ERROR("failed to find registers\n");
2256 hdata
->regs_res
= request_mem_region(res
->start
, resource_size(res
),
2258 if (!hdata
->regs_res
) {
2259 DRM_ERROR("failed to claim register region\n");
2264 hdata
->regs
= ioremap(res
->start
, resource_size(res
));
2266 DRM_ERROR("failed to map registers\n");
2268 goto err_req_region
;
2271 /* DDC i2c driver */
2272 if (i2c_add_driver(&ddc_driver
)) {
2273 DRM_ERROR("failed to register ddc i2c driver\n");
2278 hdata
->ddc_port
= hdmi_ddc
;
2280 /* hdmiphy i2c driver */
2281 if (i2c_add_driver(&hdmiphy_driver
)) {
2282 DRM_ERROR("failed to register hdmiphy i2c driver\n");
2287 hdata
->hdmiphy_port
= hdmi_hdmiphy
;
2289 hdata
->external_irq
= platform_get_irq_byname(pdev
, "external_irq");
2290 if (hdata
->external_irq
< 0) {
2291 DRM_ERROR("failed to get platform irq\n");
2292 ret
= hdata
->external_irq
;
2296 hdata
->internal_irq
= platform_get_irq_byname(pdev
, "internal_irq");
2297 if (hdata
->internal_irq
< 0) {
2298 DRM_ERROR("failed to get platform internal irq\n");
2299 ret
= hdata
->internal_irq
;
2303 ret
= request_threaded_irq(hdata
->external_irq
, NULL
,
2304 hdmi_external_irq_thread
, IRQF_TRIGGER_RISING
|
2305 IRQF_TRIGGER_FALLING
| IRQF_ONESHOT
,
2306 "hdmi_external", drm_hdmi_ctx
);
2308 DRM_ERROR("failed to register hdmi internal interrupt\n");
2313 hdata
->cfg_hpd(false);
2315 ret
= request_threaded_irq(hdata
->internal_irq
, NULL
,
2316 hdmi_internal_irq_thread
, IRQF_ONESHOT
,
2317 "hdmi_internal", drm_hdmi_ctx
);
2319 DRM_ERROR("failed to register hdmi internal interrupt\n");
2323 /* register specific callbacks to common hdmi. */
2324 exynos_hdmi_ops_register(&hdmi_ops
);
2326 pm_runtime_enable(dev
);
2331 free_irq(hdata
->external_irq
, drm_hdmi_ctx
);
2333 i2c_del_driver(&hdmiphy_driver
);
2335 i2c_del_driver(&ddc_driver
);
2337 iounmap(hdata
->regs
);
2339 release_mem_region(hdata
->regs_res
->start
,
2340 resource_size(hdata
->regs_res
));
2342 hdmi_resources_cleanup(hdata
);
2345 kfree(drm_hdmi_ctx
);
2349 static int __devexit
hdmi_remove(struct platform_device
*pdev
)
2351 struct device
*dev
= &pdev
->dev
;
2352 struct exynos_drm_hdmi_context
*ctx
= platform_get_drvdata(pdev
);
2353 struct hdmi_context
*hdata
= ctx
->ctx
;
2355 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
2357 pm_runtime_disable(dev
);
2359 free_irq(hdata
->internal_irq
, hdata
);
2361 hdmi_resources_cleanup(hdata
);
2363 iounmap(hdata
->regs
);
2365 release_mem_region(hdata
->regs_res
->start
,
2366 resource_size(hdata
->regs_res
));
2368 /* hdmiphy i2c driver */
2369 i2c_del_driver(&hdmiphy_driver
);
2370 /* DDC i2c driver */
2371 i2c_del_driver(&ddc_driver
);
2378 #ifdef CONFIG_PM_SLEEP
2379 static int hdmi_suspend(struct device
*dev
)
2381 struct exynos_drm_hdmi_context
*ctx
= get_hdmi_context(dev
);
2382 struct hdmi_context
*hdata
= ctx
->ctx
;
2384 disable_irq(hdata
->internal_irq
);
2385 disable_irq(hdata
->external_irq
);
2389 drm_helper_hpd_irq_event(ctx
->drm_dev
);
2391 hdmi_poweroff(hdata
);
2396 static int hdmi_resume(struct device
*dev
)
2398 struct exynos_drm_hdmi_context
*ctx
= get_hdmi_context(dev
);
2399 struct hdmi_context
*hdata
= ctx
->ctx
;
2401 enable_irq(hdata
->external_irq
);
2402 enable_irq(hdata
->internal_irq
);
2407 static SIMPLE_DEV_PM_OPS(hdmi_pm_ops
, hdmi_suspend
, hdmi_resume
);
2409 struct platform_driver hdmi_driver
= {
2410 .probe
= hdmi_probe
,
2411 .remove
= __devexit_p(hdmi_remove
),
2413 .name
= "exynos4-hdmi",
2414 .owner
= THIS_MODULE
,