aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Paul <seanpaul@chromium.org>2013-01-15 08:11:08 -0500
committerInki Dae <inki.dae@samsung.com>2013-02-21 01:00:27 -0500
commit2f7e2ed073f629405a8054f14bd001dc68b0e17a (patch)
tree0298598f80324acbac8bffac4a806da68fac28ff
parent29630743c97cc4c395c308ea9d0c12bf55c55a92 (diff)
drm/exynos: hdmi: support extra resolutions using drm_display_mode timings
This patch programs the core and timing generator registers using the timing data provided in drm_display_mode and not using hard-coded configurations. Additional PHY configs has been added. This allows us to support more permissible resolutions and refresh rates. Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com> Signed-off-by: Sean Paul <seanpaul@chromium.org> Signed-off-by: Shirish S <s.shirish@samsung.com> Signed-off-by: Akshay Saraswat <Akshay.s@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c1022
1 files changed, 374 insertions, 648 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index ba3301575525..6d63f9090f94 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -87,6 +87,73 @@ struct hdmi_resources {
87 int regul_count; 87 int regul_count;
88}; 88};
89 89
90struct hdmi_tg_regs {
91 u8 cmd[1];
92 u8 h_fsz[2];
93 u8 hact_st[2];
94 u8 hact_sz[2];
95 u8 v_fsz[2];
96 u8 vsync[2];
97 u8 vsync2[2];
98 u8 vact_st[2];
99 u8 vact_sz[2];
100 u8 field_chg[2];
101 u8 vact_st2[2];
102 u8 vact_st3[2];
103 u8 vact_st4[2];
104 u8 vsync_top_hdmi[2];
105 u8 vsync_bot_hdmi[2];
106 u8 field_top_hdmi[2];
107 u8 field_bot_hdmi[2];
108 u8 tg_3d[1];
109};
110
111struct hdmi_core_regs {
112 u8 h_blank[2];
113 u8 v2_blank[2];
114 u8 v1_blank[2];
115 u8 v_line[2];
116 u8 h_line[2];
117 u8 hsync_pol[1];
118 u8 vsync_pol[1];
119 u8 int_pro_mode[1];
120 u8 v_blank_f0[2];
121 u8 v_blank_f1[2];
122 u8 h_sync_start[2];
123 u8 h_sync_end[2];
124 u8 v_sync_line_bef_2[2];
125 u8 v_sync_line_bef_1[2];
126 u8 v_sync_line_aft_2[2];
127 u8 v_sync_line_aft_1[2];
128 u8 v_sync_line_aft_pxl_2[2];
129 u8 v_sync_line_aft_pxl_1[2];
130 u8 v_blank_f2[2]; /* for 3D mode */
131 u8 v_blank_f3[2]; /* for 3D mode */
132 u8 v_blank_f4[2]; /* for 3D mode */
133 u8 v_blank_f5[2]; /* for 3D mode */
134 u8 v_sync_line_aft_3[2];
135 u8 v_sync_line_aft_4[2];
136 u8 v_sync_line_aft_5[2];
137 u8 v_sync_line_aft_6[2];
138 u8 v_sync_line_aft_pxl_3[2];
139 u8 v_sync_line_aft_pxl_4[2];
140 u8 v_sync_line_aft_pxl_5[2];
141 u8 v_sync_line_aft_pxl_6[2];
142 u8 vact_space_1[2];
143 u8 vact_space_2[2];
144 u8 vact_space_3[2];
145 u8 vact_space_4[2];
146 u8 vact_space_5[2];
147 u8 vact_space_6[2];
148};
149
150struct hdmi_v14_conf {
151 int pixel_clock;
152 struct hdmi_core_regs core;
153 struct hdmi_tg_regs tg;
154 int cea_video_id;
155};
156
90struct hdmi_context { 157struct hdmi_context {
91 struct device *dev; 158 struct device *dev;
92 struct drm_device *drm_dev; 159 struct drm_device *drm_dev;
@@ -104,6 +171,7 @@ struct hdmi_context {
104 171
105 /* current hdmiphy conf index */ 172 /* current hdmiphy conf index */
106 int cur_conf; 173 int cur_conf;
174 struct hdmi_v14_conf mode_conf;
107 175
108 struct hdmi_resources res; 176 struct hdmi_resources res;
109 177
@@ -392,586 +460,132 @@ static const struct hdmi_v13_conf hdmi_v13_confs[] = {
392}; 460};
393 461
394/* HDMI Version 1.4 */ 462/* HDMI Version 1.4 */
395static const u8 hdmiphy_conf27_027[32] = { 463struct hdmiphy_config {
396 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08, 464 int pixel_clock;
397 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80, 465 u8 conf[32];
398 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
399 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
400};
401
402static const u8 hdmiphy_conf74_176[32] = {
403 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x5b, 0xef, 0x08,
404 0x81, 0xa0, 0xb9, 0xd8, 0x45, 0xa0, 0xac, 0x80,
405 0x5a, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
406 0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
407};
408
409static const u8 hdmiphy_conf74_25[32] = {
410 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
411 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
412 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
413 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
414};
415
416static const u8 hdmiphy_conf148_5[32] = {
417 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
418 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
419 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
420 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
421};
422
423struct hdmi_tg_regs {
424 u8 cmd;
425 u8 h_fsz_l;
426 u8 h_fsz_h;
427 u8 hact_st_l;
428 u8 hact_st_h;
429 u8 hact_sz_l;
430 u8 hact_sz_h;
431 u8 v_fsz_l;
432 u8 v_fsz_h;
433 u8 vsync_l;
434 u8 vsync_h;
435 u8 vsync2_l;
436 u8 vsync2_h;
437 u8 vact_st_l;
438 u8 vact_st_h;
439 u8 vact_sz_l;
440 u8 vact_sz_h;
441 u8 field_chg_l;
442 u8 field_chg_h;
443 u8 vact_st2_l;
444 u8 vact_st2_h;
445 u8 vact_st3_l;
446 u8 vact_st3_h;
447 u8 vact_st4_l;
448 u8 vact_st4_h;
449 u8 vsync_top_hdmi_l;
450 u8 vsync_top_hdmi_h;
451 u8 vsync_bot_hdmi_l;
452 u8 vsync_bot_hdmi_h;
453 u8 field_top_hdmi_l;
454 u8 field_top_hdmi_h;
455 u8 field_bot_hdmi_l;
456 u8 field_bot_hdmi_h;
457 u8 tg_3d;
458};
459
460struct hdmi_core_regs {
461 u8 h_blank[2];
462 u8 v2_blank[2];
463 u8 v1_blank[2];
464 u8 v_line[2];
465 u8 h_line[2];
466 u8 hsync_pol[1];
467 u8 vsync_pol[1];
468 u8 int_pro_mode[1];
469 u8 v_blank_f0[2];
470 u8 v_blank_f1[2];
471 u8 h_sync_start[2];
472 u8 h_sync_end[2];
473 u8 v_sync_line_bef_2[2];
474 u8 v_sync_line_bef_1[2];
475 u8 v_sync_line_aft_2[2];
476 u8 v_sync_line_aft_1[2];
477 u8 v_sync_line_aft_pxl_2[2];
478 u8 v_sync_line_aft_pxl_1[2];
479 u8 v_blank_f2[2]; /* for 3D mode */
480 u8 v_blank_f3[2]; /* for 3D mode */
481 u8 v_blank_f4[2]; /* for 3D mode */
482 u8 v_blank_f5[2]; /* for 3D mode */
483 u8 v_sync_line_aft_3[2];
484 u8 v_sync_line_aft_4[2];
485 u8 v_sync_line_aft_5[2];
486 u8 v_sync_line_aft_6[2];
487 u8 v_sync_line_aft_pxl_3[2];
488 u8 v_sync_line_aft_pxl_4[2];
489 u8 v_sync_line_aft_pxl_5[2];
490 u8 v_sync_line_aft_pxl_6[2];
491 u8 vact_space_1[2];
492 u8 vact_space_2[2];
493 u8 vact_space_3[2];
494 u8 vact_space_4[2];
495 u8 vact_space_5[2];
496 u8 vact_space_6[2];
497};
498
499struct hdmi_preset_conf {
500 struct hdmi_core_regs core;
501 struct hdmi_tg_regs tg;
502};
503
504struct hdmi_conf {
505 int width;
506 int height;
507 int vrefresh;
508 bool interlace;
509 int cea_video_id;
510 const u8 *hdmiphy_data;
511 const struct hdmi_preset_conf *conf;
512};
513
514static const struct hdmi_preset_conf hdmi_conf_480p60 = {
515 .core = {
516 .h_blank = {0x8a, 0x00},
517 .v2_blank = {0x0d, 0x02},
518 .v1_blank = {0x2d, 0x00},
519 .v_line = {0x0d, 0x02},
520 .h_line = {0x5a, 0x03},
521 .hsync_pol = {0x01},
522 .vsync_pol = {0x01},
523 .int_pro_mode = {0x00},
524 .v_blank_f0 = {0xff, 0xff},
525 .v_blank_f1 = {0xff, 0xff},
526 .h_sync_start = {0x0e, 0x00},
527 .h_sync_end = {0x4c, 0x00},
528 .v_sync_line_bef_2 = {0x0f, 0x00},
529 .v_sync_line_bef_1 = {0x09, 0x00},
530 .v_sync_line_aft_2 = {0xff, 0xff},
531 .v_sync_line_aft_1 = {0xff, 0xff},
532 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
533 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
534 .v_blank_f2 = {0xff, 0xff},
535 .v_blank_f3 = {0xff, 0xff},
536 .v_blank_f4 = {0xff, 0xff},
537 .v_blank_f5 = {0xff, 0xff},
538 .v_sync_line_aft_3 = {0xff, 0xff},
539 .v_sync_line_aft_4 = {0xff, 0xff},
540 .v_sync_line_aft_5 = {0xff, 0xff},
541 .v_sync_line_aft_6 = {0xff, 0xff},
542 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
543 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
544 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
545 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
546 .vact_space_1 = {0xff, 0xff},
547 .vact_space_2 = {0xff, 0xff},
548 .vact_space_3 = {0xff, 0xff},
549 .vact_space_4 = {0xff, 0xff},
550 .vact_space_5 = {0xff, 0xff},
551 .vact_space_6 = {0xff, 0xff},
552 /* other don't care */
553 },
554 .tg = {
555 0x00, /* cmd */
556 0x5a, 0x03, /* h_fsz */
557 0x8a, 0x00, 0xd0, 0x02, /* hact */
558 0x0d, 0x02, /* v_fsz */
559 0x01, 0x00, 0x33, 0x02, /* vsync */
560 0x2d, 0x00, 0xe0, 0x01, /* vact */
561 0x33, 0x02, /* field_chg */
562 0x48, 0x02, /* vact_st2 */
563 0x00, 0x00, /* vact_st3 */
564 0x00, 0x00, /* vact_st4 */
565 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
566 0x01, 0x00, 0x33, 0x02, /* field top/bot */
567 0x00, /* 3d FP */
568 },
569}; 466};
570 467
571static const struct hdmi_preset_conf hdmi_conf_720p50 = { 468/* list of all required phy config settings */
572 .core = { 469static const struct hdmiphy_config hdmiphy_v14_configs[] = {
573 .h_blank = {0xbc, 0x02}, 470 {
574 .v2_blank = {0xee, 0x02}, 471 .pixel_clock = 25200000,
575 .v1_blank = {0x1e, 0x00}, 472 .conf = {
576 .v_line = {0xee, 0x02}, 473 0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
577 .h_line = {0xbc, 0x07}, 474 0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
578 .hsync_pol = {0x00}, 475 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
579 .vsync_pol = {0x00}, 476 0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
580 .int_pro_mode = {0x00}, 477 },
581 .v_blank_f0 = {0xff, 0xff},
582 .v_blank_f1 = {0xff, 0xff},
583 .h_sync_start = {0xb6, 0x01},
584 .h_sync_end = {0xde, 0x01},
585 .v_sync_line_bef_2 = {0x0a, 0x00},
586 .v_sync_line_bef_1 = {0x05, 0x00},
587 .v_sync_line_aft_2 = {0xff, 0xff},
588 .v_sync_line_aft_1 = {0xff, 0xff},
589 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
590 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
591 .v_blank_f2 = {0xff, 0xff},
592 .v_blank_f3 = {0xff, 0xff},
593 .v_blank_f4 = {0xff, 0xff},
594 .v_blank_f5 = {0xff, 0xff},
595 .v_sync_line_aft_3 = {0xff, 0xff},
596 .v_sync_line_aft_4 = {0xff, 0xff},
597 .v_sync_line_aft_5 = {0xff, 0xff},
598 .v_sync_line_aft_6 = {0xff, 0xff},
599 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
600 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
601 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
602 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
603 .vact_space_1 = {0xff, 0xff},
604 .vact_space_2 = {0xff, 0xff},
605 .vact_space_3 = {0xff, 0xff},
606 .vact_space_4 = {0xff, 0xff},
607 .vact_space_5 = {0xff, 0xff},
608 .vact_space_6 = {0xff, 0xff},
609 /* other don't care */
610 },
611 .tg = {
612 0x00, /* cmd */
613 0xbc, 0x07, /* h_fsz */
614 0xbc, 0x02, 0x00, 0x05, /* hact */
615 0xee, 0x02, /* v_fsz */
616 0x01, 0x00, 0x33, 0x02, /* vsync */
617 0x1e, 0x00, 0xd0, 0x02, /* vact */
618 0x33, 0x02, /* field_chg */
619 0x48, 0x02, /* vact_st2 */
620 0x00, 0x00, /* vact_st3 */
621 0x00, 0x00, /* vact_st4 */
622 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
623 0x01, 0x00, 0x33, 0x02, /* field top/bot */
624 0x00, /* 3d FP */
625 }, 478 },
626}; 479 {
627 480 .pixel_clock = 27000000,
628static const struct hdmi_preset_conf hdmi_conf_720p60 = { 481 .conf = {
629 .core = { 482 0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
630 .h_blank = {0x72, 0x01}, 483 0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
631 .v2_blank = {0xee, 0x02}, 484 0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
632 .v1_blank = {0x1e, 0x00}, 485 0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
633 .v_line = {0xee, 0x02}, 486 },
634 .h_line = {0x72, 0x06},
635 .hsync_pol = {0x00},
636 .vsync_pol = {0x00},
637 .int_pro_mode = {0x00},
638 .v_blank_f0 = {0xff, 0xff},
639 .v_blank_f1 = {0xff, 0xff},
640 .h_sync_start = {0x6c, 0x00},
641 .h_sync_end = {0x94, 0x00},
642 .v_sync_line_bef_2 = {0x0a, 0x00},
643 .v_sync_line_bef_1 = {0x05, 0x00},
644 .v_sync_line_aft_2 = {0xff, 0xff},
645 .v_sync_line_aft_1 = {0xff, 0xff},
646 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
647 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
648 .v_blank_f2 = {0xff, 0xff},
649 .v_blank_f3 = {0xff, 0xff},
650 .v_blank_f4 = {0xff, 0xff},
651 .v_blank_f5 = {0xff, 0xff},
652 .v_sync_line_aft_3 = {0xff, 0xff},
653 .v_sync_line_aft_4 = {0xff, 0xff},
654 .v_sync_line_aft_5 = {0xff, 0xff},
655 .v_sync_line_aft_6 = {0xff, 0xff},
656 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
657 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
658 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
659 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
660 .vact_space_1 = {0xff, 0xff},
661 .vact_space_2 = {0xff, 0xff},
662 .vact_space_3 = {0xff, 0xff},
663 .vact_space_4 = {0xff, 0xff},
664 .vact_space_5 = {0xff, 0xff},
665 .vact_space_6 = {0xff, 0xff},
666 /* other don't care */
667 }, 487 },
668 .tg = { 488 {
669 0x00, /* cmd */ 489 .pixel_clock = 27027000,
670 0x72, 0x06, /* h_fsz */ 490 .conf = {
671 0x72, 0x01, 0x00, 0x05, /* hact */ 491 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
672 0xee, 0x02, /* v_fsz */ 492 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
673 0x01, 0x00, 0x33, 0x02, /* vsync */ 493 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
674 0x1e, 0x00, 0xd0, 0x02, /* vact */ 494 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
675 0x33, 0x02, /* field_chg */ 495 },
676 0x48, 0x02, /* vact_st2 */
677 0x00, 0x00, /* vact_st3 */
678 0x00, 0x00, /* vact_st4 */
679 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
680 0x01, 0x00, 0x33, 0x02, /* field top/bot */
681 0x00, /* 3d FP */
682 }, 496 },
683}; 497 {
684 498 .pixel_clock = 36000000,
685static const struct hdmi_preset_conf hdmi_conf_1080i50 = { 499 .conf = {
686 .core = { 500 0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
687 .h_blank = {0xd0, 0x02}, 501 0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
688 .v2_blank = {0x32, 0x02}, 502 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
689 .v1_blank = {0x16, 0x00}, 503 0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
690 .v_line = {0x65, 0x04}, 504 },
691 .h_line = {0x50, 0x0a},
692 .hsync_pol = {0x00},
693 .vsync_pol = {0x00},
694 .int_pro_mode = {0x01},
695 .v_blank_f0 = {0x49, 0x02},
696 .v_blank_f1 = {0x65, 0x04},
697 .h_sync_start = {0x0e, 0x02},
698 .h_sync_end = {0x3a, 0x02},
699 .v_sync_line_bef_2 = {0x07, 0x00},
700 .v_sync_line_bef_1 = {0x02, 0x00},
701 .v_sync_line_aft_2 = {0x39, 0x02},
702 .v_sync_line_aft_1 = {0x34, 0x02},
703 .v_sync_line_aft_pxl_2 = {0x38, 0x07},
704 .v_sync_line_aft_pxl_1 = {0x38, 0x07},
705 .v_blank_f2 = {0xff, 0xff},
706 .v_blank_f3 = {0xff, 0xff},
707 .v_blank_f4 = {0xff, 0xff},
708 .v_blank_f5 = {0xff, 0xff},
709 .v_sync_line_aft_3 = {0xff, 0xff},
710 .v_sync_line_aft_4 = {0xff, 0xff},
711 .v_sync_line_aft_5 = {0xff, 0xff},
712 .v_sync_line_aft_6 = {0xff, 0xff},
713 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
714 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
715 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
716 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
717 .vact_space_1 = {0xff, 0xff},
718 .vact_space_2 = {0xff, 0xff},
719 .vact_space_3 = {0xff, 0xff},
720 .vact_space_4 = {0xff, 0xff},
721 .vact_space_5 = {0xff, 0xff},
722 .vact_space_6 = {0xff, 0xff},
723 /* other don't care */
724 }, 505 },
725 .tg = { 506 {
726 0x00, /* cmd */ 507 .pixel_clock = 40000000,
727 0x50, 0x0a, /* h_fsz */ 508 .conf = {
728 0xd0, 0x02, 0x80, 0x07, /* hact */ 509 0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
729 0x65, 0x04, /* v_fsz */ 510 0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
730 0x01, 0x00, 0x33, 0x02, /* vsync */ 511 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
731 0x16, 0x00, 0x1c, 0x02, /* vact */ 512 0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
732 0x33, 0x02, /* field_chg */ 513 },
733 0x49, 0x02, /* vact_st2 */
734 0x00, 0x00, /* vact_st3 */
735 0x00, 0x00, /* vact_st4 */
736 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
737 0x01, 0x00, 0x33, 0x02, /* field top/bot */
738 0x00, /* 3d FP */
739 }, 514 },
740}; 515 {
741 516 .pixel_clock = 65000000,
742static const struct hdmi_preset_conf hdmi_conf_1080i60 = { 517 .conf = {
743 .core = { 518 0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
744 .h_blank = {0x18, 0x01}, 519 0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
745 .v2_blank = {0x32, 0x02}, 520 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
746 .v1_blank = {0x16, 0x00}, 521 0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
747 .v_line = {0x65, 0x04}, 522 },
748 .h_line = {0x98, 0x08},
749 .hsync_pol = {0x00},
750 .vsync_pol = {0x00},
751 .int_pro_mode = {0x01},
752 .v_blank_f0 = {0x49, 0x02},
753 .v_blank_f1 = {0x65, 0x04},
754 .h_sync_start = {0x56, 0x00},
755 .h_sync_end = {0x82, 0x00},
756 .v_sync_line_bef_2 = {0x07, 0x00},
757 .v_sync_line_bef_1 = {0x02, 0x00},
758 .v_sync_line_aft_2 = {0x39, 0x02},
759 .v_sync_line_aft_1 = {0x34, 0x02},
760 .v_sync_line_aft_pxl_2 = {0xa4, 0x04},
761 .v_sync_line_aft_pxl_1 = {0xa4, 0x04},
762 .v_blank_f2 = {0xff, 0xff},
763 .v_blank_f3 = {0xff, 0xff},
764 .v_blank_f4 = {0xff, 0xff},
765 .v_blank_f5 = {0xff, 0xff},
766 .v_sync_line_aft_3 = {0xff, 0xff},
767 .v_sync_line_aft_4 = {0xff, 0xff},
768 .v_sync_line_aft_5 = {0xff, 0xff},
769 .v_sync_line_aft_6 = {0xff, 0xff},
770 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
771 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
772 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
773 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
774 .vact_space_1 = {0xff, 0xff},
775 .vact_space_2 = {0xff, 0xff},
776 .vact_space_3 = {0xff, 0xff},
777 .vact_space_4 = {0xff, 0xff},
778 .vact_space_5 = {0xff, 0xff},
779 .vact_space_6 = {0xff, 0xff},
780 /* other don't care */
781 }, 523 },
782 .tg = { 524 {
783 0x00, /* cmd */ 525 .pixel_clock = 74176000,
784 0x98, 0x08, /* h_fsz */ 526 .conf = {
785 0x18, 0x01, 0x80, 0x07, /* hact */ 527 0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
786 0x65, 0x04, /* v_fsz */ 528 0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
787 0x01, 0x00, 0x33, 0x02, /* vsync */ 529 0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
788 0x16, 0x00, 0x1c, 0x02, /* vact */ 530 0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
789 0x33, 0x02, /* field_chg */ 531 },
790 0x49, 0x02, /* vact_st2 */
791 0x00, 0x00, /* vact_st3 */
792 0x00, 0x00, /* vact_st4 */
793 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
794 0x01, 0x00, 0x33, 0x02, /* field top/bot */
795 0x00, /* 3d FP */
796 }, 532 },
797}; 533 {
798 534 .pixel_clock = 74250000,
799static const struct hdmi_preset_conf hdmi_conf_1080p30 = { 535 .conf = {
800 .core = { 536 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
801 .h_blank = {0x18, 0x01}, 537 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
802 .v2_blank = {0x65, 0x04}, 538 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
803 .v1_blank = {0x2d, 0x00}, 539 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
804 .v_line = {0x65, 0x04}, 540 },
805 .h_line = {0x98, 0x08},
806 .hsync_pol = {0x00},
807 .vsync_pol = {0x00},
808 .int_pro_mode = {0x00},
809 .v_blank_f0 = {0xff, 0xff},
810 .v_blank_f1 = {0xff, 0xff},
811 .h_sync_start = {0x56, 0x00},
812 .h_sync_end = {0x82, 0x00},
813 .v_sync_line_bef_2 = {0x09, 0x00},
814 .v_sync_line_bef_1 = {0x04, 0x00},
815 .v_sync_line_aft_2 = {0xff, 0xff},
816 .v_sync_line_aft_1 = {0xff, 0xff},
817 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
818 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
819 .v_blank_f2 = {0xff, 0xff},
820 .v_blank_f3 = {0xff, 0xff},
821 .v_blank_f4 = {0xff, 0xff},
822 .v_blank_f5 = {0xff, 0xff},
823 .v_sync_line_aft_3 = {0xff, 0xff},
824 .v_sync_line_aft_4 = {0xff, 0xff},
825 .v_sync_line_aft_5 = {0xff, 0xff},
826 .v_sync_line_aft_6 = {0xff, 0xff},
827 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
828 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
829 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
830 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
831 .vact_space_1 = {0xff, 0xff},
832 .vact_space_2 = {0xff, 0xff},
833 .vact_space_3 = {0xff, 0xff},
834 .vact_space_4 = {0xff, 0xff},
835 .vact_space_5 = {0xff, 0xff},
836 .vact_space_6 = {0xff, 0xff},
837 /* other don't care */
838 }, 541 },
839 .tg = { 542 {
840 0x00, /* cmd */ 543 .pixel_clock = 83500000,
841 0x98, 0x08, /* h_fsz */ 544 .conf = {
842 0x18, 0x01, 0x80, 0x07, /* hact */ 545 0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
843 0x65, 0x04, /* v_fsz */ 546 0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
844 0x01, 0x00, 0x33, 0x02, /* vsync */ 547 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
845 0x2d, 0x00, 0x38, 0x04, /* vact */ 548 0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
846 0x33, 0x02, /* field_chg */ 549 },
847 0x48, 0x02, /* vact_st2 */
848 0x00, 0x00, /* vact_st3 */
849 0x00, 0x00, /* vact_st4 */
850 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
851 0x01, 0x00, 0x33, 0x02, /* field top/bot */
852 0x00, /* 3d FP */
853 }, 550 },
854}; 551 {
855 552 .pixel_clock = 106500000,
856static const struct hdmi_preset_conf hdmi_conf_1080p50 = { 553 .conf = {
857 .core = { 554 0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
858 .h_blank = {0xd0, 0x02}, 555 0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
859 .v2_blank = {0x65, 0x04}, 556 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
860 .v1_blank = {0x2d, 0x00}, 557 0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
861 .v_line = {0x65, 0x04}, 558 },
862 .h_line = {0x50, 0x0a},
863 .hsync_pol = {0x00},
864 .vsync_pol = {0x00},
865 .int_pro_mode = {0x00},
866 .v_blank_f0 = {0xff, 0xff},
867 .v_blank_f1 = {0xff, 0xff},
868 .h_sync_start = {0x0e, 0x02},
869 .h_sync_end = {0x3a, 0x02},
870 .v_sync_line_bef_2 = {0x09, 0x00},
871 .v_sync_line_bef_1 = {0x04, 0x00},
872 .v_sync_line_aft_2 = {0xff, 0xff},
873 .v_sync_line_aft_1 = {0xff, 0xff},
874 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
875 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
876 .v_blank_f2 = {0xff, 0xff},
877 .v_blank_f3 = {0xff, 0xff},
878 .v_blank_f4 = {0xff, 0xff},
879 .v_blank_f5 = {0xff, 0xff},
880 .v_sync_line_aft_3 = {0xff, 0xff},
881 .v_sync_line_aft_4 = {0xff, 0xff},
882 .v_sync_line_aft_5 = {0xff, 0xff},
883 .v_sync_line_aft_6 = {0xff, 0xff},
884 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
885 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
886 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
887 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
888 .vact_space_1 = {0xff, 0xff},
889 .vact_space_2 = {0xff, 0xff},
890 .vact_space_3 = {0xff, 0xff},
891 .vact_space_4 = {0xff, 0xff},
892 .vact_space_5 = {0xff, 0xff},
893 .vact_space_6 = {0xff, 0xff},
894 /* other don't care */
895 }, 559 },
896 .tg = { 560 {
897 0x00, /* cmd */ 561 .pixel_clock = 108000000,
898 0x50, 0x0a, /* h_fsz */ 562 .conf = {
899 0xd0, 0x02, 0x80, 0x07, /* hact */ 563 0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
900 0x65, 0x04, /* v_fsz */ 564 0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
901 0x01, 0x00, 0x33, 0x02, /* vsync */ 565 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
902 0x2d, 0x00, 0x38, 0x04, /* vact */ 566 0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
903 0x33, 0x02, /* field_chg */ 567 },
904 0x48, 0x02, /* vact_st2 */
905 0x00, 0x00, /* vact_st3 */
906 0x00, 0x00, /* vact_st4 */
907 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
908 0x01, 0x00, 0x33, 0x02, /* field top/bot */
909 0x00, /* 3d FP */
910 }, 568 },
911}; 569 {
912 570 .pixel_clock = 146250000,
913static const struct hdmi_preset_conf hdmi_conf_1080p60 = { 571 .conf = {
914 .core = { 572 0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
915 .h_blank = {0x18, 0x01}, 573 0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
916 .v2_blank = {0x65, 0x04}, 574 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
917 .v1_blank = {0x2d, 0x00}, 575 0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
918 .v_line = {0x65, 0x04}, 576 },
919 .h_line = {0x98, 0x08},
920 .hsync_pol = {0x00},
921 .vsync_pol = {0x00},
922 .int_pro_mode = {0x00},
923 .v_blank_f0 = {0xff, 0xff},
924 .v_blank_f1 = {0xff, 0xff},
925 .h_sync_start = {0x56, 0x00},
926 .h_sync_end = {0x82, 0x00},
927 .v_sync_line_bef_2 = {0x09, 0x00},
928 .v_sync_line_bef_1 = {0x04, 0x00},
929 .v_sync_line_aft_2 = {0xff, 0xff},
930 .v_sync_line_aft_1 = {0xff, 0xff},
931 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
932 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
933 .v_blank_f2 = {0xff, 0xff},
934 .v_blank_f3 = {0xff, 0xff},
935 .v_blank_f4 = {0xff, 0xff},
936 .v_blank_f5 = {0xff, 0xff},
937 .v_sync_line_aft_3 = {0xff, 0xff},
938 .v_sync_line_aft_4 = {0xff, 0xff},
939 .v_sync_line_aft_5 = {0xff, 0xff},
940 .v_sync_line_aft_6 = {0xff, 0xff},
941 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
942 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
943 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
944 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
945 /* other don't care */
946 }, 577 },
947 .tg = { 578 {
948 0x00, /* cmd */ 579 .pixel_clock = 148500000,
949 0x98, 0x08, /* h_fsz */ 580 .conf = {
950 0x18, 0x01, 0x80, 0x07, /* hact */ 581 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
951 0x65, 0x04, /* v_fsz */ 582 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
952 0x01, 0x00, 0x33, 0x02, /* vsync */ 583 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
953 0x2d, 0x00, 0x38, 0x04, /* vact */ 584 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
954 0x33, 0x02, /* field_chg */ 585 },
955 0x48, 0x02, /* vact_st2 */
956 0x00, 0x00, /* vact_st3 */
957 0x00, 0x00, /* vact_st4 */
958 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
959 0x01, 0x00, 0x33, 0x02, /* field top/bot */
960 0x00, /* 3d FP */
961 }, 586 },
962}; 587};
963 588
964static const struct hdmi_conf hdmi_confs[] = {
965 { 720, 480, 60, false, 3, hdmiphy_conf27_027, &hdmi_conf_480p60 },
966 { 1280, 720, 50, false, 19, hdmiphy_conf74_25, &hdmi_conf_720p50 },
967 { 1280, 720, 60, false, 4, hdmiphy_conf74_25, &hdmi_conf_720p60 },
968 { 1920, 1080, 50, true, 20, hdmiphy_conf74_25, &hdmi_conf_1080i50 },
969 { 1920, 1080, 60, true, 5, hdmiphy_conf74_25, &hdmi_conf_1080i60 },
970 { 1920, 1080, 30, false, 34, hdmiphy_conf74_176, &hdmi_conf_1080p30 },
971 { 1920, 1080, 50, false, 31, hdmiphy_conf148_5, &hdmi_conf_1080p50 },
972 { 1920, 1080, 60, false, 16, hdmiphy_conf148_5, &hdmi_conf_1080p60 },
973};
974
975struct hdmi_infoframe { 589struct hdmi_infoframe {
976 enum HDMI_PACKET_TYPE type; 590 enum HDMI_PACKET_TYPE type;
977 u8 ver; 591 u8 ver;
@@ -1275,31 +889,6 @@ static int hdmi_v13_conf_index(struct drm_display_mode *mode)
1275 return -EINVAL; 889 return -EINVAL;
1276} 890}
1277 891
1278static int hdmi_v14_conf_index(struct drm_display_mode *mode)
1279{
1280 int i;
1281
1282 for (i = 0; i < ARRAY_SIZE(hdmi_confs); ++i)
1283 if (hdmi_confs[i].width == mode->hdisplay &&
1284 hdmi_confs[i].height == mode->vdisplay &&
1285 hdmi_confs[i].vrefresh == mode->vrefresh &&
1286 hdmi_confs[i].interlace ==
1287 ((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1288 true : false))
1289 return i;
1290
1291 return -EINVAL;
1292}
1293
1294static int hdmi_conf_index(struct hdmi_context *hdata,
1295 struct drm_display_mode *mode)
1296{
1297 if (hdata->type == HDMI_TYPE13)
1298 return hdmi_v13_conf_index(mode);
1299
1300 return hdmi_v14_conf_index(mode);
1301}
1302
1303static u8 hdmi_chksum(struct hdmi_context *hdata, 892static u8 hdmi_chksum(struct hdmi_context *hdata,
1304 u32 start, u8 len, u32 hdr_sum) 893 u32 start, u8 len, u32 hdr_sum)
1305{ 894{
@@ -1357,7 +946,7 @@ static void hdmi_reg_infoframe(struct hdmi_context *hdata,
1357 if (hdata->type == HDMI_TYPE13) 946 if (hdata->type == HDMI_TYPE13)
1358 vic = hdmi_v13_confs[hdata->cur_conf].cea_video_id; 947 vic = hdmi_v13_confs[hdata->cur_conf].cea_video_id;
1359 else 948 else
1360 vic = hdmi_confs[hdata->cur_conf].cea_video_id; 949 vic = hdata->mode_conf.cea_video_id;
1361 950
1362 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), vic); 951 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), vic);
1363 952
@@ -1434,25 +1023,33 @@ static int hdmi_v13_check_timing(struct fb_videomode *check_timing)
1434 return -EINVAL; 1023 return -EINVAL;
1435} 1024}
1436 1025
1026static int hdmi_v14_find_phy_conf(int pixel_clock)
1027{
1028 int i;
1029
1030 for (i = 0; i < ARRAY_SIZE(hdmiphy_v14_configs); i++) {
1031 if (hdmiphy_v14_configs[i].pixel_clock == pixel_clock)
1032 return i;
1033 }
1034
1035 DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
1036 return -EINVAL;
1037}
1038
1437static int hdmi_v14_check_timing(struct fb_videomode *check_timing) 1039static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
1438{ 1040{
1439 int i; 1041 int i;
1440 1042
1441 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n", 1043 DRM_DEBUG_KMS("mode: xres=%d, yres=%d, refresh=%d, clock=%d, intl=%d\n",
1442 check_timing->xres, check_timing->yres, 1044 check_timing->xres, check_timing->yres,
1443 check_timing->refresh, (check_timing->vmode & 1045 check_timing->refresh, check_timing->pixclock,
1444 FB_VMODE_INTERLACED) ? true : false); 1046 (check_timing->vmode & FB_VMODE_INTERLACED) ?
1047 true : false);
1445 1048
1446 for (i = 0; i < ARRAY_SIZE(hdmi_confs); i++) 1049 for (i = 0; i < ARRAY_SIZE(hdmiphy_v14_configs); i++)
1447 if (hdmi_confs[i].width == check_timing->xres && 1050 if (hdmiphy_v14_configs[i].pixel_clock ==
1448 hdmi_confs[i].height == check_timing->yres && 1051 check_timing->pixclock)
1449 hdmi_confs[i].vrefresh == check_timing->refresh && 1052 return 0;
1450 hdmi_confs[i].interlace ==
1451 ((check_timing->vmode & FB_VMODE_INTERLACED) ?
1452 true : false))
1453 return 0;
1454
1455 /* TODO */
1456 1053
1457 return -EINVAL; 1054 return -EINVAL;
1458} 1055}
@@ -1794,9 +1391,8 @@ static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
1794 1391
1795static void hdmi_v14_timing_apply(struct hdmi_context *hdata) 1392static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
1796{ 1393{
1797 const struct hdmi_preset_conf *conf = hdmi_confs[hdata->cur_conf].conf; 1394 struct hdmi_core_regs *core = &hdata->mode_conf.core;
1798 const struct hdmi_core_regs *core = &conf->core; 1395 struct hdmi_tg_regs *tg = &hdata->mode_conf.tg;
1799 const struct hdmi_tg_regs *tg = &conf->tg;
1800 int tries; 1396 int tries;
1801 1397
1802 /* setting core registers */ 1398 /* setting core registers */
@@ -1899,39 +1495,39 @@ static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
1899 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]); 1495 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]);
1900 1496
1901 /* Timing generator registers */ 1497 /* Timing generator registers */
1902 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l); 1498 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz[0]);
1903 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h); 1499 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz[1]);
1904 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l); 1500 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st[0]);
1905 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h); 1501 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st[1]);
1906 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l); 1502 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz[0]);
1907 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h); 1503 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz[1]);
1908 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l); 1504 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz[0]);
1909 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h); 1505 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz[1]);
1910 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l); 1506 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync[0]);
1911 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h); 1507 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync[1]);
1912 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l); 1508 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2[0]);
1913 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h); 1509 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2[1]);
1914 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l); 1510 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st[0]);
1915 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h); 1511 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st[1]);
1916 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l); 1512 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz[0]);
1917 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h); 1513 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz[1]);
1918 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l); 1514 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg[0]);
1919 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h); 1515 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg[1]);
1920 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l); 1516 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2[0]);
1921 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h); 1517 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2[1]);
1922 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3_l); 1518 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3[0]);
1923 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3_h); 1519 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3[1]);
1924 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4_l); 1520 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4[0]);
1925 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4_h); 1521 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4[1]);
1926 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l); 1522 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi[0]);
1927 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h); 1523 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi[1]);
1928 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l); 1524 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi[0]);
1929 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h); 1525 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi[1]);
1930 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l); 1526 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi[0]);
1931 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h); 1527 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi[1]);
1932 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l); 1528 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi[0]);
1933 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h); 1529 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi[1]);
1934 hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d); 1530 hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d[0]);
1935 1531
1936 /* waiting for HDMIPHY's PLL to get to steady state */ 1532 /* waiting for HDMIPHY's PLL to get to steady state */
1937 for (tries = 100; tries; --tries) { 1533 for (tries = 100; tries; --tries) {
@@ -2028,10 +1624,17 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata)
2028 } 1624 }
2029 1625
2030 /* pixel clock */ 1626 /* pixel clock */
2031 if (hdata->type == HDMI_TYPE13) 1627 if (hdata->type == HDMI_TYPE13) {
2032 hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data; 1628 hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data;
2033 else 1629 } else {
2034 hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data; 1630 i = hdmi_v14_find_phy_conf(hdata->mode_conf.pixel_clock);
1631 if (i < 0) {
1632 DRM_ERROR("failed to find hdmiphy conf\n");
1633 return;
1634 }
1635
1636 hdmiphy_data = hdmiphy_v14_configs[i].conf;
1637 }
2035 1638
2036 memcpy(buffer, hdmiphy_data, 32); 1639 memcpy(buffer, hdmiphy_data, 32);
2037 ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32); 1640 ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
@@ -2099,7 +1702,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
2099 if (hdata->type == HDMI_TYPE13) 1702 if (hdata->type == HDMI_TYPE13)
2100 index = hdmi_v13_conf_index(adjusted_mode); 1703 index = hdmi_v13_conf_index(adjusted_mode);
2101 else 1704 else
2102 index = hdmi_v14_conf_index(adjusted_mode); 1705 index = hdmi_v14_find_phy_conf(adjusted_mode->clock * 1000);
2103 1706
2104 /* just return if user desired mode exists. */ 1707 /* just return if user desired mode exists. */
2105 if (index >= 0) 1708 if (index >= 0)
@@ -2113,7 +1716,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
2113 if (hdata->type == HDMI_TYPE13) 1716 if (hdata->type == HDMI_TYPE13)
2114 index = hdmi_v13_conf_index(m); 1717 index = hdmi_v13_conf_index(m);
2115 else 1718 else
2116 index = hdmi_v14_conf_index(m); 1719 index = hdmi_v14_find_phy_conf(m->clock * 1000);
2117 1720
2118 if (index >= 0) { 1721 if (index >= 0) {
2119 struct drm_mode_object base; 1722 struct drm_mode_object base;
@@ -2122,6 +1725,9 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
2122 DRM_INFO("desired mode doesn't exist so\n"); 1725 DRM_INFO("desired mode doesn't exist so\n");
2123 DRM_INFO("use the most suitable mode among modes.\n"); 1726 DRM_INFO("use the most suitable mode among modes.\n");
2124 1727
1728 DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n",
1729 m->hdisplay, m->vdisplay, m->vrefresh);
1730
2125 /* preserve display mode header while copying. */ 1731 /* preserve display mode header while copying. */
2126 head = adjusted_mode->head; 1732 head = adjusted_mode->head;
2127 base = adjusted_mode->base; 1733 base = adjusted_mode->base;
@@ -2133,6 +1739,122 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
2133 } 1739 }
2134} 1740}
2135 1741
1742static void hdmi_set_reg(u8 *reg_pair, int num_bytes, u32 value)
1743{
1744 int i;
1745 BUG_ON(num_bytes > 4);
1746 for (i = 0; i < num_bytes; i++)
1747 reg_pair[i] = (value >> (8 * i)) & 0xff;
1748}
1749
1750static void hdmi_v14_mode_set(struct hdmi_context *hdata,
1751 struct drm_display_mode *m)
1752{
1753 struct hdmi_core_regs *core = &hdata->mode_conf.core;
1754 struct hdmi_tg_regs *tg = &hdata->mode_conf.tg;
1755
1756 hdata->mode_conf.cea_video_id = drm_match_cea_mode(m);
1757
1758 hdata->mode_conf.pixel_clock = m->clock * 1000;
1759 hdmi_set_reg(core->h_blank, 2, m->htotal - m->hdisplay);
1760 hdmi_set_reg(core->v_line, 2, m->vtotal);
1761 hdmi_set_reg(core->h_line, 2, m->htotal);
1762 hdmi_set_reg(core->hsync_pol, 1,
1763 (m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0);
1764 hdmi_set_reg(core->vsync_pol, 1,
1765 (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
1766 hdmi_set_reg(core->int_pro_mode, 1,
1767 (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1768
1769 /*
1770 * Quirk requirement for exynos 5 HDMI IP design,
1771 * 2 pixels less than the actual calculation for hsync_start
1772 * and end.
1773 */
1774
1775 /* Following values & calculations differ for different type of modes */
1776 if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1777 /* Interlaced Mode */
1778 hdmi_set_reg(core->v_sync_line_bef_2, 2,
1779 (m->vsync_end - m->vdisplay) / 2);
1780 hdmi_set_reg(core->v_sync_line_bef_1, 2,
1781 (m->vsync_start - m->vdisplay) / 2);
1782 hdmi_set_reg(core->v2_blank, 2, m->vtotal / 2);
1783 hdmi_set_reg(core->v1_blank, 2, (m->vtotal - m->vdisplay) / 2);
1784 hdmi_set_reg(core->v_blank_f0, 2, (m->vtotal +
1785 ((m->vsync_end - m->vsync_start) * 4) + 5) / 2);
1786 hdmi_set_reg(core->v_blank_f1, 2, m->vtotal);
1787 hdmi_set_reg(core->v_sync_line_aft_2, 2, (m->vtotal / 2) + 7);
1788 hdmi_set_reg(core->v_sync_line_aft_1, 2, (m->vtotal / 2) + 2);
1789 hdmi_set_reg(core->v_sync_line_aft_pxl_2, 2,
1790 (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1791 hdmi_set_reg(core->v_sync_line_aft_pxl_1, 2,
1792 (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1793 hdmi_set_reg(tg->vact_st, 2, (m->vtotal - m->vdisplay) / 2);
1794 hdmi_set_reg(tg->vact_sz, 2, m->vdisplay / 2);
1795 hdmi_set_reg(tg->vact_st2, 2, 0x249);/* Reset value + 1*/
1796 hdmi_set_reg(tg->vact_st3, 2, 0x0);
1797 hdmi_set_reg(tg->vact_st4, 2, 0x0);
1798 } else {
1799 /* Progressive Mode */
1800 hdmi_set_reg(core->v_sync_line_bef_2, 2,
1801 m->vsync_end - m->vdisplay);
1802 hdmi_set_reg(core->v_sync_line_bef_1, 2,
1803 m->vsync_start - m->vdisplay);
1804 hdmi_set_reg(core->v2_blank, 2, m->vtotal);
1805 hdmi_set_reg(core->v1_blank, 2, m->vtotal - m->vdisplay);
1806 hdmi_set_reg(core->v_blank_f0, 2, 0xffff);
1807 hdmi_set_reg(core->v_blank_f1, 2, 0xffff);
1808 hdmi_set_reg(core->v_sync_line_aft_2, 2, 0xffff);
1809 hdmi_set_reg(core->v_sync_line_aft_1, 2, 0xffff);
1810 hdmi_set_reg(core->v_sync_line_aft_pxl_2, 2, 0xffff);
1811 hdmi_set_reg(core->v_sync_line_aft_pxl_1, 2, 0xffff);
1812 hdmi_set_reg(tg->vact_st, 2, m->vtotal - m->vdisplay);
1813 hdmi_set_reg(tg->vact_sz, 2, m->vdisplay);
1814 hdmi_set_reg(tg->vact_st2, 2, 0x248); /* Reset value */
1815 hdmi_set_reg(tg->vact_st3, 2, 0x47b); /* Reset value */
1816 hdmi_set_reg(tg->vact_st4, 2, 0x6ae); /* Reset value */
1817 }
1818
1819 /* Following values & calculations are same irrespective of mode type */
1820 hdmi_set_reg(core->h_sync_start, 2, m->hsync_start - m->hdisplay - 2);
1821 hdmi_set_reg(core->h_sync_end, 2, m->hsync_end - m->hdisplay - 2);
1822 hdmi_set_reg(core->vact_space_1, 2, 0xffff);
1823 hdmi_set_reg(core->vact_space_2, 2, 0xffff);
1824 hdmi_set_reg(core->vact_space_3, 2, 0xffff);
1825 hdmi_set_reg(core->vact_space_4, 2, 0xffff);
1826 hdmi_set_reg(core->vact_space_5, 2, 0xffff);
1827 hdmi_set_reg(core->vact_space_6, 2, 0xffff);
1828 hdmi_set_reg(core->v_blank_f2, 2, 0xffff);
1829 hdmi_set_reg(core->v_blank_f3, 2, 0xffff);
1830 hdmi_set_reg(core->v_blank_f4, 2, 0xffff);
1831 hdmi_set_reg(core->v_blank_f5, 2, 0xffff);
1832 hdmi_set_reg(core->v_sync_line_aft_3, 2, 0xffff);
1833 hdmi_set_reg(core->v_sync_line_aft_4, 2, 0xffff);
1834 hdmi_set_reg(core->v_sync_line_aft_5, 2, 0xffff);
1835 hdmi_set_reg(core->v_sync_line_aft_6, 2, 0xffff);
1836 hdmi_set_reg(core->v_sync_line_aft_pxl_3, 2, 0xffff);
1837 hdmi_set_reg(core->v_sync_line_aft_pxl_4, 2, 0xffff);
1838 hdmi_set_reg(core->v_sync_line_aft_pxl_5, 2, 0xffff);
1839 hdmi_set_reg(core->v_sync_line_aft_pxl_6, 2, 0xffff);
1840
1841 /* Timing generator registers */
1842 hdmi_set_reg(tg->cmd, 1, 0x0);
1843 hdmi_set_reg(tg->h_fsz, 2, m->htotal);
1844 hdmi_set_reg(tg->hact_st, 2, m->htotal - m->hdisplay);
1845 hdmi_set_reg(tg->hact_sz, 2, m->hdisplay);
1846 hdmi_set_reg(tg->v_fsz, 2, m->vtotal);
1847 hdmi_set_reg(tg->vsync, 2, 0x1);
1848 hdmi_set_reg(tg->vsync2, 2, 0x233); /* Reset value */
1849 hdmi_set_reg(tg->field_chg, 2, 0x233); /* Reset value */
1850 hdmi_set_reg(tg->vsync_top_hdmi, 2, 0x1); /* Reset value */
1851 hdmi_set_reg(tg->vsync_bot_hdmi, 2, 0x233); /* Reset value */
1852 hdmi_set_reg(tg->field_top_hdmi, 2, 0x1); /* Reset value */
1853 hdmi_set_reg(tg->field_bot_hdmi, 2, 0x233); /* Reset value */
1854 hdmi_set_reg(tg->tg_3d, 1, 0x0);
1855
1856}
1857
2136static void hdmi_mode_set(void *ctx, void *mode) 1858static void hdmi_mode_set(void *ctx, void *mode)
2137{ 1859{
2138 struct hdmi_context *hdata = ctx; 1860 struct hdmi_context *hdata = ctx;
@@ -2140,11 +1862,15 @@ static void hdmi_mode_set(void *ctx, void *mode)
2140 1862
2141 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 1863 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2142 1864
2143 conf_idx = hdmi_conf_index(hdata, mode); 1865 if (hdata->type == HDMI_TYPE13) {
2144 if (conf_idx >= 0) 1866 conf_idx = hdmi_v13_conf_index(mode);
2145 hdata->cur_conf = conf_idx; 1867 if (conf_idx >= 0)
2146 else 1868 hdata->cur_conf = conf_idx;
2147 DRM_DEBUG_KMS("not supported mode\n"); 1869 else
1870 DRM_DEBUG_KMS("not supported mode\n");
1871 } else {
1872 hdmi_v14_mode_set(hdata, mode);
1873 }
2148} 1874}
2149 1875
2150static void hdmi_get_max_resol(void *ctx, unsigned int *width, 1876static void hdmi_get_max_resol(void *ctx, unsigned int *width,