Skip to content

Commit d208261

Browse files
Jason-JH LinChun-Kuang Hu
authored andcommitted
drm/mediatek: Add wait_event_timeout when disabling plane
Our hardware registers are set through GCE, not by the CPU. DRM might assume the hardware is disabled immediately after calling atomic_disable() of drm_plane, but it is only truly disabled after the GCE IRQ is triggered. Additionally, the cursor plane in DRM uses async_commit, so DRM will not wait for vblank and will free the buffer immediately after calling atomic_disable(). To prevent the framebuffer from being freed before the layer disable settings are configured into the hardware, which can cause an IOMMU fault error, a wait_event_timeout has been added to wait for the ddp_cmdq_cb() callback,indicating that the GCE IRQ has been triggered. Fixes: 2f965be ("drm/mediatek: apply CMDQ control flow") Signed-off-by: Jason-JH Lin <[email protected]> Reviewed-by: AngeloGioacchino Del Regno <[email protected]> Reviewed-by: CK Hu <[email protected]> Link: https://patchwork.kernel.org/project/linux-mediatek/patch/[email protected]/ Signed-off-by: Chun-Kuang Hu <[email protected]>
1 parent 19272b3 commit d208261

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

drivers/gpu/drm/mediatek/mtk_crtc.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,39 @@ int mtk_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
719719
return 0;
720720
}
721721

722+
void mtk_crtc_plane_disable(struct drm_crtc *crtc, struct drm_plane *plane)
723+
{
724+
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
725+
struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
726+
struct mtk_plane_state *plane_state = to_mtk_plane_state(plane->state);
727+
int i;
728+
729+
/* no need to wait for disabling the plane by CPU */
730+
if (!mtk_crtc->cmdq_client.chan)
731+
return;
732+
733+
if (!mtk_crtc->enabled)
734+
return;
735+
736+
/* set pending plane state to disabled */
737+
for (i = 0; i < mtk_crtc->layer_nr; i++) {
738+
struct drm_plane *mtk_plane = &mtk_crtc->planes[i];
739+
struct mtk_plane_state *mtk_plane_state = to_mtk_plane_state(mtk_plane->state);
740+
741+
if (mtk_plane->index == plane->index) {
742+
memcpy(mtk_plane_state, plane_state, sizeof(*plane_state));
743+
break;
744+
}
745+
}
746+
mtk_crtc_update_config(mtk_crtc, false);
747+
748+
/* wait for planes to be disabled by CMDQ */
749+
wait_event_timeout(mtk_crtc->cb_blocking_queue,
750+
mtk_crtc->cmdq_vblank_cnt == 0,
751+
msecs_to_jiffies(500));
752+
#endif
753+
}
754+
722755
void mtk_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
723756
struct drm_atomic_state *state)
724757
{

drivers/gpu/drm/mediatek/mtk_crtc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,
2121
unsigned int num_conn_routes);
2222
int mtk_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
2323
struct mtk_plane_state *state);
24+
void mtk_crtc_plane_disable(struct drm_crtc *crtc, struct drm_plane *plane);
2425
void mtk_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
2526
struct drm_atomic_state *plane_state);
2627
struct device *mtk_crtc_dma_dev_get(struct drm_crtc *crtc);

drivers/gpu/drm/mediatek/mtk_plane.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,14 @@ static void mtk_plane_atomic_disable(struct drm_plane *plane,
285285
struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
286286
plane);
287287
struct mtk_plane_state *mtk_plane_state = to_mtk_plane_state(new_state);
288+
struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
289+
plane);
290+
288291
mtk_plane_state->pending.enable = false;
289292
wmb(); /* Make sure the above parameter is set before update */
290293
mtk_plane_state->pending.dirty = true;
294+
295+
mtk_crtc_plane_disable(old_state->crtc, plane);
291296
}
292297

293298
static void mtk_plane_atomic_update(struct drm_plane *plane,

0 commit comments

Comments
 (0)