HDMI: Add fb mode db construction
authorDandawate Saket <dsaket@ti.com>
Mon, 29 Apr 2013 06:42:11 +0000 (23:42 -0700)
committerPraneeth Bajjuri <praneeth@ti.com>
Fri, 12 Jul 2013 23:58:15 +0000 (18:58 -0500)
Add fb mode db construction function and a getter
function for HWC.

Change-Id: I83ef027ffb68e33dbe2f59d3a6b39f3ec44028a6
Signed-off-by: Dandawate Saket <dsaket@ti.com>
drivers/video/omap2/dss/hdmi.c
drivers/video/omap2/dss/hdmi_panel.c
include/video/omapdss.h

index 43f55938a5831ae054f5544ed6ea126b923c14d1..6d01b3e0bffbf16ae000e7d55810b95035f3022a 100755 (executable)
@@ -68,6 +68,9 @@ static struct {
        u8 edid[HDMI_EDID_MAX_LENGTH];
        bool edid_set;
        bool custom_set;
+       bool can_do_hdmi;
+       bool force_timings;
+       int source_physical_address;
 
        struct hdmi_ip_data ip_data;
        int hdmi_irq;
@@ -461,6 +464,54 @@ done:
 
 }
 
+void hdmi_get_monspecs(struct omap_dss_device *dssdev)
+{
+       int i, j;
+       char *edid = (char *)hdmi.edid;
+       struct fb_monspecs *specs = &dssdev->panel.monspecs;
+       u32 fclk = dispc_fclk_rate() / 1000;
+       u32 max_pclk = dssdev->clocks.hdmi.max_pixclk_khz;
+
+       if (max_pclk && max_pclk < fclk)
+               fclk = max_pclk;
+
+       memset(specs, 0x0, sizeof(*specs));
+       if (!hdmi.edid_set)
+               return;
+       fb_edid_to_monspecs(edid, specs);
+       if (specs->modedb == NULL)
+               return;
+
+       for (i = 1; i <= edid[0x7e] && i * 128 < HDMI_EDID_MAX_LENGTH; i++) {
+               if (edid[i * 128] == 0x2)
+                       fb_edid_add_monspecs(edid + i * 128, specs);
+       }
+       if (hdmi.force_timings) {
+               for (i = 0; i < specs->modedb_len; i++) {
+                       specs->modedb[i++] = hdmi.ip_data.cfg.timingsfb;
+                       break;
+               }
+               specs->modedb_len = i;
+               hdmi.force_timings = false;
+               return;
+       }
+
+       hdmi.can_do_hdmi = specs->misc & FB_MISC_HDMI;
+
+       /* filter out resolutions we don't support */
+       for (i = j = 0; i < specs->modedb_len; i++) {
+               if (!hdmi_set_timings(&specs->modedb[i], true))
+                       continue;
+               if (fclk < PICOS2KHZ(specs->modedb[i].pixclock))
+                       continue;
+               if (specs->modedb[i].flag & FB_FLAG_PIXEL_REPEAT)
+                       continue;
+               specs->modedb[j++] = specs->modedb[i];
+       }
+       specs->modedb_len = j;
+
+}
+
 static int hdmi_runtime_get(void)
 {
        int r;
index d86a158a11f09cd2b176b4c56ed9d33da1568991..fab1d3030040b1a460ffc0869dc98c3ba05f898b 100755 (executable)
@@ -499,6 +499,16 @@ MODULE_DEVICE_TABLE(of, hdmi_panel_of_match);
 #define dss_of_match NULL
 #endif
 
+static int hdmi_get_modedb(struct omap_dss_device *dssdev,
+                          struct fb_videomode *modedb, int modedb_len)
+{
+       struct fb_monspecs *specs = &dssdev->panel.monspecs;
+       if (specs->modedb_len < modedb_len)
+               modedb_len = specs->modedb_len;
+       memcpy(modedb, specs->modedb, sizeof(*modedb) * modedb_len);
+       return modedb_len;
+}
+
 static struct omap_dss_driver hdmi_driver = {
        .probe          = hdmi_panel_probe,
        .remove         = hdmi_panel_remove,
@@ -508,6 +518,7 @@ static struct omap_dss_driver hdmi_driver = {
        .set_timings    = hdmi_set_timings,
        .check_timings  = hdmi_check_timings,
        .read_edid      = hdmi_read_edid,
+       .get_modedb     = hdmi_get_modedb,
        .set_mode       = omapdss_hdmi_display_set_mode,
        .detect         = hdmi_detect,
        .audio_enable   = hdmi_panel_audio_enable,
index 3370bbe01aca6d0415e791094b5a3dc9d9db11bd..7a1c46239f3082a3713cf4212339ef643bb85399 100755 (executable)
@@ -789,11 +789,13 @@ struct omap_dss_device {
                        /* regn is one greater than TRM's REGN value */
                        u16 regn;
                        u16 regm2;
+                       u32 max_pixclk_khz;
                } hdmi;
        } clocks;
 
        struct {
                struct omap_video_timings timings;
+               struct fb_monspecs monspecs;
 
                enum omap_dss_dsi_pixel_format dsi_pix_fmt;
                enum omap_dss_dsi_mode dsi_mode;