summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@nxp.com>2020-05-11 13:17:12 +0800
committerShengjiu Wang <shengjiu.wang@nxp.com>2020-05-11 14:50:55 +0800
commitcacd4e1389be6e70bf95a82ececb4a2d9e53653e (patch)
tree7b80aaaed9b55d07fbabc80a393821958486e917
parentf25b74f7853295798fb0a7c0f3e9e783f53f65f8 (diff)
MLK-23970: ASoC: fsl_dsp: workaround for no reset controller
On imx8mp, there is no dedicated reset controller for DSP and there is no dedicated power domain for DSP. The power of DSP is bound with audiomix, so we need to check the DSP status for judging the audiomix is reset or not. We use the PID register for status check, after reset, it will be set to zero, when DSP is used we set it to 1. Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com> Reviewed-by: Peng Zhang <peng.zhang_8@nxp.com> Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
-rw-r--r--sound/soc/fsl/fsl_dsp.c40
-rw-r--r--sound/soc/fsl/fsl_dsp_audiomix.c18
-rw-r--r--sound/soc/fsl/fsl_dsp_audiomix.h2
3 files changed, 46 insertions, 14 deletions
diff --git a/sound/soc/fsl/fsl_dsp.c b/sound/soc/fsl/fsl_dsp.c
index 3aab99643dd0..a6d3a7206888 100644
--- a/sound/soc/fsl/fsl_dsp.c
+++ b/sound/soc/fsl/fsl_dsp.c
@@ -652,6 +652,19 @@ static void fsl_dsp_start(struct fsl_dsp *dsp_priv)
}
}
+static bool fsl_dsp_is_reset(struct fsl_dsp *dsp_priv)
+{
+ switch (dsp_priv->dsp_board_type) {
+ case DSP_IMX8QM_TYPE:
+ case DSP_IMX8QXP_TYPE:
+ return true;
+ case DSP_IMX8MP_TYPE:
+ return imx_audiomix_dsp_reset(dsp_priv->audiomix);
+ default:
+ return true;
+ }
+}
+
static void dsp_load_firmware(const struct firmware *fw, void *context)
{
struct fsl_dsp *dsp_priv = context;
@@ -1317,6 +1330,17 @@ static int fsl_dsp_runtime_resume(struct device *dev)
return ret;
}
+ if (!dsp_priv->dsp_mu_init && !proxy->is_ready && !fsl_dsp_is_reset(dsp_priv)) {
+ dsp_priv->dsp_mu_init = 1;
+ proxy->is_ready = 1;
+ }
+
+ /*
+ * Use PID for checking the audiomix is reset or not.
+ * After resetting, the PID should be 0, then we set the PID=1 in resume.
+ */
+ if (!dsp_priv->dsp_mu_init && !proxy->is_ready && dsp_priv->dsp_board_type == DSP_IMX8MP_TYPE)
+ imx_audiomix_dsp_pid_set(dsp_priv->audiomix, 0x1);
if (!dsp_priv->dsp_mu_init) {
MU_Init(dsp_priv->mu_base_virtaddr);
@@ -1373,16 +1397,8 @@ static int fsl_dsp_runtime_suspend(struct device *dev)
struct xf_proxy *proxy = &dsp_priv->proxy;
int i;
- /*
- * FIXME:
- * DSP in i.MX865 don't have dedicate power control
- * which bind with audiomix. if the audiomix power
- * on, we can't reload the firmware.
- */
- if (dsp_priv->dsp_board_type != DSP_IMX8MP_TYPE) {
- dsp_priv->dsp_mu_init = 0;
- proxy->is_ready = 0;
- }
+ dsp_priv->dsp_mu_init = 0;
+ proxy->is_ready = 0;
for (i = 0; i < 4; i++)
clk_disable_unprepare(dsp_priv->asrck_clk[i]);
@@ -1424,10 +1440,6 @@ static int fsl_dsp_suspend(struct device *dev)
return ret;
}
}
- if (dsp_priv->dsp_board_type == DSP_IMX8MP_TYPE) {
- dsp_priv->dsp_mu_init = 0;
- proxy->is_ready = 0;
- }
ret = pm_runtime_force_suspend(dev);
diff --git a/sound/soc/fsl/fsl_dsp_audiomix.c b/sound/soc/fsl/fsl_dsp_audiomix.c
index 91e74d17ff2b..20a76d424500 100644
--- a/sound/soc/fsl/fsl_dsp_audiomix.c
+++ b/sound/soc/fsl/fsl_dsp_audiomix.c
@@ -26,6 +26,24 @@ void imx_audiomix_dsp_start(struct imx_audiomix_dsp_data *data)
}
EXPORT_SYMBOL(imx_audiomix_dsp_start);
+void imx_audiomix_dsp_pid_set(struct imx_audiomix_dsp_data *data, u32 val)
+{
+ writel(val, data->base + AudioDSP_REG3);
+}
+EXPORT_SYMBOL(imx_audiomix_dsp_pid_set);
+
+bool imx_audiomix_dsp_reset(struct imx_audiomix_dsp_data *data)
+{
+ u32 val;
+
+ val = readl(data->base + AudioDSP_REG3);
+ if (val == 0)
+ return true;
+ else
+ return false;
+}
+EXPORT_SYMBOL(imx_audiomix_dsp_reset);
+
static int imx_audiomix_dsp_probe(struct platform_device *pdev)
{
struct imx_audiomix_dsp_data *drvdata;
diff --git a/sound/soc/fsl/fsl_dsp_audiomix.h b/sound/soc/fsl/fsl_dsp_audiomix.h
index c4dea9903575..ff251021a6a4 100644
--- a/sound/soc/fsl/fsl_dsp_audiomix.h
+++ b/sound/soc/fsl/fsl_dsp_audiomix.h
@@ -15,5 +15,7 @@
struct imx_audiomix_dsp_data;
void imx_audiomix_dsp_start(struct imx_audiomix_dsp_data *data);
+void imx_audiomix_dsp_pid_set(struct imx_audiomix_dsp_data *data, u32 val);
+bool imx_audiomix_dsp_reset(struct imx_audiomix_dsp_data *data);
#endif