diff options
author | Steve Longerbeam <slongerbeam@gmail.com> | 2018-09-21 21:46:39 +0300 |
---|---|---|
committer | Philipp Zabel <p.zabel@pengutronix.de> | 2018-11-05 16:40:07 +0300 |
commit | c4e456583a46182fc11492206aed8995af66163b (patch) | |
tree | a3575834f66a6e9d54d544bb8f43513b09688b55 /drivers/gpu/ipu-v3/ipu-image-convert.c | |
parent | b288adad61054f77b08e14ca2f833f1617119547 (diff) | |
download | linux-c4e456583a46182fc11492206aed8995af66163b.tar.xz |
gpu: ipu-v3: image-convert: Catch unaligned tile offsets
Catch calculated tile offsets that are not 8-byte aligned as required by the
IDMAC engine and return error in calc_tile_offsets().
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
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.c | 61 |
1 files changed, 37 insertions, 24 deletions
diff --git a/drivers/gpu/ipu-v3/ipu-image-convert.c b/drivers/gpu/ipu-v3/ipu-image-convert.c index b8a400182a00..5fccba176e39 100644 --- a/drivers/gpu/ipu-v3/ipu-image-convert.c +++ b/drivers/gpu/ipu-v3/ipu-image-convert.c @@ -459,8 +459,8 @@ static void calc_out_tile_map(struct ipu_image_convert_ctx *ctx) } } -static void calc_tile_offsets_planar(struct ipu_image_convert_ctx *ctx, - struct ipu_image_convert_image *image) +static int calc_tile_offsets_planar(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; @@ -509,24 +509,30 @@ static void calc_tile_offsets_planar(struct ipu_image_convert_ctx *ctx, image->tile[tile].u_off = u_off; image->tile[tile++].v_off = v_off; - dev_dbg(priv->ipu->dev, - "task %u: ctx %p: %s@[%d,%d]: y_off %08x, u_off %08x, v_off %08x\n", - chan->ic_task, ctx, - image->type == IMAGE_CONVERT_IN ? - "Input" : "Output", row, col, - y_off, u_off, v_off); + if ((y_off & 0x7) || (u_off & 0x7) || (v_off & 0x7)) { + dev_err(priv->ipu->dev, + "task %u: ctx %p: %s@[%d,%d]: " + "y_off %08x, u_off %08x, v_off %08x\n", + chan->ic_task, ctx, + image->type == IMAGE_CONVERT_IN ? + "Input" : "Output", row, col, + y_off, u_off, v_off); + return -EINVAL; + } } } + + return 0; } -static void calc_tile_offsets_packed(struct ipu_image_convert_ctx *ctx, - struct ipu_image_convert_image *image) +static int calc_tile_offsets_packed(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; const struct ipu_image_pixfmt *fmt = image->fmt; unsigned int row, col, tile = 0; - u32 w, h, bpp, stride; + u32 w, h, bpp, stride, offset; u32 row_off, col_off; /* setup some convenience vars */ @@ -541,27 +547,35 @@ static void calc_tile_offsets_packed(struct ipu_image_convert_ctx *ctx, for (col = 0; col < image->num_cols; col++) { col_off = (col * w * bpp) >> 3; - image->tile[tile].offset = row_off + col_off; + offset = row_off + col_off; + + image->tile[tile].offset = offset; image->tile[tile].u_off = 0; image->tile[tile++].v_off = 0; - dev_dbg(priv->ipu->dev, - "task %u: ctx %p: %s@[%d,%d]: phys %08x\n", - chan->ic_task, ctx, - image->type == IMAGE_CONVERT_IN ? - "Input" : "Output", row, col, - row_off + col_off); + if (offset & 0x7) { + dev_err(priv->ipu->dev, + "task %u: ctx %p: %s@[%d,%d]: " + "phys %08x\n", + chan->ic_task, ctx, + image->type == IMAGE_CONVERT_IN ? + "Input" : "Output", row, col, + row_off + col_off); + return -EINVAL; + } } } + + return 0; } -static void calc_tile_offsets(struct ipu_image_convert_ctx *ctx, +static int calc_tile_offsets(struct ipu_image_convert_ctx *ctx, struct ipu_image_convert_image *image) { if (image->fmt->planar) - calc_tile_offsets_planar(ctx, image); - else - calc_tile_offsets_packed(ctx, image); + return calc_tile_offsets_planar(ctx, image); + + return calc_tile_offsets_packed(ctx, image); } /* @@ -1199,9 +1213,8 @@ static int fill_image(struct ipu_image_convert_ctx *ctx, ic_image->stride = ic_image->base.pix.bytesperline; calc_tile_dimensions(ctx, ic_image); - calc_tile_offsets(ctx, ic_image); - return 0; + return calc_tile_offsets(ctx, ic_image); } /* borrowed from drivers/media/v4l2-core/v4l2-common.c */ |