[PATCHv2 13/17] drm/omap: fix scaling limits for WB

Tomi Valkeinen tomi.valkeinen at ti.com
Wed Feb 28 11:26:10 UTC 2018


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 at ti.com>
---
 drivers/gpu/drm/omapdrm/dss/dispc.c | 24 ++++++++++++++++++++----
 1 file 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);
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki



More information about the dri-devel mailing list