aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeeja KP <jeeja.kp@intel.com>2015-10-09 04:01:50 -0400
committerMark Brown <broonie@kernel.org>2015-10-09 06:19:00 -0400
commit84c9e2836aa7c87b19a24de091c7e7cf16124645 (patch)
treefc824b93e63993c011802311b27316511460d4e4
parentdef656fe22abb4fbf174a982dcef1d40274ddb11 (diff)
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>
-rw-r--r--sound/soc/intel/common/sst-dsp-priv.h1
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c12
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h1
-rw-r--r--sound/soc/intel/skylake/skl-sst.c56
4 files changed, 44 insertions, 26 deletions
diff --git a/sound/soc/intel/common/sst-dsp-priv.h b/sound/soc/intel/common/sst-dsp-priv.h
index cbd568eac033..2151652d37b7 100644
--- a/sound/soc/intel/common/sst-dsp-priv.h
+++ b/sound/soc/intel/common/sst-dsp-priv.h
@@ -314,6 +314,7 @@ struct sst_dsp {
314 int sst_state; 314 int sst_state;
315 struct skl_cl_dev cl_dev; 315 struct skl_cl_dev cl_dev;
316 u32 intr_status; 316 u32 intr_status;
317 const struct firmware *fw;
317}; 318};
318 319
319/* Size optimised DRAM/IRAM memcpy */ 320/* Size optimised DRAM/IRAM memcpy */
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
index 937a0a3a63a0..3345ea0d4414 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
@@ -464,6 +464,18 @@ void skl_ipc_op_int_enable(struct sst_dsp *ctx)
464 SKL_ADSP_REG_HIPCCTL_BUSY, SKL_ADSP_REG_HIPCCTL_BUSY); 464 SKL_ADSP_REG_HIPCCTL_BUSY, SKL_ADSP_REG_HIPCCTL_BUSY);
465} 465}
466 466
467void skl_ipc_op_int_disable(struct sst_dsp *ctx)
468{
469 /* disable IPC DONE interrupt */
470 sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_HIPCCTL,
471 SKL_ADSP_REG_HIPCCTL_DONE, 0);
472
473 /* Disable IPC BUSY interrupt */
474 sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_HIPCCTL,
475 SKL_ADSP_REG_HIPCCTL_BUSY, 0);
476
477}
478
467bool skl_ipc_int_status(struct sst_dsp *ctx) 479bool skl_ipc_int_status(struct sst_dsp *ctx)
468{ 480{
469 return sst_dsp_shim_read_unlocked(ctx, 481 return sst_dsp_shim_read_unlocked(ctx,
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
index 9f5f67202858..f1a154e45dc3 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
@@ -116,6 +116,7 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
116 116
117void skl_ipc_int_enable(struct sst_dsp *dsp); 117void skl_ipc_int_enable(struct sst_dsp *dsp);
118void skl_ipc_op_int_enable(struct sst_dsp *ctx); 118void skl_ipc_op_int_enable(struct sst_dsp *ctx);
119void skl_ipc_op_int_disable(struct sst_dsp *ctx);
119void skl_ipc_int_disable(struct sst_dsp *dsp); 120void skl_ipc_int_disable(struct sst_dsp *dsp);
120 121
121bool skl_ipc_int_status(struct sst_dsp *dsp); 122bool skl_ipc_int_status(struct sst_dsp *dsp);
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c
index c18ea51b7484..3b83dc99f1d4 100644
--- a/sound/soc/intel/skylake/skl-sst.c
+++ b/sound/soc/intel/skylake/skl-sst.c
@@ -70,15 +70,31 @@ static int skl_transfer_firmware(struct sst_dsp *ctx,
70static int skl_load_base_firmware(struct sst_dsp *ctx) 70static int skl_load_base_firmware(struct sst_dsp *ctx)
71{ 71{
72 int ret = 0, i; 72 int ret = 0, i;
73 const struct firmware *fw = NULL;
74 struct skl_sst *skl = ctx->thread_context; 73 struct skl_sst *skl = ctx->thread_context;
75 u32 reg; 74 u32 reg;
76 75
77 ret = request_firmware(&fw, "dsp_fw_release.bin", ctx->dev); 76 skl->boot_complete = false;
77 init_waitqueue_head(&skl->boot_wait);
78
79 if (ctx->fw == NULL) {
80 ret = request_firmware(&ctx->fw, "dsp_fw_release.bin", ctx->dev);
81 if (ret < 0) {
82 dev_err(ctx->dev, "Request firmware failed %d\n", ret);
83 skl_dsp_disable_core(ctx);
84 return -EIO;
85 }
86 }
87
88 ret = skl_dsp_boot(ctx);
78 if (ret < 0) { 89 if (ret < 0) {
79 dev_err(ctx->dev, "Request firmware failed %d\n", ret); 90 dev_err(ctx->dev, "Boot dsp core failed ret: %d", ret);
80 skl_dsp_disable_core(ctx); 91 goto skl_load_base_firmware_failed;
81 return -EIO; 92 }
93
94 ret = skl_cldma_prepare(ctx);
95 if (ret < 0) {
96 dev_err(ctx->dev, "CL dma prepare failed : %d", ret);
97 goto skl_load_base_firmware_failed;
82 } 98 }
83 99
84 /* enable Interrupt */ 100 /* enable Interrupt */
@@ -102,7 +118,7 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
102 goto skl_load_base_firmware_failed; 118 goto skl_load_base_firmware_failed;
103 } 119 }
104 120
105 ret = skl_transfer_firmware(ctx, fw->data, fw->size); 121 ret = skl_transfer_firmware(ctx, ctx->fw->data, ctx->fw->size);
106 if (ret < 0) { 122 if (ret < 0) {
107 dev_err(ctx->dev, "Transfer firmware failed%d\n", ret); 123 dev_err(ctx->dev, "Transfer firmware failed%d\n", ret);
108 goto skl_load_base_firmware_failed; 124 goto skl_load_base_firmware_failed;
@@ -118,13 +134,12 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
118 dev_dbg(ctx->dev, "Download firmware successful%d\n", ret); 134 dev_dbg(ctx->dev, "Download firmware successful%d\n", ret);
119 skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING); 135 skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING);
120 } 136 }
121 release_firmware(fw);
122
123 return 0; 137 return 0;
124 138
125skl_load_base_firmware_failed: 139skl_load_base_firmware_failed:
126 skl_dsp_disable_core(ctx); 140 skl_dsp_disable_core(ctx);
127 release_firmware(fw); 141 release_firmware(ctx->fw);
142 ctx->fw = NULL;
128 return ret; 143 return ret;
129} 144}
130 145
@@ -172,6 +187,12 @@ static int skl_set_dsp_D3(struct sst_dsp *ctx)
172 } 187 }
173 skl_dsp_set_state_locked(ctx, SKL_DSP_RESET); 188 skl_dsp_set_state_locked(ctx, SKL_DSP_RESET);
174 189
190 /* disable Interrupt */
191 ctx->cl_dev.ops.cl_cleanup_controller(ctx);
192 skl_cldma_int_disable(ctx);
193 skl_ipc_op_int_disable(ctx);
194 skl_ipc_int_disable(ctx);
195
175 return ret; 196 return ret;
176} 197}
177 198
@@ -235,22 +256,6 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
235 if (ret) 256 if (ret)
236 return ret; 257 return ret;
237 258
238 skl->boot_complete = false;
239 init_waitqueue_head(&skl->boot_wait);
240
241 ret = skl_dsp_boot(sst);
242 if (ret < 0) {
243 dev_err(skl->dev, "Boot dsp core failed ret: %d", ret);
244 goto free_ipc;
245 }
246
247 ret = skl_cldma_prepare(sst);
248 if (ret < 0) {
249 dev_err(dev, "CL dma prepare failed : %d", ret);
250 goto free_ipc;
251 }
252
253
254 ret = sst->fw_ops.load_fw(sst); 259 ret = sst->fw_ops.load_fw(sst);
255 if (ret < 0) { 260 if (ret < 0) {
256 dev_err(dev, "Load base fw failed : %d", ret); 261 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,
262 267
263 return 0; 268 return 0;
264 269
265free_ipc:
266 skl_ipc_free(&skl->ipc); 270 skl_ipc_free(&skl->ipc);
267 return ret; 271 return ret;
268} 272}