Commit eec77da2 authored by Tomi Valkeinen's avatar Tomi Valkeinen

OMAPDSS: DISPC: decimation rounding fix

The driver uses DIV_ROUND_UP when calculating decimated width & height.
For example, when decimating with 3, the width is calculated as:

  width = DIV_ROUND_UP(width, decim_x);

This yields bad results for some values. For example, 800/3=266.666...,
which is rounded to 267. When the input width is set to 267, and pixel
increment is set to 3, this causes the dispc to read a line of 801
pixels, i.e. it reads a wrong pixel at the end of the line.

Even more pressing, the above rounding causes a BUG() in pixinc(), as
the value of 801 is used to calculate row increment, leading to a bad
value being passed to pixinc().

This patch fixes the decimation by removing the DIV_ROUND_UP()s when
calculating width and height for decimation.
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
parent b28a960c
...@@ -2160,8 +2160,8 @@ static int dispc_ovl_calc_scaling_24xx(unsigned long pclk, unsigned long lclk, ...@@ -2160,8 +2160,8 @@ static int dispc_ovl_calc_scaling_24xx(unsigned long pclk, unsigned long lclk,
*five_taps = false; *five_taps = false;
do { do {
in_height = DIV_ROUND_UP(height, *decim_y); in_height = height / *decim_y;
in_width = DIV_ROUND_UP(width, *decim_x); in_width = width / *decim_x;
*core_clk = dispc.feat->calc_core_clk(pclk, in_width, *core_clk = dispc.feat->calc_core_clk(pclk, in_width,
in_height, out_width, out_height, mem_to_mem); in_height, out_width, out_height, mem_to_mem);
error = (in_width > maxsinglelinewidth || !*core_clk || error = (in_width > maxsinglelinewidth || !*core_clk ||
...@@ -2199,8 +2199,8 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk, ...@@ -2199,8 +2199,8 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,
dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
do { do {
in_height = DIV_ROUND_UP(height, *decim_y); in_height = height / *decim_y;
in_width = DIV_ROUND_UP(width, *decim_x); in_width = width / *decim_x;
*five_taps = in_height > out_height; *five_taps = in_height > out_height;
if (in_width > maxsinglelinewidth) if (in_width > maxsinglelinewidth)
...@@ -2268,7 +2268,7 @@ static int dispc_ovl_calc_scaling_44xx(unsigned long pclk, unsigned long lclk, ...@@ -2268,7 +2268,7 @@ static int dispc_ovl_calc_scaling_44xx(unsigned long pclk, unsigned long lclk,
{ {
u16 in_width, in_width_max; u16 in_width, in_width_max;
int decim_x_min = *decim_x; int decim_x_min = *decim_x;
u16 in_height = DIV_ROUND_UP(height, *decim_y); u16 in_height = height / *decim_y;
const int maxsinglelinewidth = const int maxsinglelinewidth =
dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
...@@ -2287,7 +2287,7 @@ static int dispc_ovl_calc_scaling_44xx(unsigned long pclk, unsigned long lclk, ...@@ -2287,7 +2287,7 @@ static int dispc_ovl_calc_scaling_44xx(unsigned long pclk, unsigned long lclk,
return -EINVAL; return -EINVAL;
do { do {
in_width = DIV_ROUND_UP(width, *decim_x); in_width = width / *decim_x;
} while (*decim_x <= *x_predecim && } while (*decim_x <= *x_predecim &&
in_width > maxsinglelinewidth && ++*decim_x); in_width > maxsinglelinewidth && ++*decim_x);
...@@ -2466,8 +2466,8 @@ static int dispc_ovl_setup_common(enum omap_plane plane, ...@@ -2466,8 +2466,8 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
if (r) if (r)
return r; return r;
in_width = DIV_ROUND_UP(in_width, x_predecim); in_width = in_width / x_predecim;
in_height = DIV_ROUND_UP(in_height, y_predecim); in_height = in_height / y_predecim;
if (color_mode == OMAP_DSS_COLOR_YUV2 || if (color_mode == OMAP_DSS_COLOR_YUV2 ||
color_mode == OMAP_DSS_COLOR_UYVY || color_mode == OMAP_DSS_COLOR_UYVY ||
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment