summaryrefslogtreecommitdiff
path: root/drivers/video/tegra
diff options
context:
space:
mode:
authorDonghan Ryu <dryu@nvidia.com>2011-06-20 00:39:57 +0900
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:47:37 -0800
commitd5d291d20b4fd81789cf7ddc9870f24550bb7d14 (patch)
treeed2048bdfac2da518023788223a5578c3b25383e /drivers/video/tegra
parent798e97fab289756ba1b066b3b8b81b2cf9b601f7 (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 (cherry picked from commit 8cf6e47dd3d4efaa3a1f0a15f1bd36ad34d3a951) Original-Change-Id: I744d3c6dfb553bfab190e7d82a9dc5d8782e45d5 Reviewed-on: http://git-master/r/37419 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com> Rebase-Id: R4a93c72ba0a73c561864322014a8c9a33e86304b
Diffstat (limited to 'drivers/video/tegra')
-rw-r--r--drivers/video/tegra/dc/hdmi.c20
-rw-r--r--drivers/video/tegra/fb.c6
2 files changed, 21 insertions, 5 deletions
diff --git a/drivers/video/tegra/dc/hdmi.c b/drivers/video/tegra/dc/hdmi.c
index f5ac06bbe890..ff02d442e8c7 100644
--- a/drivers/video/tegra/dc/hdmi.c
+++ b/drivers/video/tegra/dc/hdmi.c
@@ -637,11 +637,23 @@ static inline void tegra_dc_hdmi_debug_create(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;
}
@@ -663,7 +675,7 @@ 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++) {
const struct fb_videomode *supported_mode
@@ -672,9 +684,9 @@ static bool tegra_dc_hdmi_mode_filter(const struct tegra_dc *dc,
tegra_dc_hdmi_valid_pixclock(dc, supported_mode)) {
memcpy(mode, supported_mode, 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 41ea43688700..4b46fdf32c13 100644
--- a/drivers/video/tegra/fb.c
+++ b/drivers/video/tegra/fb.c
@@ -182,9 +182,13 @@ static int tegra_fb_set_par(struct fb_info *info)
if (var->pixclock) {
bool stereo;
+ 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;