2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
4 * Seung-Woo Kim <sw0312.kim@samsung.com>
5 * Inki Dae <inki.dae@samsung.com>
6 * Joonyoung Shim <jy0922.shim@samsung.com>
8 * Based on drivers/media/video/s5p-tv/hdmi_drv.c
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
19 #include "drm_crtc_helper.h"
21 #include "regs-hdmi.h"
23 #include <linux/kernel.h>
24 #include <linux/spinlock.h>
25 #include <linux/wait.h>
26 #include <linux/i2c.h>
27 #include <linux/module.h>
28 #include <linux/platform_device.h>
29 #include <linux/interrupt.h>
30 #include <linux/irq.h>
31 #include <linux/delay.h>
32 #include <linux/pm_runtime.h>
33 #include <linux/clk.h>
34 #include <linux/regulator/consumer.h>
36 #include <drm/exynos_drm.h>
38 #include "exynos_drm_drv.h"
39 #include "exynos_drm_hdmi.h"
41 #include "exynos_hdmi.h"
43 #define HDMI_OVERLAY_NUMBER 3
44 #define MAX_WIDTH 1920
45 #define MAX_HEIGHT 1080
46 #define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev))
48 struct hdmi_resources {
50 struct clk *sclk_hdmi;
51 struct clk *sclk_pixel;
52 struct clk *sclk_hdmiphy;
54 struct regulator_bulk_data *regul_bulk;
60 struct drm_device *drm_dev;
61 struct fb_videomode *default_timing;
62 unsigned int is_v13:1;
63 unsigned int default_win;
64 unsigned int default_bpp;
68 struct resource *regs_res;
71 struct workqueue_struct *wq;
72 struct work_struct hotplug_work;
74 struct i2c_client *ddc_port;
75 struct i2c_client *hdmiphy_port;
77 /* current hdmiphy conf index */
80 struct hdmi_resources res;
84 /* HDMI Version 1.3 */
85 static const u8 hdmiphy_v13_conf27[32] = {
86 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
87 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
88 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
89 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
92 static const u8 hdmiphy_v13_conf27_027[32] = {
93 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
94 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
95 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
96 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
99 static const u8 hdmiphy_v13_conf74_175[32] = {
100 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
101 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
102 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
103 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
106 static const u8 hdmiphy_v13_conf74_25[32] = {
107 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
108 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
109 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
110 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
113 static const u8 hdmiphy_v13_conf148_5[32] = {
114 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
115 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
116 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
117 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
120 struct hdmi_v13_tg_regs {
152 struct hdmi_v13_core_regs {
165 struct hdmi_v13_preset_conf {
166 struct hdmi_v13_core_regs core;
167 struct hdmi_v13_tg_regs tg;
170 struct hdmi_v13_conf {
175 const u8 *hdmiphy_data;
176 const struct hdmi_v13_preset_conf *conf;
179 static const struct hdmi_v13_preset_conf hdmi_v13_conf_480p = {
181 .h_blank = {0x8a, 0x00},
182 .v_blank = {0x0d, 0x6a, 0x01},
183 .h_v_line = {0x0d, 0xa2, 0x35},
185 .int_pro_mode = {0x00},
186 .v_blank_f = {0x00, 0x00, 0x00},
187 .h_sync_gen = {0x0e, 0x30, 0x11},
188 .v_sync_gen1 = {0x0f, 0x90, 0x00},
189 /* other don't care */
193 0x5a, 0x03, /* h_fsz */
194 0x8a, 0x00, 0xd0, 0x02, /* hact */
195 0x0d, 0x02, /* v_fsz */
196 0x01, 0x00, 0x33, 0x02, /* vsync */
197 0x2d, 0x00, 0xe0, 0x01, /* vact */
198 0x33, 0x02, /* field_chg */
199 0x49, 0x02, /* vact_st2 */
200 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
201 0x01, 0x00, 0x33, 0x02, /* field top/bot */
205 static const struct hdmi_v13_preset_conf hdmi_v13_conf_720p60 = {
207 .h_blank = {0x72, 0x01},
208 .v_blank = {0xee, 0xf2, 0x00},
209 .h_v_line = {0xee, 0x22, 0x67},
211 .int_pro_mode = {0x00},
212 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
213 .h_sync_gen = {0x6c, 0x50, 0x02},
214 .v_sync_gen1 = {0x0a, 0x50, 0x00},
215 .v_sync_gen2 = {0x01, 0x10, 0x00},
216 .v_sync_gen3 = {0x01, 0x10, 0x00},
217 /* other don't care */
221 0x72, 0x06, /* h_fsz */
222 0x71, 0x01, 0x01, 0x05, /* hact */
223 0xee, 0x02, /* v_fsz */
224 0x01, 0x00, 0x33, 0x02, /* vsync */
225 0x1e, 0x00, 0xd0, 0x02, /* vact */
226 0x33, 0x02, /* field_chg */
227 0x49, 0x02, /* vact_st2 */
228 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
229 0x01, 0x00, 0x33, 0x02, /* field top/bot */
233 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i50 = {
235 .h_blank = {0xd0, 0x02},
236 .v_blank = {0x32, 0xB2, 0x00},
237 .h_v_line = {0x65, 0x04, 0xa5},
239 .int_pro_mode = {0x01},
240 .v_blank_f = {0x49, 0x2A, 0x23},
241 .h_sync_gen = {0x0E, 0xEA, 0x08},
242 .v_sync_gen1 = {0x07, 0x20, 0x00},
243 .v_sync_gen2 = {0x39, 0x42, 0x23},
244 .v_sync_gen3 = {0x38, 0x87, 0x73},
245 /* other don't care */
249 0x50, 0x0A, /* h_fsz */
250 0xCF, 0x02, 0x81, 0x07, /* hact */
251 0x65, 0x04, /* v_fsz */
252 0x01, 0x00, 0x33, 0x02, /* vsync */
253 0x16, 0x00, 0x1c, 0x02, /* vact */
254 0x33, 0x02, /* field_chg */
255 0x49, 0x02, /* vact_st2 */
256 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
257 0x01, 0x00, 0x33, 0x02, /* field top/bot */
261 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p50 = {
263 .h_blank = {0xd0, 0x02},
264 .v_blank = {0x65, 0x6c, 0x01},
265 .h_v_line = {0x65, 0x04, 0xa5},
267 .int_pro_mode = {0x00},
268 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
269 .h_sync_gen = {0x0e, 0xea, 0x08},
270 .v_sync_gen1 = {0x09, 0x40, 0x00},
271 .v_sync_gen2 = {0x01, 0x10, 0x00},
272 .v_sync_gen3 = {0x01, 0x10, 0x00},
273 /* other don't care */
277 0x50, 0x0A, /* h_fsz */
278 0xCF, 0x02, 0x81, 0x07, /* hact */
279 0x65, 0x04, /* v_fsz */
280 0x01, 0x00, 0x33, 0x02, /* vsync */
281 0x2d, 0x00, 0x38, 0x04, /* vact */
282 0x33, 0x02, /* field_chg */
283 0x48, 0x02, /* vact_st2 */
284 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
285 0x01, 0x00, 0x33, 0x02, /* field top/bot */
289 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i60 = {
291 .h_blank = {0x18, 0x01},
292 .v_blank = {0x32, 0xB2, 0x00},
293 .h_v_line = {0x65, 0x84, 0x89},
295 .int_pro_mode = {0x01},
296 .v_blank_f = {0x49, 0x2A, 0x23},
297 .h_sync_gen = {0x56, 0x08, 0x02},
298 .v_sync_gen1 = {0x07, 0x20, 0x00},
299 .v_sync_gen2 = {0x39, 0x42, 0x23},
300 .v_sync_gen3 = {0xa4, 0x44, 0x4a},
301 /* other don't care */
305 0x98, 0x08, /* h_fsz */
306 0x17, 0x01, 0x81, 0x07, /* hact */
307 0x65, 0x04, /* v_fsz */
308 0x01, 0x00, 0x33, 0x02, /* vsync */
309 0x16, 0x00, 0x1c, 0x02, /* vact */
310 0x33, 0x02, /* field_chg */
311 0x49, 0x02, /* vact_st2 */
312 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
313 0x01, 0x00, 0x33, 0x02, /* field top/bot */
317 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60 = {
319 .h_blank = {0x18, 0x01},
320 .v_blank = {0x65, 0x6c, 0x01},
321 .h_v_line = {0x65, 0x84, 0x89},
323 .int_pro_mode = {0x00},
324 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
325 .h_sync_gen = {0x56, 0x08, 0x02},
326 .v_sync_gen1 = {0x09, 0x40, 0x00},
327 .v_sync_gen2 = {0x01, 0x10, 0x00},
328 .v_sync_gen3 = {0x01, 0x10, 0x00},
329 /* other don't care */
333 0x98, 0x08, /* h_fsz */
334 0x17, 0x01, 0x81, 0x07, /* hact */
335 0x65, 0x04, /* v_fsz */
336 0x01, 0x00, 0x33, 0x02, /* vsync */
337 0x2d, 0x00, 0x38, 0x04, /* vact */
338 0x33, 0x02, /* field_chg */
339 0x48, 0x02, /* vact_st2 */
340 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
341 0x01, 0x00, 0x33, 0x02, /* field top/bot */
345 static const struct hdmi_v13_conf hdmi_v13_confs[] = {
346 { 1280, 720, 60, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 },
347 { 1280, 720, 50, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 },
348 { 720, 480, 60, false, hdmiphy_v13_conf27_027, &hdmi_v13_conf_480p },
349 { 1920, 1080, 50, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i50 },
350 { 1920, 1080, 50, false, hdmiphy_v13_conf148_5,
351 &hdmi_v13_conf_1080p50 },
352 { 1920, 1080, 60, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i60 },
353 { 1920, 1080, 60, false, hdmiphy_v13_conf148_5,
354 &hdmi_v13_conf_1080p60 },
357 /* HDMI Version 1.4 */
358 static const u8 hdmiphy_conf27_027[32] = {
359 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
360 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
361 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
362 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
365 static const u8 hdmiphy_conf74_25[32] = {
366 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
367 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
368 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
369 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
372 static const u8 hdmiphy_conf148_5[32] = {
373 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
374 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
375 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
376 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
379 struct hdmi_tg_regs {
416 struct hdmi_core_regs {
429 u8 v_sync_line_bef_2[2];
430 u8 v_sync_line_bef_1[2];
431 u8 v_sync_line_aft_2[2];
432 u8 v_sync_line_aft_1[2];
433 u8 v_sync_line_aft_pxl_2[2];
434 u8 v_sync_line_aft_pxl_1[2];
435 u8 v_blank_f2[2]; /* for 3D mode */
436 u8 v_blank_f3[2]; /* for 3D mode */
437 u8 v_blank_f4[2]; /* for 3D mode */
438 u8 v_blank_f5[2]; /* for 3D mode */
439 u8 v_sync_line_aft_3[2];
440 u8 v_sync_line_aft_4[2];
441 u8 v_sync_line_aft_5[2];
442 u8 v_sync_line_aft_6[2];
443 u8 v_sync_line_aft_pxl_3[2];
444 u8 v_sync_line_aft_pxl_4[2];
445 u8 v_sync_line_aft_pxl_5[2];
446 u8 v_sync_line_aft_pxl_6[2];
455 struct hdmi_preset_conf {
456 struct hdmi_core_regs core;
457 struct hdmi_tg_regs tg;
465 const u8 *hdmiphy_data;
466 const struct hdmi_preset_conf *conf;
469 static const struct hdmi_preset_conf hdmi_conf_480p60 = {
471 .h_blank = {0x8a, 0x00},
472 .v2_blank = {0x0d, 0x02},
473 .v1_blank = {0x2d, 0x00},
474 .v_line = {0x0d, 0x02},
475 .h_line = {0x5a, 0x03},
478 .int_pro_mode = {0x00},
479 .v_blank_f0 = {0xff, 0xff},
480 .v_blank_f1 = {0xff, 0xff},
481 .h_sync_start = {0x0e, 0x00},
482 .h_sync_end = {0x4c, 0x00},
483 .v_sync_line_bef_2 = {0x0f, 0x00},
484 .v_sync_line_bef_1 = {0x09, 0x00},
485 .v_sync_line_aft_2 = {0xff, 0xff},
486 .v_sync_line_aft_1 = {0xff, 0xff},
487 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
488 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
489 .v_blank_f2 = {0xff, 0xff},
490 .v_blank_f3 = {0xff, 0xff},
491 .v_blank_f4 = {0xff, 0xff},
492 .v_blank_f5 = {0xff, 0xff},
493 .v_sync_line_aft_3 = {0xff, 0xff},
494 .v_sync_line_aft_4 = {0xff, 0xff},
495 .v_sync_line_aft_5 = {0xff, 0xff},
496 .v_sync_line_aft_6 = {0xff, 0xff},
497 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
498 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
499 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
500 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
501 .vact_space_1 = {0xff, 0xff},
502 .vact_space_2 = {0xff, 0xff},
503 .vact_space_3 = {0xff, 0xff},
504 .vact_space_4 = {0xff, 0xff},
505 .vact_space_5 = {0xff, 0xff},
506 .vact_space_6 = {0xff, 0xff},
507 /* other don't care */
511 0x5a, 0x03, /* h_fsz */
512 0x8a, 0x00, 0xd0, 0x02, /* hact */
513 0x0d, 0x02, /* v_fsz */
514 0x01, 0x00, 0x33, 0x02, /* vsync */
515 0x2d, 0x00, 0xe0, 0x01, /* vact */
516 0x33, 0x02, /* field_chg */
517 0x48, 0x02, /* vact_st2 */
518 0x00, 0x00, /* vact_st3 */
519 0x00, 0x00, /* vact_st4 */
520 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
521 0x01, 0x00, 0x33, 0x02, /* field top/bot */
526 static const struct hdmi_preset_conf hdmi_conf_720p50 = {
528 .h_blank = {0xbc, 0x02},
529 .v2_blank = {0xee, 0x02},
530 .v1_blank = {0x1e, 0x00},
531 .v_line = {0xee, 0x02},
532 .h_line = {0xbc, 0x07},
535 .int_pro_mode = {0x00},
536 .v_blank_f0 = {0xff, 0xff},
537 .v_blank_f1 = {0xff, 0xff},
538 .h_sync_start = {0xb6, 0x01},
539 .h_sync_end = {0xde, 0x01},
540 .v_sync_line_bef_2 = {0x0a, 0x00},
541 .v_sync_line_bef_1 = {0x05, 0x00},
542 .v_sync_line_aft_2 = {0xff, 0xff},
543 .v_sync_line_aft_1 = {0xff, 0xff},
544 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
545 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
546 .v_blank_f2 = {0xff, 0xff},
547 .v_blank_f3 = {0xff, 0xff},
548 .v_blank_f4 = {0xff, 0xff},
549 .v_blank_f5 = {0xff, 0xff},
550 .v_sync_line_aft_3 = {0xff, 0xff},
551 .v_sync_line_aft_4 = {0xff, 0xff},
552 .v_sync_line_aft_5 = {0xff, 0xff},
553 .v_sync_line_aft_6 = {0xff, 0xff},
554 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
555 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
556 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
557 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
558 .vact_space_1 = {0xff, 0xff},
559 .vact_space_2 = {0xff, 0xff},
560 .vact_space_3 = {0xff, 0xff},
561 .vact_space_4 = {0xff, 0xff},
562 .vact_space_5 = {0xff, 0xff},
563 .vact_space_6 = {0xff, 0xff},
564 /* other don't care */
568 0xbc, 0x07, /* h_fsz */
569 0xbc, 0x02, 0x00, 0x05, /* hact */
570 0xee, 0x02, /* v_fsz */
571 0x01, 0x00, 0x33, 0x02, /* vsync */
572 0x1e, 0x00, 0xd0, 0x02, /* vact */
573 0x33, 0x02, /* field_chg */
574 0x48, 0x02, /* vact_st2 */
575 0x00, 0x00, /* vact_st3 */
576 0x00, 0x00, /* vact_st4 */
577 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
578 0x01, 0x00, 0x33, 0x02, /* field top/bot */
583 static const struct hdmi_preset_conf hdmi_conf_720p60 = {
585 .h_blank = {0x72, 0x01},
586 .v2_blank = {0xee, 0x02},
587 .v1_blank = {0x1e, 0x00},
588 .v_line = {0xee, 0x02},
589 .h_line = {0x72, 0x06},
592 .int_pro_mode = {0x00},
593 .v_blank_f0 = {0xff, 0xff},
594 .v_blank_f1 = {0xff, 0xff},
595 .h_sync_start = {0x6c, 0x00},
596 .h_sync_end = {0x94, 0x00},
597 .v_sync_line_bef_2 = {0x0a, 0x00},
598 .v_sync_line_bef_1 = {0x05, 0x00},
599 .v_sync_line_aft_2 = {0xff, 0xff},
600 .v_sync_line_aft_1 = {0xff, 0xff},
601 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
602 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
603 .v_blank_f2 = {0xff, 0xff},
604 .v_blank_f3 = {0xff, 0xff},
605 .v_blank_f4 = {0xff, 0xff},
606 .v_blank_f5 = {0xff, 0xff},
607 .v_sync_line_aft_3 = {0xff, 0xff},
608 .v_sync_line_aft_4 = {0xff, 0xff},
609 .v_sync_line_aft_5 = {0xff, 0xff},
610 .v_sync_line_aft_6 = {0xff, 0xff},
611 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
612 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
613 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
614 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
615 .vact_space_1 = {0xff, 0xff},
616 .vact_space_2 = {0xff, 0xff},
617 .vact_space_3 = {0xff, 0xff},
618 .vact_space_4 = {0xff, 0xff},
619 .vact_space_5 = {0xff, 0xff},
620 .vact_space_6 = {0xff, 0xff},
621 /* other don't care */
625 0x72, 0x06, /* h_fsz */
626 0x72, 0x01, 0x00, 0x05, /* hact */
627 0xee, 0x02, /* v_fsz */
628 0x01, 0x00, 0x33, 0x02, /* vsync */
629 0x1e, 0x00, 0xd0, 0x02, /* vact */
630 0x33, 0x02, /* field_chg */
631 0x48, 0x02, /* vact_st2 */
632 0x00, 0x00, /* vact_st3 */
633 0x00, 0x00, /* vact_st4 */
634 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
635 0x01, 0x00, 0x33, 0x02, /* field top/bot */
640 static const struct hdmi_preset_conf hdmi_conf_1080i50 = {
642 .h_blank = {0xd0, 0x02},
643 .v2_blank = {0x32, 0x02},
644 .v1_blank = {0x16, 0x00},
645 .v_line = {0x65, 0x04},
646 .h_line = {0x50, 0x0a},
649 .int_pro_mode = {0x01},
650 .v_blank_f0 = {0x49, 0x02},
651 .v_blank_f1 = {0x65, 0x04},
652 .h_sync_start = {0x0e, 0x02},
653 .h_sync_end = {0x3a, 0x02},
654 .v_sync_line_bef_2 = {0x07, 0x00},
655 .v_sync_line_bef_1 = {0x02, 0x00},
656 .v_sync_line_aft_2 = {0x39, 0x02},
657 .v_sync_line_aft_1 = {0x34, 0x02},
658 .v_sync_line_aft_pxl_2 = {0x38, 0x07},
659 .v_sync_line_aft_pxl_1 = {0x38, 0x07},
660 .v_blank_f2 = {0xff, 0xff},
661 .v_blank_f3 = {0xff, 0xff},
662 .v_blank_f4 = {0xff, 0xff},
663 .v_blank_f5 = {0xff, 0xff},
664 .v_sync_line_aft_3 = {0xff, 0xff},
665 .v_sync_line_aft_4 = {0xff, 0xff},
666 .v_sync_line_aft_5 = {0xff, 0xff},
667 .v_sync_line_aft_6 = {0xff, 0xff},
668 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
669 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
670 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
671 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
672 .vact_space_1 = {0xff, 0xff},
673 .vact_space_2 = {0xff, 0xff},
674 .vact_space_3 = {0xff, 0xff},
675 .vact_space_4 = {0xff, 0xff},
676 .vact_space_5 = {0xff, 0xff},
677 .vact_space_6 = {0xff, 0xff},
678 /* other don't care */
682 0x50, 0x0a, /* h_fsz */
683 0xd0, 0x02, 0x80, 0x07, /* hact */
684 0x65, 0x04, /* v_fsz */
685 0x01, 0x00, 0x33, 0x02, /* vsync */
686 0x16, 0x00, 0x1c, 0x02, /* vact */
687 0x33, 0x02, /* field_chg */
688 0x49, 0x02, /* vact_st2 */
689 0x00, 0x00, /* vact_st3 */
690 0x00, 0x00, /* vact_st4 */
691 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
692 0x01, 0x00, 0x33, 0x02, /* field top/bot */
697 static const struct hdmi_preset_conf hdmi_conf_1080i60 = {
699 .h_blank = {0x18, 0x01},
700 .v2_blank = {0x32, 0x02},
701 .v1_blank = {0x16, 0x00},
702 .v_line = {0x65, 0x04},
703 .h_line = {0x98, 0x08},
706 .int_pro_mode = {0x01},
707 .v_blank_f0 = {0x49, 0x02},
708 .v_blank_f1 = {0x65, 0x04},
709 .h_sync_start = {0x56, 0x00},
710 .h_sync_end = {0x82, 0x00},
711 .v_sync_line_bef_2 = {0x07, 0x00},
712 .v_sync_line_bef_1 = {0x02, 0x00},
713 .v_sync_line_aft_2 = {0x39, 0x02},
714 .v_sync_line_aft_1 = {0x34, 0x02},
715 .v_sync_line_aft_pxl_2 = {0xa4, 0x04},
716 .v_sync_line_aft_pxl_1 = {0xa4, 0x04},
717 .v_blank_f2 = {0xff, 0xff},
718 .v_blank_f3 = {0xff, 0xff},
719 .v_blank_f4 = {0xff, 0xff},
720 .v_blank_f5 = {0xff, 0xff},
721 .v_sync_line_aft_3 = {0xff, 0xff},
722 .v_sync_line_aft_4 = {0xff, 0xff},
723 .v_sync_line_aft_5 = {0xff, 0xff},
724 .v_sync_line_aft_6 = {0xff, 0xff},
725 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
726 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
727 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
728 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
729 .vact_space_1 = {0xff, 0xff},
730 .vact_space_2 = {0xff, 0xff},
731 .vact_space_3 = {0xff, 0xff},
732 .vact_space_4 = {0xff, 0xff},
733 .vact_space_5 = {0xff, 0xff},
734 .vact_space_6 = {0xff, 0xff},
735 /* other don't care */
739 0x98, 0x08, /* h_fsz */
740 0x18, 0x01, 0x80, 0x07, /* hact */
741 0x65, 0x04, /* v_fsz */
742 0x01, 0x00, 0x33, 0x02, /* vsync */
743 0x16, 0x00, 0x1c, 0x02, /* vact */
744 0x33, 0x02, /* field_chg */
745 0x49, 0x02, /* vact_st2 */
746 0x00, 0x00, /* vact_st3 */
747 0x00, 0x00, /* vact_st4 */
748 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
749 0x01, 0x00, 0x33, 0x02, /* field top/bot */
754 static const struct hdmi_preset_conf hdmi_conf_1080p50 = {
756 .h_blank = {0xd0, 0x02},
757 .v2_blank = {0x65, 0x04},
758 .v1_blank = {0x2d, 0x00},
759 .v_line = {0x65, 0x04},
760 .h_line = {0x50, 0x0a},
763 .int_pro_mode = {0x00},
764 .v_blank_f0 = {0xff, 0xff},
765 .v_blank_f1 = {0xff, 0xff},
766 .h_sync_start = {0x0e, 0x02},
767 .h_sync_end = {0x3a, 0x02},
768 .v_sync_line_bef_2 = {0x09, 0x00},
769 .v_sync_line_bef_1 = {0x04, 0x00},
770 .v_sync_line_aft_2 = {0xff, 0xff},
771 .v_sync_line_aft_1 = {0xff, 0xff},
772 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
773 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
774 .v_blank_f2 = {0xff, 0xff},
775 .v_blank_f3 = {0xff, 0xff},
776 .v_blank_f4 = {0xff, 0xff},
777 .v_blank_f5 = {0xff, 0xff},
778 .v_sync_line_aft_3 = {0xff, 0xff},
779 .v_sync_line_aft_4 = {0xff, 0xff},
780 .v_sync_line_aft_5 = {0xff, 0xff},
781 .v_sync_line_aft_6 = {0xff, 0xff},
782 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
783 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
784 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
785 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
786 .vact_space_1 = {0xff, 0xff},
787 .vact_space_2 = {0xff, 0xff},
788 .vact_space_3 = {0xff, 0xff},
789 .vact_space_4 = {0xff, 0xff},
790 .vact_space_5 = {0xff, 0xff},
791 .vact_space_6 = {0xff, 0xff},
792 /* other don't care */
796 0x50, 0x0a, /* h_fsz */
797 0xd0, 0x02, 0x80, 0x07, /* hact */
798 0x65, 0x04, /* v_fsz */
799 0x01, 0x00, 0x33, 0x02, /* vsync */
800 0x2d, 0x00, 0x38, 0x04, /* vact */
801 0x33, 0x02, /* field_chg */
802 0x48, 0x02, /* vact_st2 */
803 0x00, 0x00, /* vact_st3 */
804 0x00, 0x00, /* vact_st4 */
805 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
806 0x01, 0x00, 0x33, 0x02, /* field top/bot */
811 static const struct hdmi_preset_conf hdmi_conf_1080p60 = {
813 .h_blank = {0x18, 0x01},
814 .v2_blank = {0x65, 0x04},
815 .v1_blank = {0x2d, 0x00},
816 .v_line = {0x65, 0x04},
817 .h_line = {0x98, 0x08},
820 .int_pro_mode = {0x00},
821 .v_blank_f0 = {0xff, 0xff},
822 .v_blank_f1 = {0xff, 0xff},
823 .h_sync_start = {0x56, 0x00},
824 .h_sync_end = {0x82, 0x00},
825 .v_sync_line_bef_2 = {0x09, 0x00},
826 .v_sync_line_bef_1 = {0x04, 0x00},
827 .v_sync_line_aft_2 = {0xff, 0xff},
828 .v_sync_line_aft_1 = {0xff, 0xff},
829 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
830 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
831 .v_blank_f2 = {0xff, 0xff},
832 .v_blank_f3 = {0xff, 0xff},
833 .v_blank_f4 = {0xff, 0xff},
834 .v_blank_f5 = {0xff, 0xff},
835 .v_sync_line_aft_3 = {0xff, 0xff},
836 .v_sync_line_aft_4 = {0xff, 0xff},
837 .v_sync_line_aft_5 = {0xff, 0xff},
838 .v_sync_line_aft_6 = {0xff, 0xff},
839 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
840 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
841 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
842 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
843 /* other don't care */
847 0x98, 0x08, /* h_fsz */
848 0x18, 0x01, 0x80, 0x07, /* hact */
849 0x65, 0x04, /* v_fsz */
850 0x01, 0x00, 0x33, 0x02, /* vsync */
851 0x2d, 0x00, 0x38, 0x04, /* vact */
852 0x33, 0x02, /* field_chg */
853 0x48, 0x02, /* vact_st2 */
854 0x00, 0x00, /* vact_st3 */
855 0x00, 0x00, /* vact_st4 */
856 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
857 0x01, 0x00, 0x33, 0x02, /* field top/bot */
862 static const struct hdmi_conf hdmi_confs[] = {
863 { 720, 480, 60, false, hdmiphy_conf27_027, &hdmi_conf_480p60 },
864 { 1280, 720, 50, false, hdmiphy_conf74_25, &hdmi_conf_720p50 },
865 { 1280, 720, 60, false, hdmiphy_conf74_25, &hdmi_conf_720p60 },
866 { 1920, 1080, 50, true, hdmiphy_conf74_25, &hdmi_conf_1080i50 },
867 { 1920, 1080, 60, true, hdmiphy_conf74_25, &hdmi_conf_1080i60 },
868 { 1920, 1080, 50, false, hdmiphy_conf148_5, &hdmi_conf_1080p50 },
869 { 1920, 1080, 60, false, hdmiphy_conf148_5, &hdmi_conf_1080p60 },
873 static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
875 return readl(hdata->regs + reg_id);
878 static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
879 u32 reg_id, u8 value)
881 writeb(value, hdata->regs + reg_id);
884 static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
885 u32 reg_id, u32 value, u32 mask)
887 u32 old = readl(hdata->regs + reg_id);
888 value = (value & mask) | (old & ~mask);
889 writel(value, hdata->regs + reg_id);
892 static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix)
894 #define DUMPREG(reg_id) \
895 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
896 readl(hdata->regs + reg_id))
897 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
898 DUMPREG(HDMI_INTC_FLAG);
899 DUMPREG(HDMI_INTC_CON);
900 DUMPREG(HDMI_HPD_STATUS);
901 DUMPREG(HDMI_V13_PHY_RSTOUT);
902 DUMPREG(HDMI_V13_PHY_VPLL);
903 DUMPREG(HDMI_V13_PHY_CMU);
904 DUMPREG(HDMI_V13_CORE_RSTOUT);
906 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
910 DUMPREG(HDMI_SYS_STATUS);
911 DUMPREG(HDMI_V13_PHY_STATUS);
912 DUMPREG(HDMI_STATUS_EN);
914 DUMPREG(HDMI_MODE_SEL);
915 DUMPREG(HDMI_V13_HPD_GEN);
916 DUMPREG(HDMI_V13_DC_CONTROL);
917 DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN);
919 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
920 DUMPREG(HDMI_H_BLANK_0);
921 DUMPREG(HDMI_H_BLANK_1);
922 DUMPREG(HDMI_V13_V_BLANK_0);
923 DUMPREG(HDMI_V13_V_BLANK_1);
924 DUMPREG(HDMI_V13_V_BLANK_2);
925 DUMPREG(HDMI_V13_H_V_LINE_0);
926 DUMPREG(HDMI_V13_H_V_LINE_1);
927 DUMPREG(HDMI_V13_H_V_LINE_2);
928 DUMPREG(HDMI_VSYNC_POL);
929 DUMPREG(HDMI_INT_PRO_MODE);
930 DUMPREG(HDMI_V13_V_BLANK_F_0);
931 DUMPREG(HDMI_V13_V_BLANK_F_1);
932 DUMPREG(HDMI_V13_V_BLANK_F_2);
933 DUMPREG(HDMI_V13_H_SYNC_GEN_0);
934 DUMPREG(HDMI_V13_H_SYNC_GEN_1);
935 DUMPREG(HDMI_V13_H_SYNC_GEN_2);
936 DUMPREG(HDMI_V13_V_SYNC_GEN_1_0);
937 DUMPREG(HDMI_V13_V_SYNC_GEN_1_1);
938 DUMPREG(HDMI_V13_V_SYNC_GEN_1_2);
939 DUMPREG(HDMI_V13_V_SYNC_GEN_2_0);
940 DUMPREG(HDMI_V13_V_SYNC_GEN_2_1);
941 DUMPREG(HDMI_V13_V_SYNC_GEN_2_2);
942 DUMPREG(HDMI_V13_V_SYNC_GEN_3_0);
943 DUMPREG(HDMI_V13_V_SYNC_GEN_3_1);
944 DUMPREG(HDMI_V13_V_SYNC_GEN_3_2);
946 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
947 DUMPREG(HDMI_TG_CMD);
948 DUMPREG(HDMI_TG_H_FSZ_L);
949 DUMPREG(HDMI_TG_H_FSZ_H);
950 DUMPREG(HDMI_TG_HACT_ST_L);
951 DUMPREG(HDMI_TG_HACT_ST_H);
952 DUMPREG(HDMI_TG_HACT_SZ_L);
953 DUMPREG(HDMI_TG_HACT_SZ_H);
954 DUMPREG(HDMI_TG_V_FSZ_L);
955 DUMPREG(HDMI_TG_V_FSZ_H);
956 DUMPREG(HDMI_TG_VSYNC_L);
957 DUMPREG(HDMI_TG_VSYNC_H);
958 DUMPREG(HDMI_TG_VSYNC2_L);
959 DUMPREG(HDMI_TG_VSYNC2_H);
960 DUMPREG(HDMI_TG_VACT_ST_L);
961 DUMPREG(HDMI_TG_VACT_ST_H);
962 DUMPREG(HDMI_TG_VACT_SZ_L);
963 DUMPREG(HDMI_TG_VACT_SZ_H);
964 DUMPREG(HDMI_TG_FIELD_CHG_L);
965 DUMPREG(HDMI_TG_FIELD_CHG_H);
966 DUMPREG(HDMI_TG_VACT_ST2_L);
967 DUMPREG(HDMI_TG_VACT_ST2_H);
968 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
969 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
970 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
971 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
972 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
973 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
974 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
975 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
979 static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix)
983 #define DUMPREG(reg_id) \
984 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
985 readl(hdata->regs + reg_id))
987 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
988 DUMPREG(HDMI_INTC_CON);
989 DUMPREG(HDMI_INTC_FLAG);
990 DUMPREG(HDMI_HPD_STATUS);
991 DUMPREG(HDMI_INTC_CON_1);
992 DUMPREG(HDMI_INTC_FLAG_1);
993 DUMPREG(HDMI_PHY_STATUS_0);
994 DUMPREG(HDMI_PHY_STATUS_PLL);
995 DUMPREG(HDMI_PHY_CON_0);
996 DUMPREG(HDMI_PHY_RSTOUT);
997 DUMPREG(HDMI_PHY_VPLL);
998 DUMPREG(HDMI_PHY_CMU);
999 DUMPREG(HDMI_CORE_RSTOUT);
1001 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
1002 DUMPREG(HDMI_CON_0);
1003 DUMPREG(HDMI_CON_1);
1004 DUMPREG(HDMI_CON_2);
1005 DUMPREG(HDMI_SYS_STATUS);
1006 DUMPREG(HDMI_PHY_STATUS_0);
1007 DUMPREG(HDMI_STATUS_EN);
1009 DUMPREG(HDMI_MODE_SEL);
1010 DUMPREG(HDMI_ENC_EN);
1011 DUMPREG(HDMI_DC_CONTROL);
1012 DUMPREG(HDMI_VIDEO_PATTERN_GEN);
1014 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
1015 DUMPREG(HDMI_H_BLANK_0);
1016 DUMPREG(HDMI_H_BLANK_1);
1017 DUMPREG(HDMI_V2_BLANK_0);
1018 DUMPREG(HDMI_V2_BLANK_1);
1019 DUMPREG(HDMI_V1_BLANK_0);
1020 DUMPREG(HDMI_V1_BLANK_1);
1021 DUMPREG(HDMI_V_LINE_0);
1022 DUMPREG(HDMI_V_LINE_1);
1023 DUMPREG(HDMI_H_LINE_0);
1024 DUMPREG(HDMI_H_LINE_1);
1025 DUMPREG(HDMI_HSYNC_POL);
1027 DUMPREG(HDMI_VSYNC_POL);
1028 DUMPREG(HDMI_INT_PRO_MODE);
1029 DUMPREG(HDMI_V_BLANK_F0_0);
1030 DUMPREG(HDMI_V_BLANK_F0_1);
1031 DUMPREG(HDMI_V_BLANK_F1_0);
1032 DUMPREG(HDMI_V_BLANK_F1_1);
1034 DUMPREG(HDMI_H_SYNC_START_0);
1035 DUMPREG(HDMI_H_SYNC_START_1);
1036 DUMPREG(HDMI_H_SYNC_END_0);
1037 DUMPREG(HDMI_H_SYNC_END_1);
1039 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0);
1040 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1);
1041 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0);
1042 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1);
1044 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0);
1045 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1);
1046 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0);
1047 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1);
1049 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0);
1050 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1);
1051 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0);
1052 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1);
1054 DUMPREG(HDMI_V_BLANK_F2_0);
1055 DUMPREG(HDMI_V_BLANK_F2_1);
1056 DUMPREG(HDMI_V_BLANK_F3_0);
1057 DUMPREG(HDMI_V_BLANK_F3_1);
1058 DUMPREG(HDMI_V_BLANK_F4_0);
1059 DUMPREG(HDMI_V_BLANK_F4_1);
1060 DUMPREG(HDMI_V_BLANK_F5_0);
1061 DUMPREG(HDMI_V_BLANK_F5_1);
1063 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0);
1064 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1);
1065 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0);
1066 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1);
1067 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0);
1068 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1);
1069 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0);
1070 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1);
1072 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0);
1073 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1);
1074 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0);
1075 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1);
1076 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0);
1077 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1);
1078 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0);
1079 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1);
1081 DUMPREG(HDMI_VACT_SPACE_1_0);
1082 DUMPREG(HDMI_VACT_SPACE_1_1);
1083 DUMPREG(HDMI_VACT_SPACE_2_0);
1084 DUMPREG(HDMI_VACT_SPACE_2_1);
1085 DUMPREG(HDMI_VACT_SPACE_3_0);
1086 DUMPREG(HDMI_VACT_SPACE_3_1);
1087 DUMPREG(HDMI_VACT_SPACE_4_0);
1088 DUMPREG(HDMI_VACT_SPACE_4_1);
1089 DUMPREG(HDMI_VACT_SPACE_5_0);
1090 DUMPREG(HDMI_VACT_SPACE_5_1);
1091 DUMPREG(HDMI_VACT_SPACE_6_0);
1092 DUMPREG(HDMI_VACT_SPACE_6_1);
1094 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
1095 DUMPREG(HDMI_TG_CMD);
1096 DUMPREG(HDMI_TG_H_FSZ_L);
1097 DUMPREG(HDMI_TG_H_FSZ_H);
1098 DUMPREG(HDMI_TG_HACT_ST_L);
1099 DUMPREG(HDMI_TG_HACT_ST_H);
1100 DUMPREG(HDMI_TG_HACT_SZ_L);
1101 DUMPREG(HDMI_TG_HACT_SZ_H);
1102 DUMPREG(HDMI_TG_V_FSZ_L);
1103 DUMPREG(HDMI_TG_V_FSZ_H);
1104 DUMPREG(HDMI_TG_VSYNC_L);
1105 DUMPREG(HDMI_TG_VSYNC_H);
1106 DUMPREG(HDMI_TG_VSYNC2_L);
1107 DUMPREG(HDMI_TG_VSYNC2_H);
1108 DUMPREG(HDMI_TG_VACT_ST_L);
1109 DUMPREG(HDMI_TG_VACT_ST_H);
1110 DUMPREG(HDMI_TG_VACT_SZ_L);
1111 DUMPREG(HDMI_TG_VACT_SZ_H);
1112 DUMPREG(HDMI_TG_FIELD_CHG_L);
1113 DUMPREG(HDMI_TG_FIELD_CHG_H);
1114 DUMPREG(HDMI_TG_VACT_ST2_L);
1115 DUMPREG(HDMI_TG_VACT_ST2_H);
1116 DUMPREG(HDMI_TG_VACT_ST3_L);
1117 DUMPREG(HDMI_TG_VACT_ST3_H);
1118 DUMPREG(HDMI_TG_VACT_ST4_L);
1119 DUMPREG(HDMI_TG_VACT_ST4_H);
1120 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
1121 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
1122 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
1123 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
1124 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
1125 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
1126 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
1127 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
1128 DUMPREG(HDMI_TG_3D);
1130 DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix);
1131 DUMPREG(HDMI_AVI_CON);
1132 DUMPREG(HDMI_AVI_HEADER0);
1133 DUMPREG(HDMI_AVI_HEADER1);
1134 DUMPREG(HDMI_AVI_HEADER2);
1135 DUMPREG(HDMI_AVI_CHECK_SUM);
1136 DUMPREG(HDMI_VSI_CON);
1137 DUMPREG(HDMI_VSI_HEADER0);
1138 DUMPREG(HDMI_VSI_HEADER1);
1139 DUMPREG(HDMI_VSI_HEADER2);
1140 for (i = 0; i < 7; ++i)
1141 DUMPREG(HDMI_VSI_DATA(i));
1146 static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
1149 hdmi_v13_regs_dump(hdata, prefix);
1151 hdmi_v14_regs_dump(hdata, prefix);
1154 static int hdmi_v13_conf_index(struct drm_display_mode *mode)
1158 for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1159 if (hdmi_v13_confs[i].width == mode->hdisplay &&
1160 hdmi_v13_confs[i].height == mode->vdisplay &&
1161 hdmi_v13_confs[i].vrefresh == mode->vrefresh &&
1162 hdmi_v13_confs[i].interlace ==
1163 ((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1170 static int hdmi_v14_conf_index(struct drm_display_mode *mode)
1174 for (i = 0; i < ARRAY_SIZE(hdmi_confs); ++i)
1175 if (hdmi_confs[i].width == mode->hdisplay &&
1176 hdmi_confs[i].height == mode->vdisplay &&
1177 hdmi_confs[i].vrefresh == mode->vrefresh &&
1178 hdmi_confs[i].interlace ==
1179 ((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1186 static int hdmi_conf_index(struct hdmi_context *hdata,
1187 struct drm_display_mode *mode)
1190 return hdmi_v13_conf_index(mode);
1192 return hdmi_v14_conf_index(mode);
1195 static bool hdmi_is_connected(void *ctx)
1197 struct hdmi_context *hdata = (struct hdmi_context *)ctx;
1198 u32 val = hdmi_reg_read(hdata, HDMI_HPD_STATUS);
1206 static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
1209 struct edid *raw_edid;
1210 struct hdmi_context *hdata = (struct hdmi_context *)ctx;
1212 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1214 if (!hdata->ddc_port)
1217 raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter);
1219 memcpy(edid, raw_edid, min((1 + raw_edid->extensions)
1220 * EDID_LENGTH, len));
1221 DRM_DEBUG_KMS("width[%d] x height[%d]\n",
1222 raw_edid->width_cm, raw_edid->height_cm);
1230 static int hdmi_v13_check_timing(struct fb_videomode *check_timing)
1234 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1235 check_timing->xres, check_timing->yres,
1236 check_timing->refresh, (check_timing->vmode &
1237 FB_VMODE_INTERLACED) ? true : false);
1239 for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1240 if (hdmi_v13_confs[i].width == check_timing->xres &&
1241 hdmi_v13_confs[i].height == check_timing->yres &&
1242 hdmi_v13_confs[i].vrefresh == check_timing->refresh &&
1243 hdmi_v13_confs[i].interlace ==
1244 ((check_timing->vmode & FB_VMODE_INTERLACED) ?
1253 static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
1257 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1258 check_timing->xres, check_timing->yres,
1259 check_timing->refresh, (check_timing->vmode &
1260 FB_VMODE_INTERLACED) ? true : false);
1262 for (i = 0; i < ARRAY_SIZE(hdmi_confs); i++)
1263 if (hdmi_confs[i].width == check_timing->xres &&
1264 hdmi_confs[i].height == check_timing->yres &&
1265 hdmi_confs[i].vrefresh == check_timing->refresh &&
1266 hdmi_confs[i].interlace ==
1267 ((check_timing->vmode & FB_VMODE_INTERLACED) ?
1276 static int hdmi_check_timing(void *ctx, void *timing)
1278 struct hdmi_context *hdata = (struct hdmi_context *)ctx;
1279 struct fb_videomode *check_timing = timing;
1281 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1283 DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres,
1284 check_timing->yres, check_timing->refresh,
1285 check_timing->vmode);
1288 return hdmi_v13_check_timing(check_timing);
1290 return hdmi_v14_check_timing(check_timing);
1293 static int hdmi_display_power_on(void *ctx, int mode)
1295 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1298 case DRM_MODE_DPMS_ON:
1299 DRM_DEBUG_KMS("hdmi [on]\n");
1301 case DRM_MODE_DPMS_STANDBY:
1303 case DRM_MODE_DPMS_SUSPEND:
1305 case DRM_MODE_DPMS_OFF:
1306 DRM_DEBUG_KMS("hdmi [off]\n");
1315 static struct exynos_hdmi_display_ops display_ops = {
1316 .is_connected = hdmi_is_connected,
1317 .get_edid = hdmi_get_edid,
1318 .check_timing = hdmi_check_timing,
1319 .power_on = hdmi_display_power_on,
1322 static void hdmi_conf_reset(struct hdmi_context *hdata)
1326 /* disable hpd handle for drm */
1327 hdata->hpd_handle = false;
1330 reg = HDMI_V13_CORE_RSTOUT;
1332 reg = HDMI_CORE_RSTOUT;
1334 /* resetting HDMI core */
1335 hdmi_reg_writemask(hdata, reg, 0, HDMI_CORE_SW_RSTOUT);
1337 hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT);
1340 /* enable hpd handle for drm */
1341 hdata->hpd_handle = true;
1344 static void hdmi_conf_init(struct hdmi_context *hdata)
1346 /* disable hpd handle for drm */
1347 hdata->hpd_handle = false;
1349 /* enable HPD interrupts */
1350 hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1351 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1353 hdmi_reg_writemask(hdata, HDMI_INTC_CON, ~0, HDMI_INTC_EN_GLOBAL |
1354 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1356 /* choose HDMI mode */
1357 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1358 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1359 /* disable bluescreen */
1360 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1362 if (hdata->is_v13) {
1363 /* choose bluescreen (fecal) color */
1364 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1365 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1366 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1368 /* enable AVI packet every vsync, fixes purple line problem */
1369 hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1370 /* force RGB, look to CEA-861-D, table 7 for more detail */
1371 hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1372 hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1374 hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1375 hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1376 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1378 /* enable AVI packet every vsync, fixes purple line problem */
1379 hdmi_reg_writeb(hdata, HDMI_AVI_CON, 0x02);
1380 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 2 << 5);
1381 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1384 /* enable hpd handle for drm */
1385 hdata->hpd_handle = true;
1388 static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
1390 const struct hdmi_v13_preset_conf *conf =
1391 hdmi_v13_confs[hdata->cur_conf].conf;
1392 const struct hdmi_v13_core_regs *core = &conf->core;
1393 const struct hdmi_v13_tg_regs *tg = &conf->tg;
1396 /* setting core registers */
1397 hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1398 hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1399 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_0, core->v_blank[0]);
1400 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_1, core->v_blank[1]);
1401 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_2, core->v_blank[2]);
1402 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_0, core->h_v_line[0]);
1403 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_1, core->h_v_line[1]);
1404 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_2, core->h_v_line[2]);
1405 hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1406 hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1407 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_0, core->v_blank_f[0]);
1408 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_1, core->v_blank_f[1]);
1409 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_2, core->v_blank_f[2]);
1410 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_0, core->h_sync_gen[0]);
1411 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_1, core->h_sync_gen[1]);
1412 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_2, core->h_sync_gen[2]);
1413 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_0, core->v_sync_gen1[0]);
1414 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_1, core->v_sync_gen1[1]);
1415 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_2, core->v_sync_gen1[2]);
1416 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_0, core->v_sync_gen2[0]);
1417 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_1, core->v_sync_gen2[1]);
1418 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_2, core->v_sync_gen2[2]);
1419 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_0, core->v_sync_gen3[0]);
1420 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]);
1421 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]);
1422 /* Timing generator registers */
1423 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1424 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1425 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1426 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1427 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1428 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1429 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1430 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1431 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1432 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1433 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1434 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1435 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1436 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1437 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1438 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1439 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1440 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1441 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1442 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1443 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1444 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1445 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1446 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1447 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1448 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1449 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1450 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1452 /* waiting for HDMIPHY's PLL to get to steady state */
1453 for (tries = 100; tries; --tries) {
1454 u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS);
1455 if (val & HDMI_PHY_STATUS_READY)
1459 /* steady state not achieved */
1461 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1462 hdmi_regs_dump(hdata, "timing apply");
1465 clk_disable(hdata->res.sclk_hdmi);
1466 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1467 clk_enable(hdata->res.sclk_hdmi);
1469 /* enable HDMI and timing generator */
1470 hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1471 if (core->int_pro_mode[0])
1472 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1475 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1478 static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
1480 const struct hdmi_preset_conf *conf = hdmi_confs[hdata->cur_conf].conf;
1481 const struct hdmi_core_regs *core = &conf->core;
1482 const struct hdmi_tg_regs *tg = &conf->tg;
1485 /* setting core registers */
1486 hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1487 hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1488 hdmi_reg_writeb(hdata, HDMI_V2_BLANK_0, core->v2_blank[0]);
1489 hdmi_reg_writeb(hdata, HDMI_V2_BLANK_1, core->v2_blank[1]);
1490 hdmi_reg_writeb(hdata, HDMI_V1_BLANK_0, core->v1_blank[0]);
1491 hdmi_reg_writeb(hdata, HDMI_V1_BLANK_1, core->v1_blank[1]);
1492 hdmi_reg_writeb(hdata, HDMI_V_LINE_0, core->v_line[0]);
1493 hdmi_reg_writeb(hdata, HDMI_V_LINE_1, core->v_line[1]);
1494 hdmi_reg_writeb(hdata, HDMI_H_LINE_0, core->h_line[0]);
1495 hdmi_reg_writeb(hdata, HDMI_H_LINE_1, core->h_line[1]);
1496 hdmi_reg_writeb(hdata, HDMI_HSYNC_POL, core->hsync_pol[0]);
1497 hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1498 hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1499 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_0, core->v_blank_f0[0]);
1500 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_1, core->v_blank_f0[1]);
1501 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_0, core->v_blank_f1[0]);
1502 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_1, core->v_blank_f1[1]);
1503 hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_0, core->h_sync_start[0]);
1504 hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_1, core->h_sync_start[1]);
1505 hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_0, core->h_sync_end[0]);
1506 hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_1, core->h_sync_end[1]);
1507 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_0,
1508 core->v_sync_line_bef_2[0]);
1509 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_1,
1510 core->v_sync_line_bef_2[1]);
1511 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_0,
1512 core->v_sync_line_bef_1[0]);
1513 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_1,
1514 core->v_sync_line_bef_1[1]);
1515 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_0,
1516 core->v_sync_line_aft_2[0]);
1517 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_1,
1518 core->v_sync_line_aft_2[1]);
1519 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_0,
1520 core->v_sync_line_aft_1[0]);
1521 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_1,
1522 core->v_sync_line_aft_1[1]);
1523 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0,
1524 core->v_sync_line_aft_pxl_2[0]);
1525 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_1,
1526 core->v_sync_line_aft_pxl_2[1]);
1527 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0,
1528 core->v_sync_line_aft_pxl_1[0]);
1529 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_1,
1530 core->v_sync_line_aft_pxl_1[1]);
1531 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_0, core->v_blank_f2[0]);
1532 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_1, core->v_blank_f2[1]);
1533 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_0, core->v_blank_f3[0]);
1534 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_1, core->v_blank_f3[1]);
1535 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_0, core->v_blank_f4[0]);
1536 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_1, core->v_blank_f4[1]);
1537 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_0, core->v_blank_f5[0]);
1538 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_1, core->v_blank_f5[1]);
1539 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_0,
1540 core->v_sync_line_aft_3[0]);
1541 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_1,
1542 core->v_sync_line_aft_3[1]);
1543 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_0,
1544 core->v_sync_line_aft_4[0]);
1545 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_1,
1546 core->v_sync_line_aft_4[1]);
1547 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_0,
1548 core->v_sync_line_aft_5[0]);
1549 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_1,
1550 core->v_sync_line_aft_5[1]);
1551 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_0,
1552 core->v_sync_line_aft_6[0]);
1553 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_1,
1554 core->v_sync_line_aft_6[1]);
1555 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0,
1556 core->v_sync_line_aft_pxl_3[0]);
1557 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_1,
1558 core->v_sync_line_aft_pxl_3[1]);
1559 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0,
1560 core->v_sync_line_aft_pxl_4[0]);
1561 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_1,
1562 core->v_sync_line_aft_pxl_4[1]);
1563 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0,
1564 core->v_sync_line_aft_pxl_5[0]);
1565 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_1,
1566 core->v_sync_line_aft_pxl_5[1]);
1567 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0,
1568 core->v_sync_line_aft_pxl_6[0]);
1569 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_1,
1570 core->v_sync_line_aft_pxl_6[1]);
1571 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_0, core->vact_space_1[0]);
1572 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_1, core->vact_space_1[1]);
1573 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_0, core->vact_space_2[0]);
1574 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_1, core->vact_space_2[1]);
1575 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_0, core->vact_space_3[0]);
1576 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_1, core->vact_space_3[1]);
1577 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_0, core->vact_space_4[0]);
1578 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_1, core->vact_space_4[1]);
1579 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_0, core->vact_space_5[0]);
1580 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_1, core->vact_space_5[1]);
1581 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_0, core->vact_space_6[0]);
1582 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]);
1584 /* Timing generator registers */
1585 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1586 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1587 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1588 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1589 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1590 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1591 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1592 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1593 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1594 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1595 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1596 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1597 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1598 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1599 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1600 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1601 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1602 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1603 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1604 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1605 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3_l);
1606 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3_h);
1607 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4_l);
1608 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4_h);
1609 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1610 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1611 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1612 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1613 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1614 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1615 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1616 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1617 hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d);
1619 /* waiting for HDMIPHY's PLL to get to steady state */
1620 for (tries = 100; tries; --tries) {
1621 u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0);
1622 if (val & HDMI_PHY_STATUS_READY)
1626 /* steady state not achieved */
1628 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1629 hdmi_regs_dump(hdata, "timing apply");
1632 clk_disable(hdata->res.sclk_hdmi);
1633 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1634 clk_enable(hdata->res.sclk_hdmi);
1636 /* enable HDMI and timing generator */
1637 hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1638 if (core->int_pro_mode[0])
1639 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1642 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1645 static void hdmi_timing_apply(struct hdmi_context *hdata)
1648 hdmi_v13_timing_apply(hdata);
1650 hdmi_v14_timing_apply(hdata);
1653 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1658 clk_disable(hdata->res.sclk_hdmi);
1659 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel);
1660 clk_enable(hdata->res.sclk_hdmi);
1662 /* operation mode */
1666 if (hdata->hdmiphy_port)
1667 i2c_master_send(hdata->hdmiphy_port, buffer, 2);
1670 reg = HDMI_V13_PHY_RSTOUT;
1672 reg = HDMI_PHY_RSTOUT;
1675 hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT);
1677 hdmi_reg_writemask(hdata, reg, 0, HDMI_PHY_SW_RSTOUT);
1681 static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1683 const u8 *hdmiphy_data;
1686 u8 read_buffer[32] = {0, };
1690 if (!hdata->hdmiphy_port) {
1691 DRM_ERROR("hdmiphy is not attached\n");
1697 hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data;
1699 hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data;
1701 memcpy(buffer, hdmiphy_data, 32);
1702 ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
1704 DRM_ERROR("failed to configure HDMIPHY via I2C\n");
1710 /* operation mode */
1711 operation[0] = 0x1f;
1712 operation[1] = 0x80;
1714 ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
1716 DRM_ERROR("failed to enable hdmiphy\n");
1720 ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
1722 DRM_ERROR("failed to read hdmiphy config\n");
1726 for (i = 0; i < ret; i++)
1727 DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
1728 "recv [0x%02x]\n", i, buffer[i], read_buffer[i]);
1731 static void hdmi_conf_apply(struct hdmi_context *hdata)
1733 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1735 hdmiphy_conf_reset(hdata);
1736 hdmiphy_conf_apply(hdata);
1738 hdmi_conf_reset(hdata);
1739 hdmi_conf_init(hdata);
1741 /* setting core registers */
1742 hdmi_timing_apply(hdata);
1744 hdmi_regs_dump(hdata, "start");
1747 static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
1748 struct drm_display_mode *mode,
1749 struct drm_display_mode *adjusted_mode)
1751 struct drm_display_mode *m;
1752 struct hdmi_context *hdata = (struct hdmi_context *)ctx;
1755 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1757 drm_mode_set_crtcinfo(adjusted_mode, 0);
1760 index = hdmi_v13_conf_index(adjusted_mode);
1762 index = hdmi_v14_conf_index(adjusted_mode);
1764 /* just return if user desired mode exists. */
1769 * otherwise, find the most suitable mode among modes and change it
1772 list_for_each_entry(m, &connector->modes, head) {
1774 index = hdmi_v13_conf_index(m);
1776 index = hdmi_v14_conf_index(m);
1779 DRM_INFO("desired mode doesn't exist so\n");
1780 DRM_INFO("use the most suitable mode among modes.\n");
1781 memcpy(adjusted_mode, m, sizeof(*m));
1787 static void hdmi_mode_set(void *ctx, void *mode)
1789 struct hdmi_context *hdata = (struct hdmi_context *)ctx;
1792 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1794 conf_idx = hdmi_conf_index(hdata, mode);
1796 hdata->cur_conf = conf_idx;
1798 DRM_DEBUG_KMS("not supported mode\n");
1801 static void hdmi_get_max_resol(void *ctx, unsigned int *width,
1802 unsigned int *height)
1804 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1807 *height = MAX_HEIGHT;
1810 static void hdmi_commit(void *ctx)
1812 struct hdmi_context *hdata = (struct hdmi_context *)ctx;
1814 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1816 hdmi_conf_apply(hdata);
1818 hdata->enabled = true;
1821 static void hdmi_disable(void *ctx)
1823 struct hdmi_context *hdata = (struct hdmi_context *)ctx;
1825 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1827 if (hdata->enabled) {
1828 hdmiphy_conf_reset(hdata);
1829 hdmi_conf_reset(hdata);
1833 static struct exynos_hdmi_manager_ops manager_ops = {
1834 .mode_fixup = hdmi_mode_fixup,
1835 .mode_set = hdmi_mode_set,
1836 .get_max_resol = hdmi_get_max_resol,
1837 .commit = hdmi_commit,
1838 .disable = hdmi_disable,
1842 * Handle hotplug events outside the interrupt handler proper.
1844 static void hdmi_hotplug_func(struct work_struct *work)
1846 struct hdmi_context *hdata =
1847 container_of(work, struct hdmi_context, hotplug_work);
1848 struct exynos_drm_hdmi_context *ctx =
1849 (struct exynos_drm_hdmi_context *)hdata->parent_ctx;
1851 drm_helper_hpd_irq_event(ctx->drm_dev);
1854 static irqreturn_t hdmi_irq_handler(int irq, void *arg)
1856 struct exynos_drm_hdmi_context *ctx = arg;
1857 struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx;
1860 intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG);
1861 /* clearing flags for HPD plug/unplug */
1862 if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) {
1863 DRM_DEBUG_KMS("unplugged, handling:%d\n", hdata->hpd_handle);
1864 hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
1865 HDMI_INTC_FLAG_HPD_UNPLUG);
1867 if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) {
1868 DRM_DEBUG_KMS("plugged, handling:%d\n", hdata->hpd_handle);
1869 hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
1870 HDMI_INTC_FLAG_HPD_PLUG);
1873 if (ctx->drm_dev && hdata->hpd_handle)
1874 queue_work(hdata->wq, &hdata->hotplug_work);
1879 static int __devinit hdmi_resources_init(struct hdmi_context *hdata)
1881 struct device *dev = hdata->dev;
1882 struct hdmi_resources *res = &hdata->res;
1883 static char *supply[] = {
1891 DRM_DEBUG_KMS("HDMI resource init\n");
1893 memset(res, 0, sizeof *res);
1895 /* get clocks, power */
1896 res->hdmi = clk_get(dev, "hdmi");
1897 if (IS_ERR_OR_NULL(res->hdmi)) {
1898 DRM_ERROR("failed to get clock 'hdmi'\n");
1901 res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
1902 if (IS_ERR_OR_NULL(res->sclk_hdmi)) {
1903 DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
1906 res->sclk_pixel = clk_get(dev, "sclk_pixel");
1907 if (IS_ERR_OR_NULL(res->sclk_pixel)) {
1908 DRM_ERROR("failed to get clock 'sclk_pixel'\n");
1911 res->sclk_hdmiphy = clk_get(dev, "sclk_hdmiphy");
1912 if (IS_ERR_OR_NULL(res->sclk_hdmiphy)) {
1913 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
1916 res->hdmiphy = clk_get(dev, "hdmiphy");
1917 if (IS_ERR_OR_NULL(res->hdmiphy)) {
1918 DRM_ERROR("failed to get clock 'hdmiphy'\n");
1922 clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
1924 res->regul_bulk = kzalloc(ARRAY_SIZE(supply) *
1925 sizeof res->regul_bulk[0], GFP_KERNEL);
1926 if (!res->regul_bulk) {
1927 DRM_ERROR("failed to get memory for regulators\n");
1930 for (i = 0; i < ARRAY_SIZE(supply); ++i) {
1931 res->regul_bulk[i].supply = supply[i];
1932 res->regul_bulk[i].consumer = NULL;
1934 ret = regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
1936 DRM_ERROR("failed to get regulators\n");
1939 res->regul_count = ARRAY_SIZE(supply);
1943 DRM_ERROR("HDMI resource init - failed\n");
1947 static int hdmi_resources_cleanup(struct hdmi_context *hdata)
1949 struct hdmi_resources *res = &hdata->res;
1951 regulator_bulk_free(res->regul_count, res->regul_bulk);
1952 /* kfree is NULL-safe */
1953 kfree(res->regul_bulk);
1954 if (!IS_ERR_OR_NULL(res->hdmiphy))
1955 clk_put(res->hdmiphy);
1956 if (!IS_ERR_OR_NULL(res->sclk_hdmiphy))
1957 clk_put(res->sclk_hdmiphy);
1958 if (!IS_ERR_OR_NULL(res->sclk_pixel))
1959 clk_put(res->sclk_pixel);
1960 if (!IS_ERR_OR_NULL(res->sclk_hdmi))
1961 clk_put(res->sclk_hdmi);
1962 if (!IS_ERR_OR_NULL(res->hdmi))
1964 memset(res, 0, sizeof *res);
1969 static void hdmi_resource_poweron(struct hdmi_context *hdata)
1971 struct hdmi_resources *res = &hdata->res;
1973 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1975 /* turn HDMI power on */
1976 regulator_bulk_enable(res->regul_count, res->regul_bulk);
1977 /* power-on hdmi physical interface */
1978 clk_enable(res->hdmiphy);
1979 /* turn clocks on */
1980 clk_enable(res->hdmi);
1981 clk_enable(res->sclk_hdmi);
1983 hdmiphy_conf_reset(hdata);
1984 hdmi_conf_reset(hdata);
1985 hdmi_conf_init(hdata);
1988 static void hdmi_resource_poweroff(struct hdmi_context *hdata)
1990 struct hdmi_resources *res = &hdata->res;
1992 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1994 /* turn clocks off */
1995 clk_disable(res->sclk_hdmi);
1996 clk_disable(res->hdmi);
1997 /* power-off hdmiphy */
1998 clk_disable(res->hdmiphy);
1999 /* turn HDMI power off */
2000 regulator_bulk_disable(res->regul_count, res->regul_bulk);
2003 static int hdmi_runtime_suspend(struct device *dev)
2005 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2007 DRM_DEBUG_KMS("%s\n", __func__);
2009 hdmi_resource_poweroff((struct hdmi_context *)ctx->ctx);
2014 static int hdmi_runtime_resume(struct device *dev)
2016 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2018 DRM_DEBUG_KMS("%s\n", __func__);
2020 hdmi_resource_poweron((struct hdmi_context *)ctx->ctx);
2025 static const struct dev_pm_ops hdmi_pm_ops = {
2026 .runtime_suspend = hdmi_runtime_suspend,
2027 .runtime_resume = hdmi_runtime_resume,
2030 static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
2032 void hdmi_attach_ddc_client(struct i2c_client *ddc)
2038 void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
2041 hdmi_hdmiphy = hdmiphy;
2044 static int __devinit hdmi_probe(struct platform_device *pdev)
2046 struct device *dev = &pdev->dev;
2047 struct exynos_drm_hdmi_context *drm_hdmi_ctx;
2048 struct hdmi_context *hdata;
2049 struct exynos_drm_hdmi_pdata *pdata;
2050 struct resource *res;
2053 DRM_DEBUG_KMS("[%d]\n", __LINE__);
2055 pdata = pdev->dev.platform_data;
2057 DRM_ERROR("no platform data specified\n");
2061 drm_hdmi_ctx = kzalloc(sizeof(*drm_hdmi_ctx), GFP_KERNEL);
2062 if (!drm_hdmi_ctx) {
2063 DRM_ERROR("failed to allocate common hdmi context.\n");
2067 hdata = kzalloc(sizeof(struct hdmi_context), GFP_KERNEL);
2069 DRM_ERROR("out of memory\n");
2070 kfree(drm_hdmi_ctx);
2074 drm_hdmi_ctx->ctx = (void *)hdata;
2075 hdata->parent_ctx = (void *)drm_hdmi_ctx;
2077 platform_set_drvdata(pdev, drm_hdmi_ctx);
2079 hdata->is_v13 = pdata->is_v13;
2080 hdata->default_win = pdata->default_win;
2081 hdata->default_timing = &pdata->timing;
2082 hdata->default_bpp = pdata->bpp;
2085 ret = hdmi_resources_init(hdata);
2091 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2093 DRM_ERROR("failed to find registers\n");
2098 hdata->regs_res = request_mem_region(res->start, resource_size(res),
2100 if (!hdata->regs_res) {
2101 DRM_ERROR("failed to claim register region\n");
2106 hdata->regs = ioremap(res->start, resource_size(res));
2108 DRM_ERROR("failed to map registers\n");
2110 goto err_req_region;
2113 /* DDC i2c driver */
2114 if (i2c_add_driver(&ddc_driver)) {
2115 DRM_ERROR("failed to register ddc i2c driver\n");
2120 hdata->ddc_port = hdmi_ddc;
2122 /* hdmiphy i2c driver */
2123 if (i2c_add_driver(&hdmiphy_driver)) {
2124 DRM_ERROR("failed to register hdmiphy i2c driver\n");
2129 hdata->hdmiphy_port = hdmi_hdmiphy;
2131 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
2133 DRM_ERROR("get interrupt resource failed.\n");
2138 /* create workqueue and hotplug work */
2139 hdata->wq = alloc_workqueue("exynos-drm-hdmi",
2140 WQ_UNBOUND | WQ_NON_REENTRANT, 1);
2141 if (hdata->wq == NULL) {
2142 DRM_ERROR("Failed to create workqueue.\n");
2146 INIT_WORK(&hdata->hotplug_work, hdmi_hotplug_func);
2148 /* register hpd interrupt */
2149 ret = request_irq(res->start, hdmi_irq_handler, 0, "drm_hdmi",
2152 DRM_ERROR("request interrupt failed.\n");
2155 hdata->irq = res->start;
2157 /* register specific callbacks to common hdmi. */
2158 exynos_drm_display_ops_register(&display_ops);
2159 exynos_drm_manager_ops_register(&manager_ops);
2161 hdmi_resource_poweron(hdata);
2166 destroy_workqueue(hdata->wq);
2168 i2c_del_driver(&hdmiphy_driver);
2170 i2c_del_driver(&ddc_driver);
2172 iounmap(hdata->regs);
2174 release_mem_region(hdata->regs_res->start,
2175 resource_size(hdata->regs_res));
2177 hdmi_resources_cleanup(hdata);
2180 kfree(drm_hdmi_ctx);
2184 static int __devexit hdmi_remove(struct platform_device *pdev)
2186 struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev);
2187 struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx;
2189 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2191 hdmi_resource_poweroff(hdata);
2193 disable_irq(hdata->irq);
2194 free_irq(hdata->irq, hdata);
2196 cancel_work_sync(&hdata->hotplug_work);
2197 destroy_workqueue(hdata->wq);
2199 hdmi_resources_cleanup(hdata);
2201 iounmap(hdata->regs);
2203 release_mem_region(hdata->regs_res->start,
2204 resource_size(hdata->regs_res));
2206 /* hdmiphy i2c driver */
2207 i2c_del_driver(&hdmiphy_driver);
2208 /* DDC i2c driver */
2209 i2c_del_driver(&ddc_driver);
2216 struct platform_driver hdmi_driver = {
2217 .probe = hdmi_probe,
2218 .remove = __devexit_p(hdmi_remove),
2220 .name = "exynos4-hdmi",
2221 .owner = THIS_MODULE,