HDMI: Add FB mode database setting support
authorDandawate Saket <dsaket@ti.com>
Mon, 29 Apr 2013 05:49:15 +0000 (22:49 -0700)
committerPraneeth Bajjuri <praneeth@ti.com>
Fri, 12 Jul 2013 23:58:15 +0000 (18:58 -0500)
Add FB mode parsing and setting the FB modes to
HDMI timing.

Change-Id: I37f631a850094c8fd7ae6165b19c9297194d73c7
Signed-off-by: Dandawate Saket <dsaket@ti.com>
Conflicts:
drivers/video/omap2/dss/hdmi_panel.c

drivers/video/omap2/dss/Kconfig [changed mode: 0644->0755]
drivers/video/omap2/dss/hdmi.c
drivers/video/omap2/dss/hdmi_panel.c
include/linux/omapfb.h [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index ef906e8..8ec5b57
@@ -65,6 +65,10 @@ config OMAP2_DSS_VENC
 
 config OMAP4_DSS_HDMI
        bool "OMAP4 HDMI support"
+       depends on ARCH_OMAP4 || ANDROID_SWITCH
+       select FB
+       select FB_MODE_HELPERS
+       select FB_OMAP2
         default y
        select I2C_ALGOBIT
        help
@@ -87,6 +91,9 @@ config OMAP5_DSS_HDMI
        select GPIO_PCA953X
        select MFD_PALMAS
        select REGULATOR_PALMAS
+       select FB
+       select FB_MODE_HELPERS
+       select FB_OMAP2
        help
            HDMI Interface.This add the High Deinition Multimedia Interface.
            See http://wwww.hdmi.org/ for HDMI specification.
@@ -139,4 +146,10 @@ config OMAP2_DSS_SLEEP_AFTER_VENC_RESET
          This option enables the sleep, and is enabled by default. You can
          disable the sleep if it doesn't cause problems on your platform.
 
+config USE_FB_MODE_DB
+       bool "Enable FB mode db support"
+       default y
+       help
+         Enable FB mode support.
+
 endif
index e430175689a224b199c7b5a6280dbc501970ed5f..da50133b62165270388ca638bdb351071eb63012 100755 (executable)
@@ -38,6 +38,7 @@
 #include <linux/of_gpio.h>
 #include <linux/of_i2c.h>
 #include <linux/fb.h>
+#include <linux/omapfb.h>
 #include <video/omapdss.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
@@ -447,6 +448,9 @@ done:
        DSSDBG("%s-%d\n", hdmi.ip_data.cfg.cm.mode ? "CEA" : "VESA",
                hdmi.ip_data.cfg.cm.code);
 
+       /* convert fb timing to dss timings to be in sync. */
+       omapfb_fb2dss_timings(&hdmi.ip_data.cfg.timingsfb,&hdmi.ip_data.cfg.timings);
+
        r = i >= 0 ? 1 : 0;
        return r;
 
@@ -780,7 +784,28 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
        p = &hdmi.ip_data.cfg.timings;
 
        DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
+#ifdef CONFIG_USE_FB_MODE_DB
+       if (!hdmi.custom_set) {
+               struct fb_videomode fb_mode = vesa_modes[4];
+               if ((hdmi.ip_data.cfg.cm.code != 4) &&
+                       (hdmi.ip_data.cfg.cm.mode != HDMI_DVI)) {
+                       if (hdmi.ip_data.cfg.cm.mode == HDMI_DVI)
+                               fb_mode = vesa_modes[hdmi.ip_data.cfg.cm.code];
+                       else
+                               fb_mode = cea_modes[hdmi.ip_data.cfg.cm.code];
+               }
+               if (!hdmi_set_timings(&fb_mode, false)) {
+                       /* Fallback in case we cannot set the timings */
+                       DSSERR("fallback to vesa default code");
+                       fb_mode = vesa_modes[4];
+                       hdmi_set_timings(&fb_mode, false);
+               }
+       }
 
+       /* Update the panel timing in dssdev */
+       omapfb_fb2dss_timings(&hdmi.ip_data.cfg.timingsfb,
+                                       &dssdev->panel.timings);
+#endif
        switch (hdmi.ip_data.cfg.deep_color) {
        case HDMI_DEEP_COLOR_30BIT:
                phy = (p->pixel_clock * 125) / 100 ;
@@ -928,6 +953,18 @@ int omapdss_hdmi_get_range(void)
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
                                        struct omap_video_timings *timings)
 {
+#ifdef CONFIG_USE_FB_MODE_DB
+       struct fb_videomode t;
+       omapfb_dss2fb_timings(timings, &t);
+
+       /* also check interlaced timings */
+       if (!hdmi_set_timings(&t, true)) {
+               t.yres *= 2;
+               t.vmode |= FB_VMODE_INTERLACED;
+       }
+       if (!hdmi_set_timings(&t, true))
+               return -EINVAL;
+#else
        struct hdmi_cm cm;
 
        cm = hdmi_get_code(timings);
@@ -935,6 +972,7 @@ int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
                return -EINVAL;
        }
 
+#endif
        return 0;
 
 }
