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