Commit 71b59e7a authored by Philipp Zabel's avatar Philipp Zabel Committed by Greg Kroah-Hartman

drm/imx: ipuv3-plane: fix atomic update status query for non-plus i.MX6Q

commit 137caa70 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: 70e8a0c7 ("drm/imx: ipuv3-plane: add function to query atomic update status")
Tested-by: default avatarMarco Felsch <m.felsch@pengutronix.de>
Signed-off-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3a5c0d36
...@@ -605,7 +605,6 @@ static void ipu_plane_atomic_update(struct drm_plane *plane, ...@@ -605,7 +605,6 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
active = ipu_idmac_get_current_buffer(ipu_plane->ipu_ch); active = ipu_idmac_get_current_buffer(ipu_plane->ipu_ch);
ipu_cpmem_set_buffer(ipu_plane->ipu_ch, !active, eba); ipu_cpmem_set_buffer(ipu_plane->ipu_ch, !active, eba);
ipu_idmac_select_buffer(ipu_plane->ipu_ch, !active); ipu_idmac_select_buffer(ipu_plane->ipu_ch, !active);
ipu_plane->next_buf = !active;
if (ipu_plane_separate_alpha(ipu_plane)) { if (ipu_plane_separate_alpha(ipu_plane)) {
active = ipu_idmac_get_current_buffer(ipu_plane->alpha_ch); active = ipu_idmac_get_current_buffer(ipu_plane->alpha_ch);
ipu_cpmem_set_buffer(ipu_plane->alpha_ch, !active, ipu_cpmem_set_buffer(ipu_plane->alpha_ch, !active,
...@@ -710,7 +709,6 @@ static void ipu_plane_atomic_update(struct drm_plane *plane, ...@@ -710,7 +709,6 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 1, eba); ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 1, eba);
ipu_idmac_lock_enable(ipu_plane->ipu_ch, num_bursts); ipu_idmac_lock_enable(ipu_plane->ipu_ch, num_bursts);
ipu_plane_enable(ipu_plane); ipu_plane_enable(ipu_plane);
ipu_plane->next_buf = -1;
} }
static const struct drm_plane_helper_funcs ipu_plane_helper_funcs = { static const struct drm_plane_helper_funcs ipu_plane_helper_funcs = {
...@@ -732,10 +730,15 @@ bool ipu_plane_atomic_update_pending(struct drm_plane *plane) ...@@ -732,10 +730,15 @@ bool ipu_plane_atomic_update_pending(struct drm_plane *plane)
if (ipu_state->use_pre) if (ipu_state->use_pre)
return ipu_prg_channel_configure_pending(ipu_plane->ipu_ch); 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; return false;
} }
int ipu_planes_assign_pre(struct drm_device *dev, int ipu_planes_assign_pre(struct drm_device *dev,
......
...@@ -27,7 +27,6 @@ struct ipu_plane { ...@@ -27,7 +27,6 @@ struct ipu_plane {
int dp_flow; int dp_flow;
bool disabling; bool disabling;
int next_buf;
}; };
struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu, struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment