diff options
author | Ramesh Babu <ramesh.babu@intel.com> | 2016-07-26 08:36:48 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-08-08 06:54:59 -0400 |
commit | 1ef015e611570c4cffea480e8d1c64622edef5d9 (patch) | |
tree | e61b863bc96d763f2ff3eabf82639dbcf3b1d394 | |
parent | 004d94e5ab01a175523c8e7d205f94fb44274986 (diff) |
ASoC: Intel: Skylake: Add library loading support
The library load is added as one of the ops in skl_dsp_fw_ops().
The manifest load gives the files to be loaded which are loaded during
the fw_init()
Signed-off-by: Ramesh Babu <ramesh.babu@intel.com>
Signed-off-by: Kranthi G <gudishax.kranthikumar@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/skylake/bxt-sst.c | 86 | ||||
-rw-r--r-- | sound/soc/intel/skylake/skl-sst-dsp.h | 2 |
2 files changed, 85 insertions, 3 deletions
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c index 90702cef8b64..48a4ae583dd9 100644 --- a/sound/soc/intel/skylake/bxt-sst.c +++ b/sound/soc/intel/skylake/bxt-sst.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "../common/sst-dsp.h" | 23 | #include "../common/sst-dsp.h" |
24 | #include "../common/sst-dsp-priv.h" | 24 | #include "../common/sst-dsp-priv.h" |
25 | #include "skl-sst-ipc.h" | 25 | #include "skl-sst-ipc.h" |
26 | #include "skl-tplg-interface.h" | ||
26 | 27 | ||
27 | #define BXT_BASEFW_TIMEOUT 3000 | 28 | #define BXT_BASEFW_TIMEOUT 3000 |
28 | #define BXT_INIT_TIMEOUT 500 | 29 | #define BXT_INIT_TIMEOUT 500 |
@@ -40,11 +41,73 @@ | |||
40 | #define BXT_INSTANCE_ID 0 | 41 | #define BXT_INSTANCE_ID 0 |
41 | #define BXT_BASE_FW_MODULE_ID 0 | 42 | #define BXT_BASE_FW_MODULE_ID 0 |
42 | 43 | ||
44 | #define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000 | ||
45 | |||
43 | static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) | 46 | static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) |
44 | { | 47 | { |
45 | return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE); | 48 | return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE); |
46 | } | 49 | } |
47 | 50 | ||
51 | static int | ||
52 | bxt_load_library(struct sst_dsp *ctx, struct skl_dfw_manifest *minfo) | ||
53 | { | ||
54 | struct snd_dma_buffer dmab; | ||
55 | struct skl_sst *skl = ctx->thread_context; | ||
56 | const struct firmware *fw = NULL; | ||
57 | struct firmware stripped_fw; | ||
58 | int ret = 0, i, dma_id, stream_tag; | ||
59 | |||
60 | /* library indices start from 1 to N. 0 represents base FW */ | ||
61 | for (i = 1; i < minfo->lib_count; i++) { | ||
62 | ret = request_firmware(&fw, minfo->lib[i].name, ctx->dev); | ||
63 | if (ret < 0) { | ||
64 | dev_err(ctx->dev, "Request lib %s failed:%d\n", | ||
65 | minfo->lib[i].name, ret); | ||
66 | return ret; | ||
67 | } | ||
68 | |||
69 | if (skl->is_first_boot) { | ||
70 | ret = snd_skl_parse_uuids(ctx, fw, | ||
71 | BXT_ADSP_FW_BIN_HDR_OFFSET, i); | ||
72 | if (ret < 0) | ||
73 | goto load_library_failed; | ||
74 | } | ||
75 | |||
76 | stripped_fw.data = fw->data; | ||
77 | stripped_fw.size = fw->size; | ||
78 | skl_dsp_strip_extended_manifest(&stripped_fw); | ||
79 | |||
80 | stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, | ||
81 | stripped_fw.size, &dmab); | ||
82 | if (stream_tag <= 0) { | ||
83 | dev_err(ctx->dev, "Lib prepare DMA err: %x\n", | ||
84 | stream_tag); | ||
85 | ret = stream_tag; | ||
86 | goto load_library_failed; | ||
87 | } | ||
88 | |||
89 | dma_id = stream_tag - 1; | ||
90 | memcpy(dmab.area, stripped_fw.data, stripped_fw.size); | ||
91 | |||
92 | ctx->dsp_ops.trigger(ctx->dev, true, stream_tag); | ||
93 | ret = skl_sst_ipc_load_library(&skl->ipc, dma_id, i); | ||
94 | if (ret < 0) | ||
95 | dev_err(ctx->dev, "IPC Load Lib for %s fail: %d\n", | ||
96 | minfo->lib[i].name, ret); | ||
97 | |||
98 | ctx->dsp_ops.trigger(ctx->dev, false, stream_tag); | ||
99 | ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag); | ||
100 | release_firmware(fw); | ||
101 | fw = NULL; | ||
102 | } | ||
103 | |||
104 | return ret; | ||
105 | |||
106 | load_library_failed: | ||
107 | release_firmware(fw); | ||
108 | return ret; | ||
109 | } | ||
110 | |||
48 | /* | 111 | /* |
49 | * First boot sequence has some extra steps. Core 0 waits for power | 112 | * First boot sequence has some extra steps. Core 0 waits for power |
50 | * status on core 1, so power up core 1 also momentarily, keep it in | 113 | * status on core 1, so power up core 1 also momentarily, keep it in |
@@ -157,8 +220,6 @@ static int sst_transfer_fw_host_dma(struct sst_dsp *ctx) | |||
157 | return ret; | 220 | return ret; |
158 | } | 221 | } |
159 | 222 | ||
160 | #define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000 | ||
161 | |||
162 | static int bxt_load_base_firmware(struct sst_dsp *ctx) | 223 | static int bxt_load_base_firmware(struct sst_dsp *ctx) |
163 | { | 224 | { |
164 | struct firmware stripped_fw; | 225 | struct firmware stripped_fw; |
@@ -233,12 +294,23 @@ static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) | |||
233 | int ret; | 294 | int ret; |
234 | struct skl_ipc_dxstate_info dx; | 295 | struct skl_ipc_dxstate_info dx; |
235 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); | 296 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); |
297 | struct skl_dfw_manifest *minfo = &skl->manifest; | ||
236 | 298 | ||
237 | if (skl->fw_loaded == false) { | 299 | if (skl->fw_loaded == false) { |
238 | skl->boot_complete = false; | 300 | skl->boot_complete = false; |
239 | ret = bxt_load_base_firmware(ctx); | 301 | ret = bxt_load_base_firmware(ctx); |
240 | if (ret < 0) | 302 | if (ret < 0) { |
241 | dev_err(ctx->dev, "reload fw failed: %d\n", ret); | 303 | dev_err(ctx->dev, "reload fw failed: %d\n", ret); |
304 | return ret; | ||
305 | } | ||
306 | |||
307 | if (minfo->lib_count > 1) { | ||
308 | ret = bxt_load_library(ctx, minfo); | ||
309 | if (ret < 0) { | ||
310 | dev_err(ctx->dev, "reload libs failed: %d\n", ret); | ||
311 | return ret; | ||
312 | } | ||
313 | } | ||
242 | return ret; | 314 | return ret; |
243 | } | 315 | } |
244 | 316 | ||
@@ -344,6 +416,7 @@ static struct skl_dsp_fw_ops bxt_fw_ops = { | |||
344 | .set_state_D3 = bxt_set_dsp_D3, | 416 | .set_state_D3 = bxt_set_dsp_D3, |
345 | .load_fw = bxt_load_base_firmware, | 417 | .load_fw = bxt_load_base_firmware, |
346 | .get_fw_errcode = bxt_get_errorcode, | 418 | .get_fw_errcode = bxt_get_errorcode, |
419 | .load_library = bxt_load_library, | ||
347 | }; | 420 | }; |
348 | 421 | ||
349 | static struct sst_ops skl_ops = { | 422 | static struct sst_ops skl_ops = { |
@@ -422,6 +495,13 @@ int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx) | |||
422 | 495 | ||
423 | skl_dsp_init_core_state(sst); | 496 | skl_dsp_init_core_state(sst); |
424 | 497 | ||
498 | if (ctx->manifest.lib_count > 1) { | ||
499 | ret = sst->fw_ops.load_library(sst, &ctx->manifest); | ||
500 | if (ret < 0) { | ||
501 | dev_err(dev, "Load Library failed : %x", ret); | ||
502 | return ret; | ||
503 | } | ||
504 | } | ||
425 | ctx->is_first_boot = false; | 505 | ctx->is_first_boot = false; |
426 | 506 | ||
427 | return 0; | 507 | return 0; |
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h index 5bc77e1941a5..fa053c039203 100644 --- a/sound/soc/intel/skylake/skl-sst-dsp.h +++ b/sound/soc/intel/skylake/skl-sst-dsp.h | |||
@@ -133,6 +133,8 @@ enum skl_dsp_states { | |||
133 | struct skl_dsp_fw_ops { | 133 | struct skl_dsp_fw_ops { |
134 | int (*load_fw)(struct sst_dsp *ctx); | 134 | int (*load_fw)(struct sst_dsp *ctx); |
135 | /* FW module parser/loader */ | 135 | /* FW module parser/loader */ |
136 | int (*load_library)(struct sst_dsp *ctx, | ||
137 | struct skl_dfw_manifest *minfo); | ||
136 | int (*parse_fw)(struct sst_dsp *ctx); | 138 | int (*parse_fw)(struct sst_dsp *ctx); |
137 | int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id); | 139 | int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id); |
138 | int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id); | 140 | int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id); |