diff options
author | Donghan Ryu <dryu@nvidia.com> | 2011-06-14 17:45:08 +0900 |
---|---|---|
committer | Yuhao Ding <yding@nvidia.com> | 2011-06-17 17:11:57 -0700 |
commit | 8cf6e47dd3d4efaa3a1f0a15f1bd36ad34d3a951 (patch) | |
tree | 0d9a8ea6109614f962efd3f4fbc041f5ad637521 /drivers | |
parent | 8917a5603a3e6534d6c75ed0d91077062805b111 (diff) |
video: tegra: dc: fix hdmi mode filter
If there are more than one hdmi modes that have same xres,
yres, and vmode, tegra_dc_hdmi_mode_equal can return true even
though pixclocks are way different from each other.
Now, tegra_dc_hdmi_mode_equal will retun false if pixclock has
more than 1Hz of difference. Also, tegra_fb_set_par will use
fb_find_nearest_mode instead of fb_find_best_mode to take
refresh rate into the consideration.
Bug: 815409
Change-Id: I2dd911fa337b91933f68801b636cbcc7ad6f8fea
Reviewed-on: http://git-master/r/36464
Reviewed-by: Donghan Ryu <dryu@nvidia.com>
Tested-by: Donghan Ryu <dryu@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Reviewed-by: Jonathan Mayo <jmayo@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/tegra/dc/hdmi.c | 20 | ||||
-rw-r--r-- | drivers/video/tegra/fb.c | 5 |
2 files changed, 20 insertions, 5 deletions
diff --git a/drivers/video/tegra/dc/hdmi.c b/drivers/video/tegra/dc/hdmi.c index 5d72969f9868..6add4ad7aa70 100644 --- a/drivers/video/tegra/dc/hdmi.c +++ b/drivers/video/tegra/dc/hdmi.c @@ -484,11 +484,23 @@ static void hdmi_dumpregs(struct tegra_dc_hdmi_data *hdmi) #define PIXCLOCK_TOLERANCE 200 +static int tegra_dc_calc_clock_per_frame(const struct fb_videomode *mode) +{ + return (mode->left_margin + mode->xres + + mode->right_margin + mode->hsync_len) * + (mode->upper_margin + mode->yres + + mode->lower_margin + mode->vsync_len); +} static bool tegra_dc_hdmi_mode_equal(const struct fb_videomode *mode1, const struct fb_videomode *mode2) { + int clock_per_frame = tegra_dc_calc_clock_per_frame(mode1); + + /* allows up to 1Hz of pixclock difference */ return mode1->xres == mode2->xres && mode1->yres == mode2->yres && + (abs(PICOS2KHZ(mode1->pixclock - mode2->pixclock)) * + 1000 / clock_per_frame <= 1) && mode1->vmode == mode2->vmode; } @@ -508,16 +520,16 @@ static bool tegra_dc_hdmi_mode_filter(const struct tegra_dc *dc, struct fb_videomode *mode) { int i; - int clocks; + int clock_per_frame; for (i = 0; i < ARRAY_SIZE(tegra_dc_hdmi_supported_modes); i++) { if (tegra_dc_hdmi_mode_equal(&tegra_dc_hdmi_supported_modes[i], mode) && tegra_dc_hdmi_valid_pixclock(dc, &tegra_dc_hdmi_supported_modes[i])) { memcpy(mode, &tegra_dc_hdmi_supported_modes[i], sizeof(*mode)); mode->flag = FB_MODE_IS_DETAILED; - clocks = (mode->left_margin + mode->xres + mode->right_margin + mode->hsync_len) * - (mode->upper_margin + mode->yres + mode->lower_margin + mode->vsync_len); - mode->refresh = (PICOS2KHZ(mode->pixclock) * 1000) / clocks; + clock_per_frame = tegra_dc_calc_clock_per_frame(mode); + mode->refresh = (PICOS2KHZ(mode->pixclock) * 1000) + / clock_per_frame; return true; } } diff --git a/drivers/video/tegra/fb.c b/drivers/video/tegra/fb.c index b09c30bfc3be..f52b693af207 100644 --- a/drivers/video/tegra/fb.c +++ b/drivers/video/tegra/fb.c @@ -175,9 +175,12 @@ static int tegra_fb_set_par(struct fb_info *info) if (var->pixclock) { struct tegra_dc_mode mode; + struct fb_videomode m; + + fb_var_to_videomode(&m, var); info->mode = (struct fb_videomode *) - fb_find_best_mode(var, &info->modelist); + fb_find_nearest_mode(&m, &info->modelist); if (!info->mode) { dev_warn(&tegra_fb->ndev->dev, "can't match video mode\n"); return -EINVAL; |