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;
60 struct fb_videomode *default_timing;
61 unsigned int is_v13:1;
62 unsigned int default_win;
63 unsigned int default_bpp;
67 struct resource *regs_res;
70 struct workqueue_struct *wq;
71 struct work_struct hotplug_work;
73 struct i2c_client *ddc_port;
74 struct i2c_client *hdmiphy_port;
76 /* current hdmiphy conf index */
79 struct hdmi_resources res;
83 /* HDMI Version 1.3 */
84 static const u8 hdmiphy_v13_conf27[32] = {
85 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
86 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
87 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
88 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
91 static const u8 hdmiphy_v13_conf27_027[32] = {
92 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
93 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
94 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
95 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
98 static const u8 hdmiphy_v13_conf74_175[32] = {
99 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
100 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
101 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
102 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
105 static const u8 hdmiphy_v13_conf74_25[32] = {
106 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
107 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
108 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
109 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
112 static const u8 hdmiphy_v13_conf148_5[32] = {
113 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
114 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
115 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
116 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
119 struct hdmi_v13_tg_regs {
151 struct hdmi_v13_core_regs {
164 struct hdmi_v13_preset_conf {
165 struct hdmi_v13_core_regs core;
166 struct hdmi_v13_tg_regs tg;
169 struct hdmi_v13_conf {
174 const u8 *hdmiphy_data;
175 const struct hdmi_v13_preset_conf *conf;
178 static const struct hdmi_v13_preset_conf hdmi_v13_conf_480p = {
180 .h_blank = {0x8a, 0x00},
181 .v_blank = {0x0d, 0x6a, 0x01},
182 .h_v_line = {0x0d, 0xa2, 0x35},
184 .int_pro_mode = {0x00},
185 .v_blank_f = {0x00, 0x00, 0x00},
186 .h_sync_gen = {0x0e, 0x30, 0x11},
187 .v_sync_gen1 = {0x0f, 0x90, 0x00},
188 /* other don't care */
192 0x5a, 0x03, /* h_fsz */
193 0x8a, 0x00, 0xd0, 0x02, /* hact */
194 0x0d, 0x02, /* v_fsz */
195 0x01, 0x00, 0x33, 0x02, /* vsync */
196 0x2d, 0x00, 0xe0, 0x01, /* vact */
197 0x33, 0x02, /* field_chg */
198 0x49, 0x02, /* vact_st2 */
199 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
200 0x01, 0x00, 0x33, 0x02, /* field top/bot */
204 static const struct hdmi_v13_preset_conf hdmi_v13_conf_720p60 = {
206 .h_blank = {0x72, 0x01},
207 .v_blank = {0xee, 0xf2, 0x00},
208 .h_v_line = {0xee, 0x22, 0x67},
210 .int_pro_mode = {0x00},
211 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
212 .h_sync_gen = {0x6c, 0x50, 0x02},
213 .v_sync_gen1 = {0x0a, 0x50, 0x00},
214 .v_sync_gen2 = {0x01, 0x10, 0x00},
215 .v_sync_gen3 = {0x01, 0x10, 0x00},
216 /* other don't care */
220 0x72, 0x06, /* h_fsz */
221 0x71, 0x01, 0x01, 0x05, /* hact */
222 0xee, 0x02, /* v_fsz */
223 0x01, 0x00, 0x33, 0x02, /* vsync */
224 0x1e, 0x00, 0xd0, 0x02, /* vact */
225 0x33, 0x02, /* field_chg */
226 0x49, 0x02, /* vact_st2 */
227 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
228 0x01, 0x00, 0x33, 0x02, /* field top/bot */
232 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i50 = {
234 .h_blank = {0xd0, 0x02},
235 .v_blank = {0x32, 0xB2, 0x00},
236 .h_v_line = {0x65, 0x04, 0xa5},
238 .int_pro_mode = {0x01},
239 .v_blank_f = {0x49, 0x2A, 0x23},
240 .h_sync_gen = {0x0E, 0xEA, 0x08},
241 .v_sync_gen1 = {0x07, 0x20, 0x00},
242 .v_sync_gen2 = {0x39, 0x42, 0x23},
243 .v_sync_gen3 = {0x38, 0x87, 0x73},
244 /* other don't care */
248 0x50, 0x0A, /* h_fsz */
249 0xCF, 0x02, 0x81, 0x07, /* hact */
250 0x65, 0x04, /* v_fsz */
251 0x01, 0x00, 0x33, 0x02, /* vsync */
252 0x16, 0x00, 0x1c, 0x02, /* vact */
253 0x33, 0x02, /* field_chg */
254 0x49, 0x02, /* vact_st2 */
255 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
256 0x01, 0x00, 0x33, 0x02, /* field top/bot */
260 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p50 = {
262 .h_blank = {0xd0, 0x02},
263 .v_blank = {0x65, 0x6c, 0x01},
264 .h_v_line = {0x65, 0x04, 0xa5},
266 .int_pro_mode = {0x00},
267 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
268 .h_sync_gen = {0x0e, 0xea, 0x08},
269 .v_sync_gen1 = {0x09, 0x40, 0x00},
270 .v_sync_gen2 = {0x01, 0x10, 0x00},
271 .v_sync_gen3 = {0x01, 0x10, 0x00},
272 /* other don't care */
276 0x50, 0x0A, /* h_fsz */
277 0xCF, 0x02, 0x81, 0x07, /* hact */
278 0x65, 0x04, /* v_fsz */
279 0x01, 0x00, 0x33, 0x02, /* vsync */
280 0x2d, 0x00, 0x38, 0x04, /* vact */
281 0x33, 0x02, /* field_chg */
282 0x48, 0x02, /* vact_st2 */
283 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
284 0x01, 0x00, 0x33, 0x02, /* field top/bot */
288 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i60 = {
290 .h_blank = {0x18, 0x01},
291 .v_blank = {0x32, 0xB2, 0x00},
292 .h_v_line = {0x65, 0x84, 0x89},
294 .int_pro_mode = {0x01},
295 .v_blank_f = {0x49, 0x2A, 0x23},
296 .h_sync_gen = {0x56, 0x08, 0x02},
297 .v_sync_gen1 = {0x07, 0x20, 0x00},
298 .v_sync_gen2 = {0x39, 0x42, 0x23},
299 .v_sync_gen3 = {0xa4, 0x44, 0x4a},
300 /* other don't care */
304 0x98, 0x08, /* h_fsz */
305 0x17, 0x01, 0x81, 0x07, /* hact */
306 0x65, 0x04, /* v_fsz */
307 0x01, 0x00, 0x33, 0x02, /* vsync */
308 0x16, 0x00, 0x1c, 0x02, /* vact */
309 0x33, 0x02, /* field_chg */
310 0x49, 0x02, /* vact_st2 */
311 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
312 0x01, 0x00, 0x33, 0x02, /* field top/bot */
316 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60 = {
318 .h_blank = {0x18, 0x01},
319 .v_blank = {0x65, 0x6c, 0x01},
320 .h_v_line = {0x65, 0x84, 0x89},
322 .int_pro_mode = {0x00},
323 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
324 .h_sync_gen = {0x56, 0x08, 0x02},
325 .v_sync_gen1 = {0x09, 0x40, 0x00},
326 .v_sync_gen2 = {0x01, 0x10, 0x00},
327 .v_sync_gen3 = {0x01, 0x10, 0x00},
328 /* other don't care */
332 0x98, 0x08, /* h_fsz */
333 0x17, 0x01, 0x81, 0x07, /* hact */
334 0x65, 0x04, /* v_fsz */
335 0x01, 0x00, 0x33, 0x02, /* vsync */
336 0x2d, 0x00, 0x38, 0x04, /* vact */
337 0x33, 0x02, /* field_chg */
338 0x48, 0x02, /* vact_st2 */
339 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
340 0x01, 0x00, 0x33, 0x02, /* field top/bot */
344 static const struct hdmi_v13_conf hdmi_v13_confs[] = {
345 { 1280, 720, 60, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 },
346 { 1280, 720, 50, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 },
347 { 720, 480, 60, false, hdmiphy_v13_conf27_027, &hdmi_v13_conf_480p },
348 { 1920, 1080, 50, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i50 },
349 { 1920, 1080, 50, false, hdmiphy_v13_conf148_5,
350 &hdmi_v13_conf_1080p50 },
351 { 1920, 1080, 60, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i60 },
352 { 1920, 1080, 60, false, hdmiphy_v13_conf148_5,
353 &hdmi_v13_conf_1080p60 },
356 /* HDMI Version 1.4 */
357 static const u8 hdmiphy_conf27_027[32] = {
358 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
359 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
360 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
361 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
364 static const u8 hdmiphy_conf74_25[32] = {
365 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
366 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
367 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
368 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
371 static const u8 hdmiphy_conf148_5[32] = {
372 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
373 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
374 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
375 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
378 struct hdmi_tg_regs {
415 struct hdmi_core_regs {
428 u8 v_sync_line_bef_2[2];
429 u8 v_sync_line_bef_1[2];
430 u8 v_sync_line_aft_2[2];
431 u8 v_sync_line_aft_1[2];
432 u8 v_sync_line_aft_pxl_2[2];
433 u8 v_sync_line_aft_pxl_1[2];
434 u8 v_blank_f2[2]; /* for 3D mode */
435 u8 v_blank_f3[2]; /* for 3D mode */
436 u8 v_blank_f4[2]; /* for 3D mode */
437 u8 v_blank_f5[2]; /* for 3D mode */
438 u8 v_sync_line_aft_3[2];
439 u8 v_sync_line_aft_4[2];
440 u8 v_sync_line_aft_5[2];
441 u8 v_sync_line_aft_6[2];
442 u8 v_sync_line_aft_pxl_3[2];
443 u8 v_sync_line_aft_pxl_4[2];
444 u8 v_sync_line_aft_pxl_5[2];
445 u8 v_sync_line_aft_pxl_6[2];
454 struct hdmi_preset_conf {
455 struct hdmi_core_regs core;
456 struct hdmi_tg_regs tg;
464 const u8 *hdmiphy_data;
465 const struct hdmi_preset_conf *conf;
468 static const struct hdmi_preset_conf hdmi_conf_480p60 = {
470 .h_blank = {0x8a, 0x00},
471 .v2_blank = {0x0d, 0x02},
472 .v1_blank = {0x2d, 0x00},
473 .v_line = {0x0d, 0x02},
474 .h_line = {0x5a, 0x03},
477 .int_pro_mode = {0x00},
478 .v_blank_f0 = {0xff, 0xff},
479 .v_blank_f1 = {0xff, 0xff},
480 .h_sync_start = {0x0e, 0x00},
481 .h_sync_end = {0x4c, 0x00},
482 .v_sync_line_bef_2 = {0x0f, 0x00},
483 .v_sync_line_bef_1 = {0x09, 0x00},
484 .v_sync_line_aft_2 = {0xff, 0xff},
485 .v_sync_line_aft_1 = {0xff, 0xff},
486 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
487 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
488 .v_blank_f2 = {0xff, 0xff},
489 .v_blank_f3 = {0xff, 0xff},
490 .v_blank_f4 = {0xff, 0xff},
491 .v_blank_f5 = {0xff, 0xff},
492 .v_sync_line_aft_3 = {0xff, 0xff},
493 .v_sync_line_aft_4 = {0xff, 0xff},
494 .v_sync_line_aft_5 = {0xff, 0xff},
495 .v_sync_line_aft_6 = {0xff, 0xff},
496 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
497 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
498 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
499 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
500 .vact_space_1 = {0xff, 0xff},
501 .vact_space_2 = {0xff, 0xff},
502 .vact_space_3 = {0xff, 0xff},
503 .vact_space_4 = {0xff, 0xff},
504 .vact_space_5 = {0xff, 0xff},
505 .vact_space_6 = {0xff, 0xff},
506 /* other don't care */
510 0x5a, 0x03, /* h_fsz */
511 0x8a, 0x00, 0xd0, 0x02, /* hact */
512 0x0d, 0x02, /* v_fsz */
513 0x01, 0x00, 0x33, 0x02, /* vsync */
514 0x2d, 0x00, 0xe0, 0x01, /* vact */
515 0x33, 0x02, /* field_chg */
516 0x48, 0x02, /* vact_st2 */
517 0x00, 0x00, /* vact_st3 */
518 0x00, 0x00, /* vact_st4 */
519 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
520 0x01, 0x00, 0x33, 0x02, /* field top/bot */
525 static const struct hdmi_preset_conf hdmi_conf_720p50 = {
527 .h_blank = {0xbc, 0x02},
528 .v2_blank = {0xee, 0x02},
529 .v1_blank = {0x1e, 0x00},
530 .v_line = {0xee, 0x02},
531 .h_line = {0xbc, 0x07},
534 .int_pro_mode = {0x00},
535 .v_blank_f0 = {0xff, 0xff},
536 .v_blank_f1 = {0xff, 0xff},
537 .h_sync_start = {0xb6, 0x01},
538 .h_sync_end = {0xde, 0x01},
539 .v_sync_line_bef_2 = {0x0a, 0x00},
540 .v_sync_line_bef_1 = {0x05, 0x00},
541 .v_sync_line_aft_2 = {0xff, 0xff},
542 .v_sync_line_aft_1 = {0xff, 0xff},
543 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
544 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
545 .v_blank_f2 = {0xff, 0xff},
546 .v_blank_f3 = {0xff, 0xff},
547 .v_blank_f4 = {0xff, 0xff},
548 .v_blank_f5 = {0xff, 0xff},
549 .v_sync_line_aft_3 = {0xff, 0xff},
550 .v_sync_line_aft_4 = {0xff, 0xff},
551 .v_sync_line_aft_5 = {0xff, 0xff},
552 .v_sync_line_aft_6 = {0xff, 0xff},
553 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
554 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
555 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
556 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
557 .vact_space_1 = {0xff, 0xff},
558 .vact_space_2 = {0xff, 0xff},
559 .vact_space_3 = {0xff, 0xff},
560 .vact_space_4 = {0xff, 0xff},
561 .vact_space_5 = {0xff, 0xff},
562 .vact_space_6 = {0xff, 0xff},
563 /* other don't care */
567 0xbc, 0x07, /* h_fsz */
568 0xbc, 0x02, 0x00, 0x05, /* hact */
569 0xee, 0x02, /* v_fsz */
570 0x01, 0x00, 0x33, 0x02, /* vsync */
571 0x1e, 0x00, 0xd0, 0x02, /* vact */
572 0x33, 0x02, /* field_chg */
573 0x48, 0x02, /* vact_st2 */
574 0x00, 0x00, /* vact_st3 */
575 0x00, 0x00, /* vact_st4 */
576 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
577 0x01, 0x00, 0x33, 0x02, /* field top/bot */
582 static const struct hdmi_preset_conf hdmi_conf_720p60 = {
584 .h_blank = {0x72, 0x01},
585 .v2_blank = {0xee, 0x02},
586 .v1_blank = {0x1e, 0x00},
587 .v_line = {0xee, 0x02},
588 .h_line = {0x72, 0x06},
591 .int_pro_mode = {0x00},
592 .v_blank_f0 = {0xff, 0xff},
593 .v_blank_f1 = {0xff, 0xff},
594 .h_sync_start = {0x6c, 0x00},
595 .h_sync_end = {0x94, 0x00},
596 .v_sync_line_bef_2 = {0x0a, 0x00},
597 .v_sync_line_bef_1 = {0x05, 0x00},
598 .v_sync_line_aft_2 = {0xff, 0xff},
599 .v_sync_line_aft_1 = {0xff, 0xff},
600 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
601 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
602 .v_blank_f2 = {0xff, 0xff},
603 .v_blank_f3 = {0xff, 0xff},
604 .v_blank_f4 = {0xff, 0xff},
605 .v_blank_f5 = {0xff, 0xff},
606 .v_sync_line_aft_3 = {0xff, 0xff},
607 .v_sync_line_aft_4 = {0xff, 0xff},
608 .v_sync_line_aft_5 = {0xff, 0xff},
609 .v_sync_line_aft_6 = {0xff, 0xff},
610 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
611 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
612 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
613 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
614 .vact_space_1 = {0xff, 0xff},
615 .vact_space_2 = {0xff, 0xff},
616 .vact_space_3 = {0xff, 0xff},
617 .vact_space_4 = {0xff, 0xff},
618 .vact_space_5 = {0xff, 0xff},
619 .vact_space_6 = {0xff, 0xff},
620 /* other don't care */
624 0x72, 0x06, /* h_fsz */
625 0x72, 0x01, 0x00, 0x05, /* hact */
626 0xee, 0x02, /* v_fsz */
627 0x01, 0x00, 0x33, 0x02, /* vsync */
628 0x1e, 0x00, 0xd0, 0x02, /* vact */
629 0x33, 0x02, /* field_chg */
630 0x48, 0x02, /* vact_st2 */
631 0x00, 0x00, /* vact_st3 */
632 0x00, 0x00, /* vact_st4 */
633 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
634 0x01, 0x00, 0x33, 0x02, /* field top/bot */
639 static const struct hdmi_preset_conf hdmi_conf_1080i50 = {
641 .h_blank = {0xd0, 0x02},
642 .v2_blank = {0x32, 0x02},
643 .v1_blank = {0x16, 0x00},
644 .v_line = {0x65, 0x04},
645 .h_line = {0x50, 0x0a},
648 .int_pro_mode = {0x01},
649 .v_blank_f0 = {0x49, 0x02},
650 .v_blank_f1 = {0x65, 0x04},
651 .h_sync_start = {0x0e, 0x02},
652 .h_sync_end = {0x3a, 0x02},
653 .v_sync_line_bef_2 = {0x07, 0x00},
654 .v_sync_line_bef_1 = {0x02, 0x00},
655 .v_sync_line_aft_2 = {0x39, 0x02},
656 .v_sync_line_aft_1 = {0x34, 0x02},
657 .v_sync_line_aft_pxl_2 = {0x38, 0x07},
658 .v_sync_line_aft_pxl_1 = {0x38, 0x07},
659 .v_blank_f2 = {0xff, 0xff},
660 .v_blank_f3 = {0xff, 0xff},
661 .v_blank_f4 = {0xff, 0xff},
662 .v_blank_f5 = {0xff, 0xff},
663 .v_sync_line_aft_3 = {0xff, 0xff},
664 .v_sync_line_aft_4 = {0xff, 0xff},
665 .v_sync_line_aft_5 = {0xff, 0xff},
666 .v_sync_line_aft_6 = {0xff, 0xff},
667 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
668 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
669 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
670 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
671 .vact_space_1 = {0xff, 0xff},
672 .vact_space_2 = {0xff, 0xff},
673 .vact_space_3 = {0xff, 0xff},
674 .vact_space_4 = {0xff, 0xff},
675 .vact_space_5 = {0xff, 0xff},
676 .vact_space_6 = {0xff, 0xff},
677 /* other don't care */
681 0x50, 0x0a, /* h_fsz */
682 0xd0, 0x02, 0x80, 0x07, /* hact */
683 0x65, 0x04, /* v_fsz */
684 0x01, 0x00, 0x33, 0x02, /* vsync */
685 0x16, 0x00, 0x1c, 0x02, /* vact */
686 0x33, 0x02, /* field_chg */
687 0x49, 0x02, /* vact_st2 */
688 0x00, 0x00, /* vact_st3 */
689 0x00, 0x00, /* vact_st4 */
690 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
691 0x01, 0x00, 0x33, 0x02, /* field top/bot */
696 static const struct hdmi_preset_conf hdmi_conf_1080i60 = {
698 .h_blank = {0x18, 0x01},
699 .v2_blank = {0x32, 0x02},
700 .v1_blank = {0x16, 0x00},
701 .v_line = {0x65, 0x04},
702 .h_line = {0x98, 0x08},
705 .int_pro_mode = {0x01},
706 .v_blank_f0 = {0x49, 0x02},
707 .v_blank_f1 = {0x65, 0x04},
708 .h_sync_start = {0x56, 0x00},
709 .h_sync_end = {0x82, 0x00},
710 .v_sync_line_bef_2 = {0x07, 0x00},
711 .v_sync_line_bef_1 = {0x02, 0x00},
712 .v_sync_line_aft_2 = {0x39, 0x02},
713 .v_sync_line_aft_1 = {0x34, 0x02},
714 .v_sync_line_aft_pxl_2 = {0xa4, 0x04},
715 .v_sync_line_aft_pxl_1 = {0xa4, 0x04},
716 .v_blank_f2 = {0xff, 0xff},
717 .v_blank_f3 = {0xff, 0xff},
718 .v_blank_f4 = {0xff, 0xff},
719 .v_blank_f5 = {0xff, 0xff},
720 .v_sync_line_aft_3 = {0xff, 0xff},
721 .v_sync_line_aft_4 = {0xff, 0xff},
722 .v_sync_line_aft_5 = {0xff, 0xff},
723 .v_sync_line_aft_6 = {0xff, 0xff},
724 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
725 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
726 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
727 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
728 .vact_space_1 = {0xff, 0xff},
729 .vact_space_2 = {0xff, 0xff},
730 .vact_space_3 = {0xff, 0xff},
731 .vact_space_4 = {0xff, 0xff},
732 .vact_space_5 = {0xff, 0xff},
733 .vact_space_6 = {0xff, 0xff},
734 /* other don't care */
738 0x98, 0x08, /* h_fsz */
739 0x18, 0x01, 0x80, 0x07, /* hact */
740 0x65, 0x04, /* v_fsz */
741 0x01, 0x00, 0x33, 0x02, /* vsync */
742 0x16, 0x00, 0x1c, 0x02, /* vact */
743 0x33, 0x02, /* field_chg */
744 0x49, 0x02, /* vact_st2 */
745 0x00, 0x00, /* vact_st3 */
746 0x00, 0x00, /* vact_st4 */
747 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
748 0x01, 0x00, 0x33, 0x02, /* field top/bot */
753 static const struct hdmi_preset_conf hdmi_conf_1080p50 = {
755 .h_blank = {0xd0, 0x02},
756 .v2_blank = {0x65, 0x04},
757 .v1_blank = {0x2d, 0x00},
758 .v_line = {0x65, 0x04},
759 .h_line = {0x50, 0x0a},
762 .int_pro_mode = {0x00},
763 .v_blank_f0 = {0xff, 0xff},
764 .v_blank_f1 = {0xff, 0xff},
765 .h_sync_start = {0x0e, 0x02},
766 .h_sync_end = {0x3a, 0x02},
767 .v_sync_line_bef_2 = {0x09, 0x00},
768 .v_sync_line_bef_1 = {0x04, 0x00},
769 .v_sync_line_aft_2 = {0xff, 0xff},
770 .v_sync_line_aft_1 = {0xff, 0xff},
771 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
772 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
773 .v_blank_f2 = {0xff, 0xff},
774 .v_blank_f3 = {0xff, 0xff},
775 .v_blank_f4 = {0xff, 0xff},
776 .v_blank_f5 = {0xff, 0xff},
777 .v_sync_line_aft_3 = {0xff, 0xff},
778 .v_sync_line_aft_4 = {0xff, 0xff},
779 .v_sync_line_aft_5 = {0xff, 0xff},
780 .v_sync_line_aft_6 = {0xff, 0xff},
781 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
782 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
783 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
784 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
785 .vact_space_1 = {0xff, 0xff},
786 .vact_space_2 = {0xff, 0xff},
787 .vact_space_3 = {0xff, 0xff},
788 .vact_space_4 = {0xff, 0xff},
789 .vact_space_5 = {0xff, 0xff},
790 .vact_space_6 = {0xff, 0xff},
791 /* other don't care */
795 0x50, 0x0a, /* h_fsz */
796 0xd0, 0x02, 0x80, 0x07, /* hact */
797 0x65, 0x04, /* v_fsz */
798 0x01, 0x00, 0x33, 0x02, /* vsync */
799 0x2d, 0x00, 0x38, 0x04, /* vact */
800 0x33, 0x02, /* field_chg */
801 0x48, 0x02, /* vact_st2 */
802 0x00, 0x00, /* vact_st3 */
803 0x00, 0x00, /* vact_st4 */
804 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
805 0x01, 0x00, 0x33, 0x02, /* field top/bot */
810 static const struct hdmi_preset_conf hdmi_conf_1080p60 = {
812 .h_blank = {0x18, 0x01},
813 .v2_blank = {0x65, 0x04},
814 .v1_blank = {0x2d, 0x00},
815 .v_line = {0x65, 0x04},
816 .h_line = {0x98, 0x08},
819 .int_pro_mode = {0x00},
820 .v_blank_f0 = {0xff, 0xff},
821 .v_blank_f1 = {0xff, 0xff},
822 .h_sync_start = {0x56, 0x00},
823 .h_sync_end = {0x82, 0x00},
824 .v_sync_line_bef_2 = {0x09, 0x00},
825 .v_sync_line_bef_1 = {0x04, 0x00},
826 .v_sync_line_aft_2 = {0xff, 0xff},
827 .v_sync_line_aft_1 = {0xff, 0xff},
828 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
829 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
830 .v_blank_f2 = {0xff, 0xff},
831 .v_blank_f3 = {0xff, 0xff},
832 .v_blank_f4 = {0xff, 0xff},
833 .v_blank_f5 = {0xff, 0xff},
834 .v_sync_line_aft_3 = {0xff, 0xff},
835 .v_sync_line_aft_4 = {0xff, 0xff},
836 .v_sync_line_aft_5 = {0xff, 0xff},
837 .v_sync_line_aft_6 = {0xff, 0xff},
838 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
839 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
840 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
841 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
842 /* other don't care */
846 0x98, 0x08, /* h_fsz */
847 0x18, 0x01, 0x80, 0x07, /* hact */
848 0x65, 0x04, /* v_fsz */
849 0x01, 0x00, 0x33, 0x02, /* vsync */
850 0x2d, 0x00, 0x38, 0x04, /* vact */
851 0x33, 0x02, /* field_chg */
852 0x48, 0x02, /* vact_st2 */
853 0x00, 0x00, /* vact_st3 */
854 0x00, 0x00, /* vact_st4 */
855 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
856 0x01, 0x00, 0x33, 0x02, /* field top/bot */
861 /* LCD Support only 60 FPS. Making HDMI Aligned with LCD FPS */
863 static const struct hdmi_conf hdmi_confs[] = {
864 { 1280, 720, 60, false, hdmiphy_conf74_25, &hdmi_conf_720p60 },
865 { 720, 480, 60, false, hdmiphy_conf27_027, &hdmi_conf_480p60},
866 { 1920, 1080, 60, true, hdmiphy_conf74_25, &hdmi_conf_1080i60 },
867 { 1920, 1080, 60, false, hdmiphy_conf148_5, &hdmi_conf_1080p60 },
871 static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
873 return readl(hdata->regs + reg_id);
876 static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
877 u32 reg_id, u8 value)
879 writeb(value, hdata->regs + reg_id);
882 static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
883 u32 reg_id, u32 value, u32 mask)
885 u32 old = readl(hdata->regs + reg_id);
886 value = (value & mask) | (old & ~mask);
887 writel(value, hdata->regs + reg_id);
890 static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix)
892 #define DUMPREG(reg_id) \
893 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
894 readl(hdata->regs + reg_id))
895 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
896 DUMPREG(HDMI_INTC_FLAG);
897 DUMPREG(HDMI_INTC_CON);
898 DUMPREG(HDMI_HPD_STATUS);
899 DUMPREG(HDMI_V13_PHY_RSTOUT);
900 DUMPREG(HDMI_V13_PHY_VPLL);
901 DUMPREG(HDMI_V13_PHY_CMU);
902 DUMPREG(HDMI_V13_CORE_RSTOUT);
904 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
908 DUMPREG(HDMI_SYS_STATUS);
909 DUMPREG(HDMI_V13_PHY_STATUS);
910 DUMPREG(HDMI_STATUS_EN);
912 DUMPREG(HDMI_MODE_SEL);
913 DUMPREG(HDMI_V13_HPD_GEN);
914 DUMPREG(HDMI_V13_DC_CONTROL);
915 DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN);
917 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
918 DUMPREG(HDMI_H_BLANK_0);
919 DUMPREG(HDMI_H_BLANK_1);
920 DUMPREG(HDMI_V13_V_BLANK_0);
921 DUMPREG(HDMI_V13_V_BLANK_1);
922 DUMPREG(HDMI_V13_V_BLANK_2);
923 DUMPREG(HDMI_V13_H_V_LINE_0);
924 DUMPREG(HDMI_V13_H_V_LINE_1);
925 DUMPREG(HDMI_V13_H_V_LINE_2);
926 DUMPREG(HDMI_VSYNC_POL);
927 DUMPREG(HDMI_INT_PRO_MODE);
928 DUMPREG(HDMI_V13_V_BLANK_F_0);
929 DUMPREG(HDMI_V13_V_BLANK_F_1);
930 DUMPREG(HDMI_V13_V_BLANK_F_2);
931 DUMPREG(HDMI_V13_H_SYNC_GEN_0);
932 DUMPREG(HDMI_V13_H_SYNC_GEN_1);
933 DUMPREG(HDMI_V13_H_SYNC_GEN_2);
934 DUMPREG(HDMI_V13_V_SYNC_GEN_1_0);
935 DUMPREG(HDMI_V13_V_SYNC_GEN_1_1);
936 DUMPREG(HDMI_V13_V_SYNC_GEN_1_2);
937 DUMPREG(HDMI_V13_V_SYNC_GEN_2_0);
938 DUMPREG(HDMI_V13_V_SYNC_GEN_2_1);
939 DUMPREG(HDMI_V13_V_SYNC_GEN_2_2);
940 DUMPREG(HDMI_V13_V_SYNC_GEN_3_0);
941 DUMPREG(HDMI_V13_V_SYNC_GEN_3_1);
942 DUMPREG(HDMI_V13_V_SYNC_GEN_3_2);
944 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
945 DUMPREG(HDMI_TG_CMD);
946 DUMPREG(HDMI_TG_H_FSZ_L);
947 DUMPREG(HDMI_TG_H_FSZ_H);
948 DUMPREG(HDMI_TG_HACT_ST_L);
949 DUMPREG(HDMI_TG_HACT_ST_H);
950 DUMPREG(HDMI_TG_HACT_SZ_L);
951 DUMPREG(HDMI_TG_HACT_SZ_H);
952 DUMPREG(HDMI_TG_V_FSZ_L);
953 DUMPREG(HDMI_TG_V_FSZ_H);
954 DUMPREG(HDMI_TG_VSYNC_L);
955 DUMPREG(HDMI_TG_VSYNC_H);
956 DUMPREG(HDMI_TG_VSYNC2_L);
957 DUMPREG(HDMI_TG_VSYNC2_H);
958 DUMPREG(HDMI_TG_VACT_ST_L);
959 DUMPREG(HDMI_TG_VACT_ST_H);
960 DUMPREG(HDMI_TG_VACT_SZ_L);
961 DUMPREG(HDMI_TG_VACT_SZ_H);
962 DUMPREG(HDMI_TG_FIELD_CHG_L);
963 DUMPREG(HDMI_TG_FIELD_CHG_H);
964 DUMPREG(HDMI_TG_VACT_ST2_L);
965 DUMPREG(HDMI_TG_VACT_ST2_H);
966 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
967 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
968 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
969 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
970 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
971 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
972 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
973 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
977 static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix)
981 #define DUMPREG(reg_id) \
982 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
983 readl(hdata->regs + reg_id))
985 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
986 DUMPREG(HDMI_INTC_CON);
987 DUMPREG(HDMI_INTC_FLAG);
988 DUMPREG(HDMI_HPD_STATUS);
989 DUMPREG(HDMI_INTC_CON_1);
990 DUMPREG(HDMI_INTC_FLAG_1);
991 DUMPREG(HDMI_PHY_STATUS_0);
992 DUMPREG(HDMI_PHY_STATUS_PLL);
993 DUMPREG(HDMI_PHY_CON_0);
994 DUMPREG(HDMI_PHY_RSTOUT);
995 DUMPREG(HDMI_PHY_VPLL);
996 DUMPREG(HDMI_PHY_CMU);
997 DUMPREG(HDMI_CORE_RSTOUT);
999 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
1000 DUMPREG(HDMI_CON_0);
1001 DUMPREG(HDMI_CON_1);
1002 DUMPREG(HDMI_CON_2);
1003 DUMPREG(HDMI_SYS_STATUS);
1004 DUMPREG(HDMI_PHY_STATUS_0);
1005 DUMPREG(HDMI_STATUS_EN);
1007 DUMPREG(HDMI_MODE_SEL);
1008 DUMPREG(HDMI_ENC_EN);
1009 DUMPREG(HDMI_DC_CONTROL);
1010 DUMPREG(HDMI_VIDEO_PATTERN_GEN);
1012 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
1013 DUMPREG(HDMI_H_BLANK_0);
1014 DUMPREG(HDMI_H_BLANK_1);
1015 DUMPREG(HDMI_V2_BLANK_0);
1016 DUMPREG(HDMI_V2_BLANK_1);
1017 DUMPREG(HDMI_V1_BLANK_0);
1018 DUMPREG(HDMI_V1_BLANK_1);
1019 DUMPREG(HDMI_V_LINE_0);
1020 DUMPREG(HDMI_V_LINE_1);
1021 DUMPREG(HDMI_H_LINE_0);
1022 DUMPREG(HDMI_H_LINE_1);
1023 DUMPREG(HDMI_HSYNC_POL);
1025 DUMPREG(HDMI_VSYNC_POL);
1026 DUMPREG(HDMI_INT_PRO_MODE);
1027 DUMPREG(HDMI_V_BLANK_F0_0);
1028 DUMPREG(HDMI_V_BLANK_F0_1);
1029 DUMPREG(HDMI_V_BLANK_F1_0);
1030 DUMPREG(HDMI_V_BLANK_F1_1);
1032 DUMPREG(HDMI_H_SYNC_START_0);
1033 DUMPREG(HDMI_H_SYNC_START_1);
1034 DUMPREG(HDMI_H_SYNC_END_0);
1035 DUMPREG(HDMI_H_SYNC_END_1);
1037 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0);
1038 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1);
1039 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0);
1040 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1);
1042 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0);
1043 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1);
1044 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0);
1045 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1);
1047 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0);
1048 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1);
1049 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0);
1050 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1);
1052 DUMPREG(HDMI_V_BLANK_F2_0);
1053 DUMPREG(HDMI_V_BLANK_F2_1);
1054 DUMPREG(HDMI_V_BLANK_F3_0);
1055 DUMPREG(HDMI_V_BLANK_F3_1);
1056 DUMPREG(HDMI_V_BLANK_F4_0);
1057 DUMPREG(HDMI_V_BLANK_F4_1);
1058 DUMPREG(HDMI_V_BLANK_F5_0);
1059 DUMPREG(HDMI_V_BLANK_F5_1);
1061 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0);
1062 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1);
1063 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0);
1064 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1);
1065 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0);
1066 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1);
1067 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0);
1068 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1);
1070 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0);
1071 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1);
1072 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0);
1073 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1);
1074 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0);
1075 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1);
1076 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0);
1077 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1);
1079 DUMPREG(HDMI_VACT_SPACE_1_0);
1080 DUMPREG(HDMI_VACT_SPACE_1_1);
1081 DUMPREG(HDMI_VACT_SPACE_2_0);
1082 DUMPREG(HDMI_VACT_SPACE_2_1);
1083 DUMPREG(HDMI_VACT_SPACE_3_0);
1084 DUMPREG(HDMI_VACT_SPACE_3_1);
1085 DUMPREG(HDMI_VACT_SPACE_4_0);
1086 DUMPREG(HDMI_VACT_SPACE_4_1);
1087 DUMPREG(HDMI_VACT_SPACE_5_0);
1088 DUMPREG(HDMI_VACT_SPACE_5_1);
1089 DUMPREG(HDMI_VACT_SPACE_6_0);
1090 DUMPREG(HDMI_VACT_SPACE_6_1);
1092 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
1093 DUMPREG(HDMI_TG_CMD);
1094 DUMPREG(HDMI_TG_H_FSZ_L);
1095 DUMPREG(HDMI_TG_H_FSZ_H);
1096 DUMPREG(HDMI_TG_HACT_ST_L);
1097 DUMPREG(HDMI_TG_HACT_ST_H);
1098 DUMPREG(HDMI_TG_HACT_SZ_L);
1099 DUMPREG(HDMI_TG_HACT_SZ_H);
1100 DUMPREG(HDMI_TG_V_FSZ_L);
1101 DUMPREG(HDMI_TG_V_FSZ_H);
1102 DUMPREG(HDMI_TG_VSYNC_L);
1103 DUMPREG(HDMI_TG_VSYNC_H);
1104 DUMPREG(HDMI_TG_VSYNC2_L);
1105 DUMPREG(HDMI_TG_VSYNC2_H);
1106 DUMPREG(HDMI_TG_VACT_ST_L);
1107 DUMPREG(HDMI_TG_VACT_ST_H);
1108 DUMPREG(HDMI_TG_VACT_SZ_L);
1109 DUMPREG(HDMI_TG_VACT_SZ_H);
1110 DUMPREG(HDMI_TG_FIELD_CHG_L);
1111 DUMPREG(HDMI_TG_FIELD_CHG_H);
1112 DUMPREG(HDMI_TG_VACT_ST2_L);
1113 DUMPREG(HDMI_TG_VACT_ST2_H);
1114 DUMPREG(HDMI_TG_VACT_ST3_L);
1115 DUMPREG(HDMI_TG_VACT_ST3_H);
1116 DUMPREG(HDMI_TG_VACT_ST4_L);
1117 DUMPREG(HDMI_TG_VACT_ST4_H);
1118 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
1119 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
1120 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
1121 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
1122 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
1123 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
1124 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
1125 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
1126 DUMPREG(HDMI_TG_3D);
1128 DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix);
1129 DUMPREG(HDMI_AVI_CON);
1130 DUMPREG(HDMI_AVI_HEADER0);
1131 DUMPREG(HDMI_AVI_HEADER1);
1132 DUMPREG(HDMI_AVI_HEADER2);
1133 DUMPREG(HDMI_AVI_CHECK_SUM);
1134 DUMPREG(HDMI_VSI_CON);
1135 DUMPREG(HDMI_VSI_HEADER0);
1136 DUMPREG(HDMI_VSI_HEADER1);
1137 DUMPREG(HDMI_VSI_HEADER2);
1138 for (i = 0; i < 7; ++i)
1139 DUMPREG(HDMI_VSI_DATA(i));
1144 static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
1147 hdmi_v13_regs_dump(hdata, prefix);
1149 hdmi_v14_regs_dump(hdata, prefix);
1152 static int hdmi_v13_conf_index(struct drm_display_mode *mode)
1156 for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1157 if (hdmi_v13_confs[i].width == mode->hdisplay &&
1158 hdmi_v13_confs[i].height == mode->vdisplay &&
1159 hdmi_v13_confs[i].vrefresh == mode->vrefresh &&
1160 hdmi_v13_confs[i].interlace ==
1161 ((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1168 static int hdmi_v14_conf_index(struct drm_display_mode *mode)
1173 * DRM framework passing 0 as the FPS value
1174 * which needs to be corrected.*/
1175 mode->vrefresh = 60;
1177 for (i = 0; i < ARRAY_SIZE(hdmi_confs); ++i)
1178 if (hdmi_confs[i].width == mode->hdisplay &&
1179 hdmi_confs[i].height == mode->vdisplay &&
1180 hdmi_confs[i].vrefresh == mode->vrefresh &&
1181 hdmi_confs[i].interlace ==
1182 ((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1189 static int hdmi_conf_index(struct hdmi_context *hdata,
1190 struct drm_display_mode *mode)
1193 return hdmi_v13_conf_index(mode);
1195 return hdmi_v14_conf_index(mode);
1198 static bool hdmi_is_connected(void *ctx)
1200 struct hdmi_context *hdata = ctx;
1201 u32 val = hdmi_reg_read(hdata, HDMI_HPD_STATUS);
1209 static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
1212 struct edid *raw_edid;
1213 struct hdmi_context *hdata = ctx;
1215 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1217 if (!hdata->ddc_port)
1220 raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter);
1222 memcpy(edid, raw_edid, min((1 + raw_edid->extensions)
1223 * EDID_LENGTH, len));
1224 DRM_DEBUG_KMS("width[%d] x height[%d]\n",
1225 raw_edid->width_cm, raw_edid->height_cm);
1233 static int hdmi_v13_check_timing(struct fb_videomode *check_timing)
1237 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1238 check_timing->xres, check_timing->yres,
1239 check_timing->refresh, (check_timing->vmode &
1240 FB_VMODE_INTERLACED) ? true : false);
1242 for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1243 if (hdmi_v13_confs[i].width == check_timing->xres &&
1244 hdmi_v13_confs[i].height == check_timing->yres &&
1245 hdmi_v13_confs[i].vrefresh == check_timing->refresh &&
1246 hdmi_v13_confs[i].interlace ==
1247 ((check_timing->vmode & FB_VMODE_INTERLACED) ?
1256 static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
1260 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1261 check_timing->xres, check_timing->yres,
1262 check_timing->refresh, (check_timing->vmode &
1263 FB_VMODE_INTERLACED) ? true : false);
1265 for (i = 0; i < ARRAY_SIZE(hdmi_confs); i++)
1266 if (hdmi_confs[i].width == check_timing->xres &&
1267 hdmi_confs[i].height == check_timing->yres &&
1268 hdmi_confs[i].vrefresh == check_timing->refresh &&
1269 hdmi_confs[i].interlace ==
1270 ((check_timing->vmode & FB_VMODE_INTERLACED) ?
1279 static int hdmi_check_timing(void *ctx, void *timing)
1281 struct hdmi_context *hdata = ctx;
1282 struct fb_videomode *check_timing = timing;
1284 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1286 DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres,
1287 check_timing->yres, check_timing->refresh,
1288 check_timing->vmode);
1291 return hdmi_v13_check_timing(check_timing);
1293 return hdmi_v14_check_timing(check_timing);
1296 static int hdmi_display_power_on(void *ctx, int mode)
1298 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1301 case DRM_MODE_DPMS_ON:
1302 DRM_DEBUG_KMS("hdmi [on]\n");
1304 case DRM_MODE_DPMS_STANDBY:
1306 case DRM_MODE_DPMS_SUSPEND:
1308 case DRM_MODE_DPMS_OFF:
1309 DRM_DEBUG_KMS("hdmi [off]\n");
1318 static void hdmi_set_acr(u32 freq, u8 *acr)
1358 acr[2] = cts >> 8 & 0xff;
1359 acr[3] = cts & 0xff;
1362 acr[5] = n >> 8 & 0xff;
1366 static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr)
1368 hdmi_reg_writeb(hdata, HDMI_ACR_N0, acr[6]);
1369 hdmi_reg_writeb(hdata, HDMI_ACR_N1, acr[5]);
1370 hdmi_reg_writeb(hdata, HDMI_ACR_N2, acr[4]);
1371 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS0, acr[3]);
1372 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS1, acr[2]);
1373 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS2, acr[1]);
1374 hdmi_reg_writeb(hdata, HDMI_ACR_CTS0, acr[3]);
1375 hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]);
1376 hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]);
1379 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4);
1381 hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1384 static void hdmi_audio_init(struct hdmi_context *hdata)
1386 u32 sample_rate, bits_per_sample, frame_size_code;
1387 u32 data_num, bit_ch, sample_frq;
1391 sample_rate = 44100;
1392 bits_per_sample = 16;
1393 frame_size_code = 0;
1395 switch (bits_per_sample) {
1410 hdmi_set_acr(sample_rate, acr);
1411 hdmi_reg_acr(hdata, acr);
1413 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1414 | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1415 | HDMI_I2S_MUX_ENABLE);
1417 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1418 | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1420 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1422 sample_frq = (sample_rate == 44100) ? 0 :
1423 (sample_rate == 48000) ? 2 :
1424 (sample_rate == 32000) ? 3 :
1425 (sample_rate == 96000) ? 0xa : 0x0;
1427 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1428 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1430 val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1431 hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1433 /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1434 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1435 | HDMI_I2S_SEL_LRCK(6));
1436 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1437 | HDMI_I2S_SEL_SDATA2(4));
1438 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1439 | HDMI_I2S_SEL_SDATA2(2));
1440 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1443 hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1444 | HDMI_I2S_L_CH_LOW_POL);
1445 hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1446 | HDMI_I2S_SET_BIT_CH(bit_ch)
1447 | HDMI_I2S_SET_SDATA_BIT(data_num)
1448 | HDMI_I2S_BASIC_FORMAT);
1450 /* Configure register related to CUV information */
1451 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
1452 | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1453 | HDMI_I2S_COPYRIGHT
1454 | HDMI_I2S_LINEAR_PCM
1455 | HDMI_I2S_CONSUMER_FORMAT);
1456 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1457 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1458 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1459 | HDMI_I2S_SET_SMP_FREQ(sample_frq));
1460 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1461 HDMI_I2S_ORG_SMP_FREQ_44_1
1462 | HDMI_I2S_WORD_LEN_MAX24_24BITS
1463 | HDMI_I2S_WORD_LEN_MAX_24BITS);
1465 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1468 static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1472 mod = hdmi_reg_read(hdata, HDMI_MODE_SEL);
1473 if (mod & HDMI_DVI_MODE_EN)
1476 hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
1477 hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ?
1478 HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1481 static void hdmi_conf_reset(struct hdmi_context *hdata)
1485 /* disable hpd handle for drm */
1486 hdata->hpd_handle = false;
1489 reg = HDMI_V13_CORE_RSTOUT;
1491 reg = HDMI_CORE_RSTOUT;
1493 /* resetting HDMI core */
1494 hdmi_reg_writemask(hdata, reg, 0, HDMI_CORE_SW_RSTOUT);
1496 hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT);
1499 /* enable hpd handle for drm */
1500 hdata->hpd_handle = true;
1503 static void hdmi_conf_init(struct hdmi_context *hdata)
1505 /* disable hpd handle for drm */
1506 hdata->hpd_handle = false;
1508 /* enable HPD interrupts */
1509 hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1510 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1512 hdmi_reg_writemask(hdata, HDMI_INTC_CON, ~0, HDMI_INTC_EN_GLOBAL |
1513 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1515 /* choose HDMI mode */
1516 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1517 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1518 /* disable bluescreen */
1519 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1521 if (hdata->is_v13) {
1522 /* choose bluescreen (fecal) color */
1523 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1524 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1525 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1527 /* enable AVI packet every vsync, fixes purple line problem */
1528 hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1529 /* force RGB, look to CEA-861-D, table 7 for more detail */
1530 hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1531 hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1533 hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1534 hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1535 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1537 /* enable AVI packet every vsync, fixes purple line problem */
1538 hdmi_reg_writeb(hdata, HDMI_AVI_CON, 0x02);
1539 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 2 << 5);
1540 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1543 /* enable hpd handle for drm */
1544 hdata->hpd_handle = true;
1547 static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
1549 const struct hdmi_v13_preset_conf *conf =
1550 hdmi_v13_confs[hdata->cur_conf].conf;
1551 const struct hdmi_v13_core_regs *core = &conf->core;
1552 const struct hdmi_v13_tg_regs *tg = &conf->tg;
1555 /* setting core registers */
1556 hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1557 hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1558 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_0, core->v_blank[0]);
1559 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_1, core->v_blank[1]);
1560 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_2, core->v_blank[2]);
1561 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_0, core->h_v_line[0]);
1562 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_1, core->h_v_line[1]);
1563 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_2, core->h_v_line[2]);
1564 hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1565 hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1566 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_0, core->v_blank_f[0]);
1567 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_1, core->v_blank_f[1]);
1568 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_2, core->v_blank_f[2]);
1569 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_0, core->h_sync_gen[0]);
1570 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_1, core->h_sync_gen[1]);
1571 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_2, core->h_sync_gen[2]);
1572 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_0, core->v_sync_gen1[0]);
1573 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_1, core->v_sync_gen1[1]);
1574 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_2, core->v_sync_gen1[2]);
1575 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_0, core->v_sync_gen2[0]);
1576 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_1, core->v_sync_gen2[1]);
1577 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_2, core->v_sync_gen2[2]);
1578 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_0, core->v_sync_gen3[0]);
1579 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]);
1580 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]);
1581 /* Timing generator registers */
1582 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1583 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1584 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1585 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1586 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1587 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1588 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1589 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1590 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1591 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1592 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1593 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1594 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1595 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1596 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1597 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1598 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1599 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1600 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1601 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1602 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1603 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1604 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1605 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1606 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1607 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1608 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1609 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1611 /* waiting for HDMIPHY's PLL to get to steady state */
1612 for (tries = 100; tries; --tries) {
1613 u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS);
1614 if (val & HDMI_PHY_STATUS_READY)
1618 /* steady state not achieved */
1620 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1621 hdmi_regs_dump(hdata, "timing apply");
1624 clk_disable(hdata->res.sclk_hdmi);
1625 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1626 clk_enable(hdata->res.sclk_hdmi);
1628 /* enable HDMI and timing generator */
1629 hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1630 if (core->int_pro_mode[0])
1631 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1634 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1637 static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
1639 const struct hdmi_preset_conf *conf = hdmi_confs[hdata->cur_conf].conf;
1640 const struct hdmi_core_regs *core = &conf->core;
1641 const struct hdmi_tg_regs *tg = &conf->tg;
1644 /* setting core registers */
1645 hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1646 hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1647 hdmi_reg_writeb(hdata, HDMI_V2_BLANK_0, core->v2_blank[0]);
1648 hdmi_reg_writeb(hdata, HDMI_V2_BLANK_1, core->v2_blank[1]);
1649 hdmi_reg_writeb(hdata, HDMI_V1_BLANK_0, core->v1_blank[0]);
1650 hdmi_reg_writeb(hdata, HDMI_V1_BLANK_1, core->v1_blank[1]);
1651 hdmi_reg_writeb(hdata, HDMI_V_LINE_0, core->v_line[0]);
1652 hdmi_reg_writeb(hdata, HDMI_V_LINE_1, core->v_line[1]);
1653 hdmi_reg_writeb(hdata, HDMI_H_LINE_0, core->h_line[0]);
1654 hdmi_reg_writeb(hdata, HDMI_H_LINE_1, core->h_line[1]);
1655 hdmi_reg_writeb(hdata, HDMI_HSYNC_POL, core->hsync_pol[0]);
1656 hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1657 hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1658 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_0, core->v_blank_f0[0]);
1659 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_1, core->v_blank_f0[1]);
1660 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_0, core->v_blank_f1[0]);
1661 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_1, core->v_blank_f1[1]);
1662 hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_0, core->h_sync_start[0]);
1663 hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_1, core->h_sync_start[1]);
1664 hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_0, core->h_sync_end[0]);
1665 hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_1, core->h_sync_end[1]);
1666 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_0,
1667 core->v_sync_line_bef_2[0]);
1668 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_1,
1669 core->v_sync_line_bef_2[1]);
1670 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_0,
1671 core->v_sync_line_bef_1[0]);
1672 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_1,
1673 core->v_sync_line_bef_1[1]);
1674 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_0,
1675 core->v_sync_line_aft_2[0]);
1676 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_1,
1677 core->v_sync_line_aft_2[1]);
1678 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_0,
1679 core->v_sync_line_aft_1[0]);
1680 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_1,
1681 core->v_sync_line_aft_1[1]);
1682 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0,
1683 core->v_sync_line_aft_pxl_2[0]);
1684 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_1,
1685 core->v_sync_line_aft_pxl_2[1]);
1686 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0,
1687 core->v_sync_line_aft_pxl_1[0]);
1688 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_1,
1689 core->v_sync_line_aft_pxl_1[1]);
1690 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_0, core->v_blank_f2[0]);
1691 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_1, core->v_blank_f2[1]);
1692 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_0, core->v_blank_f3[0]);
1693 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_1, core->v_blank_f3[1]);
1694 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_0, core->v_blank_f4[0]);
1695 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_1, core->v_blank_f4[1]);
1696 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_0, core->v_blank_f5[0]);
1697 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_1, core->v_blank_f5[1]);
1698 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_0,
1699 core->v_sync_line_aft_3[0]);
1700 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_1,
1701 core->v_sync_line_aft_3[1]);
1702 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_0,
1703 core->v_sync_line_aft_4[0]);
1704 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_1,
1705 core->v_sync_line_aft_4[1]);
1706 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_0,
1707 core->v_sync_line_aft_5[0]);
1708 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_1,
1709 core->v_sync_line_aft_5[1]);
1710 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_0,
1711 core->v_sync_line_aft_6[0]);
1712 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_1,
1713 core->v_sync_line_aft_6[1]);
1714 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0,
1715 core->v_sync_line_aft_pxl_3[0]);
1716 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_1,
1717 core->v_sync_line_aft_pxl_3[1]);
1718 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0,
1719 core->v_sync_line_aft_pxl_4[0]);
1720 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_1,
1721 core->v_sync_line_aft_pxl_4[1]);
1722 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0,
1723 core->v_sync_line_aft_pxl_5[0]);
1724 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_1,
1725 core->v_sync_line_aft_pxl_5[1]);
1726 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0,
1727 core->v_sync_line_aft_pxl_6[0]);
1728 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_1,
1729 core->v_sync_line_aft_pxl_6[1]);
1730 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_0, core->vact_space_1[0]);
1731 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_1, core->vact_space_1[1]);
1732 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_0, core->vact_space_2[0]);
1733 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_1, core->vact_space_2[1]);
1734 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_0, core->vact_space_3[0]);
1735 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_1, core->vact_space_3[1]);
1736 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_0, core->vact_space_4[0]);
1737 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_1, core->vact_space_4[1]);
1738 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_0, core->vact_space_5[0]);
1739 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_1, core->vact_space_5[1]);
1740 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_0, core->vact_space_6[0]);
1741 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]);
1743 /* Timing generator registers */
1744 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1745 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1746 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1747 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1748 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1749 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1750 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1751 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1752 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1753 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1754 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1755 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1756 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1757 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1758 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1759 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1760 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1761 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1762 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1763 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1764 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3_l);
1765 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3_h);
1766 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4_l);
1767 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4_h);
1768 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1769 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1770 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1771 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1772 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1773 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1774 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1775 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1776 hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d);
1778 /* waiting for HDMIPHY's PLL to get to steady state */
1779 for (tries = 100; tries; --tries) {
1780 u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0);
1781 if (val & HDMI_PHY_STATUS_READY)
1785 /* steady state not achieved */
1787 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1788 hdmi_regs_dump(hdata, "timing apply");
1791 clk_disable(hdata->res.sclk_hdmi);
1792 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1793 clk_enable(hdata->res.sclk_hdmi);
1795 /* enable HDMI and timing generator */
1796 hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1797 if (core->int_pro_mode[0])
1798 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1801 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1804 static void hdmi_timing_apply(struct hdmi_context *hdata)
1807 hdmi_v13_timing_apply(hdata);
1809 hdmi_v14_timing_apply(hdata);
1812 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1817 clk_disable(hdata->res.sclk_hdmi);
1818 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel);
1819 clk_enable(hdata->res.sclk_hdmi);
1821 /* operation mode */
1825 if (hdata->hdmiphy_port)
1826 i2c_master_send(hdata->hdmiphy_port, buffer, 2);
1829 reg = HDMI_V13_PHY_RSTOUT;
1831 reg = HDMI_PHY_RSTOUT;
1834 hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT);
1836 hdmi_reg_writemask(hdata, reg, 0, HDMI_PHY_SW_RSTOUT);
1840 static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1842 const u8 *hdmiphy_data;
1845 u8 read_buffer[32] = {0, };
1849 if (!hdata->hdmiphy_port) {
1850 DRM_ERROR("hdmiphy is not attached\n");
1856 hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data;
1858 hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data;
1860 memcpy(buffer, hdmiphy_data, 32);
1861 ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
1863 DRM_ERROR("failed to configure HDMIPHY via I2C\n");
1869 /* operation mode */
1870 operation[0] = 0x1f;
1871 operation[1] = 0x80;
1873 ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
1875 DRM_ERROR("failed to enable hdmiphy\n");
1879 ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
1881 DRM_ERROR("failed to read hdmiphy config\n");
1885 for (i = 0; i < ret; i++)
1886 DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
1887 "recv [0x%02x]\n", i, buffer[i], read_buffer[i]);
1890 static void hdmi_conf_apply(struct hdmi_context *hdata)
1892 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1894 hdmiphy_conf_reset(hdata);
1895 hdmiphy_conf_apply(hdata);
1897 hdmi_conf_reset(hdata);
1898 hdmi_conf_init(hdata);
1899 hdmi_audio_init(hdata);
1901 /* setting core registers */
1902 hdmi_timing_apply(hdata);
1903 hdmi_audio_control(hdata, true);
1905 hdmi_regs_dump(hdata, "start");
1908 static void hdmi_mode_copy(struct drm_display_mode *dst,
1909 struct drm_display_mode *src)
1911 struct drm_mode_object base;
1913 /* following information should be preserved,
1914 * required for releasing the drm_display_mode node,
1915 * duplicated to recieve adjustment info. */
1917 base.id = dst->base.id;
1918 base.type = dst->base.type;
1920 memcpy(dst, src, sizeof(struct drm_display_mode));
1922 dst->base.id = base.id;
1923 dst->base.type = base.type;
1926 static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
1927 struct drm_display_mode *mode,
1928 struct drm_display_mode *adjusted_mode)
1930 struct drm_display_mode *m;
1931 struct hdmi_context *hdata = ctx;
1934 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1936 drm_mode_set_crtcinfo(adjusted_mode, 0);
1939 index = hdmi_v13_conf_index(adjusted_mode);
1941 index = hdmi_v14_conf_index(adjusted_mode);
1943 /* just return if user desired mode exists. */
1948 * otherwise, find the most suitable mode among modes and change it
1951 list_for_each_entry(m, &connector->modes, head) {
1953 index = hdmi_v13_conf_index(m);
1955 index = hdmi_v14_conf_index(m);
1958 DRM_INFO("desired mode doesn't exist so\n");
1959 DRM_INFO("use the most suitable mode among modes.\n");
1960 hdmi_mode_copy(adjusted_mode, m);
1966 static void hdmi_mode_set(void *ctx, void *mode)
1968 struct hdmi_context *hdata = ctx;
1971 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1973 conf_idx = hdmi_conf_index(hdata, mode);
1975 hdata->cur_conf = conf_idx;
1977 DRM_DEBUG_KMS("not supported mode\n");
1980 static void hdmi_get_max_resol(void *ctx, unsigned int *width,
1981 unsigned int *height)
1983 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1986 *height = MAX_HEIGHT;
1989 static void hdmi_commit(void *ctx)
1991 struct hdmi_context *hdata = ctx;
1993 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1995 hdmi_conf_apply(hdata);
1997 hdata->enabled = true;
2000 static void hdmi_disable(void *ctx)
2002 struct hdmi_context *hdata = ctx;
2004 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2006 if (hdata->enabled) {
2007 hdmi_audio_control(hdata, false);
2008 hdmiphy_conf_reset(hdata);
2009 hdmi_conf_reset(hdata);
2013 static struct exynos_hdmi_ops hdmi_ops = {
2015 .is_connected = hdmi_is_connected,
2016 .get_edid = hdmi_get_edid,
2017 .check_timing = hdmi_check_timing,
2018 .power_on = hdmi_display_power_on,
2021 .mode_fixup = hdmi_mode_fixup,
2022 .mode_set = hdmi_mode_set,
2023 .get_max_resol = hdmi_get_max_resol,
2024 .commit = hdmi_commit,
2025 .disable = hdmi_disable,
2029 * Handle hotplug events outside the interrupt handler proper.
2031 static void hdmi_hotplug_func(struct work_struct *work)
2033 struct hdmi_context *hdata =
2034 container_of(work, struct hdmi_context, hotplug_work);
2035 struct exynos_drm_hdmi_context *ctx =
2036 (struct exynos_drm_hdmi_context *)hdata->parent_ctx;
2038 drm_helper_hpd_irq_event(ctx->drm_dev);
2041 static irqreturn_t hdmi_irq_handler(int irq, void *arg)
2043 struct exynos_drm_hdmi_context *ctx = arg;
2044 struct hdmi_context *hdata = ctx->ctx;
2047 intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG);
2048 /* clearing flags for HPD plug/unplug */
2049 if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) {
2050 DRM_DEBUG_KMS("unplugged, handling:%d\n", hdata->hpd_handle);
2051 hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
2052 HDMI_INTC_FLAG_HPD_UNPLUG);
2054 if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) {
2055 DRM_DEBUG_KMS("plugged, handling:%d\n", hdata->hpd_handle);
2056 hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
2057 HDMI_INTC_FLAG_HPD_PLUG);
2060 if (ctx->drm_dev && hdata->hpd_handle)
2061 queue_work(hdata->wq, &hdata->hotplug_work);
2066 static int __devinit hdmi_resources_init(struct hdmi_context *hdata)
2068 struct device *dev = hdata->dev;
2069 struct hdmi_resources *res = &hdata->res;
2070 #ifndef CONFIG_ARCH_EXYNOS5
2071 static char *supply[] = {
2080 DRM_DEBUG_KMS("HDMI resource init\n");
2082 memset(res, 0, sizeof *res);
2084 /* get clocks, power */
2085 res->hdmi = clk_get(dev, "hdmi");
2086 if (IS_ERR_OR_NULL(res->hdmi)) {
2087 DRM_ERROR("failed to get clock 'hdmi'\n");
2090 res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
2091 if (IS_ERR_OR_NULL(res->sclk_hdmi)) {
2092 DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
2095 res->sclk_pixel = clk_get(dev, "sclk_pixel");
2096 if (IS_ERR_OR_NULL(res->sclk_pixel)) {
2097 DRM_ERROR("failed to get clock 'sclk_pixel'\n");
2100 res->sclk_hdmiphy = clk_get(dev, "sclk_hdmiphy");
2101 if (IS_ERR_OR_NULL(res->sclk_hdmiphy)) {
2102 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
2105 res->hdmiphy = clk_get(dev, "hdmiphy");
2106 if (IS_ERR_OR_NULL(res->hdmiphy)) {
2107 DRM_ERROR("failed to get clock 'hdmiphy'\n");
2111 clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
2113 #ifndef CONFIG_ARCH_EXYNOS5
2114 res->regul_bulk = kzalloc(ARRAY_SIZE(supply) *
2115 sizeof res->regul_bulk[0], GFP_KERNEL);
2116 if (!res->regul_bulk) {
2117 DRM_ERROR("failed to get memory for regulators\n");
2120 for (i = 0; i < ARRAY_SIZE(supply); ++i) {
2121 res->regul_bulk[i].supply = supply[i];
2122 res->regul_bulk[i].consumer = NULL;
2124 ret = regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
2126 DRM_ERROR("failed to get regulators\n");
2129 res->regul_count = ARRAY_SIZE(supply);
2134 DRM_ERROR("HDMI resource init - failed\n");
2138 static int hdmi_resources_cleanup(struct hdmi_context *hdata)
2140 struct hdmi_resources *res = &hdata->res;
2142 regulator_bulk_free(res->regul_count, res->regul_bulk);
2143 /* kfree is NULL-safe */
2144 kfree(res->regul_bulk);
2145 if (!IS_ERR_OR_NULL(res->hdmiphy))
2146 clk_put(res->hdmiphy);
2147 if (!IS_ERR_OR_NULL(res->sclk_hdmiphy))
2148 clk_put(res->sclk_hdmiphy);
2149 if (!IS_ERR_OR_NULL(res->sclk_pixel))
2150 clk_put(res->sclk_pixel);
2151 if (!IS_ERR_OR_NULL(res->sclk_hdmi))
2152 clk_put(res->sclk_hdmi);
2153 if (!IS_ERR_OR_NULL(res->hdmi))
2155 memset(res, 0, sizeof *res);
2160 static void hdmi_resource_poweron(struct hdmi_context *hdata)
2162 struct hdmi_resources *res = &hdata->res;
2164 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2166 /* turn HDMI power on */
2167 regulator_bulk_enable(res->regul_count, res->regul_bulk);
2168 /* power-on hdmi physical interface */
2169 clk_enable(res->hdmiphy);
2170 /* turn clocks on */
2171 clk_enable(res->hdmi);
2172 clk_enable(res->sclk_hdmi);
2174 hdmiphy_conf_reset(hdata);
2175 hdmi_conf_reset(hdata);
2176 hdmi_conf_init(hdata);
2177 hdmi_audio_init(hdata);
2180 static void hdmi_resource_poweroff(struct hdmi_context *hdata)
2182 struct hdmi_resources *res = &hdata->res;
2184 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2186 /* turn clocks off */
2187 clk_disable(res->sclk_hdmi);
2188 clk_disable(res->hdmi);
2189 /* power-off hdmiphy */
2190 clk_disable(res->hdmiphy);
2191 /* turn HDMI power off */
2192 regulator_bulk_disable(res->regul_count, res->regul_bulk);
2195 static int hdmi_runtime_suspend(struct device *dev)
2197 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2199 DRM_DEBUG_KMS("%s\n", __func__);
2201 hdmi_resource_poweroff(ctx->ctx);
2206 static int hdmi_runtime_resume(struct device *dev)
2208 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2210 DRM_DEBUG_KMS("%s\n", __func__);
2212 hdmi_resource_poweron(ctx->ctx);
2217 static const struct dev_pm_ops hdmi_pm_ops = {
2218 .runtime_suspend = hdmi_runtime_suspend,
2219 .runtime_resume = hdmi_runtime_resume,
2222 static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
2224 void hdmi_attach_ddc_client(struct i2c_client *ddc)
2230 void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
2233 hdmi_hdmiphy = hdmiphy;
2236 static int __devinit hdmi_probe(struct platform_device *pdev)
2238 struct device *dev = &pdev->dev;
2239 struct exynos_drm_hdmi_context *drm_hdmi_ctx;
2240 struct hdmi_context *hdata;
2241 struct exynos_drm_hdmi_pdata *pdata;
2242 struct resource *res;
2245 DRM_DEBUG_KMS("[%d]\n", __LINE__);
2247 pdata = pdev->dev.platform_data;
2249 DRM_ERROR("no platform data specified\n");
2253 drm_hdmi_ctx = kzalloc(sizeof(*drm_hdmi_ctx), GFP_KERNEL);
2254 if (!drm_hdmi_ctx) {
2255 DRM_ERROR("failed to allocate common hdmi context.\n");
2259 hdata = kzalloc(sizeof(struct hdmi_context), GFP_KERNEL);
2261 DRM_ERROR("out of memory\n");
2262 kfree(drm_hdmi_ctx);
2266 drm_hdmi_ctx->ctx = (void *)hdata;
2267 hdata->parent_ctx = (void *)drm_hdmi_ctx;
2269 platform_set_drvdata(pdev, drm_hdmi_ctx);
2271 hdata->is_v13 = pdata->is_v13;
2272 hdata->default_win = pdata->default_win;
2273 hdata->default_timing = &pdata->timing;
2274 hdata->default_bpp = pdata->bpp;
2277 ret = hdmi_resources_init(hdata);
2283 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2285 DRM_ERROR("failed to find registers\n");
2290 hdata->regs_res = request_mem_region(res->start, resource_size(res),
2292 if (!hdata->regs_res) {
2293 DRM_ERROR("failed to claim register region\n");
2298 hdata->regs = ioremap(res->start, resource_size(res));
2300 DRM_ERROR("failed to map registers\n");
2302 goto err_req_region;
2305 /* DDC i2c driver */
2306 if (i2c_add_driver(&ddc_driver)) {
2307 DRM_ERROR("failed to register ddc i2c driver\n");
2312 hdata->ddc_port = hdmi_ddc;
2314 /* hdmiphy i2c driver */
2315 if (i2c_add_driver(&hdmiphy_driver)) {
2316 DRM_ERROR("failed to register hdmiphy i2c driver\n");
2321 hdata->hdmiphy_port = hdmi_hdmiphy;
2323 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
2325 DRM_ERROR("get interrupt resource failed.\n");
2330 /* create workqueue and hotplug work */
2331 hdata->wq = alloc_workqueue("exynos-drm-hdmi",
2332 WQ_UNBOUND | WQ_NON_REENTRANT, 1);
2333 if (hdata->wq == NULL) {
2334 DRM_ERROR("Failed to create workqueue.\n");
2338 INIT_WORK(&hdata->hotplug_work, hdmi_hotplug_func);
2340 /* register hpd interrupt */
2341 ret = request_irq(res->start, hdmi_irq_handler, 0, "drm_hdmi",
2344 DRM_ERROR("request interrupt failed.\n");
2347 hdata->irq = res->start;
2349 /* Attach HDMI Driver to common hdmi. */
2350 exynos_hdmi_drv_attach(drm_hdmi_ctx);
2352 /* register specific callbacks to common hdmi. */
2353 exynos_hdmi_ops_register(&hdmi_ops);
2355 hdmi_resource_poweron(hdata);
2360 destroy_workqueue(hdata->wq);
2362 i2c_del_driver(&hdmiphy_driver);
2364 i2c_del_driver(&ddc_driver);
2366 iounmap(hdata->regs);
2368 release_mem_region(hdata->regs_res->start,
2369 resource_size(hdata->regs_res));
2371 hdmi_resources_cleanup(hdata);
2374 kfree(drm_hdmi_ctx);
2378 static int __devexit hdmi_remove(struct platform_device *pdev)
2380 struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev);
2381 struct hdmi_context *hdata = ctx->ctx;
2383 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2385 hdmi_resource_poweroff(hdata);
2387 disable_irq(hdata->irq);
2388 free_irq(hdata->irq, hdata);
2390 cancel_work_sync(&hdata->hotplug_work);
2391 destroy_workqueue(hdata->wq);
2393 hdmi_resources_cleanup(hdata);
2395 iounmap(hdata->regs);
2397 release_mem_region(hdata->regs_res->start,
2398 resource_size(hdata->regs_res));
2400 /* hdmiphy i2c driver */
2401 i2c_del_driver(&hdmiphy_driver);
2402 /* DDC i2c driver */
2403 i2c_del_driver(&ddc_driver);
2410 struct platform_driver hdmi_driver = {
2411 .probe = hdmi_probe,
2412 .remove = __devexit_p(hdmi_remove),
2414 #ifdef CONFIG_ARCH_EXYNOS5
2415 .name = "exynos5-hdmi",
2417 .name = "exynos4-hdmi",
2419 .owner = THIS_MODULE,