ASoC: Intel: Skylake: Correct the runtime handler behaviour
On runtime pm resume, we need to download the firmware, also on suspend we need to ensure all the interrupts from controller and DSP are disabled. Also since we download the firmware on resume, we don't need to do so on init, so remove that bit Signed-off-by: Jeeja KP <jeeja.kp@intel.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Родитель
def656fe22
Коммит
84c9e2836a
|
@ -314,6 +314,7 @@ struct sst_dsp {
|
||||||
int sst_state;
|
int sst_state;
|
||||||
struct skl_cl_dev cl_dev;
|
struct skl_cl_dev cl_dev;
|
||||||
u32 intr_status;
|
u32 intr_status;
|
||||||
|
const struct firmware *fw;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Size optimised DRAM/IRAM memcpy */
|
/* Size optimised DRAM/IRAM memcpy */
|
||||||
|
|
|
@ -464,6 +464,18 @@ void skl_ipc_op_int_enable(struct sst_dsp *ctx)
|
||||||
SKL_ADSP_REG_HIPCCTL_BUSY, SKL_ADSP_REG_HIPCCTL_BUSY);
|
SKL_ADSP_REG_HIPCCTL_BUSY, SKL_ADSP_REG_HIPCCTL_BUSY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void skl_ipc_op_int_disable(struct sst_dsp *ctx)
|
||||||
|
{
|
||||||
|
/* disable IPC DONE interrupt */
|
||||||
|
sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_HIPCCTL,
|
||||||
|
SKL_ADSP_REG_HIPCCTL_DONE, 0);
|
||||||
|
|
||||||
|
/* Disable IPC BUSY interrupt */
|
||||||
|
sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_HIPCCTL,
|
||||||
|
SKL_ADSP_REG_HIPCCTL_BUSY, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool skl_ipc_int_status(struct sst_dsp *ctx)
|
bool skl_ipc_int_status(struct sst_dsp *ctx)
|
||||||
{
|
{
|
||||||
return sst_dsp_shim_read_unlocked(ctx,
|
return sst_dsp_shim_read_unlocked(ctx,
|
||||||
|
|
|
@ -116,6 +116,7 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
|
||||||
|
|
||||||
void skl_ipc_int_enable(struct sst_dsp *dsp);
|
void skl_ipc_int_enable(struct sst_dsp *dsp);
|
||||||
void skl_ipc_op_int_enable(struct sst_dsp *ctx);
|
void skl_ipc_op_int_enable(struct sst_dsp *ctx);
|
||||||
|
void skl_ipc_op_int_disable(struct sst_dsp *ctx);
|
||||||
void skl_ipc_int_disable(struct sst_dsp *dsp);
|
void skl_ipc_int_disable(struct sst_dsp *dsp);
|
||||||
|
|
||||||
bool skl_ipc_int_status(struct sst_dsp *dsp);
|
bool skl_ipc_int_status(struct sst_dsp *dsp);
|
||||||
|
|
|
@ -70,15 +70,31 @@ static int skl_transfer_firmware(struct sst_dsp *ctx,
|
||||||
static int skl_load_base_firmware(struct sst_dsp *ctx)
|
static int skl_load_base_firmware(struct sst_dsp *ctx)
|
||||||
{
|
{
|
||||||
int ret = 0, i;
|
int ret = 0, i;
|
||||||
const struct firmware *fw = NULL;
|
|
||||||
struct skl_sst *skl = ctx->thread_context;
|
struct skl_sst *skl = ctx->thread_context;
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
ret = request_firmware(&fw, "dsp_fw_release.bin", ctx->dev);
|
skl->boot_complete = false;
|
||||||
|
init_waitqueue_head(&skl->boot_wait);
|
||||||
|
|
||||||
|
if (ctx->fw == NULL) {
|
||||||
|
ret = request_firmware(&ctx->fw, "dsp_fw_release.bin", ctx->dev);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(ctx->dev, "Request firmware failed %d\n", ret);
|
||||||
|
skl_dsp_disable_core(ctx);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = skl_dsp_boot(ctx);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(ctx->dev, "Request firmware failed %d\n", ret);
|
dev_err(ctx->dev, "Boot dsp core failed ret: %d", ret);
|
||||||
skl_dsp_disable_core(ctx);
|
goto skl_load_base_firmware_failed;
|
||||||
return -EIO;
|
}
|
||||||
|
|
||||||
|
ret = skl_cldma_prepare(ctx);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(ctx->dev, "CL dma prepare failed : %d", ret);
|
||||||
|
goto skl_load_base_firmware_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* enable Interrupt */
|
/* enable Interrupt */
|
||||||
|
@ -102,7 +118,7 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
|
||||||
goto skl_load_base_firmware_failed;
|
goto skl_load_base_firmware_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = skl_transfer_firmware(ctx, fw->data, fw->size);
|
ret = skl_transfer_firmware(ctx, ctx->fw->data, ctx->fw->size);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(ctx->dev, "Transfer firmware failed%d\n", ret);
|
dev_err(ctx->dev, "Transfer firmware failed%d\n", ret);
|
||||||
goto skl_load_base_firmware_failed;
|
goto skl_load_base_firmware_failed;
|
||||||
|
@ -118,13 +134,12 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
|
||||||
dev_dbg(ctx->dev, "Download firmware successful%d\n", ret);
|
dev_dbg(ctx->dev, "Download firmware successful%d\n", ret);
|
||||||
skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING);
|
skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING);
|
||||||
}
|
}
|
||||||
release_firmware(fw);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
skl_load_base_firmware_failed:
|
skl_load_base_firmware_failed:
|
||||||
skl_dsp_disable_core(ctx);
|
skl_dsp_disable_core(ctx);
|
||||||
release_firmware(fw);
|
release_firmware(ctx->fw);
|
||||||
|
ctx->fw = NULL;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,6 +187,12 @@ static int skl_set_dsp_D3(struct sst_dsp *ctx)
|
||||||
}
|
}
|
||||||
skl_dsp_set_state_locked(ctx, SKL_DSP_RESET);
|
skl_dsp_set_state_locked(ctx, SKL_DSP_RESET);
|
||||||
|
|
||||||
|
/* disable Interrupt */
|
||||||
|
ctx->cl_dev.ops.cl_cleanup_controller(ctx);
|
||||||
|
skl_cldma_int_disable(ctx);
|
||||||
|
skl_ipc_op_int_disable(ctx);
|
||||||
|
skl_ipc_int_disable(ctx);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,22 +256,6 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
skl->boot_complete = false;
|
|
||||||
init_waitqueue_head(&skl->boot_wait);
|
|
||||||
|
|
||||||
ret = skl_dsp_boot(sst);
|
|
||||||
if (ret < 0) {
|
|
||||||
dev_err(skl->dev, "Boot dsp core failed ret: %d", ret);
|
|
||||||
goto free_ipc;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = skl_cldma_prepare(sst);
|
|
||||||
if (ret < 0) {
|
|
||||||
dev_err(dev, "CL dma prepare failed : %d", ret);
|
|
||||||
goto free_ipc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret = sst->fw_ops.load_fw(sst);
|
ret = sst->fw_ops.load_fw(sst);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(dev, "Load base fw failed : %d", ret);
|
dev_err(dev, "Load base fw failed : %d", ret);
|
||||||
|
@ -262,7 +267,6 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
free_ipc:
|
|
||||||
skl_ipc_free(&skl->ipc);
|
skl_ipc_free(&skl->ipc);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче