diff options
author | Philipp Zabel <p.zabel@pengutronix.de> | 2018-09-18 11:34:11 +0200 |
---|---|---|
committer | Philipp Zabel <p.zabel@pengutronix.de> | 2018-11-05 14:40:07 +0100 |
commit | 0537db801bb01b3bf8281d254f740fd8856ad15c (patch) | |
tree | 67db74c10a31db6c5aa26209a0566c7a88528287 /drivers/gpu/ipu-v3 | |
parent | 70b9b6b3bcb216926d8dcec27f1579abffd047c0 (diff) |
gpu: ipu-v3: image-convert: reconfigure IC per tile
For differently sized tiles or if the resizing coefficients change,
we have to stop, reconfigure, and restart the IC between tiles.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Acked-by: Steve Longerbeam <slongerbeam@gmail.com>
Tested-by: Steve Longerbeam <slongerbeam@gmail.com>
Diffstat (limited to 'drivers/gpu/ipu-v3')
-rw-r--r-- | drivers/gpu/ipu-v3/ipu-image-convert.c | 65 |
1 files changed, 44 insertions, 21 deletions
diff --git a/drivers/gpu/ipu-v3/ipu-image-convert.c b/drivers/gpu/ipu-v3/ipu-image-convert.c index 31e7186bcc00..cb47981741b4 100644 --- a/drivers/gpu/ipu-v3/ipu-image-convert.c +++ b/drivers/gpu/ipu-v3/ipu-image-convert.c @@ -1151,6 +1151,24 @@ static irqreturn_t do_bh(int irq, void *dev_id) return IRQ_HANDLED; } +static bool ic_settings_changed(struct ipu_image_convert_ctx *ctx) +{ + unsigned int cur_tile = ctx->next_tile - 1; + unsigned int next_tile = ctx->next_tile; + + if (ctx->resize_coeffs_h[cur_tile % ctx->in.num_cols] != + ctx->resize_coeffs_h[next_tile % ctx->in.num_cols] || + ctx->resize_coeffs_v[cur_tile / ctx->in.num_cols] != + ctx->resize_coeffs_v[next_tile / ctx->in.num_cols] || + ctx->in.tile[cur_tile].width != ctx->in.tile[next_tile].width || + ctx->in.tile[cur_tile].height != ctx->in.tile[next_tile].height || + ctx->out.tile[cur_tile].width != ctx->out.tile[next_tile].width || + ctx->out.tile[cur_tile].height != ctx->out.tile[next_tile].height) + return true; + + return false; +} + /* hold irqlock when calling */ static irqreturn_t do_irq(struct ipu_image_convert_run *run) { @@ -1194,27 +1212,32 @@ static irqreturn_t do_irq(struct ipu_image_convert_run *run) * not done, place the next tile buffers. */ if (!ctx->double_buffering) { - - src_tile = &s_image->tile[ctx->next_tile]; - dst_idx = ctx->out_tile_map[ctx->next_tile]; - dst_tile = &d_image->tile[dst_idx]; - - ipu_cpmem_set_buffer(chan->in_chan, 0, - s_image->base.phys0 + src_tile->offset); - ipu_cpmem_set_buffer(outch, 0, - d_image->base.phys0 + dst_tile->offset); - if (s_image->fmt->planar) - ipu_cpmem_set_uv_offset(chan->in_chan, - src_tile->u_off, - src_tile->v_off); - if (d_image->fmt->planar) - ipu_cpmem_set_uv_offset(outch, - dst_tile->u_off, - dst_tile->v_off); - - ipu_idmac_select_buffer(chan->in_chan, 0); - ipu_idmac_select_buffer(outch, 0); - + if (ic_settings_changed(ctx)) { + convert_stop(run); + convert_start(run, ctx->next_tile); + } else { + src_tile = &s_image->tile[ctx->next_tile]; + dst_idx = ctx->out_tile_map[ctx->next_tile]; + dst_tile = &d_image->tile[dst_idx]; + + ipu_cpmem_set_buffer(chan->in_chan, 0, + s_image->base.phys0 + + src_tile->offset); + ipu_cpmem_set_buffer(outch, 0, + d_image->base.phys0 + + dst_tile->offset); + if (s_image->fmt->planar) + ipu_cpmem_set_uv_offset(chan->in_chan, + src_tile->u_off, + src_tile->v_off); + if (d_image->fmt->planar) + ipu_cpmem_set_uv_offset(outch, + dst_tile->u_off, + dst_tile->v_off); + + ipu_idmac_select_buffer(chan->in_chan, 0); + ipu_idmac_select_buffer(outch, 0); + } } else if (ctx->next_tile < ctx->num_tiles - 1) { src_tile = &s_image->tile[ctx->next_tile + 1]; |