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.c158
1 files changed, 114 insertions, 44 deletions
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 8c9b8b3b7f77..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,
@@ -715,7 +736,7 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
715 goto err0; 736 goto err0;
716 } 737 }
717 738
718 r = hdmi_power_on(dssdev); 739 r = hdmi_power_on_full(dssdev);
719 if (r) { 740 if (r) {
720 DSSERR("failed to power on device\n"); 741 DSSERR("failed to power on device\n");
721 goto err1; 742 goto err1;
@@ -737,13 +758,48 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
737 758
738 mutex_lock(&hdmi.lock); 759 mutex_lock(&hdmi.lock);
739 760
740 hdmi_power_off(dssdev); 761 hdmi_power_off_full(dssdev);
741 762
742 omap_dss_stop_device(dssdev); 763 omap_dss_stop_device(dssdev);
743 764
744 mutex_unlock(&hdmi.lock); 765 mutex_unlock(&hdmi.lock);
745} 766}
746 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
747static int hdmi_get_clocks(struct platform_device *pdev) 803static int hdmi_get_clocks(struct platform_device *pdev)
748{ 804{
749 struct clk *clk; 805 struct clk *clk;
@@ -912,7 +968,7 @@ int hdmi_audio_config(struct omap_dss_audio *audio)
912static 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)
913{ 969{
914 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 970 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
915 const char *def_disp_name = dss_get_default_display_name(); 971 const char *def_disp_name = omapdss_get_default_display_name();
916 struct omap_dss_device *def_dssdev; 972 struct omap_dss_device *def_dssdev;
917 int i; 973 int i;
918 974
@@ -970,9 +1026,19 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
970 return; 1026 return;
971 } 1027 }
972 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
973 r = dss_add_device(dssdev); 1037 r = dss_add_device(dssdev);
974 if (r) { 1038 if (r) {
975 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);
976 dss_put_device(dssdev); 1042 dss_put_device(dssdev);
977 return; 1043 return;
978 } 1044 }
@@ -999,22 +1065,22 @@ static void __exit hdmi_uninit_output(struct platform_device *pdev)
999/* HDMI HW IP initialisation */ 1065/* HDMI HW IP initialisation */
1000static int __init omapdss_hdmihw_probe(struct platform_device *pdev) 1066static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
1001{ 1067{
1002 struct resource *hdmi_mem; 1068 struct resource *res;
1003 int r; 1069 int r;
1004 1070
1005 hdmi.pdev = pdev; 1071 hdmi.pdev = pdev;
1006 1072
1007 mutex_init(&hdmi.lock); 1073 mutex_init(&hdmi.lock);
1074 mutex_init(&hdmi.ip_data.lock);
1008 1075
1009 hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0); 1076 res = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
1010 if (!hdmi_mem) { 1077 if (!res) {
1011 DSSERR("can't get IORESOURCE_MEM HDMI\n"); 1078 DSSERR("can't get IORESOURCE_MEM HDMI\n");
1012 return -EINVAL; 1079 return -EINVAL;
1013 } 1080 }
1014 1081
1015 /* Base address taken from platform */ 1082 /* Base address taken from platform */
1016 hdmi.ip_data.base_wp = ioremap(hdmi_mem->start, 1083 hdmi.ip_data.base_wp = devm_request_and_ioremap(&pdev->dev, res);
1017 resource_size(hdmi_mem));
1018 if (!hdmi.ip_data.base_wp) { 1084 if (!hdmi.ip_data.base_wp) {
1019 DSSERR("can't ioremap WP\n"); 1085 DSSERR("can't ioremap WP\n");
1020 return -ENOMEM; 1086 return -ENOMEM;
@@ -1022,7 +1088,7 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
1022 1088
1023 r = hdmi_get_clocks(pdev); 1089 r = hdmi_get_clocks(pdev);
1024 if (r) { 1090 if (r) {
1025 iounmap(hdmi.ip_data.base_wp); 1091 DSSERR("can't get clocks\n");
1026 return r; 1092 return r;
1027 } 1093 }
1028 1094
@@ -1033,9 +1099,11 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
1033 hdmi.ip_data.pll_offset = HDMI_PLLCTRL; 1099 hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
1034 hdmi.ip_data.phy_offset = HDMI_PHY; 1100 hdmi.ip_data.phy_offset = HDMI_PHY;
1035 1101
1036 mutex_init(&hdmi.ip_data.lock); 1102 r = hdmi_panel_init();
1037 1103 if (r) {
1038 hdmi_panel_init(); 1104 DSSERR("can't init panel\n");
1105 goto err_panel_init;
1106 }
1039 1107
1040 dss_debugfs_create_file("hdmi", hdmi_dump_regs); 1108 dss_debugfs_create_file("hdmi", hdmi_dump_regs);
1041 1109
@@ -1044,6 +1112,10 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
1044 hdmi_probe_pdata(pdev); 1112 hdmi_probe_pdata(pdev);
1045 1113
1046 return 0; 1114 return 0;
1115
1116err_panel_init:
1117 hdmi_put_clocks();
1118 return r;
1047} 1119}
1048 1120
1049static int __exit hdmi_remove_child(struct device *dev, void *data) 1121static int __exit hdmi_remove_child(struct device *dev, void *data)
@@ -1067,8 +1139,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
1067 1139
1068 hdmi_put_clocks(); 1140 hdmi_put_clocks();
1069 1141
1070 iounmap(hdmi.ip_data.base_wp);
1071
1072 return 0; 1142 return 0;
1073} 1143}
1074 1144