Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

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@pengutronix.de>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Cc: stable@vger.kernel.org

+8 -6
+8 -5
drivers/gpu/drm/imx/ipuv3-plane.c
··· 605 605 active = ipu_idmac_get_current_buffer(ipu_plane->ipu_ch); 606 606 ipu_cpmem_set_buffer(ipu_plane->ipu_ch, !active, eba); 607 607 ipu_idmac_select_buffer(ipu_plane->ipu_ch, !active); 608 - ipu_plane->next_buf = !active; 609 608 if (ipu_plane_separate_alpha(ipu_plane)) { 610 609 active = ipu_idmac_get_current_buffer(ipu_plane->alpha_ch); 611 610 ipu_cpmem_set_buffer(ipu_plane->alpha_ch, !active, ··· 709 710 ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 1, eba); 710 711 ipu_idmac_lock_enable(ipu_plane->ipu_ch, num_bursts); 711 712 ipu_plane_enable(ipu_plane); 712 - ipu_plane->next_buf = -1; 713 713 } 714 714 715 715 static const struct drm_plane_helper_funcs ipu_plane_helper_funcs = { ··· 730 732 731 733 if (ipu_state->use_pre) 732 734 return ipu_prg_channel_configure_pending(ipu_plane->ipu_ch); 733 - else if (ipu_plane->next_buf >= 0) 734 - return ipu_idmac_get_current_buffer(ipu_plane->ipu_ch) != 735 - ipu_plane->next_buf; 736 735 736 + /* 737 + * Pretend no update is pending in the non-PRE/PRG case. For this to 738 + * happen, an atomic update would have to be deferred until after the 739 + * start of the next frame and simultaneously interrupt latency would 740 + * have to be high enough to let the atomic update finish and issue an 741 + * event before the previous end of frame interrupt handler can be 742 + * executed. 743 + */ 737 744 return false; 738 745 } 739 746 int ipu_planes_assign_pre(struct drm_device *dev,
-1
drivers/gpu/drm/imx/ipuv3-plane.h
··· 27 27 int dp_flow; 28 28 29 29 bool disabling; 30 - int next_buf; 31 30 }; 32 31 33 32 struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,