Message ID | c7fbd3c3e633c0b7dd6d1cd78ccbdded31e1ca0f.1734397800.git.daniel@makrotopia.org (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [v2] drm/mediatek: only touch DISP_REG_OVL_PITCH_MSB if AFBC is supported | expand |
Hi, Daniel: On Tue, 2024-12-17 at 01:18 +0000, Daniel Golle wrote: > External email : Please do not click links or open attachments until you have verified the sender or the content. > > > 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. Reviewed-by: CK Hu <ck.hu@mediatek.com> > > Fixes: c410fa9b07c3 ("drm/mediatek: Add AFBC support to Mediatek DRM driver") > Cc: stable@vger.kernel.org > Signed-off-by: Daniel Golle <daniel@makrotopia.org> > --- > 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
Hi, Daniel: Daniel Golle <daniel@makrotopia.org> 於 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@vger.kernel.org > Signed-off-by: Daniel Golle <daniel@makrotopia.org> > --- > 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
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);
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. Fixes: c410fa9b07c3 ("drm/mediatek: Add AFBC support to Mediatek DRM driver") Cc: stable@vger.kernel.org Signed-off-by: Daniel Golle <daniel@makrotopia.org> --- 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(-)