MLK-19510: ISI: fix isi cann't restore to original size after resize
authorGuoniu.Zhou <guoniu.zhou@nxp.com>
Mon, 17 Sep 2018 03:33:22 +0000 (11:33 +0800)
committerLeonard Crestez <leonard.crestez@nxp.com>
Wed, 17 Apr 2019 23:51:34 +0000 (02:51 +0300)
1. add CHNL_SCL_IMG_CFG register that is new added in QXP/QM B0
2. according to isi owner's comments, CHNL_SCL_IMG_CFG need to
equal to CHNL_IMG_CFG when scaling disabled and equal to scaled
image size when scaling enabled, so add configuration for this
register.
3. Becuse isi software reset can't reset isi register to default
, so it need to manual clear if there is no scaling.

Signed-off-by: Guoniu.Zhou <guoniu.zhou@nxp.com>
drivers/media/platform/imx8/mxc-isi-hw.c

index daec75e..5e8a4d0 100644 (file)
@@ -444,6 +444,17 @@ void mxc_isi_channel_set_crop(struct mxc_isi_dev *mxc_isi)
        writel(val, mxc_isi->regs + CHNL_IMG_CTRL);
 }
 
+static void mxc_isi_channel_clear_scaling(struct mxc_isi_dev *mxc_isi)
+{
+       u32 val0;
+
+       writel(0x10001000, mxc_isi->regs + CHNL_SCALE_FACTOR);
+
+       val0 = readl(mxc_isi->regs + CHNL_IMG_CTRL);
+       val0 &= ~(CHNL_IMG_CTRL_DEC_X_MASK | CHNL_IMG_CTRL_DEC_Y_MASK);
+       writel(val0, mxc_isi->regs + CHNL_IMG_CTRL);
+}
+
 void mxc_isi_channel_set_scaling(struct mxc_isi_dev *mxc_isi)
 {
        struct mxc_isi_frame *dst_f = &mxc_isi->isi_cap.dst_f;
@@ -461,6 +472,7 @@ void mxc_isi_channel_set_scaling(struct mxc_isi_dev *mxc_isi)
        if (dst_f->height == src_f->height ||
                        dst_f->width == src_f->width) {
                mxc_isi->scale = 0;
+               mxc_isi_channel_clear_scaling(mxc_isi);
                dev_dbg(&mxc_isi->pdev->dev, "%s: no scale\n", __func__);
                return;
        }
@@ -520,6 +532,11 @@ void mxc_isi_channel_set_scaling(struct mxc_isi_dev *mxc_isi)
        val1 = xscale | (yscale << CHNL_SCALE_FACTOR_Y_SCALE_OFFSET);
 
        writel(val1, mxc_isi->regs + CHNL_SCALE_FACTOR);
+
+       /* Update scale config if scaling enabled */
+       val1 = dst_f->o_width | (dst_f->o_height << CHNL_SCL_IMG_CFG_HEIGHT_OFFSET);
+       writel(val1, mxc_isi->regs + CHNL_SCL_IMG_CFG);
+
        writel(0, mxc_isi->regs + CHNL_SCALE_OFFSET);
 
        return;
@@ -566,6 +583,9 @@ void mxc_isi_channel_config(struct mxc_isi_dev *mxc_isi)
        val = src_f->o_width | (src_f->o_height << CHNL_IMG_CFG_HEIGHT_OFFSET);
        writel(val, mxc_isi->regs + CHNL_IMG_CFG);
 
+       /* scale size need to equal input size when scaling disabled*/
+       writel(val, mxc_isi->regs + CHNL_SCL_IMG_CFG);
+
        /* check csc and scaling  */
        mxc_isi_channel_set_csc(mxc_isi);