Skip to content

Commit

Permalink
drm/omap: fix scaling limits for WB
Browse files Browse the repository at this point in the history
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: Tomi Valkeinen <tomi.valkeinen@ti.com>
  • Loading branch information
Tomi Valkeinen committed Mar 1, 2018
1 parent 1317ef2 commit 13bb160
Showing 1 changed file with 20 additions and 4 deletions.
24 changes: 20 additions & 4 deletions drivers/gpu/drm/omapdrm/dss/dispc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2475,6 +2475,7 @@ static int dispc_ovl_calc_scaling_44xx(struct dispc_device *dispc,
((dividend) * 100 / (divisor) - ((dividend) / (divisor) * 100))

static int dispc_ovl_calc_scaling(struct dispc_device *dispc,
enum omap_plane_id plane,
unsigned long pclk, unsigned long lclk,
enum omap_overlay_caps caps,
const struct videomode *vm,
Expand All @@ -2485,14 +2486,29 @@ static int dispc_ovl_calc_scaling(struct dispc_device *dispc,
enum omap_dss_rotation_type rotation_type,
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;
unsigned long core_clk = 0;
int decim_x, decim_y, ret;

if (width == out_width && height == out_height)
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)) {
DSSERR("cannot calculate scaling settings: pclk is zero\n");
return -EINVAL;
Expand All @@ -2510,8 +2526,8 @@ static int dispc_ovl_calc_scaling(struct dispc_device *dispc,
2 : max_decim_limit;
}

decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale);
decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale);
decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxhdownscale);
decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxvdownscale);

if (decim_x > *x_predecim || out_width > width * 8)
return -EINVAL;
Expand Down Expand Up @@ -2615,7 +2631,7 @@ static int dispc_ovl_setup_common(struct dispc_device *dispc,
if (!dispc_ovl_color_mode_supported(dispc, plane, fourcc))
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,
&five_taps, &x_predecim, &y_predecim, pos_x,
rotation_type, mem_to_mem);
Expand Down

0 comments on commit 13bb160

Please sign in to comment.