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.valkei...@ti.com>
---
 drivers/gpu/drm/omapdrm/dss/dispc.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c 
b/drivers/gpu/drm/omapdrm/dss/dispc.c
index 3d804187df13..2d19852553f5 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -2381,7 +2381,8 @@ static int dispc_ovl_calc_scaling_44xx(unsigned long 
pclk, unsigned long lclk,
 #define DIV_FRAC(dividend, divisor) \
        ((dividend) * 100 / (divisor) - ((dividend) / (divisor) * 100))
 
-static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk,
+static int dispc_ovl_calc_scaling(enum omap_plane_id plane,
+               unsigned long pclk, unsigned long lclk,
                enum omap_overlay_caps caps,
                const struct videomode *vm,
                u16 width, u16 height, u16 out_width, u16 out_height,
@@ -2389,7 +2390,8 @@ static int dispc_ovl_calc_scaling(unsigned long pclk, 
unsigned long lclk,
                int *x_predecim, int *y_predecim, u16 pos_x,
                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;
@@ -2397,6 +2399,20 @@ static int dispc_ovl_calc_scaling(unsigned long pclk, 
unsigned long lclk,
        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;
@@ -2414,8 +2430,8 @@ static int dispc_ovl_calc_scaling(unsigned long pclk, 
unsigned long lclk,
                                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;
@@ -2514,7 +2530,7 @@ static int dispc_ovl_setup_common(enum omap_plane_id 
plane,
        if (!dispc_ovl_color_mode_supported(plane, fourcc))
                return -EINVAL;
 
-       r = dispc_ovl_calc_scaling(pclk, lclk, caps, vm, in_width,
+       r = dispc_ovl_calc_scaling(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

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to