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_176
[32] = {
366 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x5b, 0xef, 0x08,
367 0x81, 0xa0, 0xb9, 0xd8, 0x45, 0xa0, 0xac, 0x80,
368 0x5a, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
369 0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
372 static const u8 hdmiphy_conf74_25
[32] = {
373 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
374 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
375 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
376 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
379 static const u8 hdmiphy_conf148_5
[32] = {
380 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
381 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
382 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
383 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
386 struct hdmi_tg_regs
{
423 struct hdmi_core_regs
{
436 u8 v_sync_line_bef_2
[2];
437 u8 v_sync_line_bef_1
[2];
438 u8 v_sync_line_aft_2
[2];
439 u8 v_sync_line_aft_1
[2];
440 u8 v_sync_line_aft_pxl_2
[2];
441 u8 v_sync_line_aft_pxl_1
[2];
442 u8 v_blank_f2
[2]; /* for 3D mode */
443 u8 v_blank_f3
[2]; /* for 3D mode */
444 u8 v_blank_f4
[2]; /* for 3D mode */
445 u8 v_blank_f5
[2]; /* for 3D mode */
446 u8 v_sync_line_aft_3
[2];
447 u8 v_sync_line_aft_4
[2];
448 u8 v_sync_line_aft_5
[2];
449 u8 v_sync_line_aft_6
[2];
450 u8 v_sync_line_aft_pxl_3
[2];
451 u8 v_sync_line_aft_pxl_4
[2];
452 u8 v_sync_line_aft_pxl_5
[2];
453 u8 v_sync_line_aft_pxl_6
[2];
462 struct hdmi_preset_conf
{
463 struct hdmi_core_regs core
;
464 struct hdmi_tg_regs tg
;
472 const u8
*hdmiphy_data
;
473 const struct hdmi_preset_conf
*conf
;
476 static const struct hdmi_preset_conf hdmi_conf_480p60
= {
478 .h_blank
= {0x8a, 0x00},
479 .v2_blank
= {0x0d, 0x02},
480 .v1_blank
= {0x2d, 0x00},
481 .v_line
= {0x0d, 0x02},
482 .h_line
= {0x5a, 0x03},
485 .int_pro_mode
= {0x00},
486 .v_blank_f0
= {0xff, 0xff},
487 .v_blank_f1
= {0xff, 0xff},
488 .h_sync_start
= {0x0e, 0x00},
489 .h_sync_end
= {0x4c, 0x00},
490 .v_sync_line_bef_2
= {0x0f, 0x00},
491 .v_sync_line_bef_1
= {0x09, 0x00},
492 .v_sync_line_aft_2
= {0xff, 0xff},
493 .v_sync_line_aft_1
= {0xff, 0xff},
494 .v_sync_line_aft_pxl_2
= {0xff, 0xff},
495 .v_sync_line_aft_pxl_1
= {0xff, 0xff},
496 .v_blank_f2
= {0xff, 0xff},
497 .v_blank_f3
= {0xff, 0xff},
498 .v_blank_f4
= {0xff, 0xff},
499 .v_blank_f5
= {0xff, 0xff},
500 .v_sync_line_aft_3
= {0xff, 0xff},
501 .v_sync_line_aft_4
= {0xff, 0xff},
502 .v_sync_line_aft_5
= {0xff, 0xff},
503 .v_sync_line_aft_6
= {0xff, 0xff},
504 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
505 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
506 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
507 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
508 .vact_space_1
= {0xff, 0xff},
509 .vact_space_2
= {0xff, 0xff},
510 .vact_space_3
= {0xff, 0xff},
511 .vact_space_4
= {0xff, 0xff},
512 .vact_space_5
= {0xff, 0xff},
513 .vact_space_6
= {0xff, 0xff},
514 /* other don't care */
518 0x5a, 0x03, /* h_fsz */
519 0x8a, 0x00, 0xd0, 0x02, /* hact */
520 0x0d, 0x02, /* v_fsz */
521 0x01, 0x00, 0x33, 0x02, /* vsync */
522 0x2d, 0x00, 0xe0, 0x01, /* vact */
523 0x33, 0x02, /* field_chg */
524 0x48, 0x02, /* vact_st2 */
525 0x00, 0x00, /* vact_st3 */
526 0x00, 0x00, /* vact_st4 */
527 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
528 0x01, 0x00, 0x33, 0x02, /* field top/bot */
533 static const struct hdmi_preset_conf hdmi_conf_720p50
= {
535 .h_blank
= {0xbc, 0x02},
536 .v2_blank
= {0xee, 0x02},
537 .v1_blank
= {0x1e, 0x00},
538 .v_line
= {0xee, 0x02},
539 .h_line
= {0xbc, 0x07},
542 .int_pro_mode
= {0x00},
543 .v_blank_f0
= {0xff, 0xff},
544 .v_blank_f1
= {0xff, 0xff},
545 .h_sync_start
= {0xb6, 0x01},
546 .h_sync_end
= {0xde, 0x01},
547 .v_sync_line_bef_2
= {0x0a, 0x00},
548 .v_sync_line_bef_1
= {0x05, 0x00},
549 .v_sync_line_aft_2
= {0xff, 0xff},
550 .v_sync_line_aft_1
= {0xff, 0xff},
551 .v_sync_line_aft_pxl_2
= {0xff, 0xff},
552 .v_sync_line_aft_pxl_1
= {0xff, 0xff},
553 .v_blank_f2
= {0xff, 0xff},
554 .v_blank_f3
= {0xff, 0xff},
555 .v_blank_f4
= {0xff, 0xff},
556 .v_blank_f5
= {0xff, 0xff},
557 .v_sync_line_aft_3
= {0xff, 0xff},
558 .v_sync_line_aft_4
= {0xff, 0xff},
559 .v_sync_line_aft_5
= {0xff, 0xff},
560 .v_sync_line_aft_6
= {0xff, 0xff},
561 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
562 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
563 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
564 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
565 .vact_space_1
= {0xff, 0xff},
566 .vact_space_2
= {0xff, 0xff},
567 .vact_space_3
= {0xff, 0xff},
568 .vact_space_4
= {0xff, 0xff},
569 .vact_space_5
= {0xff, 0xff},
570 .vact_space_6
= {0xff, 0xff},
571 /* other don't care */
575 0xbc, 0x07, /* h_fsz */
576 0xbc, 0x02, 0x00, 0x05, /* hact */
577 0xee, 0x02, /* v_fsz */
578 0x01, 0x00, 0x33, 0x02, /* vsync */
579 0x1e, 0x00, 0xd0, 0x02, /* vact */
580 0x33, 0x02, /* field_chg */
581 0x48, 0x02, /* vact_st2 */
582 0x00, 0x00, /* vact_st3 */
583 0x00, 0x00, /* vact_st4 */
584 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
585 0x01, 0x00, 0x33, 0x02, /* field top/bot */
590 static const struct hdmi_preset_conf hdmi_conf_720p60
= {
592 .h_blank
= {0x72, 0x01},
593 .v2_blank
= {0xee, 0x02},
594 .v1_blank
= {0x1e, 0x00},
595 .v_line
= {0xee, 0x02},
596 .h_line
= {0x72, 0x06},
599 .int_pro_mode
= {0x00},
600 .v_blank_f0
= {0xff, 0xff},
601 .v_blank_f1
= {0xff, 0xff},
602 .h_sync_start
= {0x6c, 0x00},
603 .h_sync_end
= {0x94, 0x00},
604 .v_sync_line_bef_2
= {0x0a, 0x00},
605 .v_sync_line_bef_1
= {0x05, 0x00},
606 .v_sync_line_aft_2
= {0xff, 0xff},
607 .v_sync_line_aft_1
= {0xff, 0xff},
608 .v_sync_line_aft_pxl_2
= {0xff, 0xff},
609 .v_sync_line_aft_pxl_1
= {0xff, 0xff},
610 .v_blank_f2
= {0xff, 0xff},
611 .v_blank_f3
= {0xff, 0xff},
612 .v_blank_f4
= {0xff, 0xff},
613 .v_blank_f5
= {0xff, 0xff},
614 .v_sync_line_aft_3
= {0xff, 0xff},
615 .v_sync_line_aft_4
= {0xff, 0xff},
616 .v_sync_line_aft_5
= {0xff, 0xff},
617 .v_sync_line_aft_6
= {0xff, 0xff},
618 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
619 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
620 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
621 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
622 .vact_space_1
= {0xff, 0xff},
623 .vact_space_2
= {0xff, 0xff},
624 .vact_space_3
= {0xff, 0xff},
625 .vact_space_4
= {0xff, 0xff},
626 .vact_space_5
= {0xff, 0xff},
627 .vact_space_6
= {0xff, 0xff},
628 /* other don't care */
632 0x72, 0x06, /* h_fsz */
633 0x72, 0x01, 0x00, 0x05, /* hact */
634 0xee, 0x02, /* v_fsz */
635 0x01, 0x00, 0x33, 0x02, /* vsync */
636 0x1e, 0x00, 0xd0, 0x02, /* vact */
637 0x33, 0x02, /* field_chg */
638 0x48, 0x02, /* vact_st2 */
639 0x00, 0x00, /* vact_st3 */
640 0x00, 0x00, /* vact_st4 */
641 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
642 0x01, 0x00, 0x33, 0x02, /* field top/bot */
647 static const struct hdmi_preset_conf hdmi_conf_1080i50
= {
649 .h_blank
= {0xd0, 0x02},
650 .v2_blank
= {0x32, 0x02},
651 .v1_blank
= {0x16, 0x00},
652 .v_line
= {0x65, 0x04},
653 .h_line
= {0x50, 0x0a},
656 .int_pro_mode
= {0x01},
657 .v_blank_f0
= {0x49, 0x02},
658 .v_blank_f1
= {0x65, 0x04},
659 .h_sync_start
= {0x0e, 0x02},
660 .h_sync_end
= {0x3a, 0x02},
661 .v_sync_line_bef_2
= {0x07, 0x00},
662 .v_sync_line_bef_1
= {0x02, 0x00},
663 .v_sync_line_aft_2
= {0x39, 0x02},
664 .v_sync_line_aft_1
= {0x34, 0x02},
665 .v_sync_line_aft_pxl_2
= {0x38, 0x07},
666 .v_sync_line_aft_pxl_1
= {0x38, 0x07},
667 .v_blank_f2
= {0xff, 0xff},
668 .v_blank_f3
= {0xff, 0xff},
669 .v_blank_f4
= {0xff, 0xff},
670 .v_blank_f5
= {0xff, 0xff},
671 .v_sync_line_aft_3
= {0xff, 0xff},
672 .v_sync_line_aft_4
= {0xff, 0xff},
673 .v_sync_line_aft_5
= {0xff, 0xff},
674 .v_sync_line_aft_6
= {0xff, 0xff},
675 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
676 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
677 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
678 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
679 .vact_space_1
= {0xff, 0xff},
680 .vact_space_2
= {0xff, 0xff},
681 .vact_space_3
= {0xff, 0xff},
682 .vact_space_4
= {0xff, 0xff},
683 .vact_space_5
= {0xff, 0xff},
684 .vact_space_6
= {0xff, 0xff},
685 /* other don't care */
689 0x50, 0x0a, /* h_fsz */
690 0xd0, 0x02, 0x80, 0x07, /* hact */
691 0x65, 0x04, /* v_fsz */
692 0x01, 0x00, 0x33, 0x02, /* vsync */
693 0x16, 0x00, 0x1c, 0x02, /* vact */
694 0x33, 0x02, /* field_chg */
695 0x49, 0x02, /* vact_st2 */
696 0x00, 0x00, /* vact_st3 */
697 0x00, 0x00, /* vact_st4 */
698 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
699 0x01, 0x00, 0x33, 0x02, /* field top/bot */
704 static const struct hdmi_preset_conf hdmi_conf_1080i60
= {
706 .h_blank
= {0x18, 0x01},
707 .v2_blank
= {0x32, 0x02},
708 .v1_blank
= {0x16, 0x00},
709 .v_line
= {0x65, 0x04},
710 .h_line
= {0x98, 0x08},
713 .int_pro_mode
= {0x01},
714 .v_blank_f0
= {0x49, 0x02},
715 .v_blank_f1
= {0x65, 0x04},
716 .h_sync_start
= {0x56, 0x00},
717 .h_sync_end
= {0x82, 0x00},
718 .v_sync_line_bef_2
= {0x07, 0x00},
719 .v_sync_line_bef_1
= {0x02, 0x00},
720 .v_sync_line_aft_2
= {0x39, 0x02},
721 .v_sync_line_aft_1
= {0x34, 0x02},
722 .v_sync_line_aft_pxl_2
= {0xa4, 0x04},
723 .v_sync_line_aft_pxl_1
= {0xa4, 0x04},
724 .v_blank_f2
= {0xff, 0xff},
725 .v_blank_f3
= {0xff, 0xff},
726 .v_blank_f4
= {0xff, 0xff},
727 .v_blank_f5
= {0xff, 0xff},
728 .v_sync_line_aft_3
= {0xff, 0xff},
729 .v_sync_line_aft_4
= {0xff, 0xff},
730 .v_sync_line_aft_5
= {0xff, 0xff},
731 .v_sync_line_aft_6
= {0xff, 0xff},
732 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
733 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
734 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
735 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
736 .vact_space_1
= {0xff, 0xff},
737 .vact_space_2
= {0xff, 0xff},
738 .vact_space_3
= {0xff, 0xff},
739 .vact_space_4
= {0xff, 0xff},
740 .vact_space_5
= {0xff, 0xff},
741 .vact_space_6
= {0xff, 0xff},
742 /* other don't care */
746 0x98, 0x08, /* h_fsz */
747 0x18, 0x01, 0x80, 0x07, /* hact */
748 0x65, 0x04, /* v_fsz */
749 0x01, 0x00, 0x33, 0x02, /* vsync */
750 0x16, 0x00, 0x1c, 0x02, /* vact */
751 0x33, 0x02, /* field_chg */
752 0x49, 0x02, /* vact_st2 */
753 0x00, 0x00, /* vact_st3 */
754 0x00, 0x00, /* vact_st4 */
755 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
756 0x01, 0x00, 0x33, 0x02, /* field top/bot */
761 static const struct hdmi_preset_conf hdmi_conf_1080p30
= {
763 .h_blank
= {0x18, 0x01},
764 .v2_blank
= {0x65, 0x04},
765 .v1_blank
= {0x2d, 0x00},
766 .v_line
= {0x65, 0x04},
767 .h_line
= {0x98, 0x08},
770 .int_pro_mode
= {0x00},
771 .v_blank_f0
= {0xff, 0xff},
772 .v_blank_f1
= {0xff, 0xff},
773 .h_sync_start
= {0x56, 0x00},
774 .h_sync_end
= {0x82, 0x00},
775 .v_sync_line_bef_2
= {0x09, 0x00},
776 .v_sync_line_bef_1
= {0x04, 0x00},
777 .v_sync_line_aft_2
= {0xff, 0xff},
778 .v_sync_line_aft_1
= {0xff, 0xff},
779 .v_sync_line_aft_pxl_2
= {0xff, 0xff},
780 .v_sync_line_aft_pxl_1
= {0xff, 0xff},
781 .v_blank_f2
= {0xff, 0xff},
782 .v_blank_f3
= {0xff, 0xff},
783 .v_blank_f4
= {0xff, 0xff},
784 .v_blank_f5
= {0xff, 0xff},
785 .v_sync_line_aft_3
= {0xff, 0xff},
786 .v_sync_line_aft_4
= {0xff, 0xff},
787 .v_sync_line_aft_5
= {0xff, 0xff},
788 .v_sync_line_aft_6
= {0xff, 0xff},
789 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
790 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
791 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
792 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
793 .vact_space_1
= {0xff, 0xff},
794 .vact_space_2
= {0xff, 0xff},
795 .vact_space_3
= {0xff, 0xff},
796 .vact_space_4
= {0xff, 0xff},
797 .vact_space_5
= {0xff, 0xff},
798 .vact_space_6
= {0xff, 0xff},
799 /* other don't care */
803 0x98, 0x08, /* h_fsz */
804 0x18, 0x01, 0x80, 0x07, /* hact */
805 0x65, 0x04, /* v_fsz */
806 0x01, 0x00, 0x33, 0x02, /* vsync */
807 0x2d, 0x00, 0x38, 0x04, /* vact */
808 0x33, 0x02, /* field_chg */
809 0x48, 0x02, /* vact_st2 */
810 0x00, 0x00, /* vact_st3 */
811 0x00, 0x00, /* vact_st4 */
812 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
813 0x01, 0x00, 0x33, 0x02, /* field top/bot */
818 static const struct hdmi_preset_conf hdmi_conf_1080p50
= {
820 .h_blank
= {0xd0, 0x02},
821 .v2_blank
= {0x65, 0x04},
822 .v1_blank
= {0x2d, 0x00},
823 .v_line
= {0x65, 0x04},
824 .h_line
= {0x50, 0x0a},
827 .int_pro_mode
= {0x00},
828 .v_blank_f0
= {0xff, 0xff},
829 .v_blank_f1
= {0xff, 0xff},
830 .h_sync_start
= {0x0e, 0x02},
831 .h_sync_end
= {0x3a, 0x02},
832 .v_sync_line_bef_2
= {0x09, 0x00},
833 .v_sync_line_bef_1
= {0x04, 0x00},
834 .v_sync_line_aft_2
= {0xff, 0xff},
835 .v_sync_line_aft_1
= {0xff, 0xff},
836 .v_sync_line_aft_pxl_2
= {0xff, 0xff},
837 .v_sync_line_aft_pxl_1
= {0xff, 0xff},
838 .v_blank_f2
= {0xff, 0xff},
839 .v_blank_f3
= {0xff, 0xff},
840 .v_blank_f4
= {0xff, 0xff},
841 .v_blank_f5
= {0xff, 0xff},
842 .v_sync_line_aft_3
= {0xff, 0xff},
843 .v_sync_line_aft_4
= {0xff, 0xff},
844 .v_sync_line_aft_5
= {0xff, 0xff},
845 .v_sync_line_aft_6
= {0xff, 0xff},
846 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
847 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
848 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
849 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
850 .vact_space_1
= {0xff, 0xff},
851 .vact_space_2
= {0xff, 0xff},
852 .vact_space_3
= {0xff, 0xff},
853 .vact_space_4
= {0xff, 0xff},
854 .vact_space_5
= {0xff, 0xff},
855 .vact_space_6
= {0xff, 0xff},
856 /* other don't care */
860 0x50, 0x0a, /* h_fsz */
861 0xd0, 0x02, 0x80, 0x07, /* hact */
862 0x65, 0x04, /* v_fsz */
863 0x01, 0x00, 0x33, 0x02, /* vsync */
864 0x2d, 0x00, 0x38, 0x04, /* vact */
865 0x33, 0x02, /* field_chg */
866 0x48, 0x02, /* vact_st2 */
867 0x00, 0x00, /* vact_st3 */
868 0x00, 0x00, /* vact_st4 */
869 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
870 0x01, 0x00, 0x33, 0x02, /* field top/bot */
875 static const struct hdmi_preset_conf hdmi_conf_1080p60
= {
877 .h_blank
= {0x18, 0x01},
878 .v2_blank
= {0x65, 0x04},
879 .v1_blank
= {0x2d, 0x00},
880 .v_line
= {0x65, 0x04},
881 .h_line
= {0x98, 0x08},
884 .int_pro_mode
= {0x00},
885 .v_blank_f0
= {0xff, 0xff},
886 .v_blank_f1
= {0xff, 0xff},
887 .h_sync_start
= {0x56, 0x00},
888 .h_sync_end
= {0x82, 0x00},
889 .v_sync_line_bef_2
= {0x09, 0x00},
890 .v_sync_line_bef_1
= {0x04, 0x00},
891 .v_sync_line_aft_2
= {0xff, 0xff},
892 .v_sync_line_aft_1
= {0xff, 0xff},
893 .v_sync_line_aft_pxl_2
= {0xff, 0xff},
894 .v_sync_line_aft_pxl_1
= {0xff, 0xff},
895 .v_blank_f2
= {0xff, 0xff},
896 .v_blank_f3
= {0xff, 0xff},
897 .v_blank_f4
= {0xff, 0xff},
898 .v_blank_f5
= {0xff, 0xff},
899 .v_sync_line_aft_3
= {0xff, 0xff},
900 .v_sync_line_aft_4
= {0xff, 0xff},
901 .v_sync_line_aft_5
= {0xff, 0xff},
902 .v_sync_line_aft_6
= {0xff, 0xff},
903 .v_sync_line_aft_pxl_3
= {0xff, 0xff},
904 .v_sync_line_aft_pxl_4
= {0xff, 0xff},
905 .v_sync_line_aft_pxl_5
= {0xff, 0xff},
906 .v_sync_line_aft_pxl_6
= {0xff, 0xff},
907 /* other don't care */
911 0x98, 0x08, /* h_fsz */
912 0x18, 0x01, 0x80, 0x07, /* hact */
913 0x65, 0x04, /* v_fsz */
914 0x01, 0x00, 0x33, 0x02, /* vsync */
915 0x2d, 0x00, 0x38, 0x04, /* vact */
916 0x33, 0x02, /* field_chg */
917 0x48, 0x02, /* vact_st2 */
918 0x00, 0x00, /* vact_st3 */
919 0x00, 0x00, /* vact_st4 */
920 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
921 0x01, 0x00, 0x33, 0x02, /* field top/bot */
926 static const struct hdmi_conf hdmi_confs
[] = {
927 { 720, 480, 60, false, hdmiphy_conf27_027
, &hdmi_conf_480p60
},
928 { 1280, 720, 50, false, hdmiphy_conf74_25
, &hdmi_conf_720p50
},
929 { 1280, 720, 60, false, hdmiphy_conf74_25
, &hdmi_conf_720p60
},
930 { 1920, 1080, 50, true, hdmiphy_conf74_25
, &hdmi_conf_1080i50
},
931 { 1920, 1080, 60, true, hdmiphy_conf74_25
, &hdmi_conf_1080i60
},
932 { 1920, 1080, 30, false, hdmiphy_conf74_176
, &hdmi_conf_1080p30
},
933 { 1920, 1080, 50, false, hdmiphy_conf148_5
, &hdmi_conf_1080p50
},
934 { 1920, 1080, 60, false, hdmiphy_conf148_5
, &hdmi_conf_1080p60
},
938 static inline u32
hdmi_reg_read(struct hdmi_context
*hdata
, u32 reg_id
)
940 return readl(hdata
->regs
+ reg_id
);
943 static inline void hdmi_reg_writeb(struct hdmi_context
*hdata
,
944 u32 reg_id
, u8 value
)
946 writeb(value
, hdata
->regs
+ reg_id
);
949 static inline void hdmi_reg_writemask(struct hdmi_context
*hdata
,
950 u32 reg_id
, u32 value
, u32 mask
)
952 u32 old
= readl(hdata
->regs
+ reg_id
);
953 value
= (value
& mask
) | (old
& ~mask
);
954 writel(value
, hdata
->regs
+ reg_id
);
957 static void hdmi_v13_regs_dump(struct hdmi_context
*hdata
, char *prefix
)
959 #define DUMPREG(reg_id) \
960 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
961 readl(hdata->regs + reg_id))
962 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix
);
963 DUMPREG(HDMI_INTC_FLAG
);
964 DUMPREG(HDMI_INTC_CON
);
965 DUMPREG(HDMI_HPD_STATUS
);
966 DUMPREG(HDMI_V13_PHY_RSTOUT
);
967 DUMPREG(HDMI_V13_PHY_VPLL
);
968 DUMPREG(HDMI_V13_PHY_CMU
);
969 DUMPREG(HDMI_V13_CORE_RSTOUT
);
971 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix
);
975 DUMPREG(HDMI_SYS_STATUS
);
976 DUMPREG(HDMI_V13_PHY_STATUS
);
977 DUMPREG(HDMI_STATUS_EN
);
979 DUMPREG(HDMI_MODE_SEL
);
980 DUMPREG(HDMI_V13_HPD_GEN
);
981 DUMPREG(HDMI_V13_DC_CONTROL
);
982 DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN
);
984 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix
);
985 DUMPREG(HDMI_H_BLANK_0
);
986 DUMPREG(HDMI_H_BLANK_1
);
987 DUMPREG(HDMI_V13_V_BLANK_0
);
988 DUMPREG(HDMI_V13_V_BLANK_1
);
989 DUMPREG(HDMI_V13_V_BLANK_2
);
990 DUMPREG(HDMI_V13_H_V_LINE_0
);
991 DUMPREG(HDMI_V13_H_V_LINE_1
);
992 DUMPREG(HDMI_V13_H_V_LINE_2
);
993 DUMPREG(HDMI_VSYNC_POL
);
994 DUMPREG(HDMI_INT_PRO_MODE
);
995 DUMPREG(HDMI_V13_V_BLANK_F_0
);
996 DUMPREG(HDMI_V13_V_BLANK_F_1
);
997 DUMPREG(HDMI_V13_V_BLANK_F_2
);
998 DUMPREG(HDMI_V13_H_SYNC_GEN_0
);
999 DUMPREG(HDMI_V13_H_SYNC_GEN_1
);
1000 DUMPREG(HDMI_V13_H_SYNC_GEN_2
);
1001 DUMPREG(HDMI_V13_V_SYNC_GEN_1_0
);
1002 DUMPREG(HDMI_V13_V_SYNC_GEN_1_1
);
1003 DUMPREG(HDMI_V13_V_SYNC_GEN_1_2
);
1004 DUMPREG(HDMI_V13_V_SYNC_GEN_2_0
);
1005 DUMPREG(HDMI_V13_V_SYNC_GEN_2_1
);
1006 DUMPREG(HDMI_V13_V_SYNC_GEN_2_2
);
1007 DUMPREG(HDMI_V13_V_SYNC_GEN_3_0
);
1008 DUMPREG(HDMI_V13_V_SYNC_GEN_3_1
);
1009 DUMPREG(HDMI_V13_V_SYNC_GEN_3_2
);
1011 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix
);
1012 DUMPREG(HDMI_TG_CMD
);
1013 DUMPREG(HDMI_TG_H_FSZ_L
);
1014 DUMPREG(HDMI_TG_H_FSZ_H
);
1015 DUMPREG(HDMI_TG_HACT_ST_L
);
1016 DUMPREG(HDMI_TG_HACT_ST_H
);
1017 DUMPREG(HDMI_TG_HACT_SZ_L
);
1018 DUMPREG(HDMI_TG_HACT_SZ_H
);
1019 DUMPREG(HDMI_TG_V_FSZ_L
);
1020 DUMPREG(HDMI_TG_V_FSZ_H
);
1021 DUMPREG(HDMI_TG_VSYNC_L
);
1022 DUMPREG(HDMI_TG_VSYNC_H
);
1023 DUMPREG(HDMI_TG_VSYNC2_L
);
1024 DUMPREG(HDMI_TG_VSYNC2_H
);
1025 DUMPREG(HDMI_TG_VACT_ST_L
);
1026 DUMPREG(HDMI_TG_VACT_ST_H
);
1027 DUMPREG(HDMI_TG_VACT_SZ_L
);
1028 DUMPREG(HDMI_TG_VACT_SZ_H
);
1029 DUMPREG(HDMI_TG_FIELD_CHG_L
);
1030 DUMPREG(HDMI_TG_FIELD_CHG_H
);
1031 DUMPREG(HDMI_TG_VACT_ST2_L
);
1032 DUMPREG(HDMI_TG_VACT_ST2_H
);
1033 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L
);
1034 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H
);
1035 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L
);
1036 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H
);
1037 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L
);
1038 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H
);
1039 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L
);
1040 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H
);
1044 static void hdmi_v14_regs_dump(struct hdmi_context
*hdata
, char *prefix
)
1048 #define DUMPREG(reg_id) \
1049 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
1050 readl(hdata->regs + reg_id))
1052 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix
);
1053 DUMPREG(HDMI_INTC_CON
);
1054 DUMPREG(HDMI_INTC_FLAG
);
1055 DUMPREG(HDMI_HPD_STATUS
);
1056 DUMPREG(HDMI_INTC_CON_1
);
1057 DUMPREG(HDMI_INTC_FLAG_1
);
1058 DUMPREG(HDMI_PHY_STATUS_0
);
1059 DUMPREG(HDMI_PHY_STATUS_PLL
);
1060 DUMPREG(HDMI_PHY_CON_0
);
1061 DUMPREG(HDMI_PHY_RSTOUT
);
1062 DUMPREG(HDMI_PHY_VPLL
);
1063 DUMPREG(HDMI_PHY_CMU
);
1064 DUMPREG(HDMI_CORE_RSTOUT
);
1066 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix
);
1067 DUMPREG(HDMI_CON_0
);
1068 DUMPREG(HDMI_CON_1
);
1069 DUMPREG(HDMI_CON_2
);
1070 DUMPREG(HDMI_SYS_STATUS
);
1071 DUMPREG(HDMI_PHY_STATUS_0
);
1072 DUMPREG(HDMI_STATUS_EN
);
1074 DUMPREG(HDMI_MODE_SEL
);
1075 DUMPREG(HDMI_ENC_EN
);
1076 DUMPREG(HDMI_DC_CONTROL
);
1077 DUMPREG(HDMI_VIDEO_PATTERN_GEN
);
1079 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix
);
1080 DUMPREG(HDMI_H_BLANK_0
);
1081 DUMPREG(HDMI_H_BLANK_1
);
1082 DUMPREG(HDMI_V2_BLANK_0
);
1083 DUMPREG(HDMI_V2_BLANK_1
);
1084 DUMPREG(HDMI_V1_BLANK_0
);
1085 DUMPREG(HDMI_V1_BLANK_1
);
1086 DUMPREG(HDMI_V_LINE_0
);
1087 DUMPREG(HDMI_V_LINE_1
);
1088 DUMPREG(HDMI_H_LINE_0
);
1089 DUMPREG(HDMI_H_LINE_1
);
1090 DUMPREG(HDMI_HSYNC_POL
);
1092 DUMPREG(HDMI_VSYNC_POL
);
1093 DUMPREG(HDMI_INT_PRO_MODE
);
1094 DUMPREG(HDMI_V_BLANK_F0_0
);
1095 DUMPREG(HDMI_V_BLANK_F0_1
);
1096 DUMPREG(HDMI_V_BLANK_F1_0
);
1097 DUMPREG(HDMI_V_BLANK_F1_1
);
1099 DUMPREG(HDMI_H_SYNC_START_0
);
1100 DUMPREG(HDMI_H_SYNC_START_1
);
1101 DUMPREG(HDMI_H_SYNC_END_0
);
1102 DUMPREG(HDMI_H_SYNC_END_1
);
1104 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0
);
1105 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1
);
1106 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0
);
1107 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1
);
1109 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0
);
1110 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1
);
1111 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0
);
1112 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1
);
1114 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0
);
1115 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1
);
1116 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0
);
1117 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1
);
1119 DUMPREG(HDMI_V_BLANK_F2_0
);
1120 DUMPREG(HDMI_V_BLANK_F2_1
);
1121 DUMPREG(HDMI_V_BLANK_F3_0
);
1122 DUMPREG(HDMI_V_BLANK_F3_1
);
1123 DUMPREG(HDMI_V_BLANK_F4_0
);
1124 DUMPREG(HDMI_V_BLANK_F4_1
);
1125 DUMPREG(HDMI_V_BLANK_F5_0
);
1126 DUMPREG(HDMI_V_BLANK_F5_1
);
1128 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0
);
1129 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1
);
1130 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0
);
1131 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1
);
1132 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0
);
1133 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1
);
1134 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0
);
1135 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1
);
1137 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0
);
1138 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1
);
1139 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0
);
1140 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1
);
1141 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0
);
1142 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1
);
1143 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0
);
1144 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1
);
1146 DUMPREG(HDMI_VACT_SPACE_1_0
);
1147 DUMPREG(HDMI_VACT_SPACE_1_1
);
1148 DUMPREG(HDMI_VACT_SPACE_2_0
);
1149 DUMPREG(HDMI_VACT_SPACE_2_1
);
1150 DUMPREG(HDMI_VACT_SPACE_3_0
);
1151 DUMPREG(HDMI_VACT_SPACE_3_1
);
1152 DUMPREG(HDMI_VACT_SPACE_4_0
);
1153 DUMPREG(HDMI_VACT_SPACE_4_1
);
1154 DUMPREG(HDMI_VACT_SPACE_5_0
);
1155 DUMPREG(HDMI_VACT_SPACE_5_1
);
1156 DUMPREG(HDMI_VACT_SPACE_6_0
);
1157 DUMPREG(HDMI_VACT_SPACE_6_1
);
1159 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix
);
1160 DUMPREG(HDMI_TG_CMD
);
1161 DUMPREG(HDMI_TG_H_FSZ_L
);
1162 DUMPREG(HDMI_TG_H_FSZ_H
);
1163 DUMPREG(HDMI_TG_HACT_ST_L
);
1164 DUMPREG(HDMI_TG_HACT_ST_H
);
1165 DUMPREG(HDMI_TG_HACT_SZ_L
);
1166 DUMPREG(HDMI_TG_HACT_SZ_H
);
1167 DUMPREG(HDMI_TG_V_FSZ_L
);
1168 DUMPREG(HDMI_TG_V_FSZ_H
);
1169 DUMPREG(HDMI_TG_VSYNC_L
);
1170 DUMPREG(HDMI_TG_VSYNC_H
);
1171 DUMPREG(HDMI_TG_VSYNC2_L
);
1172 DUMPREG(HDMI_TG_VSYNC2_H
);
1173 DUMPREG(HDMI_TG_VACT_ST_L
);
1174 DUMPREG(HDMI_TG_VACT_ST_H
);
1175 DUMPREG(HDMI_TG_VACT_SZ_L
);
1176 DUMPREG(HDMI_TG_VACT_SZ_H
);
1177 DUMPREG(HDMI_TG_FIELD_CHG_L
);
1178 DUMPREG(HDMI_TG_FIELD_CHG_H
);
1179 DUMPREG(HDMI_TG_VACT_ST2_L
);
1180 DUMPREG(HDMI_TG_VACT_ST2_H
);
1181 DUMPREG(HDMI_TG_VACT_ST3_L
);
1182 DUMPREG(HDMI_TG_VACT_ST3_H
);
1183 DUMPREG(HDMI_TG_VACT_ST4_L
);
1184 DUMPREG(HDMI_TG_VACT_ST4_H
);
1185 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L
);
1186 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H
);
1187 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L
);
1188 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H
);
1189 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L
);
1190 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H
);
1191 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L
);
1192 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H
);
1193 DUMPREG(HDMI_TG_3D
);
1195 DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix
);
1196 DUMPREG(HDMI_AVI_CON
);
1197 DUMPREG(HDMI_AVI_HEADER0
);
1198 DUMPREG(HDMI_AVI_HEADER1
);
1199 DUMPREG(HDMI_AVI_HEADER2
);
1200 DUMPREG(HDMI_AVI_CHECK_SUM
);
1201 DUMPREG(HDMI_VSI_CON
);
1202 DUMPREG(HDMI_VSI_HEADER0
);
1203 DUMPREG(HDMI_VSI_HEADER1
);
1204 DUMPREG(HDMI_VSI_HEADER2
);
1205 for (i
= 0; i
< 7; ++i
)
1206 DUMPREG(HDMI_VSI_DATA(i
));
1211 static void hdmi_regs_dump(struct hdmi_context
*hdata
, char *prefix
)
1214 hdmi_v13_regs_dump(hdata
, prefix
);
1216 hdmi_v14_regs_dump(hdata
, prefix
);
1219 static int hdmi_v13_conf_index(struct drm_display_mode
*mode
)
1223 for (i
= 0; i
< ARRAY_SIZE(hdmi_v13_confs
); ++i
)
1224 if (hdmi_v13_confs
[i
].width
== mode
->hdisplay
&&
1225 hdmi_v13_confs
[i
].height
== mode
->vdisplay
&&
1226 hdmi_v13_confs
[i
].vrefresh
== mode
->vrefresh
&&
1227 hdmi_v13_confs
[i
].interlace
==
1228 ((mode
->flags
& DRM_MODE_FLAG_INTERLACE
) ?
1235 static int hdmi_v14_conf_index(struct drm_display_mode
*mode
)
1239 for (i
= 0; i
< ARRAY_SIZE(hdmi_confs
); ++i
)
1240 if (hdmi_confs
[i
].width
== mode
->hdisplay
&&
1241 hdmi_confs
[i
].height
== mode
->vdisplay
&&
1242 hdmi_confs
[i
].vrefresh
== mode
->vrefresh
&&
1243 hdmi_confs
[i
].interlace
==
1244 ((mode
->flags
& DRM_MODE_FLAG_INTERLACE
) ?
1251 static int hdmi_conf_index(struct hdmi_context
*hdata
,
1252 struct drm_display_mode
*mode
)
1255 return hdmi_v13_conf_index(mode
);
1257 return hdmi_v14_conf_index(mode
);
1260 static bool hdmi_is_connected(void *ctx
)
1262 struct hdmi_context
*hdata
= ctx
;
1267 static int hdmi_get_edid(void *ctx
, struct drm_connector
*connector
,
1270 struct edid
*raw_edid
;
1271 struct hdmi_context
*hdata
= ctx
;
1273 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1275 if (!hdata
->ddc_port
)
1278 raw_edid
= drm_get_edid(connector
, hdata
->ddc_port
->adapter
);
1280 hdata
->dvi_mode
= !drm_detect_hdmi_monitor(raw_edid
);
1281 memcpy(edid
, raw_edid
, min((1 + raw_edid
->extensions
)
1282 * EDID_LENGTH
, len
));
1283 DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
1284 (hdata
->dvi_mode
? "dvi monitor" : "hdmi monitor"),
1285 raw_edid
->width_cm
, raw_edid
->height_cm
);
1293 static int hdmi_v13_check_timing(struct fb_videomode
*check_timing
)
1297 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1298 check_timing
->xres
, check_timing
->yres
,
1299 check_timing
->refresh
, (check_timing
->vmode
&
1300 FB_VMODE_INTERLACED
) ? true : false);
1302 for (i
= 0; i
< ARRAY_SIZE(hdmi_v13_confs
); ++i
)
1303 if (hdmi_v13_confs
[i
].width
== check_timing
->xres
&&
1304 hdmi_v13_confs
[i
].height
== check_timing
->yres
&&
1305 hdmi_v13_confs
[i
].vrefresh
== check_timing
->refresh
&&
1306 hdmi_v13_confs
[i
].interlace
==
1307 ((check_timing
->vmode
& FB_VMODE_INTERLACED
) ?
1316 static int hdmi_v14_check_timing(struct fb_videomode
*check_timing
)
1320 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1321 check_timing
->xres
, check_timing
->yres
,
1322 check_timing
->refresh
, (check_timing
->vmode
&
1323 FB_VMODE_INTERLACED
) ? true : false);
1325 for (i
= 0; i
< ARRAY_SIZE(hdmi_confs
); i
++)
1326 if (hdmi_confs
[i
].width
== check_timing
->xres
&&
1327 hdmi_confs
[i
].height
== check_timing
->yres
&&
1328 hdmi_confs
[i
].vrefresh
== check_timing
->refresh
&&
1329 hdmi_confs
[i
].interlace
==
1330 ((check_timing
->vmode
& FB_VMODE_INTERLACED
) ?
1339 static int hdmi_check_timing(void *ctx
, void *timing
)
1341 struct hdmi_context
*hdata
= ctx
;
1342 struct fb_videomode
*check_timing
= timing
;
1344 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1346 DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing
->xres
,
1347 check_timing
->yres
, check_timing
->refresh
,
1348 check_timing
->vmode
);
1351 return hdmi_v13_check_timing(check_timing
);
1353 return hdmi_v14_check_timing(check_timing
);
1356 static void hdmi_set_acr(u32 freq
, u8
*acr
)
1396 acr
[2] = cts
>> 8 & 0xff;
1397 acr
[3] = cts
& 0xff;
1400 acr
[5] = n
>> 8 & 0xff;
1404 static void hdmi_reg_acr(struct hdmi_context
*hdata
, u8
*acr
)
1406 hdmi_reg_writeb(hdata
, HDMI_ACR_N0
, acr
[6]);
1407 hdmi_reg_writeb(hdata
, HDMI_ACR_N1
, acr
[5]);
1408 hdmi_reg_writeb(hdata
, HDMI_ACR_N2
, acr
[4]);
1409 hdmi_reg_writeb(hdata
, HDMI_ACR_MCTS0
, acr
[3]);
1410 hdmi_reg_writeb(hdata
, HDMI_ACR_MCTS1
, acr
[2]);
1411 hdmi_reg_writeb(hdata
, HDMI_ACR_MCTS2
, acr
[1]);
1412 hdmi_reg_writeb(hdata
, HDMI_ACR_CTS0
, acr
[3]);
1413 hdmi_reg_writeb(hdata
, HDMI_ACR_CTS1
, acr
[2]);
1414 hdmi_reg_writeb(hdata
, HDMI_ACR_CTS2
, acr
[1]);
1417 hdmi_reg_writeb(hdata
, HDMI_V13_ACR_CON
, 4);
1419 hdmi_reg_writeb(hdata
, HDMI_ACR_CON
, 4);
1422 static void hdmi_audio_init(struct hdmi_context
*hdata
)
1424 u32 sample_rate
, bits_per_sample
, frame_size_code
;
1425 u32 data_num
, bit_ch
, sample_frq
;
1429 sample_rate
= 44100;
1430 bits_per_sample
= 16;
1431 frame_size_code
= 0;
1433 switch (bits_per_sample
) {
1448 hdmi_set_acr(sample_rate
, acr
);
1449 hdmi_reg_acr(hdata
, acr
);
1451 hdmi_reg_writeb(hdata
, HDMI_I2S_MUX_CON
, HDMI_I2S_IN_DISABLE
1452 | HDMI_I2S_AUD_I2S
| HDMI_I2S_CUV_I2S_ENABLE
1453 | HDMI_I2S_MUX_ENABLE
);
1455 hdmi_reg_writeb(hdata
, HDMI_I2S_MUX_CH
, HDMI_I2S_CH0_EN
1456 | HDMI_I2S_CH1_EN
| HDMI_I2S_CH2_EN
);
1458 hdmi_reg_writeb(hdata
, HDMI_I2S_MUX_CUV
, HDMI_I2S_CUV_RL_EN
);
1460 sample_frq
= (sample_rate
== 44100) ? 0 :
1461 (sample_rate
== 48000) ? 2 :
1462 (sample_rate
== 32000) ? 3 :
1463 (sample_rate
== 96000) ? 0xa : 0x0;
1465 hdmi_reg_writeb(hdata
, HDMI_I2S_CLK_CON
, HDMI_I2S_CLK_DIS
);
1466 hdmi_reg_writeb(hdata
, HDMI_I2S_CLK_CON
, HDMI_I2S_CLK_EN
);
1468 val
= hdmi_reg_read(hdata
, HDMI_I2S_DSD_CON
) | 0x01;
1469 hdmi_reg_writeb(hdata
, HDMI_I2S_DSD_CON
, val
);
1471 /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1472 hdmi_reg_writeb(hdata
, HDMI_I2S_PIN_SEL_0
, HDMI_I2S_SEL_SCLK(5)
1473 | HDMI_I2S_SEL_LRCK(6));
1474 hdmi_reg_writeb(hdata
, HDMI_I2S_PIN_SEL_1
, HDMI_I2S_SEL_SDATA1(1)
1475 | HDMI_I2S_SEL_SDATA2(4));
1476 hdmi_reg_writeb(hdata
, HDMI_I2S_PIN_SEL_2
, HDMI_I2S_SEL_SDATA3(1)
1477 | HDMI_I2S_SEL_SDATA2(2));
1478 hdmi_reg_writeb(hdata
, HDMI_I2S_PIN_SEL_3
, HDMI_I2S_SEL_DSD(0));
1481 hdmi_reg_writeb(hdata
, HDMI_I2S_CON_1
, HDMI_I2S_SCLK_FALLING_EDGE
1482 | HDMI_I2S_L_CH_LOW_POL
);
1483 hdmi_reg_writeb(hdata
, HDMI_I2S_CON_2
, HDMI_I2S_MSB_FIRST_MODE
1484 | HDMI_I2S_SET_BIT_CH(bit_ch
)
1485 | HDMI_I2S_SET_SDATA_BIT(data_num
)
1486 | HDMI_I2S_BASIC_FORMAT
);
1488 /* Configure register related to CUV information */
1489 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_0
, HDMI_I2S_CH_STATUS_MODE_0
1490 | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1491 | HDMI_I2S_COPYRIGHT
1492 | HDMI_I2S_LINEAR_PCM
1493 | HDMI_I2S_CONSUMER_FORMAT
);
1494 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_1
, HDMI_I2S_CD_PLAYER
);
1495 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_2
, HDMI_I2S_SET_SOURCE_NUM(0));
1496 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_3
, HDMI_I2S_CLK_ACCUR_LEVEL_2
1497 | HDMI_I2S_SET_SMP_FREQ(sample_frq
));
1498 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_4
,
1499 HDMI_I2S_ORG_SMP_FREQ_44_1
1500 | HDMI_I2S_WORD_LEN_MAX24_24BITS
1501 | HDMI_I2S_WORD_LEN_MAX_24BITS
);
1503 hdmi_reg_writeb(hdata
, HDMI_I2S_CH_ST_CON
, HDMI_I2S_CH_STATUS_RELOAD
);
1506 static void hdmi_audio_control(struct hdmi_context
*hdata
, bool onoff
)
1508 if (hdata
->dvi_mode
)
1511 hdmi_reg_writeb(hdata
, HDMI_AUI_CON
, onoff
? 2 : 0);
1512 hdmi_reg_writemask(hdata
, HDMI_CON_0
, onoff
?
1513 HDMI_ASP_EN
: HDMI_ASP_DIS
, HDMI_ASP_MASK
);
1516 static void hdmi_conf_reset(struct hdmi_context
*hdata
)
1521 reg
= HDMI_V13_CORE_RSTOUT
;
1523 reg
= HDMI_CORE_RSTOUT
;
1525 /* resetting HDMI core */
1526 hdmi_reg_writemask(hdata
, reg
, 0, HDMI_CORE_SW_RSTOUT
);
1528 hdmi_reg_writemask(hdata
, reg
, ~0, HDMI_CORE_SW_RSTOUT
);
1532 static void hdmi_conf_init(struct hdmi_context
*hdata
)
1534 /* enable HPD interrupts */
1535 hdmi_reg_writemask(hdata
, HDMI_INTC_CON
, 0, HDMI_INTC_EN_GLOBAL
|
1536 HDMI_INTC_EN_HPD_PLUG
| HDMI_INTC_EN_HPD_UNPLUG
);
1538 hdmi_reg_writemask(hdata
, HDMI_INTC_CON
, ~0, HDMI_INTC_EN_GLOBAL
|
1539 HDMI_INTC_EN_HPD_PLUG
| HDMI_INTC_EN_HPD_UNPLUG
);
1541 /* choose HDMI mode */
1542 hdmi_reg_writemask(hdata
, HDMI_MODE_SEL
,
1543 HDMI_MODE_HDMI_EN
, HDMI_MODE_MASK
);
1544 /* disable bluescreen */
1545 hdmi_reg_writemask(hdata
, HDMI_CON_0
, 0, HDMI_BLUE_SCR_EN
);
1547 if (hdata
->dvi_mode
) {
1548 /* choose DVI mode */
1549 hdmi_reg_writemask(hdata
, HDMI_MODE_SEL
,
1550 HDMI_MODE_DVI_EN
, HDMI_MODE_MASK
);
1551 hdmi_reg_writeb(hdata
, HDMI_CON_2
,
1552 HDMI_VID_PREAMBLE_DIS
| HDMI_GUARD_BAND_DIS
);
1555 if (hdata
->is_v13
) {
1556 /* choose bluescreen (fecal) color */
1557 hdmi_reg_writeb(hdata
, HDMI_V13_BLUE_SCREEN_0
, 0x12);
1558 hdmi_reg_writeb(hdata
, HDMI_V13_BLUE_SCREEN_1
, 0x34);
1559 hdmi_reg_writeb(hdata
, HDMI_V13_BLUE_SCREEN_2
, 0x56);
1561 /* enable AVI packet every vsync, fixes purple line problem */
1562 hdmi_reg_writeb(hdata
, HDMI_V13_AVI_CON
, 0x02);
1563 /* force RGB, look to CEA-861-D, table 7 for more detail */
1564 hdmi_reg_writeb(hdata
, HDMI_V13_AVI_BYTE(0), 0 << 5);
1565 hdmi_reg_writemask(hdata
, HDMI_CON_1
, 0x10 << 5, 0x11 << 5);
1567 hdmi_reg_writeb(hdata
, HDMI_V13_SPD_CON
, 0x02);
1568 hdmi_reg_writeb(hdata
, HDMI_V13_AUI_CON
, 0x02);
1569 hdmi_reg_writeb(hdata
, HDMI_V13_ACR_CON
, 0x04);
1571 /* enable AVI packet every vsync, fixes purple line problem */
1572 hdmi_reg_writeb(hdata
, HDMI_AVI_CON
, 0x02);
1573 hdmi_reg_writeb(hdata
, HDMI_AVI_BYTE(1), 2 << 5);
1574 hdmi_reg_writemask(hdata
, HDMI_CON_1
, 2, 3 << 5);
1578 static void hdmi_v13_timing_apply(struct hdmi_context
*hdata
)
1580 const struct hdmi_v13_preset_conf
*conf
=
1581 hdmi_v13_confs
[hdata
->cur_conf
].conf
;
1582 const struct hdmi_v13_core_regs
*core
= &conf
->core
;
1583 const struct hdmi_v13_tg_regs
*tg
= &conf
->tg
;
1586 /* setting core registers */
1587 hdmi_reg_writeb(hdata
, HDMI_H_BLANK_0
, core
->h_blank
[0]);
1588 hdmi_reg_writeb(hdata
, HDMI_H_BLANK_1
, core
->h_blank
[1]);
1589 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_0
, core
->v_blank
[0]);
1590 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_1
, core
->v_blank
[1]);
1591 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_2
, core
->v_blank
[2]);
1592 hdmi_reg_writeb(hdata
, HDMI_V13_H_V_LINE_0
, core
->h_v_line
[0]);
1593 hdmi_reg_writeb(hdata
, HDMI_V13_H_V_LINE_1
, core
->h_v_line
[1]);
1594 hdmi_reg_writeb(hdata
, HDMI_V13_H_V_LINE_2
, core
->h_v_line
[2]);
1595 hdmi_reg_writeb(hdata
, HDMI_VSYNC_POL
, core
->vsync_pol
[0]);
1596 hdmi_reg_writeb(hdata
, HDMI_INT_PRO_MODE
, core
->int_pro_mode
[0]);
1597 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_F_0
, core
->v_blank_f
[0]);
1598 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_F_1
, core
->v_blank_f
[1]);
1599 hdmi_reg_writeb(hdata
, HDMI_V13_V_BLANK_F_2
, core
->v_blank_f
[2]);
1600 hdmi_reg_writeb(hdata
, HDMI_V13_H_SYNC_GEN_0
, core
->h_sync_gen
[0]);
1601 hdmi_reg_writeb(hdata
, HDMI_V13_H_SYNC_GEN_1
, core
->h_sync_gen
[1]);
1602 hdmi_reg_writeb(hdata
, HDMI_V13_H_SYNC_GEN_2
, core
->h_sync_gen
[2]);
1603 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_1_0
, core
->v_sync_gen1
[0]);
1604 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_1_1
, core
->v_sync_gen1
[1]);
1605 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_1_2
, core
->v_sync_gen1
[2]);
1606 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_2_0
, core
->v_sync_gen2
[0]);
1607 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_2_1
, core
->v_sync_gen2
[1]);
1608 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_2_2
, core
->v_sync_gen2
[2]);
1609 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_3_0
, core
->v_sync_gen3
[0]);
1610 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_3_1
, core
->v_sync_gen3
[1]);
1611 hdmi_reg_writeb(hdata
, HDMI_V13_V_SYNC_GEN_3_2
, core
->v_sync_gen3
[2]);
1612 /* Timing generator registers */
1613 hdmi_reg_writeb(hdata
, HDMI_TG_H_FSZ_L
, tg
->h_fsz_l
);
1614 hdmi_reg_writeb(hdata
, HDMI_TG_H_FSZ_H
, tg
->h_fsz_h
);
1615 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_ST_L
, tg
->hact_st_l
);
1616 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_ST_H
, tg
->hact_st_h
);
1617 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_SZ_L
, tg
->hact_sz_l
);
1618 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_SZ_H
, tg
->hact_sz_h
);
1619 hdmi_reg_writeb(hdata
, HDMI_TG_V_FSZ_L
, tg
->v_fsz_l
);
1620 hdmi_reg_writeb(hdata
, HDMI_TG_V_FSZ_H
, tg
->v_fsz_h
);
1621 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_L
, tg
->vsync_l
);
1622 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_H
, tg
->vsync_h
);
1623 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC2_L
, tg
->vsync2_l
);
1624 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC2_H
, tg
->vsync2_h
);
1625 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST_L
, tg
->vact_st_l
);
1626 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST_H
, tg
->vact_st_h
);
1627 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_SZ_L
, tg
->vact_sz_l
);
1628 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_SZ_H
, tg
->vact_sz_h
);
1629 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_CHG_L
, tg
->field_chg_l
);
1630 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_CHG_H
, tg
->field_chg_h
);
1631 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST2_L
, tg
->vact_st2_l
);
1632 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST2_H
, tg
->vact_st2_h
);
1633 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_TOP_HDMI_L
, tg
->vsync_top_hdmi_l
);
1634 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_TOP_HDMI_H
, tg
->vsync_top_hdmi_h
);
1635 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_BOT_HDMI_L
, tg
->vsync_bot_hdmi_l
);
1636 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_BOT_HDMI_H
, tg
->vsync_bot_hdmi_h
);
1637 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_TOP_HDMI_L
, tg
->field_top_hdmi_l
);
1638 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_TOP_HDMI_H
, tg
->field_top_hdmi_h
);
1639 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_BOT_HDMI_L
, tg
->field_bot_hdmi_l
);
1640 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_BOT_HDMI_H
, tg
->field_bot_hdmi_h
);
1642 /* waiting for HDMIPHY's PLL to get to steady state */
1643 for (tries
= 100; tries
; --tries
) {
1644 u32 val
= hdmi_reg_read(hdata
, HDMI_V13_PHY_STATUS
);
1645 if (val
& HDMI_PHY_STATUS_READY
)
1649 /* steady state not achieved */
1651 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1652 hdmi_regs_dump(hdata
, "timing apply");
1655 clk_disable(hdata
->res
.sclk_hdmi
);
1656 clk_set_parent(hdata
->res
.sclk_hdmi
, hdata
->res
.sclk_hdmiphy
);
1657 clk_enable(hdata
->res
.sclk_hdmi
);
1659 /* enable HDMI and timing generator */
1660 hdmi_reg_writemask(hdata
, HDMI_CON_0
, ~0, HDMI_EN
);
1661 if (core
->int_pro_mode
[0])
1662 hdmi_reg_writemask(hdata
, HDMI_TG_CMD
, ~0, HDMI_TG_EN
|
1665 hdmi_reg_writemask(hdata
, HDMI_TG_CMD
, ~0, HDMI_TG_EN
);
1668 static void hdmi_v14_timing_apply(struct hdmi_context
*hdata
)
1670 const struct hdmi_preset_conf
*conf
= hdmi_confs
[hdata
->cur_conf
].conf
;
1671 const struct hdmi_core_regs
*core
= &conf
->core
;
1672 const struct hdmi_tg_regs
*tg
= &conf
->tg
;
1675 /* setting core registers */
1676 hdmi_reg_writeb(hdata
, HDMI_H_BLANK_0
, core
->h_blank
[0]);
1677 hdmi_reg_writeb(hdata
, HDMI_H_BLANK_1
, core
->h_blank
[1]);
1678 hdmi_reg_writeb(hdata
, HDMI_V2_BLANK_0
, core
->v2_blank
[0]);
1679 hdmi_reg_writeb(hdata
, HDMI_V2_BLANK_1
, core
->v2_blank
[1]);
1680 hdmi_reg_writeb(hdata
, HDMI_V1_BLANK_0
, core
->v1_blank
[0]);
1681 hdmi_reg_writeb(hdata
, HDMI_V1_BLANK_1
, core
->v1_blank
[1]);
1682 hdmi_reg_writeb(hdata
, HDMI_V_LINE_0
, core
->v_line
[0]);
1683 hdmi_reg_writeb(hdata
, HDMI_V_LINE_1
, core
->v_line
[1]);
1684 hdmi_reg_writeb(hdata
, HDMI_H_LINE_0
, core
->h_line
[0]);
1685 hdmi_reg_writeb(hdata
, HDMI_H_LINE_1
, core
->h_line
[1]);
1686 hdmi_reg_writeb(hdata
, HDMI_HSYNC_POL
, core
->hsync_pol
[0]);
1687 hdmi_reg_writeb(hdata
, HDMI_VSYNC_POL
, core
->vsync_pol
[0]);
1688 hdmi_reg_writeb(hdata
, HDMI_INT_PRO_MODE
, core
->int_pro_mode
[0]);
1689 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F0_0
, core
->v_blank_f0
[0]);
1690 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F0_1
, core
->v_blank_f0
[1]);
1691 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F1_0
, core
->v_blank_f1
[0]);
1692 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F1_1
, core
->v_blank_f1
[1]);
1693 hdmi_reg_writeb(hdata
, HDMI_H_SYNC_START_0
, core
->h_sync_start
[0]);
1694 hdmi_reg_writeb(hdata
, HDMI_H_SYNC_START_1
, core
->h_sync_start
[1]);
1695 hdmi_reg_writeb(hdata
, HDMI_H_SYNC_END_0
, core
->h_sync_end
[0]);
1696 hdmi_reg_writeb(hdata
, HDMI_H_SYNC_END_1
, core
->h_sync_end
[1]);
1697 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_BEF_2_0
,
1698 core
->v_sync_line_bef_2
[0]);
1699 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_BEF_2_1
,
1700 core
->v_sync_line_bef_2
[1]);
1701 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_BEF_1_0
,
1702 core
->v_sync_line_bef_1
[0]);
1703 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_BEF_1_1
,
1704 core
->v_sync_line_bef_1
[1]);
1705 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_2_0
,
1706 core
->v_sync_line_aft_2
[0]);
1707 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_2_1
,
1708 core
->v_sync_line_aft_2
[1]);
1709 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_1_0
,
1710 core
->v_sync_line_aft_1
[0]);
1711 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_1_1
,
1712 core
->v_sync_line_aft_1
[1]);
1713 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_2_0
,
1714 core
->v_sync_line_aft_pxl_2
[0]);
1715 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_2_1
,
1716 core
->v_sync_line_aft_pxl_2
[1]);
1717 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_1_0
,
1718 core
->v_sync_line_aft_pxl_1
[0]);
1719 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_1_1
,
1720 core
->v_sync_line_aft_pxl_1
[1]);
1721 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F2_0
, core
->v_blank_f2
[0]);
1722 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F2_1
, core
->v_blank_f2
[1]);
1723 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F3_0
, core
->v_blank_f3
[0]);
1724 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F3_1
, core
->v_blank_f3
[1]);
1725 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F4_0
, core
->v_blank_f4
[0]);
1726 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F4_1
, core
->v_blank_f4
[1]);
1727 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F5_0
, core
->v_blank_f5
[0]);
1728 hdmi_reg_writeb(hdata
, HDMI_V_BLANK_F5_1
, core
->v_blank_f5
[1]);
1729 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_3_0
,
1730 core
->v_sync_line_aft_3
[0]);
1731 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_3_1
,
1732 core
->v_sync_line_aft_3
[1]);
1733 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_4_0
,
1734 core
->v_sync_line_aft_4
[0]);
1735 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_4_1
,
1736 core
->v_sync_line_aft_4
[1]);
1737 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_5_0
,
1738 core
->v_sync_line_aft_5
[0]);
1739 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_5_1
,
1740 core
->v_sync_line_aft_5
[1]);
1741 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_6_0
,
1742 core
->v_sync_line_aft_6
[0]);
1743 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_6_1
,
1744 core
->v_sync_line_aft_6
[1]);
1745 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_3_0
,
1746 core
->v_sync_line_aft_pxl_3
[0]);
1747 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_3_1
,
1748 core
->v_sync_line_aft_pxl_3
[1]);
1749 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_4_0
,
1750 core
->v_sync_line_aft_pxl_4
[0]);
1751 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_4_1
,
1752 core
->v_sync_line_aft_pxl_4
[1]);
1753 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_5_0
,
1754 core
->v_sync_line_aft_pxl_5
[0]);
1755 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_5_1
,
1756 core
->v_sync_line_aft_pxl_5
[1]);
1757 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_6_0
,
1758 core
->v_sync_line_aft_pxl_6
[0]);
1759 hdmi_reg_writeb(hdata
, HDMI_V_SYNC_LINE_AFT_PXL_6_1
,
1760 core
->v_sync_line_aft_pxl_6
[1]);
1761 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_1_0
, core
->vact_space_1
[0]);
1762 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_1_1
, core
->vact_space_1
[1]);
1763 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_2_0
, core
->vact_space_2
[0]);
1764 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_2_1
, core
->vact_space_2
[1]);
1765 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_3_0
, core
->vact_space_3
[0]);
1766 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_3_1
, core
->vact_space_3
[1]);
1767 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_4_0
, core
->vact_space_4
[0]);
1768 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_4_1
, core
->vact_space_4
[1]);
1769 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_5_0
, core
->vact_space_5
[0]);
1770 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_5_1
, core
->vact_space_5
[1]);
1771 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_6_0
, core
->vact_space_6
[0]);
1772 hdmi_reg_writeb(hdata
, HDMI_VACT_SPACE_6_1
, core
->vact_space_6
[1]);
1774 /* Timing generator registers */
1775 hdmi_reg_writeb(hdata
, HDMI_TG_H_FSZ_L
, tg
->h_fsz_l
);
1776 hdmi_reg_writeb(hdata
, HDMI_TG_H_FSZ_H
, tg
->h_fsz_h
);
1777 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_ST_L
, tg
->hact_st_l
);
1778 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_ST_H
, tg
->hact_st_h
);
1779 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_SZ_L
, tg
->hact_sz_l
);
1780 hdmi_reg_writeb(hdata
, HDMI_TG_HACT_SZ_H
, tg
->hact_sz_h
);
1781 hdmi_reg_writeb(hdata
, HDMI_TG_V_FSZ_L
, tg
->v_fsz_l
);
1782 hdmi_reg_writeb(hdata
, HDMI_TG_V_FSZ_H
, tg
->v_fsz_h
);
1783 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_L
, tg
->vsync_l
);
1784 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_H
, tg
->vsync_h
);
1785 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC2_L
, tg
->vsync2_l
);
1786 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC2_H
, tg
->vsync2_h
);
1787 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST_L
, tg
->vact_st_l
);
1788 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST_H
, tg
->vact_st_h
);
1789 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_SZ_L
, tg
->vact_sz_l
);
1790 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_SZ_H
, tg
->vact_sz_h
);
1791 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_CHG_L
, tg
->field_chg_l
);
1792 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_CHG_H
, tg
->field_chg_h
);
1793 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST2_L
, tg
->vact_st2_l
);
1794 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST2_H
, tg
->vact_st2_h
);
1795 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST3_L
, tg
->vact_st3_l
);
1796 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST3_H
, tg
->vact_st3_h
);
1797 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST4_L
, tg
->vact_st4_l
);
1798 hdmi_reg_writeb(hdata
, HDMI_TG_VACT_ST4_H
, tg
->vact_st4_h
);
1799 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_TOP_HDMI_L
, tg
->vsync_top_hdmi_l
);
1800 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_TOP_HDMI_H
, tg
->vsync_top_hdmi_h
);
1801 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_BOT_HDMI_L
, tg
->vsync_bot_hdmi_l
);
1802 hdmi_reg_writeb(hdata
, HDMI_TG_VSYNC_BOT_HDMI_H
, tg
->vsync_bot_hdmi_h
);
1803 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_TOP_HDMI_L
, tg
->field_top_hdmi_l
);
1804 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_TOP_HDMI_H
, tg
->field_top_hdmi_h
);
1805 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_BOT_HDMI_L
, tg
->field_bot_hdmi_l
);
1806 hdmi_reg_writeb(hdata
, HDMI_TG_FIELD_BOT_HDMI_H
, tg
->field_bot_hdmi_h
);
1807 hdmi_reg_writeb(hdata
, HDMI_TG_3D
, tg
->tg_3d
);
1809 /* waiting for HDMIPHY's PLL to get to steady state */
1810 for (tries
= 100; tries
; --tries
) {
1811 u32 val
= hdmi_reg_read(hdata
, HDMI_PHY_STATUS_0
);
1812 if (val
& HDMI_PHY_STATUS_READY
)
1816 /* steady state not achieved */
1818 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1819 hdmi_regs_dump(hdata
, "timing apply");
1822 clk_disable(hdata
->res
.sclk_hdmi
);
1823 clk_set_parent(hdata
->res
.sclk_hdmi
, hdata
->res
.sclk_hdmiphy
);
1824 clk_enable(hdata
->res
.sclk_hdmi
);
1826 /* enable HDMI and timing generator */
1827 hdmi_reg_writemask(hdata
, HDMI_CON_0
, ~0, HDMI_EN
);
1828 if (core
->int_pro_mode
[0])
1829 hdmi_reg_writemask(hdata
, HDMI_TG_CMD
, ~0, HDMI_TG_EN
|
1832 hdmi_reg_writemask(hdata
, HDMI_TG_CMD
, ~0, HDMI_TG_EN
);
1835 static void hdmi_timing_apply(struct hdmi_context
*hdata
)
1838 hdmi_v13_timing_apply(hdata
);
1840 hdmi_v14_timing_apply(hdata
);
1843 static void hdmiphy_conf_reset(struct hdmi_context
*hdata
)
1848 clk_disable(hdata
->res
.sclk_hdmi
);
1849 clk_set_parent(hdata
->res
.sclk_hdmi
, hdata
->res
.sclk_pixel
);
1850 clk_enable(hdata
->res
.sclk_hdmi
);
1852 /* operation mode */
1856 if (hdata
->hdmiphy_port
)
1857 i2c_master_send(hdata
->hdmiphy_port
, buffer
, 2);
1860 reg
= HDMI_V13_PHY_RSTOUT
;
1862 reg
= HDMI_PHY_RSTOUT
;
1865 hdmi_reg_writemask(hdata
, reg
, ~0, HDMI_PHY_SW_RSTOUT
);
1867 hdmi_reg_writemask(hdata
, reg
, 0, HDMI_PHY_SW_RSTOUT
);
1871 static void hdmiphy_conf_apply(struct hdmi_context
*hdata
)
1873 const u8
*hdmiphy_data
;
1876 u8 read_buffer
[32] = {0, };
1880 if (!hdata
->hdmiphy_port
) {
1881 DRM_ERROR("hdmiphy is not attached\n");
1887 hdmiphy_data
= hdmi_v13_confs
[hdata
->cur_conf
].hdmiphy_data
;
1889 hdmiphy_data
= hdmi_confs
[hdata
->cur_conf
].hdmiphy_data
;
1891 memcpy(buffer
, hdmiphy_data
, 32);
1892 ret
= i2c_master_send(hdata
->hdmiphy_port
, buffer
, 32);
1894 DRM_ERROR("failed to configure HDMIPHY via I2C\n");
1900 /* operation mode */
1901 operation
[0] = 0x1f;
1902 operation
[1] = 0x80;
1904 ret
= i2c_master_send(hdata
->hdmiphy_port
, operation
, 2);
1906 DRM_ERROR("failed to enable hdmiphy\n");
1910 ret
= i2c_master_recv(hdata
->hdmiphy_port
, read_buffer
, 32);
1912 DRM_ERROR("failed to read hdmiphy config\n");
1916 for (i
= 0; i
< ret
; i
++)
1917 DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
1918 "recv [0x%02x]\n", i
, buffer
[i
], read_buffer
[i
]);
1921 static void hdmi_conf_apply(struct hdmi_context
*hdata
)
1923 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1925 hdmiphy_conf_reset(hdata
);
1926 hdmiphy_conf_apply(hdata
);
1928 mutex_lock(&hdata
->hdmi_mutex
);
1929 hdmi_conf_reset(hdata
);
1930 hdmi_conf_init(hdata
);
1931 mutex_unlock(&hdata
->hdmi_mutex
);
1933 hdmi_audio_init(hdata
);
1935 /* setting core registers */
1936 hdmi_timing_apply(hdata
);
1937 hdmi_audio_control(hdata
, true);
1939 hdmi_regs_dump(hdata
, "start");
1942 static void hdmi_mode_fixup(void *ctx
, struct drm_connector
*connector
,
1943 struct drm_display_mode
*mode
,
1944 struct drm_display_mode
*adjusted_mode
)
1946 struct drm_display_mode
*m
;
1947 struct hdmi_context
*hdata
= ctx
;
1950 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1952 drm_mode_set_crtcinfo(adjusted_mode
, 0);
1955 index
= hdmi_v13_conf_index(adjusted_mode
);
1957 index
= hdmi_v14_conf_index(adjusted_mode
);
1959 /* just return if user desired mode exists. */
1964 * otherwise, find the most suitable mode among modes and change it
1967 list_for_each_entry(m
, &connector
->modes
, head
) {
1969 index
= hdmi_v13_conf_index(m
);
1971 index
= hdmi_v14_conf_index(m
);
1974 DRM_INFO("desired mode doesn't exist so\n");
1975 DRM_INFO("use the most suitable mode among modes.\n");
1976 memcpy(adjusted_mode
, m
, sizeof(*m
));
1982 static void hdmi_mode_set(void *ctx
, void *mode
)
1984 struct hdmi_context
*hdata
= ctx
;
1987 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
1989 conf_idx
= hdmi_conf_index(hdata
, mode
);
1991 hdata
->cur_conf
= conf_idx
;
1993 DRM_DEBUG_KMS("not supported mode\n");
1996 static void hdmi_get_max_resol(void *ctx
, unsigned int *width
,
1997 unsigned int *height
)
1999 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
2002 *height
= MAX_HEIGHT
;
2005 static void hdmi_commit(void *ctx
)
2007 struct hdmi_context
*hdata
= ctx
;
2009 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
2011 hdmi_conf_apply(hdata
);
2014 static void hdmi_poweron(struct hdmi_context
*hdata
)
2016 struct hdmi_resources
*res
= &hdata
->res
;
2018 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
2020 mutex_lock(&hdata
->hdmi_mutex
);
2021 if (hdata
->powered
) {
2022 mutex_unlock(&hdata
->hdmi_mutex
);
2026 hdata
->powered
= true;
2029 hdata
->cfg_hpd(true);
2030 mutex_unlock(&hdata
->hdmi_mutex
);
2032 pm_runtime_get_sync(hdata
->dev
);
2034 regulator_bulk_enable(res
->regul_count
, res
->regul_bulk
);
2035 clk_enable(res
->hdmiphy
);
2036 clk_enable(res
->hdmi
);
2037 clk_enable(res
->sclk_hdmi
);
2040 static void hdmi_poweroff(struct hdmi_context
*hdata
)
2042 struct hdmi_resources
*res
= &hdata
->res
;
2044 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
2046 mutex_lock(&hdata
->hdmi_mutex
);
2047 if (!hdata
->powered
)
2049 mutex_unlock(&hdata
->hdmi_mutex
);
2052 * The TV power domain needs any condition of hdmiphy to turn off and
2053 * its reset state seems to meet the condition.
2055 hdmiphy_conf_reset(hdata
);
2057 clk_disable(res
->sclk_hdmi
);
2058 clk_disable(res
->hdmi
);
2059 clk_disable(res
->hdmiphy
);
2060 regulator_bulk_disable(res
->regul_count
, res
->regul_bulk
);
2062 pm_runtime_put_sync(hdata
->dev
);
2064 mutex_lock(&hdata
->hdmi_mutex
);
2066 hdata
->cfg_hpd(false);
2068 hdata
->powered
= false;
2071 mutex_unlock(&hdata
->hdmi_mutex
);
2074 static void hdmi_dpms(void *ctx
, int mode
)
2076 struct hdmi_context
*hdata
= ctx
;
2078 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
2081 case DRM_MODE_DPMS_ON
:
2082 hdmi_poweron(hdata
);
2084 case DRM_MODE_DPMS_STANDBY
:
2085 case DRM_MODE_DPMS_SUSPEND
:
2086 case DRM_MODE_DPMS_OFF
:
2087 hdmi_poweroff(hdata
);
2090 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode
);
2095 static struct exynos_hdmi_ops hdmi_ops
= {
2097 .is_connected
= hdmi_is_connected
,
2098 .get_edid
= hdmi_get_edid
,
2099 .check_timing
= hdmi_check_timing
,
2102 .mode_fixup
= hdmi_mode_fixup
,
2103 .mode_set
= hdmi_mode_set
,
2104 .get_max_resol
= hdmi_get_max_resol
,
2105 .commit
= hdmi_commit
,
2109 static irqreturn_t
hdmi_external_irq_thread(int irq
, void *arg
)
2111 struct exynos_drm_hdmi_context
*ctx
= arg
;
2112 struct hdmi_context
*hdata
= ctx
->ctx
;
2114 if (!hdata
->get_hpd
)
2117 mutex_lock(&hdata
->hdmi_mutex
);
2118 hdata
->hpd
= hdata
->get_hpd();
2119 mutex_unlock(&hdata
->hdmi_mutex
);
2122 drm_helper_hpd_irq_event(ctx
->drm_dev
);
2128 static irqreturn_t
hdmi_internal_irq_thread(int irq
, void *arg
)
2130 struct exynos_drm_hdmi_context
*ctx
= arg
;
2131 struct hdmi_context
*hdata
= ctx
->ctx
;
2134 intc_flag
= hdmi_reg_read(hdata
, HDMI_INTC_FLAG
);
2135 /* clearing flags for HPD plug/unplug */
2136 if (intc_flag
& HDMI_INTC_FLAG_HPD_UNPLUG
) {
2137 DRM_DEBUG_KMS("unplugged\n");
2138 hdmi_reg_writemask(hdata
, HDMI_INTC_FLAG
, ~0,
2139 HDMI_INTC_FLAG_HPD_UNPLUG
);
2141 if (intc_flag
& HDMI_INTC_FLAG_HPD_PLUG
) {
2142 DRM_DEBUG_KMS("plugged\n");
2143 hdmi_reg_writemask(hdata
, HDMI_INTC_FLAG
, ~0,
2144 HDMI_INTC_FLAG_HPD_PLUG
);
2147 mutex_lock(&hdata
->hdmi_mutex
);
2148 hdata
->hpd
= hdmi_reg_read(hdata
, HDMI_HPD_STATUS
);
2149 if (hdata
->powered
&& hdata
->hpd
) {
2150 mutex_unlock(&hdata
->hdmi_mutex
);
2153 mutex_unlock(&hdata
->hdmi_mutex
);
2156 drm_helper_hpd_irq_event(ctx
->drm_dev
);
2162 static int __devinit
hdmi_resources_init(struct hdmi_context
*hdata
)
2164 struct device
*dev
= hdata
->dev
;
2165 struct hdmi_resources
*res
= &hdata
->res
;
2166 static char *supply
[] = {
2174 DRM_DEBUG_KMS("HDMI resource init\n");
2176 memset(res
, 0, sizeof *res
);
2178 /* get clocks, power */
2179 res
->hdmi
= clk_get(dev
, "hdmi");
2180 if (IS_ERR_OR_NULL(res
->hdmi
)) {
2181 DRM_ERROR("failed to get clock 'hdmi'\n");
2184 res
->sclk_hdmi
= clk_get(dev
, "sclk_hdmi");
2185 if (IS_ERR_OR_NULL(res
->sclk_hdmi
)) {
2186 DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
2189 res
->sclk_pixel
= clk_get(dev
, "sclk_pixel");
2190 if (IS_ERR_OR_NULL(res
->sclk_pixel
)) {
2191 DRM_ERROR("failed to get clock 'sclk_pixel'\n");
2194 res
->sclk_hdmiphy
= clk_get(dev
, "sclk_hdmiphy");
2195 if (IS_ERR_OR_NULL(res
->sclk_hdmiphy
)) {
2196 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
2199 res
->hdmiphy
= clk_get(dev
, "hdmiphy");
2200 if (IS_ERR_OR_NULL(res
->hdmiphy
)) {
2201 DRM_ERROR("failed to get clock 'hdmiphy'\n");
2205 clk_set_parent(res
->sclk_hdmi
, res
->sclk_pixel
);
2207 res
->regul_bulk
= kzalloc(ARRAY_SIZE(supply
) *
2208 sizeof res
->regul_bulk
[0], GFP_KERNEL
);
2209 if (!res
->regul_bulk
) {
2210 DRM_ERROR("failed to get memory for regulators\n");
2213 for (i
= 0; i
< ARRAY_SIZE(supply
); ++i
) {
2214 res
->regul_bulk
[i
].supply
= supply
[i
];
2215 res
->regul_bulk
[i
].consumer
= NULL
;
2217 ret
= regulator_bulk_get(dev
, ARRAY_SIZE(supply
), res
->regul_bulk
);
2219 DRM_ERROR("failed to get regulators\n");
2222 res
->regul_count
= ARRAY_SIZE(supply
);
2226 DRM_ERROR("HDMI resource init - failed\n");
2230 static int hdmi_resources_cleanup(struct hdmi_context
*hdata
)
2232 struct hdmi_resources
*res
= &hdata
->res
;
2234 regulator_bulk_free(res
->regul_count
, res
->regul_bulk
);
2235 /* kfree is NULL-safe */
2236 kfree(res
->regul_bulk
);
2237 if (!IS_ERR_OR_NULL(res
->hdmiphy
))
2238 clk_put(res
->hdmiphy
);
2239 if (!IS_ERR_OR_NULL(res
->sclk_hdmiphy
))
2240 clk_put(res
->sclk_hdmiphy
);
2241 if (!IS_ERR_OR_NULL(res
->sclk_pixel
))
2242 clk_put(res
->sclk_pixel
);
2243 if (!IS_ERR_OR_NULL(res
->sclk_hdmi
))
2244 clk_put(res
->sclk_hdmi
);
2245 if (!IS_ERR_OR_NULL(res
->hdmi
))
2247 memset(res
, 0, sizeof *res
);
2252 static struct i2c_client
*hdmi_ddc
, *hdmi_hdmiphy
;
2254 void hdmi_attach_ddc_client(struct i2c_client
*ddc
)
2260 void hdmi_attach_hdmiphy_client(struct i2c_client
*hdmiphy
)
2263 hdmi_hdmiphy
= hdmiphy
;
2266 static int __devinit
hdmi_probe(struct platform_device
*pdev
)
2268 struct device
*dev
= &pdev
->dev
;
2269 struct exynos_drm_hdmi_context
*drm_hdmi_ctx
;
2270 struct hdmi_context
*hdata
;
2271 struct exynos_drm_hdmi_pdata
*pdata
;
2272 struct resource
*res
;
2275 DRM_DEBUG_KMS("[%d]\n", __LINE__
);
2277 pdata
= pdev
->dev
.platform_data
;
2279 DRM_ERROR("no platform data specified\n");
2283 drm_hdmi_ctx
= kzalloc(sizeof(*drm_hdmi_ctx
), GFP_KERNEL
);
2284 if (!drm_hdmi_ctx
) {
2285 DRM_ERROR("failed to allocate common hdmi context.\n");
2289 hdata
= kzalloc(sizeof(struct hdmi_context
), GFP_KERNEL
);
2291 DRM_ERROR("out of memory\n");
2292 kfree(drm_hdmi_ctx
);
2296 mutex_init(&hdata
->hdmi_mutex
);
2298 drm_hdmi_ctx
->ctx
= (void *)hdata
;
2299 hdata
->parent_ctx
= (void *)drm_hdmi_ctx
;
2301 platform_set_drvdata(pdev
, drm_hdmi_ctx
);
2303 hdata
->is_v13
= pdata
->is_v13
;
2304 hdata
->cfg_hpd
= pdata
->cfg_hpd
;
2305 hdata
->get_hpd
= pdata
->get_hpd
;
2308 ret
= hdmi_resources_init(hdata
);
2314 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
2316 DRM_ERROR("failed to find registers\n");
2321 hdata
->regs_res
= request_mem_region(res
->start
, resource_size(res
),
2323 if (!hdata
->regs_res
) {
2324 DRM_ERROR("failed to claim register region\n");
2329 hdata
->regs
= ioremap(res
->start
, resource_size(res
));
2331 DRM_ERROR("failed to map registers\n");
2333 goto err_req_region
;
2336 /* DDC i2c driver */
2337 if (i2c_add_driver(&ddc_driver
)) {
2338 DRM_ERROR("failed to register ddc i2c driver\n");
2343 hdata
->ddc_port
= hdmi_ddc
;
2345 /* hdmiphy i2c driver */
2346 if (i2c_add_driver(&hdmiphy_driver
)) {
2347 DRM_ERROR("failed to register hdmiphy i2c driver\n");
2352 hdata
->hdmiphy_port
= hdmi_hdmiphy
;
2354 hdata
->external_irq
= platform_get_irq_byname(pdev
, "external_irq");
2355 if (hdata
->external_irq
< 0) {
2356 DRM_ERROR("failed to get platform irq\n");
2357 ret
= hdata
->external_irq
;
2361 hdata
->internal_irq
= platform_get_irq_byname(pdev
, "internal_irq");
2362 if (hdata
->internal_irq
< 0) {
2363 DRM_ERROR("failed to get platform internal irq\n");
2364 ret
= hdata
->internal_irq
;
2368 ret
= request_threaded_irq(hdata
->external_irq
, NULL
,
2369 hdmi_external_irq_thread
, IRQF_TRIGGER_RISING
|
2370 IRQF_TRIGGER_FALLING
| IRQF_ONESHOT
,
2371 "hdmi_external", drm_hdmi_ctx
);
2373 DRM_ERROR("failed to register hdmi internal interrupt\n");
2378 hdata
->cfg_hpd(false);
2380 ret
= request_threaded_irq(hdata
->internal_irq
, NULL
,
2381 hdmi_internal_irq_thread
, IRQF_ONESHOT
,
2382 "hdmi_internal", drm_hdmi_ctx
);
2384 DRM_ERROR("failed to register hdmi internal interrupt\n");
2388 /* register specific callbacks to common hdmi. */
2389 exynos_hdmi_ops_register(&hdmi_ops
);
2391 pm_runtime_enable(dev
);
2396 free_irq(hdata
->external_irq
, drm_hdmi_ctx
);
2398 i2c_del_driver(&hdmiphy_driver
);
2400 i2c_del_driver(&ddc_driver
);
2402 iounmap(hdata
->regs
);
2404 release_mem_region(hdata
->regs_res
->start
,
2405 resource_size(hdata
->regs_res
));
2407 hdmi_resources_cleanup(hdata
);
2410 kfree(drm_hdmi_ctx
);
2414 static int __devexit
hdmi_remove(struct platform_device
*pdev
)
2416 struct device
*dev
= &pdev
->dev
;
2417 struct exynos_drm_hdmi_context
*ctx
= platform_get_drvdata(pdev
);
2418 struct hdmi_context
*hdata
= ctx
->ctx
;
2420 DRM_DEBUG_KMS("[%d] %s\n", __LINE__
, __func__
);
2422 pm_runtime_disable(dev
);
2424 free_irq(hdata
->internal_irq
, hdata
);
2426 hdmi_resources_cleanup(hdata
);
2428 iounmap(hdata
->regs
);
2430 release_mem_region(hdata
->regs_res
->start
,
2431 resource_size(hdata
->regs_res
));
2433 /* hdmiphy i2c driver */
2434 i2c_del_driver(&hdmiphy_driver
);
2435 /* DDC i2c driver */
2436 i2c_del_driver(&ddc_driver
);
2443 #ifdef CONFIG_PM_SLEEP
2444 static int hdmi_suspend(struct device
*dev
)
2446 struct exynos_drm_hdmi_context
*ctx
= get_hdmi_context(dev
);
2447 struct hdmi_context
*hdata
= ctx
->ctx
;
2449 disable_irq(hdata
->internal_irq
);
2450 disable_irq(hdata
->external_irq
);
2454 drm_helper_hpd_irq_event(ctx
->drm_dev
);
2456 hdmi_poweroff(hdata
);
2461 static int hdmi_resume(struct device
*dev
)
2463 struct exynos_drm_hdmi_context
*ctx
= get_hdmi_context(dev
);
2464 struct hdmi_context
*hdata
= ctx
->ctx
;
2466 enable_irq(hdata
->external_irq
);
2467 enable_irq(hdata
->internal_irq
);
2472 static SIMPLE_DEV_PM_OPS(hdmi_pm_ops
, hdmi_suspend
, hdmi_resume
);
2474 struct platform_driver hdmi_driver
= {
2475 .probe
= hdmi_probe
,
2476 .remove
= __devexit_p(hdmi_remove
),
2478 .name
= "exynos4-hdmi",
2479 .owner
= THIS_MODULE
,