aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeeja KP <jeeja.kp@intel.com>2017-02-17 12:18:56 -0500
committerMark Brown <broonie@kernel.org>2017-03-07 07:47:34 -0500
commit31d648f051fe82c9d6c2176b1b5ee402b1a18f21 (patch)
tree5fad975672bd80ce28c0587ed779c2ae29fe26c8
parentb3ec72ace939b0abd75d5d875e77cf0b777debb7 (diff)
ASoC: Intel: bxtn: Store the FW/Library context at boot
Store the DSP firmware/library at boot, so that for S3 to S0 transition use the stored ctx for downloading the firmware to DSP memory. Signed-off-by: Jeeja KP <jeeja.kp@intel.com> Acked-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/intel/skylake/bxt-sst.c55
1 files changed, 36 insertions, 19 deletions
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c
index 15a063a403cc..7762d5a18fce 100644
--- a/sound/soc/intel/skylake/bxt-sst.c
+++ b/sound/soc/intel/skylake/bxt-sst.c
@@ -50,33 +50,47 @@ static unsigned int bxt_get_errorcode(struct sst_dsp *ctx)
50 return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE); 50 return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE);
51} 51}
52 52
53static void sst_bxt_release_library(struct skl_lib_info *linfo, int lib_count)
54{
55 int i;
56
57 for (i = 1; i < lib_count; i++) {
58 if (linfo[i].fw) {
59 release_firmware(linfo[i].fw);
60 linfo[i].fw = NULL;
61 }
62 }
63}
64
53static int 65static int
54bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count) 66bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
55{ 67{
56 struct snd_dma_buffer dmab; 68 struct snd_dma_buffer dmab;
57 struct skl_sst *skl = ctx->thread_context; 69 struct skl_sst *skl = ctx->thread_context;
58 const struct firmware *fw = NULL;
59 struct firmware stripped_fw; 70 struct firmware stripped_fw;
60 int ret = 0, i, dma_id, stream_tag; 71 int ret = 0, i, dma_id, stream_tag;
61 72
62 /* library indices start from 1 to N. 0 represents base FW */ 73 /* library indices start from 1 to N. 0 represents base FW */
63 for (i = 1; i < lib_count; i++) { 74 for (i = 1; i < lib_count; i++) {
64 ret = request_firmware(&fw, linfo[i].name, ctx->dev); 75 if (linfo[i].fw == NULL) {
65 if (ret < 0) { 76 ret = request_firmware(&linfo[i].fw, linfo[i].name,
66 dev_err(ctx->dev, "Request lib %s failed:%d\n", 77 ctx->dev);
78 if (ret < 0) {
79 dev_err(ctx->dev, "Request lib %s failed:%d\n",
67 linfo[i].name, ret); 80 linfo[i].name, ret);
68 return ret; 81 goto load_library_failed;
82 }
69 } 83 }
70 84
71 if (skl->is_first_boot) { 85 if (skl->is_first_boot) {
72 ret = snd_skl_parse_uuids(ctx, fw, 86 ret = snd_skl_parse_uuids(ctx, linfo[i].fw,
73 BXT_ADSP_FW_BIN_HDR_OFFSET, i); 87 BXT_ADSP_FW_BIN_HDR_OFFSET, i);
74 if (ret < 0) 88 if (ret < 0)
75 goto load_library_failed; 89 goto load_library_failed;
76 } 90 }
77 91
78 stripped_fw.data = fw->data; 92 stripped_fw.data = linfo[i].fw->data;
79 stripped_fw.size = fw->size; 93 stripped_fw.size = linfo[i].fw->size;
80 skl_dsp_strip_extended_manifest(&stripped_fw); 94 skl_dsp_strip_extended_manifest(&stripped_fw);
81 95
82 stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, 96 stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40,
@@ -99,14 +113,12 @@ bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
99 113
100 ctx->dsp_ops.trigger(ctx->dev, false, stream_tag); 114 ctx->dsp_ops.trigger(ctx->dev, false, stream_tag);
101 ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag); 115 ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag);
102 release_firmware(fw);
103 fw = NULL;
104 } 116 }
105 117
106 return ret; 118 return ret;
107 119
108load_library_failed: 120load_library_failed:
109 release_firmware(fw); 121 sst_bxt_release_library(linfo, lib_count);
110 return ret; 122 return ret;
111} 123}
112 124
@@ -208,16 +220,14 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
208 struct skl_sst *skl = ctx->thread_context; 220 struct skl_sst *skl = ctx->thread_context;
209 int ret; 221 int ret;
210 222
211 ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev); 223 if (ctx->fw == NULL) {
212 if (ret < 0) { 224 ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev);
213 dev_err(ctx->dev, "Request firmware failed %d\n", ret); 225 if (ret < 0) {
214 goto sst_load_base_firmware_failed; 226 dev_err(ctx->dev, "Request firmware failed %d\n", ret);
227 return ret;
228 }
215 } 229 }
216 230
217 /* check for extended manifest */
218 if (ctx->fw == NULL)
219 goto sst_load_base_firmware_failed;
220
221 /* prase uuids on first boot */ 231 /* prase uuids on first boot */
222 if (skl->is_first_boot) { 232 if (skl->is_first_boot) {
223 ret = snd_skl_parse_uuids(ctx, ctx->fw, BXT_ADSP_FW_BIN_HDR_OFFSET, 0); 233 ret = snd_skl_parse_uuids(ctx, ctx->fw, BXT_ADSP_FW_BIN_HDR_OFFSET, 0);
@@ -265,8 +275,11 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
265 } 275 }
266 } 276 }
267 277
278 return ret;
279
268sst_load_base_firmware_failed: 280sst_load_base_firmware_failed:
269 release_firmware(ctx->fw); 281 release_firmware(ctx->fw);
282 ctx->fw = NULL;
270 return ret; 283 return ret;
271} 284}
272 285
@@ -635,6 +648,10 @@ EXPORT_SYMBOL_GPL(bxt_sst_init_fw);
635 648
636void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) 649void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
637{ 650{
651
652 sst_bxt_release_library(ctx->lib_info, ctx->lib_count);
653 if (ctx->dsp->fw)
654 release_firmware(ctx->dsp->fw);
638 skl_freeup_uuid_list(ctx); 655 skl_freeup_uuid_list(ctx);
639 skl_ipc_free(&ctx->ipc); 656 skl_ipc_free(&ctx->ipc);
640 ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp); 657 ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp);