[PATCH 5.1 77/85] drm/imx: ipuv3-plane: fix atomic update status query for non-plus i.MX6Q

From: Greg Kroah-Hartman
Date: Fri Jun 07 2019 - 11:56:00 EST


From: Philipp Zabel <p.zabel@xxxxxxxxxxxxxx>

commit 137caa702f2308f7ef03876e164b0d0f3300712a upstream.

The current buffer check halves the frame rate on non-plus i.MX6Q,
as the IDMAC current buffer pointer is not yet updated when
ipu_plane_atomic_update_pending is called from the EOF irq handler.

Fixes: 70e8a0c71e9 ("drm/imx: ipuv3-plane: add function to query atomic update status")
Tested-by: Marco Felsch <m.felsch@xxxxxxxxxxxxxx>
Signed-off-by: Philipp Zabel <p.zabel@xxxxxxxxxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
drivers/gpu/drm/imx/ipuv3-plane.c | 13 ++++++++-----
drivers/gpu/drm/imx/ipuv3-plane.h | 1 -
2 files changed, 8 insertions(+), 6 deletions(-)

--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -605,7 +605,6 @@ static void ipu_plane_atomic_update(stru
active = ipu_idmac_get_current_buffer(ipu_plane->ipu_ch);
ipu_cpmem_set_buffer(ipu_plane->ipu_ch, !active, eba);
ipu_idmac_select_buffer(ipu_plane->ipu_ch, !active);
- ipu_plane->next_buf = !active;
if (ipu_plane_separate_alpha(ipu_plane)) {
active = ipu_idmac_get_current_buffer(ipu_plane->alpha_ch);
ipu_cpmem_set_buffer(ipu_plane->alpha_ch, !active,
@@ -710,7 +709,6 @@ static void ipu_plane_atomic_update(stru
ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 1, eba);
ipu_idmac_lock_enable(ipu_plane->ipu_ch, num_bursts);
ipu_plane_enable(ipu_plane);
- ipu_plane->next_buf = -1;
}

static const struct drm_plane_helper_funcs ipu_plane_helper_funcs = {
@@ -732,10 +730,15 @@ bool ipu_plane_atomic_update_pending(str

if (ipu_state->use_pre)
return ipu_prg_channel_configure_pending(ipu_plane->ipu_ch);
- else if (ipu_plane->next_buf >= 0)
- return ipu_idmac_get_current_buffer(ipu_plane->ipu_ch) !=
- ipu_plane->next_buf;

+ /*
+ * Pretend no update is pending in the non-PRE/PRG case. For this to
+ * happen, an atomic update would have to be deferred until after the
+ * start of the next frame and simultaneously interrupt latency would
+ * have to be high enough to let the atomic update finish and issue an
+ * event before the previous end of frame interrupt handler can be
+ * executed.
+ */
return false;
}
int ipu_planes_assign_pre(struct drm_device *dev,
--- a/drivers/gpu/drm/imx/ipuv3-plane.h
+++ b/drivers/gpu/drm/imx/ipuv3-plane.h
@@ -27,7 +27,6 @@ struct ipu_plane {
int dp_flow;

bool disabling;
- int next_buf;
};

struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,