Hi, Daniel: Daniel Golle <daniel@xxxxxxxxxxxxxx> 於 2024年12月17日 週二 上午9:18寫道: > > 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 c410fa9b07c3 ("drm/mediatek: Add AFBC > support to Mediatek DRM driver") on non-AFBC hardware. Applied to mediatek-drm-fixes [1], thanks. [1] https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-fixes Regards, Chun-Kuang. > > Fixes: c410fa9b07c3 ("drm/mediatek: Add AFBC support to Mediatek DRM driver") > Cc: stable@xxxxxxxxxxxxxxx > Signed-off-by: Daniel Golle <daniel@xxxxxxxxxxxxxx> > --- > v2: move AFBC layer config into a new function > > drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 57 +++++++++++++------------ > 1 file changed, 29 insertions(+), 28 deletions(-) > > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > index f731d4fbe8b6..e0e24f0a6edd 100644 > --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > @@ -460,6 +460,29 @@ static unsigned int mtk_ovl_fmt_convert(struct mtk_disp_ovl *ovl, > } > } > > +static void mtk_ovl_afbc_layer_config(struct mtk_disp_ovl *ovl, > + unsigned int idx, > + struct mtk_plane_pending_state *pending, > + struct cmdq_pkt *cmdq_pkt) > +{ > + unsigned int pitch_msb = pending->pitch >> 16; > + unsigned int hdr_pitch = pending->hdr_pitch; > + unsigned int hdr_addr = pending->hdr_addr; > + > + if (pending->modifier != DRM_FORMAT_MOD_LINEAR) { > + mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs, > + DISP_REG_OVL_HDR_ADDR(ovl, idx)); > + mtk_ddp_write_relaxed(cmdq_pkt, > + OVL_PITCH_MSB_2ND_SUBBUF | pitch_msb, > + &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx)); > + mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs, > + DISP_REG_OVL_HDR_PITCH(ovl, idx)); > + } else { > + mtk_ddp_write_relaxed(cmdq_pkt, pitch_msb, > + &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx)); > + } > +} > + > void mtk_ovl_layer_config(struct device *dev, unsigned int idx, > struct mtk_plane_state *state, > struct cmdq_pkt *cmdq_pkt) > @@ -467,25 +490,13 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, > struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); > struct mtk_plane_pending_state *pending = &state->pending; > unsigned int addr = pending->addr; > - unsigned int hdr_addr = pending->hdr_addr; > - unsigned int pitch = pending->pitch; > - unsigned int hdr_pitch = pending->hdr_pitch; > + unsigned int pitch_lsb = pending->pitch & GENMASK(15, 0); > unsigned int fmt = pending->format; > unsigned int offset = (pending->y << 16) | pending->x; > unsigned int src_size = (pending->height << 16) | pending->width; > unsigned int blend_mode = state->base.pixel_blend_mode; > unsigned int ignore_pixel_alpha = 0; > unsigned int con; > - bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR; > - union overlay_pitch { > - struct split_pitch { > - u16 lsb; > - u16 msb; > - } split_pitch; > - u32 pitch; > - } overlay_pitch; > - > - overlay_pitch.pitch = pitch; > > if (!pending->enable) { > mtk_ovl_layer_off(dev, idx, cmdq_pkt); > @@ -524,11 +535,12 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, > } > > if (ovl->data->supports_afbc) > - mtk_ovl_set_afbc(ovl, cmdq_pkt, idx, is_afbc); > + mtk_ovl_set_afbc(ovl, cmdq_pkt, idx, > + pending->modifier != DRM_FORMAT_MOD_LINEAR); > > mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs, > DISP_REG_OVL_CON(idx)); > - mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb | ignore_pixel_alpha, > + mtk_ddp_write_relaxed(cmdq_pkt, pitch_lsb | ignore_pixel_alpha, > &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH(idx)); > mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs, > DISP_REG_OVL_SRC_SIZE(idx)); > @@ -537,19 +549,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, > mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl->regs, > DISP_REG_OVL_ADDR(ovl, idx)); > > - if (is_afbc) { > - mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs, > - DISP_REG_OVL_HDR_ADDR(ovl, idx)); > - mtk_ddp_write_relaxed(cmdq_pkt, > - OVL_PITCH_MSB_2ND_SUBBUF | overlay_pitch.split_pitch.msb, > - &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx)); > - mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs, > - DISP_REG_OVL_HDR_PITCH(ovl, idx)); > - } else { > - mtk_ddp_write_relaxed(cmdq_pkt, > - overlay_pitch.split_pitch.msb, > - &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx)); > - } > + if (ovl->data->supports_afbc) > + mtk_ovl_afbc_layer_config(ovl, idx, pending, cmdq_pkt); > > mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt); > mtk_ovl_layer_on(dev, idx, cmdq_pkt); > -- > 2.47.1