drivers: video: tegra: Add 1000/1001 for HDMI_EXT
Aly Hirani [Mon, 30 Nov 2015 02:37:15 +0000 (18:37 -0800)]
Previous changed limited 1000/1001 modes to only CEA SVD. A problem
raised by this was with the modes that were read from the HDMI EXT
blocks. They supported 1000/1001 as well.

This change marks the HDMI EXT modes as such and modifies the 1000/1001
code to consider these modes too.

Bug 200156983

Change-Id: I0c774fb75efac6f51b51f75b1badeeb47e90b66c
Signed-off-by: Aly Hirani <ahirani@nvidia.com>
Reviewed-on: http://git-master/r/839054
GVS: Gerrit_Virtual_Submit
Reviewed-by: Vinayak Pane <vpane@nvidia.com>
Reviewed-by: Jon Mayo <jmayo@nvidia.com>

drivers/video/tegra/dc/edid.c
drivers/video/tegra/dc/hdmi2.0.c
include/uapi/linux/fb.h

index 93ee3ce..13b51e1 100644 (file)
@@ -730,6 +730,7 @@ int tegra_edid_get_monspecs(struct tegra_edid *edid, struct fb_monspecs *specs)
                                    }
                                    memcpy(&m[l], &hdmi_ext_modes[vic],
                                                sizeof(m[l]));
+                                   m[l].vmode |= FB_VMODE_IS_HDMI_EXT;
                                    l++;
                                }
                                kfree(specs->modedb);
@@ -753,10 +754,17 @@ int tegra_edid_get_monspecs(struct tegra_edid *edid, struct fb_monspecs *specs)
                if (frac_modes) {
                        for (j = 0; j < specs->modedb_len; ++j) {
                                int rate = tegra_dc_calc_fb_refresh(&specs->modedb[j]);
-                               /* 1000/1001 modes are only supported on CEA SVDs. */
-                               bool svd = (specs->modedb[j].vmode & FB_VMODE_IS_CEA) &&
-                                          !(specs->modedb[j].vmode & FB_VMODE_IS_DETAILED);
-                               if (svd && (rate == 24000 ||
+                               /*
+                                * 1000/1001 modes are only supported on CEA
+                                * SVDs or on HDMI EXT
+                                * */
+                               bool supported = ((specs->modedb[j].vmode &
+                                                  FB_VMODE_IS_CEA) &&
+                                                 !(specs->modedb[j].vmode &
+                                                   FB_VMODE_IS_DETAILED)) ||
+                                                specs->modedb[j].vmode &
+                                                FB_VMODE_IS_HDMI_EXT;
+                               if (supported && (rate == 24000 ||
                                     rate == 30000 ||
                                    (rate > (60000 - 20) && rate < (60000 + 20))) &&
                                    frac_n < max_modes) {
index 4115874..cdea6cc 100644 (file)
@@ -1367,12 +1367,16 @@ static int tegra_hdmi_get_extended_vic(const struct tegra_dc_mode *mode)
        mode_fixed = *mode;
 
        if (mode_fixed.vmode & FB_VMODE_1000DIV1001) {
-               mode_fixed.pclk = (u64)mode_fixed.pclk * 1001 / 1000;
+               mode_fixed.pclk = DIV_ROUND_UP((u64)mode_fixed.pclk * 1001,
+                                                       1000);
                mode_fixed.vmode &= ~FB_VMODE_1000DIV1001;
        }
 
        tegra_dc_to_fb_videomode(&m, &mode_fixed);
 
+       /* only interlaced required for VIC identification */
+       m.vmode &= FB_VMODE_INTERLACED;
+
        for (i = 1; i < HDMI_EXT_MODEDB_SIZE; i++) {
                const struct fb_videomode *curr = &hdmi_ext_modes[i];
 
index b182965..a1a1866 100644 (file)
@@ -274,8 +274,9 @@ struct fb_bitfield {
 #define FB_VMODE_1000DIV1001   0x008000
 #define FB_VMODE_IS_DETAILED   0x080000
 #define FB_VMODE_IS_CEA                0x100000
+#define FB_VMODE_IS_HDMI_EXT   0x200000
 
-#define FB_VMODE_MASK          0x18ffff
+#define FB_VMODE_MASK          0x38ffff
 
 #define FB_VMODE_YWRAP         0x10000 /* ywrap instead of panning     */
 #define FB_VMODE_SMOOTH_XPAN   0x20000 /* smooth xpan possible (internally used) */