@@ -1052,6 +1090,21 @@ err0:
 void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
                struct omap_video_timings *timings)
 {
+#ifdef CONFIG_USE_FB_MODE_DB
+       struct fb_videomode t;
+
+       DSSDBG("x_res= %d y_res = %d\n",
+               dssdev->panel.timings.x_res,
+               dssdev->panel.timings.y_res);
+
+       omapfb_dss2fb_timings(&dssdev->panel.timings, &t);
+       /* also check interlaced timings */
+       if (!hdmi_set_timings(&t, true)) {
+               t.yres *= 2;
+               t.vmode |= FB_VMODE_INTERLACED;
+       }
+       omapdss_hdmi_display_set_mode(dssdev, &t);
+#else
        struct hdmi_cm cm;
        const struct hdmi_config *t;
 
@@ -1065,6 +1118,7 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
                hdmi.ip_data.cfg = *t;
 
        mutex_unlock(&hdmi.lock);
+#endif
 }
 
 static void hdmi_dump_regs(struct seq_file *s)
index 236bb61c13ed6e7716312e2bc8e182a7f82c2631..d86a158a11f09cd2b176b4c56ed9d33da1568991 100755 (executable)
@@ -143,11 +143,10 @@ static int hdmi_panel_probe(struct omap_dss_device *dssdev)
        DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
                dssdev->panel.timings.x_res,
                dssdev->panel.timings.y_res);
-
+#ifndef CONFIG_USE_FB_MODE_DB
        omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings);
-
        hdmi.dssdev = dssdev;
-
+#endif
        return 0;
 }
 
@@ -326,9 +325,9 @@ static int hdmi_panel_enable(struct omap_dss_device *dssdev)
                r = -EINVAL;
                goto err;
        }
-
+#ifndef CONFIG_USE_FB_MODE_DB
        omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings);
-
+#endif
        r = omapdss_hdmi_display_enable(dssdev);
        if (r) {
                DSSERR("failed to power on\n");
@@ -412,10 +411,14 @@ static void hdmi_set_timings(struct omap_dss_device *dssdev,
         */
        hdmi_panel_audio_disable(dssdev);
 
-       omapdss_hdmi_display_set_timing(dssdev, timings);
        dssdev->panel.timings = *timings;
-
+#ifndef CONFIG_USE_FB_MODE_DB
+       omapdss_hdmi_display_set_timing(dssdev, timings);
        mutex_unlock(&hdmi.lock);
+#else
+       mutex_unlock(&hdmi.lock);
+       omapdss_hdmi_display_set_timing(dssdev, timings);
+#endif
 }
 
 static int hdmi_check_timings(struct omap_dss_device *dssdev,
old mode 100644 (file)
new mode 100755 (executable)
index 5605c9b..d49cf94
@@ -69,5 +69,9 @@ void __init omapfb_set_lcd_config(const struct omap_lcd_config *config);
 enum omap_color_mode;
 int omapfb_mode_to_dss_mode(struct fb_var_screeninfo *var,
                        enum omap_color_mode *mode);
-
+struct omap_video_timings;
+void omapfb_fb2dss_timings(struct fb_videomode *fb_timings,
+                       struct omap_video_timings *dss_timings);
+void omapfb_dss2fb_timings(struct omap_video_timings *dss_timings,
+                       struct fb_videomode *fb_timings);
 #endif /* __OMAPFB_H */