diff options
author | Ivaylo Dimitrov <freemangordon@abv.bg> | 2014-01-13 11:33:02 -0500 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2014-01-14 03:06:45 -0500 |
commit | e4998634dd3874e24bbf7937305c5ac708243908 (patch) | |
tree | 9722b5e03d8e5fdadbb19b671591034e677aad47 /drivers/video | |
parent | 0eb0dafb674cd6bfac2e3204b2f8b907e26b1138 (diff) |
OMAPDSS: DISPC: Fix 34xx overlay scaling calculation
commit 7faa92339bbb1e6b9a80983b206642517327eb75 OMAPDSS: DISPC: Handle
synclost errors in OMAP3 introduces limits check to prevent SYNCLOST errors
on OMAP3. However, it misses the logic found in Nokia kernels that is
needed to correctly calculate whether 3 tap or 5 tap rescaler to be used as
well as the logic to fallback to 3 taps if 5 taps clock results in too
tight horizontal timings. Without that patch "horizontal timing too tight"
errors are seen when a video with resolution above 640x350 is tried to be
played. The patch is a forward-ported logic found in Nokia N900 and N9/50
kernels.
Signed-off-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index b05bf3fe364e..f51646f15cf2 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c | |||
@@ -2001,7 +2001,8 @@ static void calc_tiler_rotation_offset(u16 screen_width, u16 width, | |||
2001 | */ | 2001 | */ |
2002 | static int check_horiz_timing_omap3(unsigned long pclk, unsigned long lclk, | 2002 | static int check_horiz_timing_omap3(unsigned long pclk, unsigned long lclk, |
2003 | const struct omap_video_timings *t, u16 pos_x, | 2003 | const struct omap_video_timings *t, u16 pos_x, |
2004 | u16 width, u16 height, u16 out_width, u16 out_height) | 2004 | u16 width, u16 height, u16 out_width, u16 out_height, |
2005 | bool five_taps) | ||
2005 | { | 2006 | { |
2006 | const int ds = DIV_ROUND_UP(height, out_height); | 2007 | const int ds = DIV_ROUND_UP(height, out_height); |
2007 | unsigned long nonactive; | 2008 | unsigned long nonactive; |
@@ -2021,6 +2022,10 @@ static int check_horiz_timing_omap3(unsigned long pclk, unsigned long lclk, | |||
2021 | if (blank <= limits[i]) | 2022 | if (blank <= limits[i]) |
2022 | return -EINVAL; | 2023 | return -EINVAL; |
2023 | 2024 | ||
2025 | /* FIXME add checks for 3-tap filter once the limitations are known */ | ||
2026 | if (!five_taps) | ||
2027 | return 0; | ||
2028 | |||
2024 | /* | 2029 | /* |
2025 | * Pixel data should be prepared before visible display point starts. | 2030 | * Pixel data should be prepared before visible display point starts. |
2026 | * So, atleast DS-2 lines must have already been fetched by DISPC | 2031 | * So, atleast DS-2 lines must have already been fetched by DISPC |
@@ -2196,22 +2201,30 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk, | |||
2196 | do { | 2201 | do { |
2197 | in_height = DIV_ROUND_UP(height, *decim_y); | 2202 | in_height = DIV_ROUND_UP(height, *decim_y); |
2198 | in_width = DIV_ROUND_UP(width, *decim_x); | 2203 | in_width = DIV_ROUND_UP(width, *decim_x); |
2199 | *core_clk = calc_core_clk_five_taps(pclk, mgr_timings, | 2204 | *five_taps = in_height > out_height; |
2200 | in_width, in_height, out_width, out_height, color_mode); | ||
2201 | |||
2202 | error = check_horiz_timing_omap3(pclk, lclk, mgr_timings, | ||
2203 | pos_x, in_width, in_height, out_width, | ||
2204 | out_height); | ||
2205 | 2205 | ||
2206 | if (in_width > maxsinglelinewidth) | 2206 | if (in_width > maxsinglelinewidth) |
2207 | if (in_height > out_height && | 2207 | if (in_height > out_height && |
2208 | in_height < out_height * 2) | 2208 | in_height < out_height * 2) |
2209 | *five_taps = false; | 2209 | *five_taps = false; |
2210 | if (!*five_taps) | 2210 | again: |
2211 | if (*five_taps) | ||
2212 | *core_clk = calc_core_clk_five_taps(pclk, mgr_timings, | ||
2213 | in_width, in_height, out_width, | ||
2214 | out_height, color_mode); | ||
2215 | else | ||
2211 | *core_clk = dispc.feat->calc_core_clk(pclk, in_width, | 2216 | *core_clk = dispc.feat->calc_core_clk(pclk, in_width, |
2212 | in_height, out_width, out_height, | 2217 | in_height, out_width, out_height, |
2213 | mem_to_mem); | 2218 | mem_to_mem); |
2214 | 2219 | ||
2220 | error = check_horiz_timing_omap3(pclk, lclk, mgr_timings, | ||
2221 | pos_x, in_width, in_height, out_width, | ||
2222 | out_height, *five_taps); | ||
2223 | if (error && *five_taps) { | ||
2224 | *five_taps = false; | ||
2225 | goto again; | ||
2226 | } | ||
2227 | |||
2215 | error = (error || in_width > maxsinglelinewidth * 2 || | 2228 | error = (error || in_width > maxsinglelinewidth * 2 || |
2216 | (in_width > maxsinglelinewidth && *five_taps) || | 2229 | (in_width > maxsinglelinewidth && *five_taps) || |
2217 | !*core_clk || *core_clk > dispc_core_clk_rate()); | 2230 | !*core_clk || *core_clk > dispc_core_clk_rate()); |
@@ -2228,7 +2241,7 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk, | |||
2228 | } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error); | 2241 | } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error); |
2229 | 2242 | ||
2230 | if (check_horiz_timing_omap3(pclk, lclk, mgr_timings, pos_x, width, | 2243 | if (check_horiz_timing_omap3(pclk, lclk, mgr_timings, pos_x, width, |
2231 | height, out_width, out_height)){ | 2244 | height, out_width, out_height, *five_taps)) { |
2232 | DSSERR("horizontal timing too tight\n"); | 2245 | DSSERR("horizontal timing too tight\n"); |
2233 | return -EINVAL; | 2246 | return -EINVAL; |
2234 | } | 2247 | } |