Commit 13bb1601 authored by Tomi Valkeinen's avatar Tomi Valkeinen

drm/omap: fix scaling limits for WB

WB has additional scaling limits when the output color format is one of
the YUV formats. These limits are not handled at the moment, causing
bad scaling and/or NULL dereference crash.

This patchs adds the check so that dispc returns an error for bad
scaling request.
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
parent 1317ef21
...@@ -2475,6 +2475,7 @@ static int dispc_ovl_calc_scaling_44xx(struct dispc_device *dispc, ...@@ -2475,6 +2475,7 @@ static int dispc_ovl_calc_scaling_44xx(struct dispc_device *dispc,
((dividend) * 100 / (divisor) - ((dividend) / (divisor) * 100)) ((dividend) * 100 / (divisor) - ((dividend) / (divisor) * 100))
static int dispc_ovl_calc_scaling(struct dispc_device *dispc, static int dispc_ovl_calc_scaling(struct dispc_device *dispc,
enum omap_plane_id plane,
unsigned long pclk, unsigned long lclk, unsigned long pclk, unsigned long lclk,
enum omap_overlay_caps caps, enum omap_overlay_caps caps,
const struct videomode *vm, const struct videomode *vm,
...@@ -2485,7 +2486,8 @@ static int dispc_ovl_calc_scaling(struct dispc_device *dispc, ...@@ -2485,7 +2486,8 @@ static int dispc_ovl_calc_scaling(struct dispc_device *dispc,
enum omap_dss_rotation_type rotation_type, enum omap_dss_rotation_type rotation_type,
bool mem_to_mem) bool mem_to_mem)
{ {
const int maxdownscale = dispc->feat->max_downscale; int maxhdownscale = dispc->feat->max_downscale;
int maxvdownscale = dispc->feat->max_downscale;
const int max_decim_limit = 16; const int max_decim_limit = 16;
unsigned long core_clk = 0; unsigned long core_clk = 0;
int decim_x, decim_y, ret; int decim_x, decim_y, ret;
...@@ -2493,6 +2495,20 @@ static int dispc_ovl_calc_scaling(struct dispc_device *dispc, ...@@ -2493,6 +2495,20 @@ static int dispc_ovl_calc_scaling(struct dispc_device *dispc,
if (width == out_width && height == out_height) if (width == out_width && height == out_height)
return 0; return 0;
if (plane == OMAP_DSS_WB) {
switch (fourcc) {
case DRM_FORMAT_NV12:
maxhdownscale = maxvdownscale = 2;
break;
case DRM_FORMAT_YUYV:
case DRM_FORMAT_UYVY:
maxhdownscale = 2;
maxvdownscale = 4;
break;
default:
break;
}
}
if (!mem_to_mem && (pclk == 0 || vm->pixelclock == 0)) { if (!mem_to_mem && (pclk == 0 || vm->pixelclock == 0)) {
DSSERR("cannot calculate scaling settings: pclk is zero\n"); DSSERR("cannot calculate scaling settings: pclk is zero\n");
return -EINVAL; return -EINVAL;
...@@ -2510,8 +2526,8 @@ static int dispc_ovl_calc_scaling(struct dispc_device *dispc, ...@@ -2510,8 +2526,8 @@ static int dispc_ovl_calc_scaling(struct dispc_device *dispc,
2 : max_decim_limit; 2 : max_decim_limit;
} }
decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale); decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxhdownscale);
decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale); decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxvdownscale);
if (decim_x > *x_predecim || out_width > width * 8) if (decim_x > *x_predecim || out_width > width * 8)
return -EINVAL; return -EINVAL;
...@@ -2615,7 +2631,7 @@ static int dispc_ovl_setup_common(struct dispc_device *dispc, ...@@ -2615,7 +2631,7 @@ static int dispc_ovl_setup_common(struct dispc_device *dispc,
if (!dispc_ovl_color_mode_supported(dispc, plane, fourcc)) if (!dispc_ovl_color_mode_supported(dispc, plane, fourcc))
return -EINVAL; return -EINVAL;
r = dispc_ovl_calc_scaling(dispc, pclk, lclk, caps, vm, in_width, r = dispc_ovl_calc_scaling(dispc, plane, pclk, lclk, caps, vm, in_width,
in_height, out_width, out_height, fourcc, in_height, out_width, out_height, fourcc,
&five_taps, &x_predecim, &y_predecim, pos_x, &five_taps, &x_predecim, &y_predecim, pos_x,
rotation_type, mem_to_mem); rotation_type, mem_to_mem);
......
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