2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
4 * Seung-Woo Kim <sw0312.kim@samsung.com>
5 * Inki Dae <inki.dae@samsung.com>
6 * Joonyoung Shim <jy0922.shim@samsung.com>
8 * Based on drivers/media/video/s5p-tv/hdmi_drv.c
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
18 #include <drm/drm_edid.h>
19 #include <drm/drm_crtc_helper.h>
21 #include "regs-hdmi.h"
23 #include <linux/kernel.h>
24 #include <linux/spinlock.h>
25 #include <linux/wait.h>
26 #include <linux/i2c.h>
27 #include <linux/module.h>
28 #include <linux/platform_device.h>
29 #include <linux/interrupt.h>
30 #include <linux/irq.h>
31 #include <linux/delay.h>
32 #include <linux/pm_runtime.h>
33 #include <linux/clk.h>
34 #include <linux/regulator/consumer.h>
36 #include <linux/of_gpio.h>
37 #include <plat/gpio-cfg.h>
39 #include <drm/exynos_drm.h>
41 #include "exynos_drm_drv.h"
42 #include "exynos_drm_hdmi.h"
44 #include "exynos_hdmi.h"
46 #include <linux/gpio.h>
47 #include <media/s5p_hdmi.h>
49 #define MAX_WIDTH 1920
50 #define MAX_HEIGHT 1080
51 #define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev))
58 struct hdmi_resources {
60 struct clk *sclk_hdmi;
61 struct clk *sclk_pixel;
62 struct clk *sclk_hdmiphy;
64 struct regulator_bulk_data *regul_bulk;
70 struct drm_device *drm_dev;
74 struct mutex hdmi_mutex;
80 struct i2c_client *ddc_port;
81 struct i2c_client *hdmiphy_port;
83 /* current hdmiphy conf index */
86 struct hdmi_resources res;
94 /* HDMI Version 1.3 */
95 static const u8 hdmiphy_v13_conf27[32] = {
96 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
97 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
98 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
99 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
102 static const u8 hdmiphy_v13_conf27_027[32] = {
103 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
104 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
105 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
106 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
109 static const u8 hdmiphy_v13_conf74_175[32] = {
110 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
111 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
112 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
113 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
116 static const u8 hdmiphy_v13_conf74_25[32] = {
117 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
118 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
119 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
120 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
123 static const u8 hdmiphy_v13_conf148_5[32] = {
124 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
125 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
126 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
127 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
130 struct hdmi_v13_tg_regs {
162 struct hdmi_v13_core_regs {
175 struct hdmi_v13_preset_conf {
176 struct hdmi_v13_core_regs core;
177 struct hdmi_v13_tg_regs tg;
180 struct hdmi_v13_conf {
185 const u8 *hdmiphy_data;
186 const struct hdmi_v13_preset_conf *conf;
189 static const struct hdmi_v13_preset_conf hdmi_v13_conf_480p = {
191 .h_blank = {0x8a, 0x00},
192 .v_blank = {0x0d, 0x6a, 0x01},
193 .h_v_line = {0x0d, 0xa2, 0x35},
195 .int_pro_mode = {0x00},
196 .v_blank_f = {0x00, 0x00, 0x00},
197 .h_sync_gen = {0x0e, 0x30, 0x11},
198 .v_sync_gen1 = {0x0f, 0x90, 0x00},
199 /* other don't care */
203 0x5a, 0x03, /* h_fsz */
204 0x8a, 0x00, 0xd0, 0x02, /* hact */
205 0x0d, 0x02, /* v_fsz */
206 0x01, 0x00, 0x33, 0x02, /* vsync */
207 0x2d, 0x00, 0xe0, 0x01, /* vact */
208 0x33, 0x02, /* field_chg */
209 0x49, 0x02, /* vact_st2 */
210 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
211 0x01, 0x00, 0x33, 0x02, /* field top/bot */
215 static const struct hdmi_v13_preset_conf hdmi_v13_conf_720p60 = {
217 .h_blank = {0x72, 0x01},
218 .v_blank = {0xee, 0xf2, 0x00},
219 .h_v_line = {0xee, 0x22, 0x67},
221 .int_pro_mode = {0x00},
222 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
223 .h_sync_gen = {0x6c, 0x50, 0x02},
224 .v_sync_gen1 = {0x0a, 0x50, 0x00},
225 .v_sync_gen2 = {0x01, 0x10, 0x00},
226 .v_sync_gen3 = {0x01, 0x10, 0x00},
227 /* other don't care */
231 0x72, 0x06, /* h_fsz */
232 0x71, 0x01, 0x01, 0x05, /* hact */
233 0xee, 0x02, /* v_fsz */
234 0x01, 0x00, 0x33, 0x02, /* vsync */
235 0x1e, 0x00, 0xd0, 0x02, /* vact */
236 0x33, 0x02, /* field_chg */
237 0x49, 0x02, /* vact_st2 */
238 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
239 0x01, 0x00, 0x33, 0x02, /* field top/bot */
243 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i50 = {
245 .h_blank = {0xd0, 0x02},
246 .v_blank = {0x32, 0xB2, 0x00},
247 .h_v_line = {0x65, 0x04, 0xa5},
249 .int_pro_mode = {0x01},
250 .v_blank_f = {0x49, 0x2A, 0x23},
251 .h_sync_gen = {0x0E, 0xEA, 0x08},
252 .v_sync_gen1 = {0x07, 0x20, 0x00},
253 .v_sync_gen2 = {0x39, 0x42, 0x23},
254 .v_sync_gen3 = {0x38, 0x87, 0x73},
255 /* other don't care */
259 0x50, 0x0A, /* h_fsz */
260 0xCF, 0x02, 0x81, 0x07, /* hact */
261 0x65, 0x04, /* v_fsz */
262 0x01, 0x00, 0x33, 0x02, /* vsync */
263 0x16, 0x00, 0x1c, 0x02, /* vact */
264 0x33, 0x02, /* field_chg */
265 0x49, 0x02, /* vact_st2 */
266 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
267 0x01, 0x00, 0x33, 0x02, /* field top/bot */
271 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p50 = {
273 .h_blank = {0xd0, 0x02},
274 .v_blank = {0x65, 0x6c, 0x01},
275 .h_v_line = {0x65, 0x04, 0xa5},
277 .int_pro_mode = {0x00},
278 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
279 .h_sync_gen = {0x0e, 0xea, 0x08},
280 .v_sync_gen1 = {0x09, 0x40, 0x00},
281 .v_sync_gen2 = {0x01, 0x10, 0x00},
282 .v_sync_gen3 = {0x01, 0x10, 0x00},
283 /* other don't care */
287 0x50, 0x0A, /* h_fsz */
288 0xCF, 0x02, 0x81, 0x07, /* hact */
289 0x65, 0x04, /* v_fsz */
290 0x01, 0x00, 0x33, 0x02, /* vsync */
291 0x2d, 0x00, 0x38, 0x04, /* vact */
292 0x33, 0x02, /* field_chg */
293 0x48, 0x02, /* vact_st2 */
294 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
295 0x01, 0x00, 0x33, 0x02, /* field top/bot */
299 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i60 = {
301 .h_blank = {0x18, 0x01},
302 .v_blank = {0x32, 0xB2, 0x00},
303 .h_v_line = {0x65, 0x84, 0x89},
305 .int_pro_mode = {0x01},
306 .v_blank_f = {0x49, 0x2A, 0x23},
307 .h_sync_gen = {0x56, 0x08, 0x02},
308 .v_sync_gen1 = {0x07, 0x20, 0x00},
309 .v_sync_gen2 = {0x39, 0x42, 0x23},
310 .v_sync_gen3 = {0xa4, 0x44, 0x4a},
311 /* other don't care */
315 0x98, 0x08, /* h_fsz */
316 0x17, 0x01, 0x81, 0x07, /* hact */
317 0x65, 0x04, /* v_fsz */
318 0x01, 0x00, 0x33, 0x02, /* vsync */
319 0x16, 0x00, 0x1c, 0x02, /* vact */
320 0x33, 0x02, /* field_chg */
321 0x49, 0x02, /* vact_st2 */
322 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
323 0x01, 0x00, 0x33, 0x02, /* field top/bot */
327 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60 = {
329 .h_blank = {0x18, 0x01},
330 .v_blank = {0x65, 0x6c, 0x01},
331 .h_v_line = {0x65, 0x84, 0x89},
333 .int_pro_mode = {0x00},
334 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
335 .h_sync_gen = {0x56, 0x08, 0x02},
336 .v_sync_gen1 = {0x09, 0x40, 0x00},
337 .v_sync_gen2 = {0x01, 0x10, 0x00},
338 .v_sync_gen3 = {0x01, 0x10, 0x00},
339 /* other don't care */
343 0x98, 0x08, /* h_fsz */
344 0x17, 0x01, 0x81, 0x07, /* hact */
345 0x65, 0x04, /* v_fsz */
346 0x01, 0x00, 0x33, 0x02, /* vsync */
347 0x2d, 0x00, 0x38, 0x04, /* vact */
348 0x33, 0x02, /* field_chg */
349 0x48, 0x02, /* vact_st2 */
350 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
351 0x01, 0x00, 0x33, 0x02, /* field top/bot */
355 static const struct hdmi_v13_conf hdmi_v13_confs[] = {
356 { 1280, 720, 60, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 },
357 { 1280, 720, 50, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 },
358 { 720, 480, 60, false, hdmiphy_v13_conf27_027, &hdmi_v13_conf_480p },
359 { 1920, 1080, 50, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i50 },
360 { 1920, 1080, 50, false, hdmiphy_v13_conf148_5,
361 &hdmi_v13_conf_1080p50 },
362 { 1920, 1080, 60, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i60 },
363 { 1920, 1080, 60, false, hdmiphy_v13_conf148_5,
364 &hdmi_v13_conf_1080p60 },
367 /* HDMI Version 1.4 */
368 static const u8 hdmiphy_conf27_027[32] = {
369 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
370 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
371 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
372 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
375 static const u8 hdmiphy_conf74_176[32] = {
376 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x5b, 0xef, 0x08,
377 0x81, 0xa0, 0xb9, 0xd8, 0x45, 0xa0, 0xac, 0x80,
378 0x5a, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
379 0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
382 static const u8 hdmiphy_conf74_25[32] = {
383 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
384 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
385 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
386 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
389 static const u8 hdmiphy_conf148_5[32] = {
390 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
391 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
392 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
393 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
396 struct hdmi_tg_regs {
433 struct hdmi_core_regs {
446 u8 v_sync_line_bef_2[2];
447 u8 v_sync_line_bef_1[2];
448 u8 v_sync_line_aft_2[2];
449 u8 v_sync_line_aft_1[2];
450 u8 v_sync_line_aft_pxl_2[2];
451 u8 v_sync_line_aft_pxl_1[2];
452 u8 v_blank_f2[2]; /* for 3D mode */
453 u8 v_blank_f3[2]; /* for 3D mode */
454 u8 v_blank_f4[2]; /* for 3D mode */
455 u8 v_blank_f5[2]; /* for 3D mode */
456 u8 v_sync_line_aft_3[2];
457 u8 v_sync_line_aft_4[2];
458 u8 v_sync_line_aft_5[2];
459 u8 v_sync_line_aft_6[2];
460 u8 v_sync_line_aft_pxl_3[2];
461 u8 v_sync_line_aft_pxl_4[2];
462 u8 v_sync_line_aft_pxl_5[2];
463 u8 v_sync_line_aft_pxl_6[2];
472 struct hdmi_preset_conf {
473 struct hdmi_core_regs core;
474 struct hdmi_tg_regs tg;
482 const u8 *hdmiphy_data;
483 const struct hdmi_preset_conf *conf;
486 static const struct hdmi_preset_conf hdmi_conf_480p60 = {
488 .h_blank = {0x8a, 0x00},
489 .v2_blank = {0x0d, 0x02},
490 .v1_blank = {0x2d, 0x00},
491 .v_line = {0x0d, 0x02},
492 .h_line = {0x5a, 0x03},
495 .int_pro_mode = {0x00},
496 .v_blank_f0 = {0xff, 0xff},
497 .v_blank_f1 = {0xff, 0xff},
498 .h_sync_start = {0x0e, 0x00},
499 .h_sync_end = {0x4c, 0x00},
500 .v_sync_line_bef_2 = {0x0f, 0x00},
501 .v_sync_line_bef_1 = {0x09, 0x00},
502 .v_sync_line_aft_2 = {0xff, 0xff},
503 .v_sync_line_aft_1 = {0xff, 0xff},
504 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
505 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
506 .v_blank_f2 = {0xff, 0xff},
507 .v_blank_f3 = {0xff, 0xff},
508 .v_blank_f4 = {0xff, 0xff},
509 .v_blank_f5 = {0xff, 0xff},
510 .v_sync_line_aft_3 = {0xff, 0xff},
511 .v_sync_line_aft_4 = {0xff, 0xff},
512 .v_sync_line_aft_5 = {0xff, 0xff},
513 .v_sync_line_aft_6 = {0xff, 0xff},
514 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
515 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
516 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
517 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
518 .vact_space_1 = {0xff, 0xff},
519 .vact_space_2 = {0xff, 0xff},
520 .vact_space_3 = {0xff, 0xff},
521 .vact_space_4 = {0xff, 0xff},
522 .vact_space_5 = {0xff, 0xff},
523 .vact_space_6 = {0xff, 0xff},
524 /* other don't care */
528 0x5a, 0x03, /* h_fsz */
529 0x8a, 0x00, 0xd0, 0x02, /* hact */
530 0x0d, 0x02, /* v_fsz */
531 0x01, 0x00, 0x33, 0x02, /* vsync */
532 0x2d, 0x00, 0xe0, 0x01, /* vact */
533 0x33, 0x02, /* field_chg */
534 0x48, 0x02, /* vact_st2 */
535 0x00, 0x00, /* vact_st3 */
536 0x00, 0x00, /* vact_st4 */
537 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
538 0x01, 0x00, 0x33, 0x02, /* field top/bot */
543 static const struct hdmi_preset_conf hdmi_conf_720p50 = {
545 .h_blank = {0xbc, 0x02},
546 .v2_blank = {0xee, 0x02},
547 .v1_blank = {0x1e, 0x00},
548 .v_line = {0xee, 0x02},
549 .h_line = {0xbc, 0x07},
552 .int_pro_mode = {0x00},
553 .v_blank_f0 = {0xff, 0xff},
554 .v_blank_f1 = {0xff, 0xff},
555 .h_sync_start = {0xb6, 0x01},
556 .h_sync_end = {0xde, 0x01},
557 .v_sync_line_bef_2 = {0x0a, 0x00},
558 .v_sync_line_bef_1 = {0x05, 0x00},
559 .v_sync_line_aft_2 = {0xff, 0xff},
560 .v_sync_line_aft_1 = {0xff, 0xff},
561 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
562 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
563 .v_blank_f2 = {0xff, 0xff},
564 .v_blank_f3 = {0xff, 0xff},
565 .v_blank_f4 = {0xff, 0xff},
566 .v_blank_f5 = {0xff, 0xff},
567 .v_sync_line_aft_3 = {0xff, 0xff},
568 .v_sync_line_aft_4 = {0xff, 0xff},
569 .v_sync_line_aft_5 = {0xff, 0xff},
570 .v_sync_line_aft_6 = {0xff, 0xff},
571 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
572 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
573 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
574 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
575 .vact_space_1 = {0xff, 0xff},
576 .vact_space_2 = {0xff, 0xff},
577 .vact_space_3 = {0xff, 0xff},
578 .vact_space_4 = {0xff, 0xff},
579 .vact_space_5 = {0xff, 0xff},
580 .vact_space_6 = {0xff, 0xff},
581 /* other don't care */
585 0xbc, 0x07, /* h_fsz */
586 0xbc, 0x02, 0x00, 0x05, /* hact */
587 0xee, 0x02, /* v_fsz */
588 0x01, 0x00, 0x33, 0x02, /* vsync */
589 0x1e, 0x00, 0xd0, 0x02, /* vact */
590 0x33, 0x02, /* field_chg */
591 0x48, 0x02, /* vact_st2 */
592 0x00, 0x00, /* vact_st3 */
593 0x00, 0x00, /* vact_st4 */
594 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
595 0x01, 0x00, 0x33, 0x02, /* field top/bot */
600 static const struct hdmi_preset_conf hdmi_conf_720p60 = {
602 .h_blank = {0x72, 0x01},
603 .v2_blank = {0xee, 0x02},
604 .v1_blank = {0x1e, 0x00},
605 .v_line = {0xee, 0x02},
606 .h_line = {0x72, 0x06},
609 .int_pro_mode = {0x00},
610 .v_blank_f0 = {0xff, 0xff},
611 .v_blank_f1 = {0xff, 0xff},
612 .h_sync_start = {0x6c, 0x00},
613 .h_sync_end = {0x94, 0x00},
614 .v_sync_line_bef_2 = {0x0a, 0x00},
615 .v_sync_line_bef_1 = {0x05, 0x00},
616 .v_sync_line_aft_2 = {0xff, 0xff},
617 .v_sync_line_aft_1 = {0xff, 0xff},
618 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
619 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
620 .v_blank_f2 = {0xff, 0xff},
621 .v_blank_f3 = {0xff, 0xff},
622 .v_blank_f4 = {0xff, 0xff},
623 .v_blank_f5 = {0xff, 0xff},
624 .v_sync_line_aft_3 = {0xff, 0xff},
625 .v_sync_line_aft_4 = {0xff, 0xff},
626 .v_sync_line_aft_5 = {0xff, 0xff},
627 .v_sync_line_aft_6 = {0xff, 0xff},
628 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
629 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
630 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
631 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
632 .vact_space_1 = {0xff, 0xff},
633 .vact_space_2 = {0xff, 0xff},
634 .vact_space_3 = {0xff, 0xff},
635 .vact_space_4 = {0xff, 0xff},
636 .vact_space_5 = {0xff, 0xff},
637 .vact_space_6 = {0xff, 0xff},
638 /* other don't care */
642 0x72, 0x06, /* h_fsz */
643 0x72, 0x01, 0x00, 0x05, /* hact */
644 0xee, 0x02, /* v_fsz */
645 0x01, 0x00, 0x33, 0x02, /* vsync */
646 0x1e, 0x00, 0xd0, 0x02, /* vact */
647 0x33, 0x02, /* field_chg */
648 0x48, 0x02, /* vact_st2 */
649 0x00, 0x00, /* vact_st3 */
650 0x00, 0x00, /* vact_st4 */
651 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
652 0x01, 0x00, 0x33, 0x02, /* field top/bot */
657 static const struct hdmi_preset_conf hdmi_conf_1080i50 = {
659 .h_blank = {0xd0, 0x02},
660 .v2_blank = {0x32, 0x02},
661 .v1_blank = {0x16, 0x00},
662 .v_line = {0x65, 0x04},
663 .h_line = {0x50, 0x0a},
666 .int_pro_mode = {0x01},
667 .v_blank_f0 = {0x49, 0x02},
668 .v_blank_f1 = {0x65, 0x04},
669 .h_sync_start = {0x0e, 0x02},
670 .h_sync_end = {0x3a, 0x02},
671 .v_sync_line_bef_2 = {0x07, 0x00},
672 .v_sync_line_bef_1 = {0x02, 0x00},
673 .v_sync_line_aft_2 = {0x39, 0x02},
674 .v_sync_line_aft_1 = {0x34, 0x02},
675 .v_sync_line_aft_pxl_2 = {0x38, 0x07},
676 .v_sync_line_aft_pxl_1 = {0x38, 0x07},
677 .v_blank_f2 = {0xff, 0xff},
678 .v_blank_f3 = {0xff, 0xff},
679 .v_blank_f4 = {0xff, 0xff},
680 .v_blank_f5 = {0xff, 0xff},
681 .v_sync_line_aft_3 = {0xff, 0xff},
682 .v_sync_line_aft_4 = {0xff, 0xff},
683 .v_sync_line_aft_5 = {0xff, 0xff},
684 .v_sync_line_aft_6 = {0xff, 0xff},
685 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
686 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
687 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
688 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
689 .vact_space_1 = {0xff, 0xff},
690 .vact_space_2 = {0xff, 0xff},
691 .vact_space_3 = {0xff, 0xff},
692 .vact_space_4 = {0xff, 0xff},
693 .vact_space_5 = {0xff, 0xff},
694 .vact_space_6 = {0xff, 0xff},
695 /* other don't care */
699 0x50, 0x0a, /* h_fsz */
700 0xd0, 0x02, 0x80, 0x07, /* hact */
701 0x65, 0x04, /* v_fsz */
702 0x01, 0x00, 0x33, 0x02, /* vsync */
703 0x16, 0x00, 0x1c, 0x02, /* vact */
704 0x33, 0x02, /* field_chg */
705 0x49, 0x02, /* vact_st2 */
706 0x00, 0x00, /* vact_st3 */
707 0x00, 0x00, /* vact_st4 */
708 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
709 0x01, 0x00, 0x33, 0x02, /* field top/bot */
714 static const struct hdmi_preset_conf hdmi_conf_1080i60 = {
716 .h_blank = {0x18, 0x01},
717 .v2_blank = {0x32, 0x02},
718 .v1_blank = {0x16, 0x00},
719 .v_line = {0x65, 0x04},
720 .h_line = {0x98, 0x08},
723 .int_pro_mode = {0x01},
724 .v_blank_f0 = {0x49, 0x02},
725 .v_blank_f1 = {0x65, 0x04},
726 .h_sync_start = {0x56, 0x00},
727 .h_sync_end = {0x82, 0x00},
728 .v_sync_line_bef_2 = {0x07, 0x00},
729 .v_sync_line_bef_1 = {0x02, 0x00},
730 .v_sync_line_aft_2 = {0x39, 0x02},
731 .v_sync_line_aft_1 = {0x34, 0x02},
732 .v_sync_line_aft_pxl_2 = {0xa4, 0x04},
733 .v_sync_line_aft_pxl_1 = {0xa4, 0x04},
734 .v_blank_f2 = {0xff, 0xff},
735 .v_blank_f3 = {0xff, 0xff},
736 .v_blank_f4 = {0xff, 0xff},
737 .v_blank_f5 = {0xff, 0xff},
738 .v_sync_line_aft_3 = {0xff, 0xff},
739 .v_sync_line_aft_4 = {0xff, 0xff},
740 .v_sync_line_aft_5 = {0xff, 0xff},
741 .v_sync_line_aft_6 = {0xff, 0xff},
742 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
743 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
744 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
745 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
746 .vact_space_1 = {0xff, 0xff},
747 .vact_space_2 = {0xff, 0xff},
748 .vact_space_3 = {0xff, 0xff},
749 .vact_space_4 = {0xff, 0xff},
750 .vact_space_5 = {0xff, 0xff},
751 .vact_space_6 = {0xff, 0xff},
752 /* other don't care */
756 0x98, 0x08, /* h_fsz */
757 0x18, 0x01, 0x80, 0x07, /* hact */
758 0x65, 0x04, /* v_fsz */
759 0x01, 0x00, 0x33, 0x02, /* vsync */
760 0x16, 0x00, 0x1c, 0x02, /* vact */
761 0x33, 0x02, /* field_chg */
762 0x49, 0x02, /* vact_st2 */
763 0x00, 0x00, /* vact_st3 */
764 0x00, 0x00, /* vact_st4 */
765 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
766 0x01, 0x00, 0x33, 0x02, /* field top/bot */
771 static const struct hdmi_preset_conf hdmi_conf_1080p30 = {
773 .h_blank = {0x18, 0x01},
774 .v2_blank = {0x65, 0x04},
775 .v1_blank = {0x2d, 0x00},
776 .v_line = {0x65, 0x04},
777 .h_line = {0x98, 0x08},
780 .int_pro_mode = {0x00},
781 .v_blank_f0 = {0xff, 0xff},
782 .v_blank_f1 = {0xff, 0xff},
783 .h_sync_start = {0x56, 0x00},
784 .h_sync_end = {0x82, 0x00},
785 .v_sync_line_bef_2 = {0x09, 0x00},
786 .v_sync_line_bef_1 = {0x04, 0x00},
787 .v_sync_line_aft_2 = {0xff, 0xff},
788 .v_sync_line_aft_1 = {0xff, 0xff},
789 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
790 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
791 .v_blank_f2 = {0xff, 0xff},
792 .v_blank_f3 = {0xff, 0xff},
793 .v_blank_f4 = {0xff, 0xff},
794 .v_blank_f5 = {0xff, 0xff},
795 .v_sync_line_aft_3 = {0xff, 0xff},
796 .v_sync_line_aft_4 = {0xff, 0xff},
797 .v_sync_line_aft_5 = {0xff, 0xff},
798 .v_sync_line_aft_6 = {0xff, 0xff},
799 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
800 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
801 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
802 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
803 .vact_space_1 = {0xff, 0xff},
804 .vact_space_2 = {0xff, 0xff},
805 .vact_space_3 = {0xff, 0xff},
806 .vact_space_4 = {0xff, 0xff},
807 .vact_space_5 = {0xff, 0xff},
808 .vact_space_6 = {0xff, 0xff},
809 /* other don't care */
813 0x98, 0x08, /* h_fsz */
814 0x18, 0x01, 0x80, 0x07, /* hact */
815 0x65, 0x04, /* v_fsz */
816 0x01, 0x00, 0x33, 0x02, /* vsync */
817 0x2d, 0x00, 0x38, 0x04, /* vact */
818 0x33, 0x02, /* field_chg */
819 0x48, 0x02, /* vact_st2 */
820 0x00, 0x00, /* vact_st3 */
821 0x00, 0x00, /* vact_st4 */
822 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
823 0x01, 0x00, 0x33, 0x02, /* field top/bot */
828 static const struct hdmi_preset_conf hdmi_conf_1080p50 = {
830 .h_blank = {0xd0, 0x02},
831 .v2_blank = {0x65, 0x04},
832 .v1_blank = {0x2d, 0x00},
833 .v_line = {0x65, 0x04},
834 .h_line = {0x50, 0x0a},
837 .int_pro_mode = {0x00},
838 .v_blank_f0 = {0xff, 0xff},
839 .v_blank_f1 = {0xff, 0xff},
840 .h_sync_start = {0x0e, 0x02},
841 .h_sync_end = {0x3a, 0x02},
842 .v_sync_line_bef_2 = {0x09, 0x00},
843 .v_sync_line_bef_1 = {0x04, 0x00},
844 .v_sync_line_aft_2 = {0xff, 0xff},
845 .v_sync_line_aft_1 = {0xff, 0xff},
846 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
847 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
848 .v_blank_f2 = {0xff, 0xff},
849 .v_blank_f3 = {0xff, 0xff},
850 .v_blank_f4 = {0xff, 0xff},
851 .v_blank_f5 = {0xff, 0xff},
852 .v_sync_line_aft_3 = {0xff, 0xff},
853 .v_sync_line_aft_4 = {0xff, 0xff},
854 .v_sync_line_aft_5 = {0xff, 0xff},
855 .v_sync_line_aft_6 = {0xff, 0xff},
856 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
857 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
858 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
859 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
860 .vact_space_1 = {0xff, 0xff},
861 .vact_space_2 = {0xff, 0xff},
862 .vact_space_3 = {0xff, 0xff},
863 .vact_space_4 = {0xff, 0xff},
864 .vact_space_5 = {0xff, 0xff},
865 .vact_space_6 = {0xff, 0xff},
866 /* other don't care */
870 0x50, 0x0a, /* h_fsz */
871 0xd0, 0x02, 0x80, 0x07, /* hact */
872 0x65, 0x04, /* v_fsz */
873 0x01, 0x00, 0x33, 0x02, /* vsync */
874 0x2d, 0x00, 0x38, 0x04, /* vact */
875 0x33, 0x02, /* field_chg */
876 0x48, 0x02, /* vact_st2 */
877 0x00, 0x00, /* vact_st3 */
878 0x00, 0x00, /* vact_st4 */
879 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
880 0x01, 0x00, 0x33, 0x02, /* field top/bot */
885 static const struct hdmi_preset_conf hdmi_conf_1080p60 = {
887 .h_blank = {0x18, 0x01},
888 .v2_blank = {0x65, 0x04},
889 .v1_blank = {0x2d, 0x00},
890 .v_line = {0x65, 0x04},
891 .h_line = {0x98, 0x08},
894 .int_pro_mode = {0x00},
895 .v_blank_f0 = {0xff, 0xff},
896 .v_blank_f1 = {0xff, 0xff},
897 .h_sync_start = {0x56, 0x00},
898 .h_sync_end = {0x82, 0x00},
899 .v_sync_line_bef_2 = {0x09, 0x00},
900 .v_sync_line_bef_1 = {0x04, 0x00},
901 .v_sync_line_aft_2 = {0xff, 0xff},
902 .v_sync_line_aft_1 = {0xff, 0xff},
903 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
904 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
905 .v_blank_f2 = {0xff, 0xff},
906 .v_blank_f3 = {0xff, 0xff},
907 .v_blank_f4 = {0xff, 0xff},
908 .v_blank_f5 = {0xff, 0xff},
909 .v_sync_line_aft_3 = {0xff, 0xff},
910 .v_sync_line_aft_4 = {0xff, 0xff},
911 .v_sync_line_aft_5 = {0xff, 0xff},
912 .v_sync_line_aft_6 = {0xff, 0xff},
913 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
914 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
915 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
916 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
917 /* other don't care */
921 0x98, 0x08, /* h_fsz */
922 0x18, 0x01, 0x80, 0x07, /* hact */
923 0x65, 0x04, /* v_fsz */
924 0x01, 0x00, 0x33, 0x02, /* vsync */
925 0x2d, 0x00, 0x38, 0x04, /* vact */
926 0x33, 0x02, /* field_chg */
927 0x48, 0x02, /* vact_st2 */
928 0x00, 0x00, /* vact_st3 */
929 0x00, 0x00, /* vact_st4 */
930 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
931 0x01, 0x00, 0x33, 0x02, /* field top/bot */
936 static const struct hdmi_conf hdmi_confs[] = {
937 { 720, 480, 60, false, hdmiphy_conf27_027, &hdmi_conf_480p60 },
938 { 1280, 720, 50, false, hdmiphy_conf74_25, &hdmi_conf_720p50 },
939 { 1280, 720, 60, false, hdmiphy_conf74_25, &hdmi_conf_720p60 },
940 { 1920, 1080, 50, true, hdmiphy_conf74_25, &hdmi_conf_1080i50 },
941 { 1920, 1080, 60, true, hdmiphy_conf74_25, &hdmi_conf_1080i60 },
942 { 1920, 1080, 30, false, hdmiphy_conf74_176, &hdmi_conf_1080p30 },
943 { 1920, 1080, 50, false, hdmiphy_conf148_5, &hdmi_conf_1080p50 },
944 { 1920, 1080, 60, false, hdmiphy_conf148_5, &hdmi_conf_1080p60 },
948 static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
950 return readl(hdata->regs + reg_id);
953 static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
954 u32 reg_id, u8 value)
956 writeb(value, hdata->regs + reg_id);
959 static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
960 u32 reg_id, u32 value, u32 mask)
962 u32 old = readl(hdata->regs + reg_id);
963 value = (value & mask) | (old & ~mask);
964 writel(value, hdata->regs + reg_id);
967 static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix)
969 #define DUMPREG(reg_id) \
970 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
971 readl(hdata->regs + reg_id))
972 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
973 DUMPREG(HDMI_INTC_FLAG);
974 DUMPREG(HDMI_INTC_CON);
975 DUMPREG(HDMI_HPD_STATUS);
976 DUMPREG(HDMI_V13_PHY_RSTOUT);
977 DUMPREG(HDMI_V13_PHY_VPLL);
978 DUMPREG(HDMI_V13_PHY_CMU);
979 DUMPREG(HDMI_V13_CORE_RSTOUT);
981 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
985 DUMPREG(HDMI_SYS_STATUS);
986 DUMPREG(HDMI_V13_PHY_STATUS);
987 DUMPREG(HDMI_STATUS_EN);
989 DUMPREG(HDMI_MODE_SEL);
990 DUMPREG(HDMI_V13_HPD_GEN);
991 DUMPREG(HDMI_V13_DC_CONTROL);
992 DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN);
994 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
995 DUMPREG(HDMI_H_BLANK_0);
996 DUMPREG(HDMI_H_BLANK_1);
997 DUMPREG(HDMI_V13_V_BLANK_0);
998 DUMPREG(HDMI_V13_V_BLANK_1);
999 DUMPREG(HDMI_V13_V_BLANK_2);
1000 DUMPREG(HDMI_V13_H_V_LINE_0);
1001 DUMPREG(HDMI_V13_H_V_LINE_1);
1002 DUMPREG(HDMI_V13_H_V_LINE_2);
1003 DUMPREG(HDMI_VSYNC_POL);
1004 DUMPREG(HDMI_INT_PRO_MODE);
1005 DUMPREG(HDMI_V13_V_BLANK_F_0);
1006 DUMPREG(HDMI_V13_V_BLANK_F_1);
1007 DUMPREG(HDMI_V13_V_BLANK_F_2);
1008 DUMPREG(HDMI_V13_H_SYNC_GEN_0);
1009 DUMPREG(HDMI_V13_H_SYNC_GEN_1);
1010 DUMPREG(HDMI_V13_H_SYNC_GEN_2);
1011 DUMPREG(HDMI_V13_V_SYNC_GEN_1_0);
1012 DUMPREG(HDMI_V13_V_SYNC_GEN_1_1);
1013 DUMPREG(HDMI_V13_V_SYNC_GEN_1_2);
1014 DUMPREG(HDMI_V13_V_SYNC_GEN_2_0);
1015 DUMPREG(HDMI_V13_V_SYNC_GEN_2_1);
1016 DUMPREG(HDMI_V13_V_SYNC_GEN_2_2);
1017 DUMPREG(HDMI_V13_V_SYNC_GEN_3_0);
1018 DUMPREG(HDMI_V13_V_SYNC_GEN_3_1);
1019 DUMPREG(HDMI_V13_V_SYNC_GEN_3_2);
1021 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
1022 DUMPREG(HDMI_TG_CMD);
1023 DUMPREG(HDMI_TG_H_FSZ_L);
1024 DUMPREG(HDMI_TG_H_FSZ_H);
1025 DUMPREG(HDMI_TG_HACT_ST_L);
1026 DUMPREG(HDMI_TG_HACT_ST_H);
1027 DUMPREG(HDMI_TG_HACT_SZ_L);
1028 DUMPREG(HDMI_TG_HACT_SZ_H);
1029 DUMPREG(HDMI_TG_V_FSZ_L);
1030 DUMPREG(HDMI_TG_V_FSZ_H);
1031 DUMPREG(HDMI_TG_VSYNC_L);
1032 DUMPREG(HDMI_TG_VSYNC_H);
1033 DUMPREG(HDMI_TG_VSYNC2_L);
1034 DUMPREG(HDMI_TG_VSYNC2_H);
1035 DUMPREG(HDMI_TG_VACT_ST_L);
1036 DUMPREG(HDMI_TG_VACT_ST_H);
1037 DUMPREG(HDMI_TG_VACT_SZ_L);
1038 DUMPREG(HDMI_TG_VACT_SZ_H);
1039 DUMPREG(HDMI_TG_FIELD_CHG_L);
1040 DUMPREG(HDMI_TG_FIELD_CHG_H);
1041 DUMPREG(HDMI_TG_VACT_ST2_L);
1042 DUMPREG(HDMI_TG_VACT_ST2_H);
1043 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
1044 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
1045 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
1046 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
1047 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
1048 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
1049 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
1050 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
1054 static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix)
1058 #define DUMPREG(reg_id) \
1059 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
1060 readl(hdata->regs + reg_id))
1062 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
1063 DUMPREG(HDMI_INTC_CON);
1064 DUMPREG(HDMI_INTC_FLAG);
1065 DUMPREG(HDMI_HPD_STATUS);
1066 DUMPREG(HDMI_INTC_CON_1);
1067 DUMPREG(HDMI_INTC_FLAG_1);
1068 DUMPREG(HDMI_PHY_STATUS_0);
1069 DUMPREG(HDMI_PHY_STATUS_PLL);
1070 DUMPREG(HDMI_PHY_CON_0);
1071 DUMPREG(HDMI_PHY_RSTOUT);
1072 DUMPREG(HDMI_PHY_VPLL);
1073 DUMPREG(HDMI_PHY_CMU);
1074 DUMPREG(HDMI_CORE_RSTOUT);
1076 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
1077 DUMPREG(HDMI_CON_0);
1078 DUMPREG(HDMI_CON_1);
1079 DUMPREG(HDMI_CON_2);
1080 DUMPREG(HDMI_SYS_STATUS);
1081 DUMPREG(HDMI_PHY_STATUS_0);
1082 DUMPREG(HDMI_STATUS_EN);
1084 DUMPREG(HDMI_MODE_SEL);
1085 DUMPREG(HDMI_ENC_EN);
1086 DUMPREG(HDMI_DC_CONTROL);
1087 DUMPREG(HDMI_VIDEO_PATTERN_GEN);
1089 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
1090 DUMPREG(HDMI_H_BLANK_0);
1091 DUMPREG(HDMI_H_BLANK_1);
1092 DUMPREG(HDMI_V2_BLANK_0);
1093 DUMPREG(HDMI_V2_BLANK_1);
1094 DUMPREG(HDMI_V1_BLANK_0);
1095 DUMPREG(HDMI_V1_BLANK_1);
1096 DUMPREG(HDMI_V_LINE_0);
1097 DUMPREG(HDMI_V_LINE_1);
1098 DUMPREG(HDMI_H_LINE_0);
1099 DUMPREG(HDMI_H_LINE_1);
1100 DUMPREG(HDMI_HSYNC_POL);
1102 DUMPREG(HDMI_VSYNC_POL);
1103 DUMPREG(HDMI_INT_PRO_MODE);
1104 DUMPREG(HDMI_V_BLANK_F0_0);
1105 DUMPREG(HDMI_V_BLANK_F0_1);
1106 DUMPREG(HDMI_V_BLANK_F1_0);
1107 DUMPREG(HDMI_V_BLANK_F1_1);
1109 DUMPREG(HDMI_H_SYNC_START_0);
1110 DUMPREG(HDMI_H_SYNC_START_1);
1111 DUMPREG(HDMI_H_SYNC_END_0);
1112 DUMPREG(HDMI_H_SYNC_END_1);
1114 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0);
1115 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1);
1116 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0);
1117 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1);
1119 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0);
1120 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1);
1121 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0);
1122 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1);
1124 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0);
1125 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1);
1126 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0);
1127 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1);
1129 DUMPREG(HDMI_V_BLANK_F2_0);
1130 DUMPREG(HDMI_V_BLANK_F2_1);
1131 DUMPREG(HDMI_V_BLANK_F3_0);
1132 DUMPREG(HDMI_V_BLANK_F3_1);
1133 DUMPREG(HDMI_V_BLANK_F4_0);
1134 DUMPREG(HDMI_V_BLANK_F4_1);
1135 DUMPREG(HDMI_V_BLANK_F5_0);
1136 DUMPREG(HDMI_V_BLANK_F5_1);
1138 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0);
1139 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1);
1140 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0);
1141 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1);
1142 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0);
1143 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1);
1144 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0);
1145 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1);
1147 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0);
1148 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1);
1149 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0);
1150 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1);
1151 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0);
1152 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1);
1153 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0);
1154 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1);
1156 DUMPREG(HDMI_VACT_SPACE_1_0);
1157 DUMPREG(HDMI_VACT_SPACE_1_1);
1158 DUMPREG(HDMI_VACT_SPACE_2_0);
1159 DUMPREG(HDMI_VACT_SPACE_2_1);
1160 DUMPREG(HDMI_VACT_SPACE_3_0);
1161 DUMPREG(HDMI_VACT_SPACE_3_1);
1162 DUMPREG(HDMI_VACT_SPACE_4_0);
1163 DUMPREG(HDMI_VACT_SPACE_4_1);
1164 DUMPREG(HDMI_VACT_SPACE_5_0);
1165 DUMPREG(HDMI_VACT_SPACE_5_1);
1166 DUMPREG(HDMI_VACT_SPACE_6_0);
1167 DUMPREG(HDMI_VACT_SPACE_6_1);
1169 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
1170 DUMPREG(HDMI_TG_CMD);
1171 DUMPREG(HDMI_TG_H_FSZ_L);
1172 DUMPREG(HDMI_TG_H_FSZ_H);
1173 DUMPREG(HDMI_TG_HACT_ST_L);
1174 DUMPREG(HDMI_TG_HACT_ST_H);
1175 DUMPREG(HDMI_TG_HACT_SZ_L);
1176 DUMPREG(HDMI_TG_HACT_SZ_H);
1177 DUMPREG(HDMI_TG_V_FSZ_L);
1178 DUMPREG(HDMI_TG_V_FSZ_H);
1179 DUMPREG(HDMI_TG_VSYNC_L);
1180 DUMPREG(HDMI_TG_VSYNC_H);
1181 DUMPREG(HDMI_TG_VSYNC2_L);
1182 DUMPREG(HDMI_TG_VSYNC2_H);
1183 DUMPREG(HDMI_TG_VACT_ST_L);
1184 DUMPREG(HDMI_TG_VACT_ST_H);
1185 DUMPREG(HDMI_TG_VACT_SZ_L);
1186 DUMPREG(HDMI_TG_VACT_SZ_H);
1187 DUMPREG(HDMI_TG_FIELD_CHG_L);
1188 DUMPREG(HDMI_TG_FIELD_CHG_H);
1189 DUMPREG(HDMI_TG_VACT_ST2_L);
1190 DUMPREG(HDMI_TG_VACT_ST2_H);
1191 DUMPREG(HDMI_TG_VACT_ST3_L);
1192 DUMPREG(HDMI_TG_VACT_ST3_H);
1193 DUMPREG(HDMI_TG_VACT_ST4_L);
1194 DUMPREG(HDMI_TG_VACT_ST4_H);
1195 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
1196 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
1197 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
1198 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
1199 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
1200 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
1201 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
1202 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
1203 DUMPREG(HDMI_TG_3D);
1205 DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix);
1206 DUMPREG(HDMI_AVI_CON);
1207 DUMPREG(HDMI_AVI_HEADER0);
1208 DUMPREG(HDMI_AVI_HEADER1);
1209 DUMPREG(HDMI_AVI_HEADER2);
1210 DUMPREG(HDMI_AVI_CHECK_SUM);
1211 DUMPREG(HDMI_VSI_CON);
1212 DUMPREG(HDMI_VSI_HEADER0);
1213 DUMPREG(HDMI_VSI_HEADER1);
1214 DUMPREG(HDMI_VSI_HEADER2);
1215 for (i = 0; i < 7; ++i)
1216 DUMPREG(HDMI_VSI_DATA(i));
1221 static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
1223 if (hdata->type == HDMI_TYPE13)
1224 hdmi_v13_regs_dump(hdata, prefix);
1226 hdmi_v14_regs_dump(hdata, prefix);
1229 static int hdmi_v13_conf_index(struct drm_display_mode *mode)
1233 for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1234 if (hdmi_v13_confs[i].width == mode->hdisplay &&
1235 hdmi_v13_confs[i].height == mode->vdisplay &&
1236 hdmi_v13_confs[i].vrefresh == mode->vrefresh &&
1237 hdmi_v13_confs[i].interlace ==
1238 ((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1245 static int hdmi_v14_conf_index(struct drm_display_mode *mode)
1249 for (i = 0; i < ARRAY_SIZE(hdmi_confs); ++i)
1250 if (hdmi_confs[i].width == mode->hdisplay &&
1251 hdmi_confs[i].height == mode->vdisplay &&
1252 hdmi_confs[i].vrefresh == mode->vrefresh &&
1253 hdmi_confs[i].interlace ==
1254 ((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1261 static int hdmi_conf_index(struct hdmi_context *hdata,
1262 struct drm_display_mode *mode)
1264 if (hdata->type == HDMI_TYPE13)
1265 return hdmi_v13_conf_index(mode);
1267 return hdmi_v14_conf_index(mode);
1270 static bool hdmi_is_connected(void *ctx)
1272 struct hdmi_context *hdata = ctx;
1277 static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
1280 struct edid *raw_edid;
1281 struct hdmi_context *hdata = ctx;
1283 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1285 if (!hdata->ddc_port)
1288 raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter);
1290 hdata->dvi_mode = !drm_detect_hdmi_monitor(raw_edid);
1291 memcpy(edid, raw_edid, min((1 + raw_edid->extensions)
1292 * EDID_LENGTH, len));
1293 DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
1294 (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
1295 raw_edid->width_cm, raw_edid->height_cm);
1303 static int hdmi_v13_check_timing(struct fb_videomode *check_timing)
1307 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1308 check_timing->xres, check_timing->yres,
1309 check_timing->refresh, (check_timing->vmode &
1310 FB_VMODE_INTERLACED) ? true : false);
1312 for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1313 if (hdmi_v13_confs[i].width == check_timing->xres &&
1314 hdmi_v13_confs[i].height == check_timing->yres &&
1315 hdmi_v13_confs[i].vrefresh == check_timing->refresh &&
1316 hdmi_v13_confs[i].interlace ==
1317 ((check_timing->vmode & FB_VMODE_INTERLACED) ?
1326 static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
1330 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1331 check_timing->xres, check_timing->yres,
1332 check_timing->refresh, (check_timing->vmode &
1333 FB_VMODE_INTERLACED) ? true : false);
1335 for (i = 0; i < ARRAY_SIZE(hdmi_confs); i++)
1336 if (hdmi_confs[i].width == check_timing->xres &&
1337 hdmi_confs[i].height == check_timing->yres &&
1338 hdmi_confs[i].vrefresh == check_timing->refresh &&
1339 hdmi_confs[i].interlace ==
1340 ((check_timing->vmode & FB_VMODE_INTERLACED) ?
1349 static int hdmi_check_timing(void *ctx, void *timing)
1351 struct hdmi_context *hdata = ctx;
1352 struct fb_videomode *check_timing = timing;
1354 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1356 DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres,
1357 check_timing->yres, check_timing->refresh,
1358 check_timing->vmode);
1360 if (hdata->type == HDMI_TYPE13)
1361 return hdmi_v13_check_timing(check_timing);
1363 return hdmi_v14_check_timing(check_timing);
1366 static void hdmi_set_acr(u32 freq, u8 *acr)
1406 acr[2] = cts >> 8 & 0xff;
1407 acr[3] = cts & 0xff;
1410 acr[5] = n >> 8 & 0xff;
1414 static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr)
1416 hdmi_reg_writeb(hdata, HDMI_ACR_N0, acr[6]);
1417 hdmi_reg_writeb(hdata, HDMI_ACR_N1, acr[5]);
1418 hdmi_reg_writeb(hdata, HDMI_ACR_N2, acr[4]);
1419 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS0, acr[3]);
1420 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS1, acr[2]);
1421 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS2, acr[1]);
1422 hdmi_reg_writeb(hdata, HDMI_ACR_CTS0, acr[3]);
1423 hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]);
1424 hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]);
1426 if (hdata->type == HDMI_TYPE13)
1427 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4);
1429 hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1432 static void hdmi_audio_init(struct hdmi_context *hdata)
1434 u32 sample_rate, bits_per_sample, frame_size_code;
1435 u32 data_num, bit_ch, sample_frq;
1439 sample_rate = 44100;
1440 bits_per_sample = 16;
1441 frame_size_code = 0;
1443 switch (bits_per_sample) {
1458 hdmi_set_acr(sample_rate, acr);
1459 hdmi_reg_acr(hdata, acr);
1461 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1462 | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1463 | HDMI_I2S_MUX_ENABLE);
1465 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1466 | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1468 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1470 sample_frq = (sample_rate == 44100) ? 0 :
1471 (sample_rate == 48000) ? 2 :
1472 (sample_rate == 32000) ? 3 :
1473 (sample_rate == 96000) ? 0xa : 0x0;
1475 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1476 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1478 val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1479 hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1481 /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1482 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1483 | HDMI_I2S_SEL_LRCK(6));
1484 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1485 | HDMI_I2S_SEL_SDATA2(4));
1486 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1487 | HDMI_I2S_SEL_SDATA2(2));
1488 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1491 hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1492 | HDMI_I2S_L_CH_LOW_POL);
1493 hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1494 | HDMI_I2S_SET_BIT_CH(bit_ch)
1495 | HDMI_I2S_SET_SDATA_BIT(data_num)
1496 | HDMI_I2S_BASIC_FORMAT);
1498 /* Configure register related to CUV information */
1499 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
1500 | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1501 | HDMI_I2S_COPYRIGHT
1502 | HDMI_I2S_LINEAR_PCM
1503 | HDMI_I2S_CONSUMER_FORMAT);
1504 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1505 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1506 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1507 | HDMI_I2S_SET_SMP_FREQ(sample_frq));
1508 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1509 HDMI_I2S_ORG_SMP_FREQ_44_1
1510 | HDMI_I2S_WORD_LEN_MAX24_24BITS
1511 | HDMI_I2S_WORD_LEN_MAX_24BITS);
1513 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1516 static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1518 if (hdata->dvi_mode)
1521 hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
1522 hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ?
1523 HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1526 static void hdmi_conf_reset(struct hdmi_context *hdata)
1530 if (hdata->type == HDMI_TYPE13)
1531 reg = HDMI_V13_CORE_RSTOUT;
1533 reg = HDMI_CORE_RSTOUT;
1535 /* resetting HDMI core */
1536 hdmi_reg_writemask(hdata, reg, 0, HDMI_CORE_SW_RSTOUT);
1538 hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT);
1542 static void hdmi_conf_init(struct hdmi_context *hdata)
1544 /* disable HPD interrupts */
1545 hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1546 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1548 /* choose HDMI mode */
1549 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1550 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1551 /* disable bluescreen */
1552 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1554 if (hdata->dvi_mode) {
1555 /* choose DVI mode */
1556 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1557 HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1558 hdmi_reg_writeb(hdata, HDMI_CON_2,
1559 HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1562 if (hdata->type == HDMI_TYPE13) {
1563 /* choose bluescreen (fecal) color */
1564 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1565 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1566 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1568 /* enable AVI packet every vsync, fixes purple line problem */
1569 hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1570 /* force RGB, look to CEA-861-D, table 7 for more detail */
1571 hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1572 hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1574 hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1575 hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1576 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1578 /* enable AVI packet every vsync, fixes purple line problem */
1579 hdmi_reg_writeb(hdata, HDMI_AVI_CON, 0x02);
1580 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 2 << 5);
1581 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1585 static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
1587 const struct hdmi_v13_preset_conf *conf =
1588 hdmi_v13_confs[hdata->cur_conf].conf;
1589 const struct hdmi_v13_core_regs *core = &conf->core;
1590 const struct hdmi_v13_tg_regs *tg = &conf->tg;
1593 /* setting core registers */
1594 hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1595 hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1596 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_0, core->v_blank[0]);
1597 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_1, core->v_blank[1]);
1598 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_2, core->v_blank[2]);
1599 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_0, core->h_v_line[0]);
1600 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_1, core->h_v_line[1]);
1601 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_2, core->h_v_line[2]);
1602 hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1603 hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1604 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_0, core->v_blank_f[0]);
1605 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_1, core->v_blank_f[1]);
1606 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_2, core->v_blank_f[2]);
1607 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_0, core->h_sync_gen[0]);
1608 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_1, core->h_sync_gen[1]);
1609 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_2, core->h_sync_gen[2]);
1610 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_0, core->v_sync_gen1[0]);
1611 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_1, core->v_sync_gen1[1]);
1612 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_2, core->v_sync_gen1[2]);
1613 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_0, core->v_sync_gen2[0]);
1614 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_1, core->v_sync_gen2[1]);
1615 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_2, core->v_sync_gen2[2]);
1616 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_0, core->v_sync_gen3[0]);
1617 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]);
1618 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]);
1619 /* Timing generator registers */
1620 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1621 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1622 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1623 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1624 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1625 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1626 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1627 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1628 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1629 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1630 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1631 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1632 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1633 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1634 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1635 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1636 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1637 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1638 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1639 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1640 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1641 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1642 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1643 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1644 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1645 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1646 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1647 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1649 /* waiting for HDMIPHY's PLL to get to steady state */
1650 for (tries = 100; tries; --tries) {
1651 u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS);
1652 if (val & HDMI_PHY_STATUS_READY)
1656 /* steady state not achieved */
1658 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1659 hdmi_regs_dump(hdata, "timing apply");
1662 clk_disable(hdata->res.sclk_hdmi);
1663 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1664 clk_enable(hdata->res.sclk_hdmi);
1666 /* enable HDMI and timing generator */
1667 hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1668 if (core->int_pro_mode[0])
1669 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1672 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1675 static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
1677 const struct hdmi_preset_conf *conf = hdmi_confs[hdata->cur_conf].conf;
1678 const struct hdmi_core_regs *core = &conf->core;
1679 const struct hdmi_tg_regs *tg = &conf->tg;
1682 /* setting core registers */
1683 hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1684 hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1685 hdmi_reg_writeb(hdata, HDMI_V2_BLANK_0, core->v2_blank[0]);
1686 hdmi_reg_writeb(hdata, HDMI_V2_BLANK_1, core->v2_blank[1]);
1687 hdmi_reg_writeb(hdata, HDMI_V1_BLANK_0, core->v1_blank[0]);
1688 hdmi_reg_writeb(hdata, HDMI_V1_BLANK_1, core->v1_blank[1]);
1689 hdmi_reg_writeb(hdata, HDMI_V_LINE_0, core->v_line[0]);
1690 hdmi_reg_writeb(hdata, HDMI_V_LINE_1, core->v_line[1]);
1691 hdmi_reg_writeb(hdata, HDMI_H_LINE_0, core->h_line[0]);
1692 hdmi_reg_writeb(hdata, HDMI_H_LINE_1, core->h_line[1]);
1693 hdmi_reg_writeb(hdata, HDMI_HSYNC_POL, core->hsync_pol[0]);
1694 hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1695 hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1696 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_0, core->v_blank_f0[0]);
1697 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_1, core->v_blank_f0[1]);
1698 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_0, core->v_blank_f1[0]);
1699 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_1, core->v_blank_f1[1]);
1700 hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_0, core->h_sync_start[0]);
1701 hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_1, core->h_sync_start[1]);
1702 hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_0, core->h_sync_end[0]);
1703 hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_1, core->h_sync_end[1]);
1704 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_0,
1705 core->v_sync_line_bef_2[0]);
1706 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_1,
1707 core->v_sync_line_bef_2[1]);
1708 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_0,
1709 core->v_sync_line_bef_1[0]);
1710 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_1,
1711 core->v_sync_line_bef_1[1]);
1712 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_0,
1713 core->v_sync_line_aft_2[0]);
1714 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_1,
1715 core->v_sync_line_aft_2[1]);
1716 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_0,
1717 core->v_sync_line_aft_1[0]);
1718 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_1,
1719 core->v_sync_line_aft_1[1]);
1720 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0,
1721 core->v_sync_line_aft_pxl_2[0]);
1722 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_1,
1723 core->v_sync_line_aft_pxl_2[1]);
1724 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0,
1725 core->v_sync_line_aft_pxl_1[0]);
1726 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_1,
1727 core->v_sync_line_aft_pxl_1[1]);
1728 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_0, core->v_blank_f2[0]);
1729 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_1, core->v_blank_f2[1]);
1730 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_0, core->v_blank_f3[0]);
1731 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_1, core->v_blank_f3[1]);
1732 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_0, core->v_blank_f4[0]);
1733 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_1, core->v_blank_f4[1]);
1734 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_0, core->v_blank_f5[0]);
1735 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_1, core->v_blank_f5[1]);
1736 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_0,
1737 core->v_sync_line_aft_3[0]);
1738 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_1,
1739 core->v_sync_line_aft_3[1]);
1740 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_0,
1741 core->v_sync_line_aft_4[0]);
1742 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_1,
1743 core->v_sync_line_aft_4[1]);
1744 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_0,
1745 core->v_sync_line_aft_5[0]);
1746 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_1,
1747 core->v_sync_line_aft_5[1]);
1748 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_0,
1749 core->v_sync_line_aft_6[0]);
1750 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_1,
1751 core->v_sync_line_aft_6[1]);
1752 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0,
1753 core->v_sync_line_aft_pxl_3[0]);
1754 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_1,
1755 core->v_sync_line_aft_pxl_3[1]);
1756 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0,
1757 core->v_sync_line_aft_pxl_4[0]);
1758 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_1,
1759 core->v_sync_line_aft_pxl_4[1]);
1760 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0,
1761 core->v_sync_line_aft_pxl_5[0]);
1762 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_1,
1763 core->v_sync_line_aft_pxl_5[1]);
1764 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0,
1765 core->v_sync_line_aft_pxl_6[0]);
1766 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_1,
1767 core->v_sync_line_aft_pxl_6[1]);
1768 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_0, core->vact_space_1[0]);
1769 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_1, core->vact_space_1[1]);
1770 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_0, core->vact_space_2[0]);
1771 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_1, core->vact_space_2[1]);
1772 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_0, core->vact_space_3[0]);
1773 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_1, core->vact_space_3[1]);
1774 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_0, core->vact_space_4[0]);
1775 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_1, core->vact_space_4[1]);
1776 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_0, core->vact_space_5[0]);
1777 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_1, core->vact_space_5[1]);
1778 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_0, core->vact_space_6[0]);
1779 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]);
1781 /* Timing generator registers */
1782 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1783 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1784 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1785 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1786 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1787 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1788 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1789 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1790 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1791 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1792 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1793 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1794 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1795 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1796 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1797 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1798 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1799 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1800 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1801 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1802 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3_l);
1803 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3_h);
1804 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4_l);
1805 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4_h);
1806 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1807 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1808 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1809 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1810 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1811 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1812 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1813 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1814 hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d);
1816 /* waiting for HDMIPHY's PLL to get to steady state */
1817 for (tries = 100; tries; --tries) {
1818 u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0);
1819 if (val & HDMI_PHY_STATUS_READY)
1823 /* steady state not achieved */
1825 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1826 hdmi_regs_dump(hdata, "timing apply");
1829 clk_disable(hdata->res.sclk_hdmi);
1830 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1831 clk_enable(hdata->res.sclk_hdmi);
1833 /* enable HDMI and timing generator */
1834 hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1835 if (core->int_pro_mode[0])
1836 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1839 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1842 static void hdmi_timing_apply(struct hdmi_context *hdata)
1844 if (hdata->type == HDMI_TYPE13)
1845 hdmi_v13_timing_apply(hdata);
1847 hdmi_v14_timing_apply(hdata);
1850 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1855 clk_disable(hdata->res.sclk_hdmi);
1856 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel);
1857 clk_enable(hdata->res.sclk_hdmi);
1859 /* operation mode */
1863 if (hdata->hdmiphy_port)
1864 i2c_master_send(hdata->hdmiphy_port, buffer, 2);
1866 if (hdata->type == HDMI_TYPE13)
1867 reg = HDMI_V13_PHY_RSTOUT;
1869 reg = HDMI_PHY_RSTOUT;
1872 hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT);
1874 hdmi_reg_writemask(hdata, reg, 0, HDMI_PHY_SW_RSTOUT);
1878 static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1880 const u8 *hdmiphy_data;
1883 u8 read_buffer[32] = {0, };
1887 if (!hdata->hdmiphy_port) {
1888 DRM_ERROR("hdmiphy is not attached\n");
1893 if (hdata->type == HDMI_TYPE13)
1894 hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data;
1896 hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data;
1898 memcpy(buffer, hdmiphy_data, 32);
1899 ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
1901 DRM_ERROR("failed to configure HDMIPHY via I2C\n");
1907 /* operation mode */
1908 operation[0] = 0x1f;
1909 operation[1] = 0x80;
1911 ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
1913 DRM_ERROR("failed to enable hdmiphy\n");
1917 ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
1919 DRM_ERROR("failed to read hdmiphy config\n");
1923 for (i = 0; i < ret; i++)
1924 DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
1925 "recv [0x%02x]\n", i, buffer[i], read_buffer[i]);
1928 static void hdmi_conf_apply(struct hdmi_context *hdata)
1930 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1932 hdmiphy_conf_reset(hdata);
1933 hdmiphy_conf_apply(hdata);
1935 mutex_lock(&hdata->hdmi_mutex);
1936 hdmi_conf_reset(hdata);
1937 hdmi_conf_init(hdata);
1938 mutex_unlock(&hdata->hdmi_mutex);
1940 hdmi_audio_init(hdata);
1942 /* setting core registers */
1943 hdmi_timing_apply(hdata);
1944 hdmi_audio_control(hdata, true);
1946 hdmi_regs_dump(hdata, "start");
1949 static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
1950 const struct drm_display_mode *mode,
1951 struct drm_display_mode *adjusted_mode)
1953 struct drm_display_mode *m;
1954 struct hdmi_context *hdata = ctx;
1957 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1959 drm_mode_set_crtcinfo(adjusted_mode, 0);
1961 if (hdata->type == HDMI_TYPE13)
1962 index = hdmi_v13_conf_index(adjusted_mode);
1964 index = hdmi_v14_conf_index(adjusted_mode);
1966 /* just return if user desired mode exists. */
1971 * otherwise, find the most suitable mode among modes and change it
1974 list_for_each_entry(m, &connector->modes, head) {
1975 if (hdata->type == HDMI_TYPE13)
1976 index = hdmi_v13_conf_index(m);
1978 index = hdmi_v14_conf_index(m);
1981 DRM_INFO("desired mode doesn't exist so\n");
1982 DRM_INFO("use the most suitable mode among modes.\n");
1983 memcpy(adjusted_mode, m, sizeof(*m));
1989 static void hdmi_mode_set(void *ctx, void *mode)
1991 struct hdmi_context *hdata = ctx;
1994 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1996 conf_idx = hdmi_conf_index(hdata, mode);
1998 hdata->cur_conf = conf_idx;
2000 DRM_DEBUG_KMS("not supported mode\n");
2003 static void hdmi_get_max_resol(void *ctx, unsigned int *width,
2004 unsigned int *height)
2006 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2009 *height = MAX_HEIGHT;
2012 static void hdmi_commit(void *ctx)
2014 struct hdmi_context *hdata = ctx;
2016 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2018 hdmi_conf_apply(hdata);
2021 static void hdmi_poweron(struct hdmi_context *hdata)
2023 struct hdmi_resources *res = &hdata->res;
2025 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2027 mutex_lock(&hdata->hdmi_mutex);
2028 if (hdata->powered) {
2029 mutex_unlock(&hdata->hdmi_mutex);
2033 hdata->powered = true;
2035 mutex_unlock(&hdata->hdmi_mutex);
2037 pm_runtime_get_sync(hdata->dev);
2039 regulator_bulk_enable(res->regul_count, res->regul_bulk);
2040 clk_enable(res->hdmiphy);
2041 clk_enable(res->hdmi);
2042 clk_enable(res->sclk_hdmi);
2045 static void hdmi_poweroff(struct hdmi_context *hdata)
2047 struct hdmi_resources *res = &hdata->res;
2049 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2051 mutex_lock(&hdata->hdmi_mutex);
2052 if (!hdata->powered)
2054 mutex_unlock(&hdata->hdmi_mutex);
2057 * The TV power domain needs any condition of hdmiphy to turn off and
2058 * its reset state seems to meet the condition.
2060 hdmiphy_conf_reset(hdata);
2062 clk_disable(res->sclk_hdmi);
2063 clk_disable(res->hdmi);
2064 clk_disable(res->hdmiphy);
2065 regulator_bulk_disable(res->regul_count, res->regul_bulk);
2067 pm_runtime_put_sync(hdata->dev);
2069 mutex_lock(&hdata->hdmi_mutex);
2071 hdata->powered = false;
2074 mutex_unlock(&hdata->hdmi_mutex);
2077 static void hdmi_dpms(void *ctx, int mode)
2079 struct hdmi_context *hdata = ctx;
2081 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2084 case DRM_MODE_DPMS_ON:
2085 hdmi_poweron(hdata);
2087 case DRM_MODE_DPMS_STANDBY:
2088 case DRM_MODE_DPMS_SUSPEND:
2089 case DRM_MODE_DPMS_OFF:
2090 hdmi_poweroff(hdata);
2093 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
2098 static struct exynos_hdmi_ops hdmi_ops = {
2100 .is_connected = hdmi_is_connected,
2101 .get_edid = hdmi_get_edid,
2102 .check_timing = hdmi_check_timing,
2105 .mode_fixup = hdmi_mode_fixup,
2106 .mode_set = hdmi_mode_set,
2107 .get_max_resol = hdmi_get_max_resol,
2108 .commit = hdmi_commit,
2112 static irqreturn_t hdmi_external_irq_thread(int irq, void *arg)
2114 struct exynos_drm_hdmi_context *ctx = arg;
2115 struct hdmi_context *hdata = ctx->ctx;
2117 mutex_lock(&hdata->hdmi_mutex);
2118 hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2119 mutex_unlock(&hdata->hdmi_mutex);
2122 drm_helper_hpd_irq_event(ctx->drm_dev);
2127 static irqreturn_t hdmi_internal_irq_thread(int irq, void *arg)
2129 struct exynos_drm_hdmi_context *ctx = arg;
2130 struct hdmi_context *hdata = ctx->ctx;
2133 intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG);
2134 /* clearing flags for HPD plug/unplug */
2135 if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) {
2136 DRM_DEBUG_KMS("unplugged\n");
2137 hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
2138 HDMI_INTC_FLAG_HPD_UNPLUG);
2140 if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) {
2141 DRM_DEBUG_KMS("plugged\n");
2142 hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
2143 HDMI_INTC_FLAG_HPD_PLUG);
2147 drm_helper_hpd_irq_event(ctx->drm_dev);
2152 static int __devinit hdmi_resources_init(struct hdmi_context *hdata)
2154 struct device *dev = hdata->dev;
2155 struct hdmi_resources *res = &hdata->res;
2156 static char *supply[] = {
2164 DRM_DEBUG_KMS("HDMI resource init\n");
2166 memset(res, 0, sizeof(*res));
2168 /* get clocks, power */
2169 res->hdmi = clk_get(dev, "hdmi");
2170 if (IS_ERR_OR_NULL(res->hdmi)) {
2171 DRM_ERROR("failed to get clock 'hdmi'\n");
2174 res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
2175 if (IS_ERR_OR_NULL(res->sclk_hdmi)) {
2176 DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
2179 res->sclk_pixel = clk_get(dev, "sclk_pixel");
2180 if (IS_ERR_OR_NULL(res->sclk_pixel)) {
2181 DRM_ERROR("failed to get clock 'sclk_pixel'\n");
2184 res->sclk_hdmiphy = clk_get(dev, "sclk_hdmiphy");
2185 if (IS_ERR_OR_NULL(res->sclk_hdmiphy)) {
2186 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
2189 res->hdmiphy = clk_get(dev, "hdmiphy");
2190 if (IS_ERR_OR_NULL(res->hdmiphy)) {
2191 DRM_ERROR("failed to get clock 'hdmiphy'\n");
2195 clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
2197 res->regul_bulk = kzalloc(ARRAY_SIZE(supply) *
2198 sizeof(res->regul_bulk[0]), GFP_KERNEL);
2199 if (!res->regul_bulk) {
2200 DRM_ERROR("failed to get memory for regulators\n");
2203 for (i = 0; i < ARRAY_SIZE(supply); ++i) {
2204 res->regul_bulk[i].supply = supply[i];
2205 res->regul_bulk[i].consumer = NULL;
2207 ret = regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
2209 DRM_ERROR("failed to get regulators\n");
2212 res->regul_count = ARRAY_SIZE(supply);
2216 DRM_ERROR("HDMI resource init - failed\n");
2220 static int hdmi_resources_cleanup(struct hdmi_context *hdata)
2222 struct hdmi_resources *res = &hdata->res;
2224 regulator_bulk_free(res->regul_count, res->regul_bulk);
2225 /* kfree is NULL-safe */
2226 kfree(res->regul_bulk);
2227 if (!IS_ERR_OR_NULL(res->hdmiphy))
2228 clk_put(res->hdmiphy);
2229 if (!IS_ERR_OR_NULL(res->sclk_hdmiphy))
2230 clk_put(res->sclk_hdmiphy);
2231 if (!IS_ERR_OR_NULL(res->sclk_pixel))
2232 clk_put(res->sclk_pixel);
2233 if (!IS_ERR_OR_NULL(res->sclk_hdmi))
2234 clk_put(res->sclk_hdmi);
2235 if (!IS_ERR_OR_NULL(res->hdmi))
2237 memset(res, 0, sizeof(*res));
2242 static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
2244 void hdmi_attach_ddc_client(struct i2c_client *ddc)
2250 void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
2253 hdmi_hdmiphy = hdmiphy;
2257 static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
2258 (struct device *dev)
2260 struct device_node *np = dev->of_node;
2261 struct s5p_hdmi_platform_data *pd;
2262 enum of_gpio_flags flags;
2265 pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
2267 DRM_ERROR("memory allocation for pdata failed\n");
2271 if (!of_find_property(np, "hpd-gpio", &value)) {
2272 DRM_ERROR("no hpd gpio property found\n");
2276 pd->hpd_gpio = of_get_named_gpio_flags(np, "hpd-gpio", 0, &flags);
2284 static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
2285 (struct device *dev)
2291 static struct platform_device_id hdmi_driver_types[] = {
2293 .name = "s5pv210-hdmi",
2294 .driver_data = HDMI_TYPE13,
2296 .name = "exynos4-hdmi",
2297 .driver_data = HDMI_TYPE13,
2299 .name = "exynos4-hdmi14",
2300 .driver_data = HDMI_TYPE14,
2302 .name = "exynos5-hdmi",
2303 .driver_data = HDMI_TYPE14,
2309 static struct of_device_id hdmi_match_types[] = {
2311 .compatible = "samsung,exynos5-hdmi",
2312 .data = (void *)HDMI_TYPE14,
2318 static int __devinit hdmi_probe(struct platform_device *pdev)
2320 struct device *dev = &pdev->dev;
2321 struct exynos_drm_hdmi_context *drm_hdmi_ctx;
2322 struct hdmi_context *hdata;
2323 struct s5p_hdmi_platform_data *pdata;
2324 struct resource *res;
2327 DRM_DEBUG_KMS("[%d]\n", __LINE__);
2329 if (pdev->dev.of_node) {
2330 pdata = drm_hdmi_dt_parse_pdata(dev);
2331 if (IS_ERR(pdata)) {
2332 DRM_ERROR("failed to parse dt\n");
2333 return PTR_ERR(pdata);
2336 pdata = pdev->dev.platform_data;
2340 DRM_ERROR("no platform data specified\n");
2344 drm_hdmi_ctx = devm_kzalloc(&pdev->dev, sizeof(*drm_hdmi_ctx),
2346 if (!drm_hdmi_ctx) {
2347 DRM_ERROR("failed to allocate common hdmi context.\n");
2351 hdata = devm_kzalloc(&pdev->dev, sizeof(struct hdmi_context),
2354 DRM_ERROR("out of memory\n");
2358 mutex_init(&hdata->hdmi_mutex);
2360 drm_hdmi_ctx->ctx = (void *)hdata;
2361 hdata->parent_ctx = (void *)drm_hdmi_ctx;
2363 platform_set_drvdata(pdev, drm_hdmi_ctx);
2366 const struct of_device_id *match;
2367 match = of_match_node(of_match_ptr(hdmi_match_types),
2369 hdata->type = (enum hdmi_type)match->data;
2371 hdata->type = (enum hdmi_type)platform_get_device_id
2372 (pdev)->driver_data;
2375 hdata->hpd_gpio = pdata->hpd_gpio;
2378 ret = hdmi_resources_init(hdata);
2382 DRM_ERROR("hdmi_resources_init failed\n");
2386 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2388 DRM_ERROR("failed to find registers\n");
2393 hdata->regs = devm_request_and_ioremap(&pdev->dev, res);
2395 DRM_ERROR("failed to map registers\n");
2400 ret = gpio_request(hdata->hpd_gpio, "HPD");
2402 DRM_ERROR("failed to request HPD gpio\n");
2406 /* DDC i2c driver */
2407 if (i2c_add_driver(&ddc_driver)) {
2408 DRM_ERROR("failed to register ddc i2c driver\n");
2413 hdata->ddc_port = hdmi_ddc;
2415 /* hdmiphy i2c driver */
2416 if (i2c_add_driver(&hdmiphy_driver)) {
2417 DRM_ERROR("failed to register hdmiphy i2c driver\n");
2422 hdata->hdmiphy_port = hdmi_hdmiphy;
2424 hdata->external_irq = gpio_to_irq(hdata->hpd_gpio);
2425 if (hdata->external_irq < 0) {
2426 DRM_ERROR("failed to get GPIO external irq\n");
2427 ret = hdata->external_irq;
2431 hdata->internal_irq = platform_get_irq(pdev, 0);
2432 if (hdata->internal_irq < 0) {
2433 DRM_ERROR("failed to get platform internal irq\n");
2434 ret = hdata->internal_irq;
2438 hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2440 ret = request_threaded_irq(hdata->external_irq, NULL,
2441 hdmi_external_irq_thread, IRQF_TRIGGER_RISING |
2442 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
2443 "hdmi_external", drm_hdmi_ctx);
2445 DRM_ERROR("failed to register hdmi external interrupt\n");
2449 ret = request_threaded_irq(hdata->internal_irq, NULL,
2450 hdmi_internal_irq_thread, IRQF_ONESHOT,
2451 "hdmi_internal", drm_hdmi_ctx);
2453 DRM_ERROR("failed to register hdmi internal interrupt\n");
2457 /* Attach HDMI Driver to common hdmi. */
2458 exynos_hdmi_drv_attach(drm_hdmi_ctx);
2460 /* register specific callbacks to common hdmi. */
2461 exynos_hdmi_ops_register(&hdmi_ops);
2463 pm_runtime_enable(dev);
2468 free_irq(hdata->external_irq, drm_hdmi_ctx);
2470 i2c_del_driver(&hdmiphy_driver);
2472 i2c_del_driver(&ddc_driver);
2474 gpio_free(hdata->hpd_gpio);
2476 hdmi_resources_cleanup(hdata);
2481 static int __devexit hdmi_remove(struct platform_device *pdev)
2483 struct device *dev = &pdev->dev;
2484 struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev);
2485 struct hdmi_context *hdata = ctx->ctx;
2487 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2489 pm_runtime_disable(dev);
2491 free_irq(hdata->internal_irq, hdata);
2492 free_irq(hdata->external_irq, hdata);
2494 gpio_free(hdata->hpd_gpio);
2496 hdmi_resources_cleanup(hdata);
2498 /* hdmiphy i2c driver */
2499 i2c_del_driver(&hdmiphy_driver);
2500 /* DDC i2c driver */
2501 i2c_del_driver(&ddc_driver);
2506 #ifdef CONFIG_PM_SLEEP
2507 static int hdmi_suspend(struct device *dev)
2509 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2510 struct hdmi_context *hdata = ctx->ctx;
2512 disable_irq(hdata->internal_irq);
2513 disable_irq(hdata->external_irq);
2517 drm_helper_hpd_irq_event(ctx->drm_dev);
2519 hdmi_poweroff(hdata);
2524 static int hdmi_resume(struct device *dev)
2526 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2527 struct hdmi_context *hdata = ctx->ctx;
2529 enable_irq(hdata->external_irq);
2530 enable_irq(hdata->internal_irq);
2535 static SIMPLE_DEV_PM_OPS(hdmi_pm_ops, hdmi_suspend, hdmi_resume);
2537 struct platform_driver hdmi_driver = {
2538 .probe = hdmi_probe,
2539 .remove = __devexit_p(hdmi_remove),
2540 .id_table = hdmi_driver_types,
2542 .name = "exynos-hdmi",
2543 .owner = THIS_MODULE,
2545 .of_match_table = hdmi_match_types,