video: tegra: dc: get default mode from EDID
Jong Kim [Tue, 8 Apr 2014 17:39:16 +0000 (10:39 -0700)]
Override hard-coded default HDMI mode with the preferred mode
obtained from EDID read. Since the preferred mode is obtained
dynamically from EDID, the default hard-coded HDMI mode is set
to 640x480 @60Hz, which is universally supported.

bug 1495496

Change-Id: I19bc910758015927938fe5dde3e5359a78d905d4
Signed-off-by: Jong Kim <jongk@nvidia.com>
Reviewed-on: http://git-master/r/393564
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Matthew Pedro <mapedro@nvidia.com>
Tested-by: Winnie Hsu <whsu@nvidia.com>

arch/arm/mach-tegra/board-ardbeg-panel.c
drivers/video/tegra/dc/dc.c

index 8b39532..e2b4566 100644 (file)
@@ -335,17 +335,17 @@ struct tegra_hdmi_out ardbeg_hdmi_out = {
 #if defined(CONFIG_FRAMEBUFFER_CONSOLE)
 static struct tegra_dc_mode hdmi_panel_modes[] = {
        {
-               .pclk =                 148500000,
+               .pclk =                 25200000,
                .h_ref_to_sync =        1,
                .v_ref_to_sync =        1,
-               .h_sync_width =         44,     /* hsync_len */
-               .v_sync_width =         5,      /* vsync_len */
-               .h_back_porch =         148,    /* left_margin */
-               .v_back_porch =         36,     /* upper_margin */
-               .h_active =             1920,   /* xres */
-               .v_active =             1080,   /* yres */
-               .h_front_porch =        88,     /* right_margin */
-               .v_front_porch =        4,      /* lower_margin */
+               .h_sync_width =         96,     /* hsync_len */
+               .v_sync_width =         2,      /* vsync_len */
+               .h_back_porch =         48,     /* left_margin */
+               .v_back_porch =         33,     /* upper_margin */
+               .h_active =             640,    /* xres */
+               .v_active =             480,    /* yres */
+               .h_front_porch =        16,     /* right_margin */
+               .v_front_porch =        10,     /* lower_margin */
        },
 };
 #elif defined(CONFIG_TEGRA_HDMI_PRIMARY)
index 4030c55..6c516a6 100644 (file)
@@ -62,6 +62,7 @@
 #include "dev.h"
 #include "nvsd.h"
 #include "dp.h"
+#include "hdmi.h"
 
 /* HACK! This needs to come from DT */
 #include "../../../../arch/arm/mach-tegra/iomap.h"
@@ -2913,6 +2914,9 @@ static int tegra_dc_probe(struct platform_device *ndev)
 
        tegra_dc_feature_register(dc);
 
+       if (dc->pdata->default_out && dc->pdata->default_out->hotplug_init)
+               dc->pdata->default_out->hotplug_init(&dc->ndev->dev);
+
        if (dc->pdata->default_out) {
                ret = tegra_dc_set_out(dc, dc->pdata->default_out);
                if (ret < 0) {
@@ -2925,6 +2929,31 @@ static int tegra_dc_probe(struct platform_device *ndev)
        }
        dc->mode_dirty = false; /* ignore changes tegra_dc_set_out has done */
 
+       if (dc->out && dc->out->n_modes &&
+           (dc->out->type == TEGRA_DC_OUT_HDMI)) {
+               struct fb_monspecs specs;
+               struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
+               if (!tegra_edid_get_monspecs(hdmi->edid, &specs)) {
+                       struct tegra_dc_mode *dcmode = &dc->out->modes[0];
+                       dcmode->pclk          = specs.modedb->pixclock;
+                       dcmode->pclk          = PICOS2KHZ(dcmode->pclk);
+                       dcmode->pclk         *= 1000;
+                       dcmode->h_ref_to_sync = 1;
+                       dcmode->v_ref_to_sync = 1;
+                       dcmode->h_sync_width  = specs.modedb->hsync_len;
+                       dcmode->v_sync_width  = specs.modedb->vsync_len;
+                       dcmode->h_back_porch  = specs.modedb->left_margin;
+                       dcmode->v_back_porch  = specs.modedb->upper_margin;
+                       dcmode->h_active      = specs.modedb->xres;
+                       dcmode->v_active      = specs.modedb->yres;
+                       dcmode->h_front_porch = specs.modedb->right_margin;
+                       dcmode->v_front_porch = specs.modedb->lower_margin;
+                       tegra_dc_set_mode(dc, dcmode);
+                       dc->pdata->fb->xres = dcmode->h_active;
+                       dc->pdata->fb->yres = dcmode->v_active;
+               }
+       }
+
 #ifdef CONFIG_TEGRA_ISOMGR
        if (isomgr_client_id == -1) {
                dc->isomgr_handle = NULL;
@@ -3020,9 +3049,6 @@ static int tegra_dc_probe(struct platform_device *ndev)
        if (dc->out && dc->out->n_modes)
                tegra_dc_add_modes(dc);
 
-       if (dc->out && dc->out->hotplug_init)
-               dc->out->hotplug_init(&ndev->dev);
-
        if (dc->out_ops) {
                if (dc->out_ops->detect)
                        dc->out_ops->detect(dc);