Skip to content

Commit fe30bae

Browse files
Jason-JH.LinChun-Kuang Hu
authored andcommitted
drm/mediatek: Fix missing configuration flags in mtk_crtc_ddp_config()
In mtk_crtc_ddp_config(), mtk_crtc will use some configuration flags to generate instructions to cmdq_handle, such as: state->pending_config mtk_crtc->pending_planes plane_state->pending.config mtk_crtc->pending_async_planes plane_state->pending.async_config These configuration flags may be set to false when a GCE IRQ comes calling ddp_cmdq_cb(). This may result in missing prepare instructions, especially if mtk_crtc_update_config() with the flase need_vblank (no need to wait for vblank) cases. Therefore, the mtk_crtc->config_updating flag is set at the beginning of mtk_crtc_update_config() to ensure that these configuration flags won't be changed when the mtk_crtc_ddp_config() is preparing instructions. But somehow the ddp_cmdq_cb() didn't use the mtk_crtc->config_updating flag to prevent those pending config flags from being cleared. To avoid missing the configuration when generating the config instruction, the config_updating flag should be added into ddp_cmdq_cb() and be protected with spin_lock. Fixes: 7f82d9c ("drm/mediatek: Clear pending flag when cmdq packet is done") Signed-off-by: Jason-JH.Lin <[email protected]> Reviewed-by: CK Hu <[email protected]> Reviewed-by: Fei Shao <[email protected]> Link: https://patchwork.kernel.org/project/dri-devel/patch/[email protected]/ Link: https://patchwork.kernel.org/project/dri-devel/patch/[email protected]/ Signed-off-by: Chun-Kuang Hu <[email protected]>
1 parent d79ae47 commit fe30bae

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

drivers/gpu/drm/mediatek/mtk_crtc.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ struct mtk_crtc {
6969
/* lock for display hardware access */
7070
struct mutex hw_lock;
7171
bool config_updating;
72+
/* lock for config_updating to cmd buffer */
73+
spinlock_t config_lock;
7274
};
7375

7476
struct mtk_crtc_state {
@@ -106,11 +108,16 @@ static void mtk_crtc_finish_page_flip(struct mtk_crtc *mtk_crtc)
106108

107109
static void mtk_drm_finish_page_flip(struct mtk_crtc *mtk_crtc)
108110
{
111+
unsigned long flags;
112+
109113
drm_crtc_handle_vblank(&mtk_crtc->base);
114+
115+
spin_lock_irqsave(&mtk_crtc->config_lock, flags);
110116
if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) {
111117
mtk_crtc_finish_page_flip(mtk_crtc);
112118
mtk_crtc->pending_needs_vblank = false;
113119
}
120+
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
114121
}
115122

116123
static void mtk_crtc_destroy(struct drm_crtc *crtc)
@@ -270,12 +277,19 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
270277
struct mtk_crtc *mtk_crtc = container_of(cmdq_cl, struct mtk_crtc, cmdq_client);
271278
struct mtk_crtc_state *state;
272279
unsigned int i;
280+
unsigned long flags;
273281

274282
if (data->sta < 0)
275283
return;
276284

277285
state = to_mtk_crtc_state(mtk_crtc->base.state);
278286

287+
spin_lock_irqsave(&mtk_crtc->config_lock, flags);
288+
if (mtk_crtc->config_updating) {
289+
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
290+
goto ddp_cmdq_cb_out;
291+
}
292+
279293
state->pending_config = false;
280294

281295
if (mtk_crtc->pending_planes) {
@@ -302,6 +316,10 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
302316
mtk_crtc->pending_async_planes = false;
303317
}
304318

319+
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
320+
321+
ddp_cmdq_cb_out:
322+
305323
mtk_crtc->cmdq_vblank_cnt = 0;
306324
wake_up(&mtk_crtc->cb_blocking_queue);
307325
}
@@ -531,9 +549,14 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank)
531549
struct mtk_drm_private *priv = crtc->dev->dev_private;
532550
unsigned int pending_planes = 0, pending_async_planes = 0;
533551
int i;
552+
unsigned long flags;
534553

535554
mutex_lock(&mtk_crtc->hw_lock);
555+
556+
spin_lock_irqsave(&mtk_crtc->config_lock, flags);
536557
mtk_crtc->config_updating = true;
558+
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
559+
537560
if (needs_vblank)
538561
mtk_crtc->pending_needs_vblank = true;
539562

@@ -587,7 +610,10 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank)
587610
mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
588611
}
589612
#endif
613+
spin_lock_irqsave(&mtk_crtc->config_lock, flags);
590614
mtk_crtc->config_updating = false;
615+
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
616+
591617
mutex_unlock(&mtk_crtc->hw_lock);
592618
}
593619

@@ -1030,6 +1056,7 @@ int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,
10301056
drm_mode_crtc_set_gamma_size(&mtk_crtc->base, gamma_lut_size);
10311057
drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size);
10321058
mutex_init(&mtk_crtc->hw_lock);
1059+
spin_lock_init(&mtk_crtc->config_lock);
10331060

10341061
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
10351062
i = priv->mbox_index++;

0 commit comments

Comments
 (0)