summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm/dss/dispc.c
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2015-12-22 15:45:20 -0600
committerTomi Valkeinen <tomi.valkeinen@ti.com>2018-03-01 09:18:18 +0200
commit13bb1601c721f395d272d58438c9e747317f7c1a (patch)
tree3e9654f7e10df7ae6d661a83b82a34b218f5bbf5 /drivers/gpu/drm/omapdrm/dss/dispc.c
parent1317ef2113a14b631df15c9d09ce1283836c1456 (diff)
downloadlinux-13bb1601c721f395d272d58438c9e747317f7c1a.tar.bz2
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: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/gpu/drm/omapdrm/dss/dispc.c')
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dispc.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c
index 72f00e8a1329..2aa72845f819 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -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,
@@ -2485,7 +2486,8 @@ 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;
@@ -2493,6 +2495,20 @@ static int dispc_ovl_calc_scaling(struct dispc_device *dispc,
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;
@@ -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;
@@ -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);