Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c4e45658 authored by Steve Longerbeam's avatar Steve Longerbeam Committed by Philipp Zabel
Browse files

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: default avatarSteve Longerbeam <slongerbeam@gmail.com>
Tested-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
parent b288adad
Loading
Loading
Loading
Loading
+37 −24
Original line number Diff line number Diff line
@@ -459,7 +459,7 @@ static void calc_out_tile_map(struct ipu_image_convert_ctx *ctx)
	}
}

static void calc_tile_offsets_planar(struct ipu_image_convert_ctx *ctx,
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;
@@ -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",
			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,
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",
			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;
			}
		}
	}

static void calc_tile_offsets(struct ipu_image_convert_ctx *ctx,
	return 0;
}

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 */