MLK-22115: media: Fix system hang issue
authorGuoniu.Zhou <guoniu.zhou@nxp.com>
Thu, 27 Jun 2019 06:37:18 +0000 (14:37 +0800)
committerGuoniu.Zhou <guoniu.zhou@nxp.com>
Wed, 7 Aug 2019 06:29:03 +0000 (14:29 +0800)
System will hang when disable ISI and CSI clock in ATF by dispmix GPR.
The value of dispmix GPR will be cleared when its power domain off/on
although driver set it in probe. So driver need to reset its value in
runtime resume callback.

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

index e71f7e2..5cb6cae 100644 (file)
@@ -61,12 +61,12 @@ static void disp_mix_sft_rstn(struct regmap *gpr, bool enable)
                /* release isi soft reset */
                regmap_update_bits(gpr,
                                DISP_MIX_SFT_RSTN_CSR,
-                               EN_BUS_BLK_CLK_RSTN | EN_ISI_APB_CLK_RSTN | EN_ISI_PROC_CLK_RSTN,
-                               EN_BUS_BLK_CLK_RSTN | EN_ISI_APB_CLK_RSTN | EN_ISI_PROC_CLK_RSTN);
+                               EN_ISI_APB_CLK_RSTN | EN_ISI_PROC_CLK_RSTN,
+                               EN_ISI_APB_CLK_RSTN | EN_ISI_PROC_CLK_RSTN);
        else
                regmap_update_bits(gpr,
                                DISP_MIX_SFT_RSTN_CSR,
-                               EN_BUS_BLK_CLK_RSTN | EN_ISI_APB_CLK_RSTN | EN_ISI_APB_CLK_RSTN,
+                               EN_ISI_APB_CLK_RSTN | EN_ISI_APB_CLK_RSTN,
                                0x0);
 
 }
@@ -80,13 +80,13 @@ static void disp_mix_clks_enable(struct regmap *gpr, bool enable)
                /* enable isi clks */
                regmap_update_bits(gpr,
                                DISP_MIX_CLK_EN_CSR,
-                               EN_BUS_BLK_CLK | EN_ISI_APB_CLK | EN_ISI_PROC_CLK,
-                               EN_BUS_BLK_CLK | EN_ISI_APB_CLK | EN_ISI_PROC_CLK);
+                               EN_ISI_APB_CLK | EN_ISI_PROC_CLK,
+                               EN_ISI_APB_CLK | EN_ISI_PROC_CLK);
        else
                /* disable isi clks */
                regmap_update_bits(gpr,
                                DISP_MIX_CLK_EN_CSR,
-                               EN_BUS_BLK_CLK | EN_ISI_APB_CLK | EN_ISI_PROC_CLK,
+                               EN_ISI_APB_CLK | EN_ISI_PROC_CLK,
                                0x0);
 }
 
@@ -426,16 +426,12 @@ static int mxc_isi_pm_suspend(struct device *dev)
 
 static int mxc_isi_pm_resume(struct device *dev)
 {
-       struct mxc_isi_dev *mxc_isi = dev_get_drvdata(dev);
        int ret;
 
        ret = pm_runtime_force_resume(dev);
        if (ret < 0)
                return ret;
 
-       disp_mix_sft_rstn(mxc_isi->gpr, false);
-       disp_mix_clks_enable(mxc_isi->gpr, true);
-
        return 0;
 }
 #endif
@@ -444,6 +440,7 @@ static int mxc_isi_runtime_suspend(struct device *dev)
 {
        struct mxc_isi_dev *mxc_isi = dev_get_drvdata(dev);
 
+       disp_mix_clks_enable(mxc_isi->gpr, false);
        mxc_isi_clk_disable(mxc_isi);
 
        return 0;
@@ -459,6 +456,8 @@ static int mxc_isi_runtime_resume(struct device *dev)
                dev_err(dev, "%s clk enable fail\n", __func__);
                return ret;
        }
+       disp_mix_sft_rstn(mxc_isi->gpr, false);
+       disp_mix_clks_enable(mxc_isi->gpr, true);
 
        return 0;
 }
index c7392f2..a738c6a 100644 (file)
@@ -1053,7 +1053,6 @@ static int mipi_csis_system_suspend(struct device *dev)
 
 static int mipi_csis_system_resume(struct device *dev)
 {
-       struct csi_state *state = dev_get_drvdata(dev);
        int ret;
 
        ret = pm_runtime_force_resume(dev);
@@ -1061,8 +1060,6 @@ static int mipi_csis_system_resume(struct device *dev)
                dev_err(dev, "force resume %s failed!\n", dev_name(dev));
                return ret;
        }
-       disp_mix_clks_enable(state->gpr, true);
-       disp_mix_sft_rstn(state->gpr, false);
 
        return 0;
 }
@@ -1076,6 +1073,7 @@ static int mipi_csis_runtime_suspend(struct device *dev)
        if (ret < 0)
                return ret;
 
+       disp_mix_clks_enable(state->gpr, false);
        mipi_csis_clk_disable(state);
        return 0;
 }
@@ -1089,7 +1087,14 @@ static int mipi_csis_runtime_resume(struct device *dev)
        if (ret < 0)
                return ret;
 
-       return mipi_csis_clk_enable(state);
+       ret = mipi_csis_clk_enable(state);
+       if (ret < 0)
+               return ret;
+
+       disp_mix_clks_enable(state->gpr, true);
+       disp_mix_sft_rstn(state->gpr, false);
+
+       return 0;
 }
 
 static int mipi_csis_remove(struct platform_device *pdev)