video: tegra: fb: Call mode filter from check var
Shashank Sharma [Mon, 30 Apr 2012 13:53:57 +0000 (18:53 +0530)]
Call dc_hdmi_mode_filter to validate a videomode. X prepares its
own modedb of supported HDMI modes, but all of them may not be
supported from the HDMI driver. This call makes sure a X-mode is
listed only if supported in DC driver.

Bug: 959676

Change-Id: I8aff65f4e08fcc4471af096150e3972b5913a95a
Signed-off-by: Shashank Sharma <shashanks@nvidia.com>
Reviewed-on: http://git-master/r/99650
Reviewed-by: Rohan Somvanshi <rsomvanshi@nvidia.com>
Tested-by: Rohan Somvanshi <rsomvanshi@nvidia.com>

drivers/video/tegra/dc/dc_priv.h
drivers/video/tegra/dc/hdmi.c
drivers/video/tegra/fb.c

index c08cd12..2f2dcec 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/io.h>
 #include <linux/mutex.h>
 #include <linux/wait.h>
+#include <linux/fb.h>
 #include <linux/completion.h>
 #include <linux/switch.h>
 
@@ -64,11 +65,13 @@ struct tegra_dc_out_ops {
        void (*enable)(struct tegra_dc *dc);
        /* disable output.  dc clocks are on at this point */
        void (*disable)(struct tegra_dc *dc);
-
        /* suspend output.  dc clocks are on at this point */
        void (*suspend)(struct tegra_dc *dc);
        /* resume output.  dc clocks are on at this point */
        void (*resume)(struct tegra_dc *dc);
+       /* mode filter. to provide a list of supported modes*/
+       bool (*mode_filter)(struct tegra_dc *dc,
+                       struct fb_videomode *mode);
 };
 
 struct tegra_dc {
index 498e691..2ddccb4 100644 (file)
@@ -1290,7 +1290,6 @@ static bool tegra_dc_hdmi_mode_filter(const struct tegra_dc *dc,
        return false;
 }
 
-
 static bool tegra_dc_hdmi_hpd(struct tegra_dc *dc)
 {
        return tegra_dc_hpd(dc);
@@ -2400,6 +2399,7 @@ struct tegra_dc_out_ops tegra_dc_hdmi_ops = {
        .detect = tegra_dc_hdmi_detect,
        .suspend = tegra_dc_hdmi_suspend,
        .resume = tegra_dc_hdmi_resume,
+       .mode_filter = tegra_dc_hdmi_mode_filter,
 };
 
 struct tegra_dc_edid *tegra_dc_get_edid(struct tegra_dc *dc)
index 32ae652..fc9befd 100644 (file)
@@ -64,11 +64,27 @@ static u32 pseudo_palette[16];
 static int tegra_fb_check_var(struct fb_var_screeninfo *var,
                              struct fb_info *info)
 {
+       struct tegra_fb_info *tegra_fb = info->par;
+       struct tegra_dc *dc = tegra_fb->win->dc;
+       struct tegra_dc_out_ops *ops = dc->out_ops;
+       struct fb_videomode mode;
+
        if ((var->yres * var->xres * var->bits_per_pixel / 8 * 2) >
            info->screen_size)
                return -EINVAL;
 
-       /* double yres_virtual to allow double buffering through pan_display */
+       /* Apply mode filter for HDMI only -LVDS supports only fix mode */
+       if (ops && ops->mode_filter) {
+
+               fb_var_to_videomode(&mode, var);
+               if (!ops->mode_filter(dc, &mode))
+                       return -EINVAL;
+
+               /* Mode filter may have modified the mode */
+               fb_videomode_to_var(var, &mode);
+       }
+
+       /* Double yres_virtual to allow double buffering through pan_display */
        var->yres_virtual = var->yres * 2;
 
        return 0;