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:
Jeeja KP 2015-10-09 09:01:50 +01:00 коммит произвёл Mark Brown
Родитель def656fe22
Коммит 84c9e2836a
4 изменённых файлов: 44 добавлений и 26 удалений

Просмотреть файл

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