aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorIvaylo Dimitrov <freemangordon@abv.bg>2014-01-13 11:33:02 -0500
committerTomi Valkeinen <tomi.valkeinen@ti.com>2014-01-14 03:06:45 -0500
commite4998634dd3874e24bbf7937305c5ac708243908 (patch)
tree9722b5e03d8e5fdadbb19b671591034e677aad47 /drivers/video
parent0eb0dafb674cd6bfac2e3204b2f8b907e26b1138 (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.c31
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 */
2002static int check_horiz_timing_omap3(unsigned long pclk, unsigned long lclk, 2002static 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) 2210again:
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 }