summaryrefslogtreecommitdiff
path: root/drivers/gpu/ipu-v3/ipu-image-convert.c
diff options
context:
space:
mode:
authorPhilipp Zabel <p.zabel@pengutronix.de>2019-08-13 14:39:50 +0200
committerPhilipp Zabel <p.zabel@pengutronix.de>2019-08-19 16:25:30 +0200
commit5fb8b650cc1170f5e7a0f1a4ab3bb2042c007102 (patch)
treeabba89342e8ef511b763724afbe33d1c0a420a18 /drivers/gpu/ipu-v3/ipu-image-convert.c
parentde2564c70fcc1dfee89fff92eccba5a711a921cc (diff)
gpu: ipu-v3: image-convert: bail on invalid tile sizes
If we managed to create tiles sized 0x0 because of a bug in the seam calculation, return with an error message instead of letting the driver run into a division by zero later. Also check for tile sizes that are larger than supported by the hardware. Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Diffstat (limited to 'drivers/gpu/ipu-v3/ipu-image-convert.c')
-rw-r--r--drivers/gpu/ipu-v3/ipu-image-convert.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/gpu/ipu-v3/ipu-image-convert.c b/drivers/gpu/ipu-v3/ipu-image-convert.c
index a3375eec35ce..699c9b45683c 100644
--- a/drivers/gpu/ipu-v3/ipu-image-convert.c
+++ b/drivers/gpu/ipu-v3/ipu-image-convert.c
@@ -836,13 +836,21 @@ static void find_seams(struct ipu_image_convert_ctx *ctx,
in_bottom, flipped_out_top, out_bottom);
}
-static void calc_tile_dimensions(struct ipu_image_convert_ctx *ctx,
- struct ipu_image_convert_image *image)
+static int calc_tile_dimensions(struct ipu_image_convert_ctx *ctx,
+ struct ipu_image_convert_image *image)
{
struct ipu_image_convert_chan *chan = ctx->chan;
struct ipu_image_convert_priv *priv = chan->priv;
+ unsigned int max_width = 1024;
+ unsigned int max_height = 1024;
unsigned int i;
+ if (image->type == IMAGE_CONVERT_IN) {
+ /* Up to 4096x4096 input tile size */
+ max_width <<= ctx->downsize_coeff_h;
+ max_height <<= ctx->downsize_coeff_v;
+ }
+
for (i = 0; i < ctx->num_tiles; i++) {
struct ipu_image_tile *tile;
const unsigned int row = i / image->num_cols;
@@ -872,7 +880,17 @@ static void calc_tile_dimensions(struct ipu_image_convert_ctx *ctx,
image->type == IMAGE_CONVERT_IN ? "Input" : "Output",
row, col,
tile->width, tile->height, tile->left, tile->top);
+
+ if (!tile->width || tile->width > max_width ||
+ !tile->height || tile->height > max_height) {
+ dev_err(priv->ipu->dev, "invalid %s tile size: %ux%u\n",
+ image->type == IMAGE_CONVERT_IN ? "input" :
+ "output", tile->width, tile->height);
+ return -EINVAL;
+ }
}
+
+ return 0;
}
/*
@@ -2083,7 +2101,10 @@ ipu_image_convert_prepare(struct ipu_soc *ipu, enum ipu_ic_task ic_task,
find_seams(ctx, s_image, d_image);
- calc_tile_dimensions(ctx, s_image);
+ ret = calc_tile_dimensions(ctx, s_image);
+ if (ret)
+ goto out_free;
+
ret = calc_tile_offsets(ctx, s_image);
if (ret)
goto out_free;