[PATCH] gpu: ipu-v3: pre: don't trigger update if buffer address doesn't change
Philipp Zabel
philipp.zabel at gmail.com
Fri Dec 21 11:11:25 UTC 2018
Hi Lucas,
On Wed, Dec 19, 2018 at 4:40 PM Lucas Stach <l.stach at pengutronix.de> wrote:
>
> On a NOP double buffer update where current buffer address is the same
> as the next buffer address, the SDW_UPDATE bit clears too late.
What does this mean, exactly? Does the hardware behave differently
if the writel to IPU_PRE_NEXT_BUF doesn't change the value?
> As we
> are now using this bit to determine when it is safe to signal flip
> completion to userspace this will delay completion of atomic commits
> where one plane doesn't change the buffer by a whole frame period.
This sounds like the problem is not the way PRE behaves, but that we are
setting the SDW_UPDATE flag again and then later use it to check whether
the previous buffer was released, resulting in a false negative.
> Fix this by remembering the last buffer address and just skip the
> double buffer update if it would not change the buffer address.
It looks to me like ipu_plane_atomic_update does not have to call
ipu_prg_channel_configure (which then just relays to ipu_pre_update)
at all in this case. Should we just skip this in ipuv3-plane.c already?
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> ---
> drivers/gpu/ipu-v3/ipu-pre.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/drivers/gpu/ipu-v3/ipu-pre.c b/drivers/gpu/ipu-v3/ipu-pre.c
> index f933c1911e65..d383e8dbd6cc 100644
> --- a/drivers/gpu/ipu-v3/ipu-pre.c
> +++ b/drivers/gpu/ipu-v3/ipu-pre.c
> @@ -106,6 +106,7 @@ struct ipu_pre {
> void *buffer_virt;
> bool in_use;
> unsigned int safe_window_end;
> + unsigned int last_bufaddr;
This looks a lot like plane state.
> };
>
> static DEFINE_MUTEX(ipu_pre_list_mutex);
> @@ -242,7 +243,11 @@ void ipu_pre_update(struct ipu_pre *pre, unsigned int bufaddr)
> unsigned short current_yblock;
> u32 val;
>
> + if (bufaddr == pre->last_bufaddr)
> + return;
Hypothetical question, could this wrongly return if the channel is
first disabled, leaving
last_buffaddr set to X, and then the channel is reenabled, which
doesn't touch last_bufaddr,
and then the first update contains a buffer at the same address X?
> +
> writel(bufaddr, pre->regs + IPU_PRE_NEXT_BUF);
> + pre->last_bufaddr = bufaddr;
>
> do {
> if (time_after(jiffies, timeout)) {
> --
> 2.19.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
regards
Philipp
More information about the dri-devel
mailing list