summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/board-cardhu-panel.c2
-rw-r--r--arch/arm/mach-tegra/include/mach/dc.h2
-rw-r--r--drivers/video/tegra/dc/dc.c61
-rw-r--r--drivers/video/tegra/dc/hdmi.c10
4 files changed, 60 insertions, 15 deletions
diff --git a/arch/arm/mach-tegra/board-cardhu-panel.c b/arch/arm/mach-tegra/board-cardhu-panel.c
index aa48ab3273de..8ae073fdab81 100644
--- a/arch/arm/mach-tegra/board-cardhu-panel.c
+++ b/arch/arm/mach-tegra/board-cardhu-panel.c
@@ -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,
diff --git a/arch/arm/mach-tegra/include/mach/dc.h b/arch/arm/mach-tegra/include/mach/dc.h
index 9e71ca2a21ab..71f1be769507 100644
--- a/arch/arm/mach-tegra/include/mach/dc.h
+++ b/arch/arm/mach-tegra/include/mach/dc.h
@@ -507,6 +507,8 @@ int tegra_dc_get_stride(struct tegra_dc *dc, unsigned win);
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);
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
index 67fb904bbedf..935f18bc8cfd 100644
--- a/drivers/video/tegra/dc/dc.c
+++ b/drivers/video/tegra/dc/dc.c
@@ -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
@@ -65,6 +66,20 @@
#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);
@@ -621,6 +636,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)
@@ -2637,10 +2666,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;
@@ -2955,9 +3009,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);
diff --git a/drivers/video/tegra/dc/hdmi.c b/drivers/video/tegra/dc/hdmi.c
index eb670c38bacc..59b9afcec0e4 100644
--- a/drivers/video/tegra/dc/hdmi.c
+++ b/drivers/video/tegra/dc/hdmi.c
@@ -1344,15 +1344,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);
}