Skip to content

Commit ac7f564

Browse files
dangowrtgregkh
authored andcommitted
drm/mediatek: Only touch DISP_REG_OVL_PITCH_MSB if AFBC is supported
[ Upstream commit f8d9b91 ] Touching DISP_REG_OVL_PITCH_MSB leads to video overlay on MT2701, MT7623N and probably other older SoCs being broken. Move setting up AFBC layer configuration into a separate function only being called on hardware which actually supports AFBC which restores the behavior as it was before commit c410fa9 ("drm/mediatek: Add AFBC support to Mediatek DRM driver") on non-AFBC hardware. Fixes: c410fa9 ("drm/mediatek: Add AFBC support to Mediatek DRM driver") Cc: stable@vger.kernel.org Signed-off-by: Daniel Golle <daniel@makrotopia.org> Reviewed-by: CK Hu <ck.hu@mediatek.com> Link: https://patchwork.kernel.org/project/dri-devel/patch/c7fbd3c3e633c0b7dd6d1cd78ccbdded31e1ca0f.1734397800.git.daniel@makrotopia.org/ Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 08a2117 commit ac7f564

File tree

1 file changed

+29
-28
lines changed

1 file changed

+29
-28
lines changed

drivers/gpu/drm/mediatek/mtk_disp_ovl.c

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -403,31 +403,42 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
403403
}
404404
}
405405

406+
static void mtk_ovl_afbc_layer_config(struct mtk_disp_ovl *ovl,
407+
unsigned int idx,
408+
struct mtk_plane_pending_state *pending,
409+
struct cmdq_pkt *cmdq_pkt)
410+
{
411+
unsigned int pitch_msb = pending->pitch >> 16;
412+
unsigned int hdr_pitch = pending->hdr_pitch;
413+
unsigned int hdr_addr = pending->hdr_addr;
414+
415+
if (pending->modifier != DRM_FORMAT_MOD_LINEAR) {
416+
mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs,
417+
DISP_REG_OVL_HDR_ADDR(ovl, idx));
418+
mtk_ddp_write_relaxed(cmdq_pkt,
419+
OVL_PITCH_MSB_2ND_SUBBUF | pitch_msb,
420+
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
421+
mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs,
422+
DISP_REG_OVL_HDR_PITCH(ovl, idx));
423+
} else {
424+
mtk_ddp_write_relaxed(cmdq_pkt, pitch_msb,
425+
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
426+
}
427+
}
428+
406429
void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
407430
struct mtk_plane_state *state,
408431
struct cmdq_pkt *cmdq_pkt)
409432
{
410433
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
411434
struct mtk_plane_pending_state *pending = &state->pending;
412435
unsigned int addr = pending->addr;
413-
unsigned int hdr_addr = pending->hdr_addr;
414-
unsigned int pitch = pending->pitch;
415-
unsigned int hdr_pitch = pending->hdr_pitch;
436+
unsigned int pitch_lsb = pending->pitch & GENMASK(15, 0);
416437
unsigned int fmt = pending->format;
417438
unsigned int offset = (pending->y << 16) | pending->x;
418439
unsigned int src_size = (pending->height << 16) | pending->width;
419440
unsigned int ignore_pixel_alpha = 0;
420441
unsigned int con;
421-
bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR;
422-
union overlay_pitch {
423-
struct split_pitch {
424-
u16 lsb;
425-
u16 msb;
426-
} split_pitch;
427-
u32 pitch;
428-
} overlay_pitch;
429-
430-
overlay_pitch.pitch = pitch;
431442

432443
if (!pending->enable) {
433444
mtk_ovl_layer_off(dev, idx, cmdq_pkt);
@@ -457,11 +468,12 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
457468
}
458469

459470
if (ovl->data->supports_afbc)
460-
mtk_ovl_set_afbc(ovl, cmdq_pkt, idx, is_afbc);
471+
mtk_ovl_set_afbc(ovl, cmdq_pkt, idx,
472+
pending->modifier != DRM_FORMAT_MOD_LINEAR);
461473

462474
mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs,
463475
DISP_REG_OVL_CON(idx));
464-
mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb | ignore_pixel_alpha,
476+
mtk_ddp_write_relaxed(cmdq_pkt, pitch_lsb | ignore_pixel_alpha,
465477
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH(idx));
466478
mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs,
467479
DISP_REG_OVL_SRC_SIZE(idx));
@@ -470,19 +482,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
470482
mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl->regs,
471483
DISP_REG_OVL_ADDR(ovl, idx));
472484

473-
if (is_afbc) {
474-
mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs,
475-
DISP_REG_OVL_HDR_ADDR(ovl, idx));
476-
mtk_ddp_write_relaxed(cmdq_pkt,
477-
OVL_PITCH_MSB_2ND_SUBBUF | overlay_pitch.split_pitch.msb,
478-
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
479-
mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs,
480-
DISP_REG_OVL_HDR_PITCH(ovl, idx));
481-
} else {
482-
mtk_ddp_write_relaxed(cmdq_pkt,
483-
overlay_pitch.split_pitch.msb,
484-
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
485-
}
485+
if (ovl->data->supports_afbc)
486+
mtk_ovl_afbc_layer_config(ovl, idx, pending, cmdq_pkt);
486487

487488
mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt);
488489
mtk_ovl_layer_on(dev, idx, cmdq_pkt);

0 commit comments

Comments
 (0)