1
0
Fork 0

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>
5.4-rM2-2.2.x-imx-squashed
Shengjiu Wang 2020-05-11 13:17:12 +08:00
parent f25b74f785
commit cacd4e1389
3 changed files with 46 additions and 14 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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