aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/hdmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss/hdmi.c')
-rw-r--r--drivers/video/omap2/dss/hdmi.c162
1 files changed, 117 insertions, 45 deletions
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index a48a7dd75b33..769d0828581c 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -60,6 +60,7 @@
60static struct { 60static struct {
61 struct mutex lock; 61 struct mutex lock;
62 struct platform_device *pdev; 62 struct platform_device *pdev;
63
63 struct hdmi_ip_data ip_data; 64 struct hdmi_ip_data ip_data;
64 65
65 struct clk *sys_clk; 66 struct clk *sys_clk;
@@ -295,6 +296,12 @@ static const struct hdmi_config vesa_timings[] = {
295 false, }, 296 false, },
296 { 0x55, HDMI_DVI }, 297 { 0x55, HDMI_DVI },
297 }, 298 },
299 {
300 { 1920, 1200, 154000, 32, 48, 80, 6, 3, 26,
301 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
302 false, },
303 { 0x44, HDMI_DVI },
304 },
298}; 305};
299 306
300static int hdmi_runtime_get(void) 307static int hdmi_runtime_get(void)
@@ -333,13 +340,17 @@ static int __init hdmi_init_display(struct omap_dss_device *dssdev)
333 340
334 DSSDBG("init_display\n"); 341 DSSDBG("init_display\n");
335 342
336 dss_init_hdmi_ip_ops(&hdmi.ip_data); 343 dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version());
337 344
338 if (hdmi.vdda_hdmi_dac_reg == NULL) { 345 if (hdmi.vdda_hdmi_dac_reg == NULL) {
339 struct regulator *reg; 346 struct regulator *reg;
340 347
341 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac"); 348 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
342 349
350 /* DT HACK: try VDAC to make omapdss work for o4 sdp/panda */
351 if (IS_ERR(reg))
352 reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC");
353
343 if (IS_ERR(reg)) { 354 if (IS_ERR(reg)) {
344 DSSERR("can't get VDDA_HDMI_DAC regulator\n"); 355 DSSERR("can't get VDDA_HDMI_DAC regulator\n");
345 return PTR_ERR(reg); 356 return PTR_ERR(reg);
@@ -355,7 +366,7 @@ static int __init hdmi_init_display(struct omap_dss_device *dssdev)
355 return 0; 366 return 0;
356} 367}
357 368
358static void __exit hdmi_uninit_display(struct omap_dss_device *dssdev) 369static void hdmi_uninit_display(struct omap_dss_device *dssdev)
359{ 370{
360 DSSDBG("uninit_display\n"); 371 DSSDBG("uninit_display\n");
361 372
@@ -398,7 +409,8 @@ static bool hdmi_timings_compare(struct omap_video_timings *timing1,
398{ 409{
399 int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync; 410 int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
400 411
401 if ((timing2->pixel_clock == timing1->pixel_clock) && 412 if ((DIV_ROUND_CLOSEST(timing2->pixel_clock, 1000) ==
413 DIV_ROUND_CLOSEST(timing1->pixel_clock, 1000)) &&
402 (timing2->x_res == timing1->x_res) && 414 (timing2->x_res == timing1->x_res) &&
403 (timing2->y_res == timing1->y_res)) { 415 (timing2->y_res == timing1->y_res)) {
404 416
@@ -500,12 +512,9 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
500 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd); 512 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
501} 513}
502 514
503static int hdmi_power_on(struct omap_dss_device *dssdev) 515static int hdmi_power_on_core(struct omap_dss_device *dssdev)
504{ 516{
505 int r; 517 int r;
506 struct omap_video_timings *p;
507 struct omap_overlay_manager *mgr = dssdev->output->manager;
508 unsigned long phy;
509 518
510 gpio_set_value(hdmi.ct_cp_hpd_gpio, 1); 519 gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
511 gpio_set_value(hdmi.ls_oe_gpio, 1); 520 gpio_set_value(hdmi.ls_oe_gpio, 1);
@@ -521,6 +530,38 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
521 if (r) 530 if (r)
522 goto err_runtime_get; 531 goto err_runtime_get;
523 532
533 /* Make selection of HDMI in DSS */
534 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
535
536 return 0;
537
538err_runtime_get:
539 regulator_disable(hdmi.vdda_hdmi_dac_reg);
540err_vdac_enable:
541 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
542 gpio_set_value(hdmi.ls_oe_gpio, 0);
543 return r;
544}
545
546static void hdmi_power_off_core(struct omap_dss_device *dssdev)
547{
548 hdmi_runtime_put();
549 regulator_disable(hdmi.vdda_hdmi_dac_reg);
550 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
551 gpio_set_value(hdmi.ls_oe_gpio, 0);
552}
553
554static int hdmi_power_on_full(struct omap_dss_device *dssdev)
555{
556 int r;
557 struct omap_video_timings *p;
558 struct omap_overlay_manager *mgr = dssdev->output->manager;
559 unsigned long phy;
560
561 r = hdmi_power_on_core(dssdev);
562 if (r)
563 return r;
564
524 dss_mgr_disable(mgr); 565 dss_mgr_disable(mgr);
525 566
526 p = &hdmi.ip_data.cfg.timings; 567 p = &hdmi.ip_data.cfg.timings;
@@ -548,17 +589,6 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
548 589
549 hdmi.ip_data.ops->video_configure(&hdmi.ip_data); 590 hdmi.ip_data.ops->video_configure(&hdmi.ip_data);
550 591
551 /* Make selection of HDMI in DSS */
552 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
553
554 /* Select the dispc clock source as PRCM clock, to ensure that it is not
555 * DSI PLL source as the clock selected by DSI PLL might not be
556 * sufficient for the resolution selected / that can be changed
557 * dynamically by user. This can be moved to single location , say
558 * Boardfile.
559 */
560 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
561
562 /* bypass TV gamma table */ 592 /* bypass TV gamma table */
563 dispc_enable_gamma_table(0); 593 dispc_enable_gamma_table(0);
564 594
@@ -582,16 +612,11 @@ err_vid_enable:
582err_phy_enable: 612err_phy_enable:
583 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); 613 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
584err_pll_enable: 614err_pll_enable:
585 hdmi_runtime_put(); 615 hdmi_power_off_core(dssdev);
586err_runtime_get:
587 regulator_disable(hdmi.vdda_hdmi_dac_reg);
588err_vdac_enable:
589 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
590 gpio_set_value(hdmi.ls_oe_gpio, 0);
591 return -EIO; 616 return -EIO;
592} 617}
593 618
594static void hdmi_power_off(struct omap_dss_device *dssdev) 619static void hdmi_power_off_full(struct omap_dss_device *dssdev)
595{ 620{
596 struct omap_overlay_manager *mgr = dssdev->output->manager; 621 struct omap_overlay_manager *mgr = dssdev->output->manager;
597 622
@@ -600,12 +625,8 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
600 hdmi.ip_data.ops->video_disable(&hdmi.ip_data); 625 hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
601 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); 626 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
602 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); 627 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
603 hdmi_runtime_put();
604
605 regulator_disable(hdmi.vdda_hdmi_dac_reg);
606 628
607 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0); 629 hdmi_power_off_core(dssdev);
608 gpio_set_value(hdmi.ls_oe_gpio, 0);
609} 630}
610 631
611int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, 632int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
@@ -644,8 +665,10 @@ static void hdmi_dump_regs(struct seq_file *s)
644{ 665{
645 mutex_lock(&hdmi.lock); 666 mutex_lock(&hdmi.lock);
646 667
647 if (hdmi_runtime_get()) 668 if (hdmi_runtime_get()) {
669 mutex_unlock(&hdmi.lock);
648 return; 670 return;
671 }
649 672
650 hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s); 673 hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s);
651 hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s); 674 hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s);
@@ -713,7 +736,7 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
713 goto err0; 736 goto err0;
714 } 737 }
715 738
716 r = hdmi_power_on(dssdev); 739 r = hdmi_power_on_full(dssdev);
717 if (r) { 740 if (r) {
718 DSSERR("failed to power on device\n"); 741 DSSERR("failed to power on device\n");
719 goto err1; 742 goto err1;
@@ -735,13 +758,48 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
735 758
736 mutex_lock(&hdmi.lock); 759 mutex_lock(&hdmi.lock);
737 760
738 hdmi_power_off(dssdev); 761 hdmi_power_off_full(dssdev);
739 762
740 omap_dss_stop_device(dssdev); 763 omap_dss_stop_device(dssdev);
741 764
742 mutex_unlock(&hdmi.lock); 765 mutex_unlock(&hdmi.lock);
743} 766}
744 767
768int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev)
769{
770 int r = 0;
771
772 DSSDBG("ENTER omapdss_hdmi_core_enable\n");
773
774 mutex_lock(&hdmi.lock);
775
776 hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
777
778 r = hdmi_power_on_core(dssdev);
779 if (r) {
780 DSSERR("failed to power on device\n");
781 goto err0;
782 }
783
784 mutex_unlock(&hdmi.lock);
785 return 0;
786
787err0:
788 mutex_unlock(&hdmi.lock);
789 return r;
790}
791
792void omapdss_hdmi_core_disable(struct omap_dss_device *dssdev)
793{
794 DSSDBG("Enter omapdss_hdmi_core_disable\n");
795
796 mutex_lock(&hdmi.lock);
797
798 hdmi_power_off_core(dssdev);
799
800 mutex_unlock(&hdmi.lock);
801}
802
745static int hdmi_get_clocks(struct platform_device *pdev) 803static int hdmi_get_clocks(struct platform_device *pdev)
746{ 804{
747 struct clk *clk; 805 struct clk *clk;
@@ -910,7 +968,7 @@ int hdmi_audio_config(struct omap_dss_audio *audio)
910static struct omap_dss_device * __init hdmi_find_dssdev(struct platform_device *pdev) 968static struct omap_dss_device * __init hdmi_find_dssdev(struct platform_device *pdev)
911{ 969{
912 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 970 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
913 const char *def_disp_name = dss_get_default_display_name(); 971 const char *def_disp_name = omapdss_get_default_display_name();
914 struct omap_dss_device *def_dssdev; 972 struct omap_dss_device *def_dssdev;
915 int i; 973 int i;
916 974
@@ -968,9 +1026,19 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
968 return; 1026 return;
969 } 1027 }
970 1028
1029 r = omapdss_output_set_device(&hdmi.output, dssdev);
1030 if (r) {
1031 DSSERR("failed to connect output to new device: %s\n",
1032 dssdev->name);
1033 dss_put_device(dssdev);
1034 return;
1035 }
1036
971 r = dss_add_device(dssdev); 1037 r = dss_add_device(dssdev);
972 if (r) { 1038 if (r) {
973 DSSERR("device %s register failed: %d\n", dssdev->name, r); 1039 DSSERR("device %s register failed: %d\n", dssdev->name, r);
1040 omapdss_output_unset_device(&hdmi.output);
1041 hdmi_uninit_display(dssdev);
974 dss_put_device(dssdev); 1042 dss_put_device(dssdev);
975 return; 1043 return;
976 } 1044 }
@@ -997,22 +1065,22 @@ static void __exit hdmi_uninit_output(struct platform_device *pdev)
997/* HDMI HW IP initialisation */ 1065/* HDMI HW IP initialisation */
998static int __init omapdss_hdmihw_probe(struct platform_device *pdev) 1066static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
999{ 1067{
1000 struct resource *hdmi_mem; 1068 struct resource *res;
1001 int r; 1069 int r;
1002 1070
1003 hdmi.pdev = pdev; 1071 hdmi.pdev = pdev;
1004 1072
1005 mutex_init(&hdmi.lock); 1073 mutex_init(&hdmi.lock);
1074 mutex_init(&hdmi.ip_data.lock);
1006 1075
1007 hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0); 1076 res = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
1008 if (!hdmi_mem) { 1077 if (!res) {
1009 DSSERR("can't get IORESOURCE_MEM HDMI\n"); 1078 DSSERR("can't get IORESOURCE_MEM HDMI\n");
1010 return -EINVAL; 1079 return -EINVAL;
1011 } 1080 }
1012 1081
1013 /* Base address taken from platform */ 1082 /* Base address taken from platform */
1014 hdmi.ip_data.base_wp = ioremap(hdmi_mem->start, 1083 hdmi.ip_data.base_wp = devm_request_and_ioremap(&pdev->dev, res);
1015 resource_size(hdmi_mem));
1016 if (!hdmi.ip_data.base_wp) { 1084 if (!hdmi.ip_data.base_wp) {
1017 DSSERR("can't ioremap WP\n"); 1085 DSSERR("can't ioremap WP\n");
1018 return -ENOMEM; 1086 return -ENOMEM;
@@ -1020,7 +1088,7 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
1020 1088
1021 r = hdmi_get_clocks(pdev); 1089 r = hdmi_get_clocks(pdev);
1022 if (r) { 1090 if (r) {
1023 iounmap(hdmi.ip_data.base_wp); 1091 DSSERR("can't get clocks\n");
1024 return r; 1092 return r;
1025 } 1093 }
1026 1094
@@ -1031,9 +1099,11 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
1031 hdmi.ip_data.pll_offset = HDMI_PLLCTRL; 1099 hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
1032 hdmi.ip_data.phy_offset = HDMI_PHY; 1100 hdmi.ip_data.phy_offset = HDMI_PHY;
1033 1101
1034 mutex_init(&hdmi.ip_data.lock); 1102 r = hdmi_panel_init();
1035 1103 if (r) {
1036 hdmi_panel_init(); 1104 DSSERR("can't init panel\n");
1105 goto err_panel_init;
1106 }
1037 1107
1038 dss_debugfs_create_file("hdmi", hdmi_dump_regs); 1108 dss_debugfs_create_file("hdmi", hdmi_dump_regs);
1039 1109
@@ -1042,6 +1112,10 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
1042 hdmi_probe_pdata(pdev); 1112 hdmi_probe_pdata(pdev);
1043 1113
1044 return 0; 1114 return 0;
1115
1116err_panel_init:
1117 hdmi_put_clocks();
1118 return r;
1045} 1119}
1046 1120
1047static int __exit hdmi_remove_child(struct device *dev, void *data) 1121static int __exit hdmi_remove_child(struct device *dev, void *data)
@@ -1065,8 +1139,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
1065 1139
1066 hdmi_put_clocks(); 1140 hdmi_put_clocks();
1067 1141
1068 iounmap(hdmi.ip_data.base_wp);
1069
1070 return 0; 1142 return 0;
1071} 1143}
1072 1144