MLK-15960-4: ASoC: fsl_asrc: refine pm runtime function
authorShengjiu Wang <shengjiu.wang@freescale.com>
Thu, 13 Jul 2017 02:44:30 +0000 (10:44 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:33:35 +0000 (15:33 -0500)
In imx8qm/imx8qxp, the power domain of IP is enabled when
pm_runtime_get_sync() is called, and disabled when pm_runtime
_put_sync() is called. when power domain is disabled, the value
of registers will lost, so we need to use the regcache_sync()
to restore the registers in fsl_asrc_runtime_resume.

Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
sound/soc/fsl/fsl_asrc.c

index 78e2e18..520b9a9 100644 (file)
@@ -1125,6 +1125,8 @@ static int fsl_asrc_probe(struct platform_device *pdev)
        pm_runtime_enable(&pdev->dev);
        spin_lock_init(&asrc_priv->lock);
 
+       regcache_cache_only(asrc_priv->regmap, true);
+
        ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component,
                                              &fsl_asrc_dai, 1);
        if (ret) {
@@ -1152,6 +1154,7 @@ static int fsl_asrc_runtime_resume(struct device *dev)
 {
        struct fsl_asrc *asrc_priv = dev_get_drvdata(dev);
        int i, ret;
+       u32 asrctr;
 
        ret = clk_prepare_enable(asrc_priv->mem_clk);
        if (ret)
@@ -1170,6 +1173,24 @@ static int fsl_asrc_runtime_resume(struct device *dev)
                        goto disable_asrck_clk;
        }
 
+       /* Stop all pairs provisionally */
+       regmap_read(asrc_priv->regmap, REG_ASRCTR, &asrctr);
+       regmap_update_bits(asrc_priv->regmap, REG_ASRCTR,
+                          ASRCTR_ASRCEi_ALL_MASK, 0);
+
+       /* Restore all registers */
+       regcache_cache_only(asrc_priv->regmap, false);
+       regcache_mark_dirty(asrc_priv->regmap);
+       regcache_sync(asrc_priv->regmap);
+
+       regmap_update_bits(asrc_priv->regmap, REG_ASRCFG,
+                          ASRCFG_NDPRi_ALL_MASK | ASRCFG_POSTMODi_ALL_MASK |
+                          ASRCFG_PREMODi_ALL_MASK, asrc_priv->regcache_cfg);
+
+       /* Restart enabled pairs */
+       regmap_update_bits(asrc_priv->regmap, REG_ASRCTR,
+                          ASRCTR_ASRCEi_ALL_MASK, asrctr);
+
        return 0;
 
 disable_asrck_clk:
@@ -1189,6 +1210,11 @@ static int fsl_asrc_runtime_suspend(struct device *dev)
        struct fsl_asrc *asrc_priv = dev_get_drvdata(dev);
        int i;
 
+       regmap_read(asrc_priv->regmap, REG_ASRCFG,
+                   &asrc_priv->regcache_cfg);
+
+       regcache_cache_only(asrc_priv->regmap, true);
+
        for (i = 0; i < ASRC_CLK_MAX_NUM; i++)
                clk_disable_unprepare(asrc_priv->asrck_clk[i]);
        if (!IS_ERR(asrc_priv->spba_clk))