Le vendredi 15 août 2025 à 16:52 +0800, Yunfei Dong a écrit : > The driver need to clean xpc status when receive decoder hardware > interrupt for mt8196 platform. > > Signed-off-by: Yunfei Dong > --- >  .../vcodec/decoder/mtk_vcodec_dec_hw.c        | 28 +++++++++++++++++++ >  .../vcodec/decoder/mtk_vcodec_dec_hw.h        | 13 +++++++-- >  2 files changed, 39 insertions(+), 2 deletions(-) > > diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.c > index 881d5de41e05..e4e527fe54dc 100644 > --- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.c > +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.c > @@ -61,6 +61,31 @@ static int mtk_vdec_hw_prob_done(struct mtk_vcodec_dec_dev *vdec_dev) >   return 0; >  } >   > +static void mtk_vdec_hw_write_reg_mask(void __iomem *reg_base, u32 reg_offset, u32 val, u32 mask) > +{ > + void __iomem *reg_addr = reg_base + reg_offset; > + u32 reg_val; > + > + reg_val =  readl(reg_addr); > + reg_val &= ~mask; > + reg_val |= (val & mask); > + writel(reg_val, reg_addr); > +} > + > +static void mtk_vdec_hw_clean_xpc(struct mtk_vdec_hw_dev *dev) > +{ > + u32 val, mask, addr = VDEC_XPC_CLEAN_ADDR; > + > + if (dev->main_dev->chip_name != MTK_VDEC_MT8196) > + return; > + > + val = dev->hw_idx == MTK_VDEC_LAT0 ? VDEC_XPC_LAT_VAL : VDEC_XPC_CORE_VAL; > + mask = dev->hw_idx == MTK_VDEC_LAT0 ? VDEC_XPC_LAT_MASK : VDEC_XPC_CORE_MASK; Avoid repeating conditions, less line does not make it more readable. if (dev->hw_idx == MTK_VDEC_LAT0) { val = VDEC_XPC_LAT_VAL; mask = VDEC_XPC_LAT_MASK; } else { val = VDEC_XPC_CORE_VAL; mask = VDEC_XPC_CORE_MASK; } > + > + mtk_vdec_hw_write_reg_mask(dev->reg_base[VDEC_HW_XPC], addr, val, mask); > + mtk_vdec_hw_write_reg_mask(dev->reg_base[VDEC_HW_XPC], addr, 0, mask); > +} > + >  static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv) >  { >   struct mtk_vdec_hw_dev *dev = priv; > @@ -88,6 +113,8 @@ static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv) >   writel(dec_done_status | VDEC_IRQ_CFG, vdec_misc_addr); >   writel(dec_done_status & ~VDEC_IRQ_CLR, vdec_misc_addr); >   > + mtk_vdec_hw_clean_xpc(dev); > + >   wake_up_dec_ctx(ctx, MTK_INST_IRQ_RECEIVED, dev->hw_idx); >   >   mtk_v4l2_vdec_dbg(3, ctx, "wake up ctx %d, dec_done_status=%x", > @@ -166,6 +193,7 @@ static int mtk_vdec_hw_probe(struct platform_device *pdev) >   subdev_dev->hw_idx = hw_idx; >   subdev_dev->main_dev = main_dev; >   subdev_dev->reg_base[VDEC_HW_SYS] = main_dev->reg_base[VDEC_HW_SYS]; > + subdev_dev->reg_base[VDEC_HW_XPC] = main_dev->reg_base[VDEC_HW_MISC]; >   set_bit(subdev_dev->hw_idx, main_dev->subdev_bitmap); >   >   if (IS_SUPPORT_VDEC_HW_IRQ(hw_idx)) { > diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.h b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.h > index 83fe8b9428e6..50ce6c1d25a2 100644 > --- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.h > +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.h > @@ -18,17 +18,26 @@ >  #define VDEC_IRQ_CLR 0x10 >  #define VDEC_IRQ_CFG_REG 0xa4 >   > +#define VDEC_XPC_CLEAN_ADDR 0xc > +#define VDEC_XPC_LAT_VAL BIT(0) > +#define VDEC_XPC_LAT_MASK BIT(0) > + > +#define VDEC_XPC_CORE_VAL BIT(4) > +#define VDEC_XPC_CORE_MASK BIT(4) > + >  #define IS_SUPPORT_VDEC_HW_IRQ(hw_idx) ((hw_idx) != MTK_VDEC_LAT_SOC) >   >  /** >   * enum mtk_vdec_hw_reg_idx - subdev hardware register base index > - * @VDEC_HW_SYS : vdec soc register index > + * @VDEC_HW_SYS:  vdec soc register index >   * @VDEC_HW_MISC: vdec misc register index > - * @VDEC_HW_MAX : vdec supported max register index > + * @VDEC_HW_XPC:  vdec xpc register index > + * @VDEC_HW_MAX:  vdec supported max register index >   */ >  enum mtk_vdec_hw_reg_idx { >   VDEC_HW_SYS, >   VDEC_HW_MISC, > + VDEC_HW_XPC, >   VDEC_HW_MAX >  }; But otherwise nothing important to report here. Reviewed-by: Nicolas Dufresne