video: tegra: dc: Set default videomode
Shashank Sharma [Mon, 30 Apr 2012 12:06:24 +0000 (17:06 +0530)]
Set default videomode during the dc probe. This patch enables
HDMI during the probe only and fixes following issues:
1. Until Xinit there was no display on HDMI.
2. Framebuffer console on HDMI needs it to be enabled well before
   Xinit.
To avoide un-necessary powering on HDMI,Check HPD and enable HDMI
only if it's present.

Bug: 930136
Bug: 977705
Change-Id: Ifb71328e5df0ccbb5751669db71fd24719fe3738
Signed-off-by: Shashank Sharma <shashanks@nvidia.com>
Reviewed-on: http://git-master/r/100656
Reviewed-by: Rohan Somvanshi <rsomvanshi@nvidia.com>
Tested-by: Rohan Somvanshi <rsomvanshi@nvidia.com>

arch/arm/mach-tegra/board-cardhu-panel.c
arch/arm/mach-tegra/include/mach/dc.h
drivers/video/tegra/dc/dc.c
drivers/video/tegra/dc/hdmi.c

index 80adfc0..5c7bd87 100644 (file)
@@ -734,7 +734,7 @@ static struct tegra_dc_out cardhu_disp2_out = {
 };
 
 static struct tegra_dc_platform_data cardhu_disp2_pdata = {
-       .flags          = 0,
+       .flags          = TEGRA_DC_FLAG_ENABLED,
        .default_out    = &cardhu_disp2_out,
        .fb             = &cardhu_hdmi_fb_data,
        .emc_clk_rate   = 300000000,
index a5f7210..3b9b431 100644 (file)
@@ -505,6 +505,8 @@ struct tegra_dc_platform_data {
 struct tegra_dc *tegra_dc_get_dc(unsigned idx);
 struct tegra_dc_win *tegra_dc_get_window(struct tegra_dc *dc, unsigned win);
 bool tegra_dc_get_connected(struct tegra_dc *);
+bool tegra_dc_hpd(struct tegra_dc *dc);
+
 
 void tegra_dc_blank(struct tegra_dc *dc);
 
index 11e6281..c42df4c 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/backlight.h>
+#include <linux/gpio.h>
 #include <video/tegrafb.h>
 #include <drm/drm_fixed.h>
 #ifdef CONFIG_SWITCH
 #endif
 
 static int no_vsync;
+static struct fb_videomode tegra_dc_hdmi_fallback_mode = {
+       .refresh = 60,
+       .xres = 640,
+       .yres = 480,
+       .pixclock = KHZ2PICOS(25200),
+       .hsync_len = 96,        /* h_sync_width */
+       .vsync_len = 2,         /* v_sync_width */
+       .left_margin = 48,      /* h_back_porch */
+       .upper_margin = 33,     /* v_back_porch */
+       .right_margin = 16,     /* h_front_porch */
+       .lower_margin = 10,     /* v_front_porch */
+       .vmode = 0,
+       .sync = 0,
+};
 
 static void _tegra_dc_controller_disable(struct tegra_dc *dc);
 
@@ -614,6 +629,20 @@ bool tegra_dc_get_connected(struct tegra_dc *dc)
 }
 EXPORT_SYMBOL(tegra_dc_get_connected);
 
+bool tegra_dc_hpd(struct tegra_dc *dc)
+{
+       int sense;
+       int level;
+
+       level = gpio_get_value(dc->out->hotplug_gpio);
+
+       sense = dc->out->flags & TEGRA_DC_OUT_HOTPLUG_MASK;
+
+       return (sense == TEGRA_DC_OUT_HOTPLUG_HIGH && level) ||
+               (sense == TEGRA_DC_OUT_HOTPLUG_LOW && !level);
+}
+EXPORT_SYMBOL(tegra_dc_hpd);
+
 static u32 blend_topwin(u32 flags)
 {
        if (flags & TEGRA_WIN_FLAG_BLEND_COVERAGE)
@@ -2622,10 +2651,35 @@ static bool _tegra_dc_controller_reset_enable(struct tegra_dc *dc)
 }
 #endif
 
+static int _tegra_dc_set_default_videomode(struct tegra_dc *dc)
+{
+       return tegra_dc_set_fb_mode(dc, &tegra_dc_hdmi_fallback_mode, 0);
+}
+
 static bool _tegra_dc_enable(struct tegra_dc *dc)
 {
-       if (dc->mode.pclk == 0)
-               return false;
+       if (dc->mode.pclk == 0) {
+               switch (dc->out->type) {
+               case TEGRA_DC_OUT_HDMI:
+               /* DC enable called but no videomode is loaded.
+                    Check if HDMI is connected, then set fallback mdoe */
+               if (tegra_dc_hpd(dc)) {
+                       if (_tegra_dc_set_default_videomode(dc))
+                               return false;
+               } else
+                       return false;
+
+               break;
+
+               /* Do nothing for other outputs for now */
+               case TEGRA_DC_OUT_RGB:
+
+               case TEGRA_DC_OUT_DSI:
+
+               default:
+                       return false;
+               }
+       }
 
        if (!dc->out)
                return false;
@@ -2939,9 +2993,6 @@ static int tegra_dc_probe(struct nvhost_device *ndev)
         */
        dc->emc_clk_rate = 0;
 
-       if (dc->pdata->flags & TEGRA_DC_FLAG_ENABLED)
-               dc->enabled = true;
-
        mutex_init(&dc->lock);
        mutex_init(&dc->one_shot_lock);
        init_completion(&dc->frame_end_complete);
@@ -3005,8 +3056,8 @@ static int tegra_dc_probe(struct nvhost_device *ndev)
        disable_dc_irq(dc->irq);
 
        mutex_lock(&dc->lock);
-       if (dc->enabled)
-               _tegra_dc_enable(dc);
+       if (dc->pdata->flags & TEGRA_DC_FLAG_ENABLED)
+               dc->enabled = _tegra_dc_enable(dc);
        mutex_unlock(&dc->lock);
 
        tegra_dc_create_debugfs(dc);
index 112c1aa..67d0819 100644 (file)
@@ -1292,15 +1292,7 @@ static bool tegra_dc_hdmi_mode_filter(const struct tegra_dc *dc,
 
 static bool tegra_dc_hdmi_hpd(struct tegra_dc *dc)
 {
-       int sense;
-       int level;
-
-       level = gpio_get_value(dc->out->hotplug_gpio);
-
-       sense = dc->out->flags & TEGRA_DC_OUT_HOTPLUG_MASK;
-
-       return (sense == TEGRA_DC_OUT_HOTPLUG_HIGH && level) ||
-               (sense == TEGRA_DC_OUT_HOTPLUG_LOW && !level);
+       return tegra_dc_hpd(dc);
 }