diff options
-rw-r--r-- | sound/soc/intel/skylake/bxt-sst.c | 22 | ||||
-rw-r--r-- | sound/soc/intel/skylake/skl-sst-dsp.c | 253 | ||||
-rw-r--r-- | sound/soc/intel/skylake/skl-sst-dsp.h | 96 | ||||
-rw-r--r-- | sound/soc/intel/skylake/skl-sst-ipc.h | 11 | ||||
-rw-r--r-- | sound/soc/intel/skylake/skl-sst.c | 16 |
5 files changed, 278 insertions, 120 deletions
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c index 622da5d3e3b3..c6cc1cfd04c8 100644 --- a/sound/soc/intel/skylake/bxt-sst.c +++ b/sound/soc/intel/skylake/bxt-sst.c | |||
@@ -58,7 +58,7 @@ static int sst_bxt_prepare_fw(struct sst_dsp *ctx, | |||
58 | ctx->dsp_ops.stream_tag = stream_tag; | 58 | ctx->dsp_ops.stream_tag = stream_tag; |
59 | memcpy(ctx->dmab.area, fwdata, fwsize); | 59 | memcpy(ctx->dmab.area, fwdata, fwsize); |
60 | 60 | ||
61 | ret = skl_dsp_core_power_up(ctx); | 61 | ret = skl_dsp_core_power_up(ctx, SKL_DSP_CORE0_MASK); |
62 | if (ret < 0) { | 62 | if (ret < 0) { |
63 | dev_err(ctx->dev, "Boot dsp core failed ret: %d\n", ret); | 63 | dev_err(ctx->dev, "Boot dsp core failed ret: %d\n", ret); |
64 | goto base_fw_load_failed; | 64 | goto base_fw_load_failed; |
@@ -68,7 +68,7 @@ static int sst_bxt_prepare_fw(struct sst_dsp *ctx, | |||
68 | sst_dsp_shim_write(ctx, SKL_ADSP_REG_HIPCI, SKL_ADSP_REG_HIPCI_BUSY | | 68 | sst_dsp_shim_write(ctx, SKL_ADSP_REG_HIPCI, SKL_ADSP_REG_HIPCI_BUSY | |
69 | (BXT_IPC_PURGE_FW | ((stream_tag - 1) << 9))); | 69 | (BXT_IPC_PURGE_FW | ((stream_tag - 1) << 9))); |
70 | 70 | ||
71 | ret = skl_dsp_start_core(ctx); | 71 | ret = skl_dsp_start_core(ctx, SKL_DSP_CORE0_MASK); |
72 | if (ret < 0) { | 72 | if (ret < 0) { |
73 | dev_err(ctx->dev, "Start dsp core failed ret: %d\n", ret); | 73 | dev_err(ctx->dev, "Start dsp core failed ret: %d\n", ret); |
74 | ret = -EIO; | 74 | ret = -EIO; |
@@ -118,7 +118,8 @@ static int sst_bxt_prepare_fw(struct sst_dsp *ctx, | |||
118 | 118 | ||
119 | base_fw_load_failed: | 119 | base_fw_load_failed: |
120 | ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, stream_tag); | 120 | ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, stream_tag); |
121 | skl_dsp_disable_core(ctx); | 121 | skl_dsp_core_power_down(ctx, SKL_DSP_CORE_MASK(1)); |
122 | skl_dsp_disable_core(ctx, SKL_DSP_CORE_MASK(1)); | ||
122 | return ret; | 123 | return ret; |
123 | } | 124 | } |
124 | 125 | ||
@@ -183,14 +184,14 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx) | |||
183 | sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE), | 184 | sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE), |
184 | sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS)); | 185 | sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS)); |
185 | 186 | ||
186 | skl_dsp_disable_core(ctx); | 187 | skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); |
187 | } else { | 188 | } else { |
188 | dev_dbg(ctx->dev, "Firmware download successful\n"); | 189 | dev_dbg(ctx->dev, "Firmware download successful\n"); |
189 | ret = wait_event_timeout(skl->boot_wait, skl->boot_complete, | 190 | ret = wait_event_timeout(skl->boot_wait, skl->boot_complete, |
190 | msecs_to_jiffies(SKL_IPC_BOOT_MSECS)); | 191 | msecs_to_jiffies(SKL_IPC_BOOT_MSECS)); |
191 | if (ret == 0) { | 192 | if (ret == 0) { |
192 | dev_err(ctx->dev, "DSP boot fail, FW Ready timeout\n"); | 193 | dev_err(ctx->dev, "DSP boot fail, FW Ready timeout\n"); |
193 | skl_dsp_disable_core(ctx); | 194 | skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); |
194 | ret = -EIO; | 195 | ret = -EIO; |
195 | } else { | 196 | } else { |
196 | skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING); | 197 | skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING); |
@@ -204,7 +205,7 @@ sst_load_base_firmware_failed: | |||
204 | return ret; | 205 | return ret; |
205 | } | 206 | } |
206 | 207 | ||
207 | static int bxt_set_dsp_D0(struct sst_dsp *ctx) | 208 | static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) |
208 | { | 209 | { |
209 | struct skl_sst *skl = ctx->thread_context; | 210 | struct skl_sst *skl = ctx->thread_context; |
210 | int ret; | 211 | int ret; |
@@ -219,7 +220,7 @@ static int bxt_set_dsp_D0(struct sst_dsp *ctx) | |||
219 | return ret; | 220 | return ret; |
220 | } | 221 | } |
221 | 222 | ||
222 | ret = skl_dsp_enable_core(ctx); | 223 | ret = skl_dsp_enable_core(ctx, SKL_DSP_CORE0_MASK); |
223 | if (ret < 0) { | 224 | if (ret < 0) { |
224 | dev_err(ctx->dev, "enable dsp core failed ret: %d\n", ret); | 225 | dev_err(ctx->dev, "enable dsp core failed ret: %d\n", ret); |
225 | return ret; | 226 | return ret; |
@@ -243,7 +244,7 @@ static int bxt_set_dsp_D0(struct sst_dsp *ctx) | |||
243 | return 0; | 244 | return 0; |
244 | } | 245 | } |
245 | 246 | ||
246 | static int bxt_set_dsp_D3(struct sst_dsp *ctx) | 247 | static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) |
247 | { | 248 | { |
248 | struct skl_ipc_dxstate_info dx; | 249 | struct skl_ipc_dxstate_info dx; |
249 | struct skl_sst *skl = ctx->thread_context; | 250 | struct skl_sst *skl = ctx->thread_context; |
@@ -262,7 +263,7 @@ static int bxt_set_dsp_D3(struct sst_dsp *ctx) | |||
262 | return ret; | 263 | return ret; |
263 | } | 264 | } |
264 | 265 | ||
265 | ret = skl_dsp_disable_core(ctx); | 266 | ret = skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); |
266 | if (ret < 0) { | 267 | if (ret < 0) { |
267 | dev_err(ctx->dev, "disbale dsp core failed: %d\n", ret); | 268 | dev_err(ctx->dev, "disbale dsp core failed: %d\n", ret); |
268 | ret = -EIO; | 269 | ret = -EIO; |
@@ -329,6 +330,7 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | |||
329 | if (ret) | 330 | if (ret) |
330 | return ret; | 331 | return ret; |
331 | 332 | ||
333 | skl->cores.count = 2; | ||
332 | skl->boot_complete = false; | 334 | skl->boot_complete = false; |
333 | init_waitqueue_head(&skl->boot_wait); | 335 | init_waitqueue_head(&skl->boot_wait); |
334 | 336 | ||
@@ -338,6 +340,8 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | |||
338 | return ret; | 340 | return ret; |
339 | } | 341 | } |
340 | 342 | ||
343 | skl_dsp_init_core_state(sst); | ||
344 | |||
341 | if (dsp) | 345 | if (dsp) |
342 | *dsp = skl; | 346 | *dsp = skl; |
343 | 347 | ||
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.c b/sound/soc/intel/skylake/skl-sst-dsp.c index 33c45aa53532..c3deefab65d6 100644 --- a/sound/soc/intel/skylake/skl-sst-dsp.c +++ b/sound/soc/intel/skylake/skl-sst-dsp.c | |||
@@ -34,33 +34,84 @@ void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state) | |||
34 | mutex_unlock(&ctx->mutex); | 34 | mutex_unlock(&ctx->mutex); |
35 | } | 35 | } |
36 | 36 | ||
37 | static int skl_dsp_core_set_reset_state(struct sst_dsp *ctx) | 37 | /* |
38 | * Initialize core power state and usage count. To be called after | ||
39 | * successful first boot. Hence core 0 will be running and other cores | ||
40 | * will be reset | ||
41 | */ | ||
42 | void skl_dsp_init_core_state(struct sst_dsp *ctx) | ||
43 | { | ||
44 | struct skl_sst *skl = ctx->thread_context; | ||
45 | int i; | ||
46 | |||
47 | skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING; | ||
48 | skl->cores.usage_count[SKL_DSP_CORE0_ID] = 1; | ||
49 | |||
50 | for (i = SKL_DSP_CORE0_ID + 1; i < SKL_DSP_CORES_MAX; i++) { | ||
51 | skl->cores.state[i] = SKL_DSP_RESET; | ||
52 | skl->cores.usage_count[i] = 0; | ||
53 | } | ||
54 | } | ||
55 | |||
56 | /* Get the mask for all enabled cores */ | ||
57 | unsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx) | ||
58 | { | ||
59 | struct skl_sst *skl = ctx->thread_context; | ||
60 | unsigned int core_mask, en_cores_mask; | ||
61 | u32 val; | ||
62 | |||
63 | core_mask = SKL_DSP_CORES_MASK(skl->cores.count); | ||
64 | |||
65 | val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS); | ||
66 | |||
67 | /* Cores having CPA bit set */ | ||
68 | en_cores_mask = (val & SKL_ADSPCS_CPA_MASK(core_mask)) >> | ||
69 | SKL_ADSPCS_CPA_SHIFT; | ||
70 | |||
71 | /* And cores having CRST bit cleared */ | ||
72 | en_cores_mask &= (~val & SKL_ADSPCS_CRST_MASK(core_mask)) >> | ||
73 | SKL_ADSPCS_CRST_SHIFT; | ||
74 | |||
75 | /* And cores having CSTALL bit cleared */ | ||
76 | en_cores_mask &= (~val & SKL_ADSPCS_CSTALL_MASK(core_mask)) >> | ||
77 | SKL_ADSPCS_CSTALL_SHIFT; | ||
78 | en_cores_mask &= core_mask; | ||
79 | |||
80 | dev_dbg(ctx->dev, "DSP enabled cores mask = %x\n", en_cores_mask); | ||
81 | |||
82 | return en_cores_mask; | ||
83 | } | ||
84 | |||
85 | static int | ||
86 | skl_dsp_core_set_reset_state(struct sst_dsp *ctx, unsigned int core_mask) | ||
38 | { | 87 | { |
39 | int ret; | 88 | int ret; |
40 | 89 | ||
41 | /* update bits */ | 90 | /* update bits */ |
42 | sst_dsp_shim_update_bits_unlocked(ctx, | 91 | sst_dsp_shim_update_bits_unlocked(ctx, |
43 | SKL_ADSP_REG_ADSPCS, SKL_ADSPCS_CRST_MASK, | 92 | SKL_ADSP_REG_ADSPCS, SKL_ADSPCS_CRST_MASK(core_mask), |
44 | SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK)); | 93 | SKL_ADSPCS_CRST_MASK(core_mask)); |
45 | 94 | ||
46 | /* poll with timeout to check if operation successful */ | 95 | /* poll with timeout to check if operation successful */ |
47 | ret = sst_dsp_register_poll(ctx, | 96 | ret = sst_dsp_register_poll(ctx, |
48 | SKL_ADSP_REG_ADSPCS, | 97 | SKL_ADSP_REG_ADSPCS, |
49 | SKL_ADSPCS_CRST_MASK, | 98 | SKL_ADSPCS_CRST_MASK(core_mask), |
50 | SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK), | 99 | SKL_ADSPCS_CRST_MASK(core_mask), |
51 | SKL_DSP_RESET_TO, | 100 | SKL_DSP_RESET_TO, |
52 | "Set reset"); | 101 | "Set reset"); |
53 | if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) & | 102 | if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) & |
54 | SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK)) != | 103 | SKL_ADSPCS_CRST_MASK(core_mask)) != |
55 | SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK)) { | 104 | SKL_ADSPCS_CRST_MASK(core_mask)) { |
56 | dev_err(ctx->dev, "Set reset state failed\n"); | 105 | dev_err(ctx->dev, "Set reset state failed: core_mask %x\n", |
106 | core_mask); | ||
57 | ret = -EIO; | 107 | ret = -EIO; |
58 | } | 108 | } |
59 | 109 | ||
60 | return ret; | 110 | return ret; |
61 | } | 111 | } |
62 | 112 | ||
63 | static int skl_dsp_core_unset_reset_state(struct sst_dsp *ctx) | 113 | int skl_dsp_core_unset_reset_state( |
114 | struct sst_dsp *ctx, unsigned int core_mask) | ||
64 | { | 115 | { |
65 | int ret; | 116 | int ret; |
66 | 117 | ||
@@ -68,151 +119,160 @@ static int skl_dsp_core_unset_reset_state(struct sst_dsp *ctx) | |||
68 | 119 | ||
69 | /* update bits */ | 120 | /* update bits */ |
70 | sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS, | 121 | sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS, |
71 | SKL_ADSPCS_CRST_MASK, 0); | 122 | SKL_ADSPCS_CRST_MASK(core_mask), 0); |
72 | 123 | ||
73 | /* poll with timeout to check if operation successful */ | 124 | /* poll with timeout to check if operation successful */ |
74 | ret = sst_dsp_register_poll(ctx, | 125 | ret = sst_dsp_register_poll(ctx, |
75 | SKL_ADSP_REG_ADSPCS, | 126 | SKL_ADSP_REG_ADSPCS, |
76 | SKL_ADSPCS_CRST_MASK, | 127 | SKL_ADSPCS_CRST_MASK(core_mask), |
77 | 0, | 128 | 0, |
78 | SKL_DSP_RESET_TO, | 129 | SKL_DSP_RESET_TO, |
79 | "Unset reset"); | 130 | "Unset reset"); |
80 | 131 | ||
81 | if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) & | 132 | if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) & |
82 | SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK)) != 0) { | 133 | SKL_ADSPCS_CRST_MASK(core_mask)) != 0) { |
83 | dev_err(ctx->dev, "Unset reset state failed\n"); | 134 | dev_err(ctx->dev, "Unset reset state failed: core_mask %x\n", |
135 | core_mask); | ||
84 | ret = -EIO; | 136 | ret = -EIO; |
85 | } | 137 | } |
86 | 138 | ||
87 | return ret; | 139 | return ret; |
88 | } | 140 | } |
89 | 141 | ||
90 | static bool is_skl_dsp_core_enable(struct sst_dsp *ctx) | 142 | static bool |
143 | is_skl_dsp_core_enable(struct sst_dsp *ctx, unsigned int core_mask) | ||
91 | { | 144 | { |
92 | int val; | 145 | int val; |
93 | bool is_enable; | 146 | bool is_enable; |
94 | 147 | ||
95 | val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS); | 148 | val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS); |
96 | 149 | ||
97 | is_enable = ((val & SKL_ADSPCS_CPA(SKL_DSP_CORES_MASK)) && | 150 | is_enable = ((val & SKL_ADSPCS_CPA_MASK(core_mask)) && |
98 | (val & SKL_ADSPCS_SPA(SKL_DSP_CORES_MASK)) && | 151 | (val & SKL_ADSPCS_SPA_MASK(core_mask)) && |
99 | !(val & SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK)) && | 152 | !(val & SKL_ADSPCS_CRST_MASK(core_mask)) && |
100 | !(val & SKL_ADSPCS_CSTALL(SKL_DSP_CORES_MASK))); | 153 | !(val & SKL_ADSPCS_CSTALL_MASK(core_mask))); |
154 | |||
155 | dev_dbg(ctx->dev, "DSP core(s) enabled? %d : core_mask %x\n", | ||
156 | is_enable, core_mask); | ||
101 | 157 | ||
102 | dev_dbg(ctx->dev, "DSP core is enabled=%d\n", is_enable); | ||
103 | return is_enable; | 158 | return is_enable; |
104 | } | 159 | } |
105 | 160 | ||
106 | static int skl_dsp_reset_core(struct sst_dsp *ctx) | 161 | static int skl_dsp_reset_core(struct sst_dsp *ctx, unsigned int core_mask) |
107 | { | 162 | { |
108 | /* stall core */ | 163 | /* stall core */ |
109 | sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS, | 164 | sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS, |
110 | SKL_ADSPCS_CSTALL_MASK, | 165 | SKL_ADSPCS_CSTALL_MASK(core_mask), |
111 | SKL_ADSPCS_CSTALL(SKL_DSP_CORES_MASK)); | 166 | SKL_ADSPCS_CSTALL_MASK(core_mask)); |
112 | 167 | ||
113 | /* set reset state */ | 168 | /* set reset state */ |
114 | return skl_dsp_core_set_reset_state(ctx); | 169 | return skl_dsp_core_set_reset_state(ctx, core_mask); |
115 | } | 170 | } |
116 | 171 | ||
117 | int skl_dsp_start_core(struct sst_dsp *ctx) | 172 | int skl_dsp_start_core(struct sst_dsp *ctx, unsigned int core_mask) |
118 | { | 173 | { |
119 | int ret; | 174 | int ret; |
120 | 175 | ||
121 | /* unset reset state */ | 176 | /* unset reset state */ |
122 | ret = skl_dsp_core_unset_reset_state(ctx); | 177 | ret = skl_dsp_core_unset_reset_state(ctx, core_mask); |
123 | if (ret < 0) { | 178 | if (ret < 0) |
124 | dev_dbg(ctx->dev, "dsp unset reset fails\n"); | ||
125 | return ret; | 179 | return ret; |
126 | } | ||
127 | 180 | ||
128 | /* run core */ | 181 | /* run core */ |
129 | dev_dbg(ctx->dev, "run core...\n"); | 182 | dev_dbg(ctx->dev, "unstall/run core: core_mask = %x\n", core_mask); |
130 | sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS, | 183 | sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS, |
131 | SKL_ADSPCS_CSTALL_MASK, 0); | 184 | SKL_ADSPCS_CSTALL_MASK(core_mask), 0); |
132 | 185 | ||
133 | if (!is_skl_dsp_core_enable(ctx)) { | 186 | if (!is_skl_dsp_core_enable(ctx, core_mask)) { |
134 | skl_dsp_reset_core(ctx); | 187 | skl_dsp_reset_core(ctx, core_mask); |
135 | dev_err(ctx->dev, "DSP core enable failed\n"); | 188 | dev_err(ctx->dev, "DSP start core failed: core_mask %x\n", |
189 | core_mask); | ||
136 | ret = -EIO; | 190 | ret = -EIO; |
137 | } | 191 | } |
138 | 192 | ||
139 | return ret; | 193 | return ret; |
140 | } | 194 | } |
141 | 195 | ||
142 | int skl_dsp_core_power_up(struct sst_dsp *ctx) | 196 | int skl_dsp_core_power_up(struct sst_dsp *ctx, unsigned int core_mask) |
143 | { | 197 | { |
144 | int ret; | 198 | int ret; |
145 | 199 | ||
146 | /* update bits */ | 200 | /* update bits */ |
147 | sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS, | 201 | sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS, |
148 | SKL_ADSPCS_SPA_MASK, SKL_ADSPCS_SPA(SKL_DSP_CORES_MASK)); | 202 | SKL_ADSPCS_SPA_MASK(core_mask), |
203 | SKL_ADSPCS_SPA_MASK(core_mask)); | ||
149 | 204 | ||
150 | /* poll with timeout to check if operation successful */ | 205 | /* poll with timeout to check if operation successful */ |
151 | ret = sst_dsp_register_poll(ctx, | 206 | ret = sst_dsp_register_poll(ctx, |
152 | SKL_ADSP_REG_ADSPCS, | 207 | SKL_ADSP_REG_ADSPCS, |
153 | SKL_ADSPCS_CPA_MASK, | 208 | SKL_ADSPCS_CPA_MASK(core_mask), |
154 | SKL_ADSPCS_CPA(SKL_DSP_CORES_MASK), | 209 | SKL_ADSPCS_CPA_MASK(core_mask), |
155 | SKL_DSP_PU_TO, | 210 | SKL_DSP_PU_TO, |
156 | "Power up"); | 211 | "Power up"); |
157 | 212 | ||
158 | if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) & | 213 | if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) & |
159 | SKL_ADSPCS_CPA(SKL_DSP_CORES_MASK)) != | 214 | SKL_ADSPCS_CPA_MASK(core_mask)) != |
160 | SKL_ADSPCS_CPA(SKL_DSP_CORES_MASK)) { | 215 | SKL_ADSPCS_CPA_MASK(core_mask)) { |
161 | dev_err(ctx->dev, "DSP core power up failed\n"); | 216 | dev_err(ctx->dev, "DSP core power up failed: core_mask %x\n", |
217 | core_mask); | ||
162 | ret = -EIO; | 218 | ret = -EIO; |
163 | } | 219 | } |
164 | 220 | ||
165 | return ret; | 221 | return ret; |
166 | } | 222 | } |
167 | 223 | ||
168 | static int skl_dsp_core_power_down(struct sst_dsp *ctx) | 224 | int skl_dsp_core_power_down(struct sst_dsp *ctx, unsigned int core_mask) |
169 | { | 225 | { |
170 | /* update bits */ | 226 | /* update bits */ |
171 | sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS, | 227 | sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS, |
172 | SKL_ADSPCS_SPA_MASK, 0); | 228 | SKL_ADSPCS_SPA_MASK(core_mask), 0); |
173 | 229 | ||
174 | /* poll with timeout to check if operation successful */ | 230 | /* poll with timeout to check if operation successful */ |
175 | return sst_dsp_register_poll(ctx, | 231 | return sst_dsp_register_poll(ctx, |
176 | SKL_ADSP_REG_ADSPCS, | 232 | SKL_ADSP_REG_ADSPCS, |
177 | SKL_ADSPCS_CPA_MASK, | 233 | SKL_ADSPCS_CPA_MASK(core_mask), |
178 | 0, | 234 | 0, |
179 | SKL_DSP_PD_TO, | 235 | SKL_DSP_PD_TO, |
180 | "Power down"); | 236 | "Power down"); |
181 | } | 237 | } |
182 | 238 | ||
183 | int skl_dsp_enable_core(struct sst_dsp *ctx) | 239 | int skl_dsp_enable_core(struct sst_dsp *ctx, unsigned int core_mask) |
184 | { | 240 | { |
185 | int ret; | 241 | int ret; |
186 | 242 | ||
187 | /* power up */ | 243 | /* power up */ |
188 | ret = skl_dsp_core_power_up(ctx); | 244 | ret = skl_dsp_core_power_up(ctx, core_mask); |
189 | if (ret < 0) { | 245 | if (ret < 0) { |
190 | dev_dbg(ctx->dev, "dsp core power up failed\n"); | 246 | dev_err(ctx->dev, "dsp core power up failed: core_mask %x\n", |
247 | core_mask); | ||
191 | return ret; | 248 | return ret; |
192 | } | 249 | } |
193 | 250 | ||
194 | return skl_dsp_start_core(ctx); | 251 | return skl_dsp_start_core(ctx, core_mask); |
195 | } | 252 | } |
196 | 253 | ||
197 | int skl_dsp_disable_core(struct sst_dsp *ctx) | 254 | int skl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core_mask) |
198 | { | 255 | { |
199 | int ret; | 256 | int ret; |
200 | 257 | ||
201 | ret = skl_dsp_reset_core(ctx); | 258 | ret = skl_dsp_reset_core(ctx, core_mask); |
202 | if (ret < 0) { | 259 | if (ret < 0) { |
203 | dev_err(ctx->dev, "dsp core reset failed\n"); | 260 | dev_err(ctx->dev, "dsp core reset failed: core_mask %x\n", |
261 | core_mask); | ||
204 | return ret; | 262 | return ret; |
205 | } | 263 | } |
206 | 264 | ||
207 | /* power down core*/ | 265 | /* power down core*/ |
208 | ret = skl_dsp_core_power_down(ctx); | 266 | ret = skl_dsp_core_power_down(ctx, core_mask); |
209 | if (ret < 0) { | 267 | if (ret < 0) { |
210 | dev_err(ctx->dev, "dsp core power down failed\n"); | 268 | dev_err(ctx->dev, "dsp core power down fail mask %x: %d\n", |
269 | core_mask, ret); | ||
211 | return ret; | 270 | return ret; |
212 | } | 271 | } |
213 | 272 | ||
214 | if (is_skl_dsp_core_enable(ctx)) { | 273 | if (is_skl_dsp_core_enable(ctx, core_mask)) { |
215 | dev_err(ctx->dev, "DSP core disable failed\n"); | 274 | dev_err(ctx->dev, "dsp core disable fail mask %x: %d\n", |
275 | core_mask, ret); | ||
216 | ret = -EIO; | 276 | ret = -EIO; |
217 | } | 277 | } |
218 | 278 | ||
@@ -223,28 +283,25 @@ int skl_dsp_boot(struct sst_dsp *ctx) | |||
223 | { | 283 | { |
224 | int ret; | 284 | int ret; |
225 | 285 | ||
226 | if (is_skl_dsp_core_enable(ctx)) { | 286 | if (is_skl_dsp_core_enable(ctx, SKL_DSP_CORE0_MASK)) { |
227 | dev_dbg(ctx->dev, "dsp core is already enabled, so reset the dap core\n"); | 287 | ret = skl_dsp_reset_core(ctx, SKL_DSP_CORE0_MASK); |
228 | ret = skl_dsp_reset_core(ctx); | ||
229 | if (ret < 0) { | 288 | if (ret < 0) { |
230 | dev_err(ctx->dev, "dsp reset failed\n"); | 289 | dev_err(ctx->dev, "dsp core0 reset fail: %d\n", ret); |
231 | return ret; | 290 | return ret; |
232 | } | 291 | } |
233 | 292 | ||
234 | ret = skl_dsp_start_core(ctx); | 293 | ret = skl_dsp_start_core(ctx, SKL_DSP_CORE0_MASK); |
235 | if (ret < 0) { | 294 | if (ret < 0) { |
236 | dev_err(ctx->dev, "dsp start failed\n"); | 295 | dev_err(ctx->dev, "dsp core0 start fail: %d\n", ret); |
237 | return ret; | 296 | return ret; |
238 | } | 297 | } |
239 | } else { | 298 | } else { |
240 | dev_dbg(ctx->dev, "disable and enable to make sure DSP is invalid state\n"); | 299 | ret = skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); |
241 | ret = skl_dsp_disable_core(ctx); | ||
242 | |||
243 | if (ret < 0) { | 300 | if (ret < 0) { |
244 | dev_err(ctx->dev, "dsp disable core failes\n"); | 301 | dev_err(ctx->dev, "dsp core0 disable fail: %d\n", ret); |
245 | return ret; | 302 | return ret; |
246 | } | 303 | } |
247 | ret = skl_dsp_enable_core(ctx); | 304 | ret = skl_dsp_enable_core(ctx, SKL_DSP_CORE0_MASK); |
248 | } | 305 | } |
249 | 306 | ||
250 | return ret; | 307 | return ret; |
@@ -280,16 +337,74 @@ irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id) | |||
280 | 337 | ||
281 | return result; | 338 | return result; |
282 | } | 339 | } |
340 | /* | ||
341 | * skl_dsp_get_core/skl_dsp_put_core will be called inside DAPM context | ||
342 | * within the dapm mutex. Hence no separate lock is used. | ||
343 | */ | ||
344 | int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id) | ||
345 | { | ||
346 | struct skl_sst *skl = ctx->thread_context; | ||
347 | int ret = 0; | ||
348 | |||
349 | if (core_id >= skl->cores.count) { | ||
350 | dev_err(ctx->dev, "invalid core id: %d\n", core_id); | ||
351 | return -EINVAL; | ||
352 | } | ||
353 | |||
354 | if (skl->cores.state[core_id] == SKL_DSP_RESET) { | ||
355 | ret = ctx->fw_ops.set_state_D0(ctx, core_id); | ||
356 | if (ret < 0) { | ||
357 | dev_err(ctx->dev, "unable to get core%d\n", core_id); | ||
358 | return ret; | ||
359 | } | ||
360 | } | ||
361 | |||
362 | skl->cores.usage_count[core_id]++; | ||
363 | |||
364 | dev_dbg(ctx->dev, "core id %d state %d usage_count %d\n", | ||
365 | core_id, skl->cores.state[core_id], | ||
366 | skl->cores.usage_count[core_id]); | ||
367 | |||
368 | return ret; | ||
369 | } | ||
370 | EXPORT_SYMBOL_GPL(skl_dsp_get_core); | ||
371 | |||
372 | int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id) | ||
373 | { | ||
374 | struct skl_sst *skl = ctx->thread_context; | ||
375 | int ret = 0; | ||
376 | |||
377 | if (core_id >= skl->cores.count) { | ||
378 | dev_err(ctx->dev, "invalid core id: %d\n", core_id); | ||
379 | return -EINVAL; | ||
380 | } | ||
381 | |||
382 | if (--skl->cores.usage_count[core_id] == 0) { | ||
383 | ret = ctx->fw_ops.set_state_D3(ctx, core_id); | ||
384 | if (ret < 0) { | ||
385 | dev_err(ctx->dev, "unable to put core %d: %d\n", | ||
386 | core_id, ret); | ||
387 | skl->cores.usage_count[core_id]++; | ||
388 | } | ||
389 | } | ||
390 | |||
391 | dev_dbg(ctx->dev, "core id %d state %d usage_count %d\n", | ||
392 | core_id, skl->cores.state[core_id], | ||
393 | skl->cores.usage_count[core_id]); | ||
394 | |||
395 | return ret; | ||
396 | } | ||
397 | EXPORT_SYMBOL_GPL(skl_dsp_put_core); | ||
283 | 398 | ||
284 | int skl_dsp_wake(struct sst_dsp *ctx) | 399 | int skl_dsp_wake(struct sst_dsp *ctx) |
285 | { | 400 | { |
286 | return ctx->fw_ops.set_state_D0(ctx); | 401 | return skl_dsp_get_core(ctx, SKL_DSP_CORE0_ID); |
287 | } | 402 | } |
288 | EXPORT_SYMBOL_GPL(skl_dsp_wake); | 403 | EXPORT_SYMBOL_GPL(skl_dsp_wake); |
289 | 404 | ||
290 | int skl_dsp_sleep(struct sst_dsp *ctx) | 405 | int skl_dsp_sleep(struct sst_dsp *ctx) |
291 | { | 406 | { |
292 | return ctx->fw_ops.set_state_D3(ctx); | 407 | return skl_dsp_put_core(ctx, SKL_DSP_CORE0_ID); |
293 | } | 408 | } |
294 | EXPORT_SYMBOL_GPL(skl_dsp_sleep); | 409 | EXPORT_SYMBOL_GPL(skl_dsp_sleep); |
295 | 410 | ||
@@ -336,9 +451,7 @@ void skl_dsp_free(struct sst_dsp *dsp) | |||
336 | 451 | ||
337 | free_irq(dsp->irq, dsp); | 452 | free_irq(dsp->irq, dsp); |
338 | skl_ipc_op_int_disable(dsp); | 453 | skl_ipc_op_int_disable(dsp); |
339 | skl_ipc_int_disable(dsp); | 454 | skl_dsp_disable_core(dsp, SKL_DSP_CORE0_MASK); |
340 | |||
341 | skl_dsp_disable_core(dsp); | ||
342 | } | 455 | } |
343 | EXPORT_SYMBOL_GPL(skl_dsp_free); | 456 | EXPORT_SYMBOL_GPL(skl_dsp_free); |
344 | 457 | ||
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h index 22fbe1075cb5..0f8629ef79ac 100644 --- a/sound/soc/intel/skylake/skl-sst-dsp.h +++ b/sound/soc/intel/skylake/skl-sst-dsp.h | |||
@@ -77,35 +77,53 @@ struct sst_dsp_device; | |||
77 | #define SKL_ADSPIC_IPC 1 | 77 | #define SKL_ADSPIC_IPC 1 |
78 | #define SKL_ADSPIS_IPC 1 | 78 | #define SKL_ADSPIS_IPC 1 |
79 | 79 | ||
80 | /* Core ID of core0 */ | ||
81 | #define SKL_DSP_CORE0_ID 0 | ||
82 | |||
83 | /* Mask for a given core index, c = 0.. number of supported cores - 1 */ | ||
84 | #define SKL_DSP_CORE_MASK(c) BIT(c) | ||
85 | |||
86 | /* | ||
87 | * Core 0 mask = SKL_DSP_CORE_MASK(0); Defined separately | ||
88 | * since Core0 is primary core and it is used often | ||
89 | */ | ||
90 | #define SKL_DSP_CORE0_MASK BIT(0) | ||
91 | |||
92 | /* | ||
93 | * Mask for a given number of cores | ||
94 | * nc = number of supported cores | ||
95 | */ | ||
96 | #define SKL_DSP_CORES_MASK(nc) GENMASK((nc - 1), 0) | ||
97 | |||
80 | /* ADSPCS - Audio DSP Control & Status */ | 98 | /* ADSPCS - Audio DSP Control & Status */ |
81 | #define SKL_DSP_CORES 1 | 99 | |
82 | #define SKL_DSP_CORE0_MASK 1 | 100 | /* |
83 | #define SKL_DSP_CORES_MASK ((1 << SKL_DSP_CORES) - 1) | 101 | * Core Reset - asserted high |
84 | 102 | * CRST Mask for a given core mask pattern, cm | |
85 | /* Core Reset - asserted high */ | 103 | */ |
86 | #define SKL_ADSPCS_CRST_SHIFT 0 | 104 | #define SKL_ADSPCS_CRST_SHIFT 0 |
87 | #define SKL_ADSPCS_CRST_MASK (SKL_DSP_CORES_MASK << SKL_ADSPCS_CRST_SHIFT) | 105 | #define SKL_ADSPCS_CRST_MASK(cm) ((cm) << SKL_ADSPCS_CRST_SHIFT) |
88 | #define SKL_ADSPCS_CRST(x) ((x << SKL_ADSPCS_CRST_SHIFT) & SKL_ADSPCS_CRST_MASK) | 106 | |
89 | 107 | /* | |
90 | /* Core run/stall - when set to '1' core is stalled */ | 108 | * Core run/stall - when set to '1' core is stalled |
91 | #define SKL_ADSPCS_CSTALL_SHIFT 8 | 109 | * CSTALL Mask for a given core mask pattern, cm |
92 | #define SKL_ADSPCS_CSTALL_MASK (SKL_DSP_CORES_MASK << \ | 110 | */ |
93 | SKL_ADSPCS_CSTALL_SHIFT) | 111 | #define SKL_ADSPCS_CSTALL_SHIFT 8 |
94 | #define SKL_ADSPCS_CSTALL(x) ((x << SKL_ADSPCS_CSTALL_SHIFT) & \ | 112 | #define SKL_ADSPCS_CSTALL_MASK(cm) ((cm) << SKL_ADSPCS_CSTALL_SHIFT) |
95 | SKL_ADSPCS_CSTALL_MASK) | 113 | |
96 | 114 | /* | |
97 | /* Set Power Active - when set to '1' turn cores on */ | 115 | * Set Power Active - when set to '1' turn cores on |
98 | #define SKL_ADSPCS_SPA_SHIFT 16 | 116 | * SPA Mask for a given core mask pattern, cm |
99 | #define SKL_ADSPCS_SPA_MASK (SKL_DSP_CORES_MASK << SKL_ADSPCS_SPA_SHIFT) | 117 | */ |
100 | #define SKL_ADSPCS_SPA(x) ((x << SKL_ADSPCS_SPA_SHIFT) & SKL_ADSPCS_SPA_MASK) | 118 | #define SKL_ADSPCS_SPA_SHIFT 16 |
101 | 119 | #define SKL_ADSPCS_SPA_MASK(cm) ((cm) << SKL_ADSPCS_SPA_SHIFT) | |
102 | /* Current Power Active - power status of cores, set by hardware */ | 120 | |
103 | #define SKL_ADSPCS_CPA_SHIFT 24 | 121 | /* |
104 | #define SKL_ADSPCS_CPA_MASK (SKL_DSP_CORES_MASK << SKL_ADSPCS_CPA_SHIFT) | 122 | * Current Power Active - power status of cores, set by hardware |
105 | #define SKL_ADSPCS_CPA(x) ((x << SKL_ADSPCS_CPA_SHIFT) & SKL_ADSPCS_CPA_MASK) | 123 | * CPA Mask for a given core mask pattern, cm |
106 | 124 | */ | |
107 | #define SST_DSP_POWER_D0 0x0 /* full On */ | 125 | #define SKL_ADSPCS_CPA_SHIFT 24 |
108 | #define SST_DSP_POWER_D3 0x3 /* Off */ | 126 | #define SKL_ADSPCS_CPA_MASK(cm) ((cm) << SKL_ADSPCS_CPA_SHIFT) |
109 | 127 | ||
110 | enum skl_dsp_states { | 128 | enum skl_dsp_states { |
111 | SKL_DSP_RUNNING = 1, | 129 | SKL_DSP_RUNNING = 1, |
@@ -116,8 +134,8 @@ struct skl_dsp_fw_ops { | |||
116 | int (*load_fw)(struct sst_dsp *ctx); | 134 | int (*load_fw)(struct sst_dsp *ctx); |
117 | /* FW module parser/loader */ | 135 | /* FW module parser/loader */ |
118 | int (*parse_fw)(struct sst_dsp *ctx); | 136 | int (*parse_fw)(struct sst_dsp *ctx); |
119 | int (*set_state_D0)(struct sst_dsp *ctx); | 137 | int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id); |
120 | int (*set_state_D3)(struct sst_dsp *ctx); | 138 | int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id); |
121 | unsigned int (*get_fw_errcode)(struct sst_dsp *ctx); | 139 | unsigned int (*get_fw_errcode)(struct sst_dsp *ctx); |
122 | int (*load_mod)(struct sst_dsp *ctx, u16 mod_id, u8 *mod_name); | 140 | int (*load_mod)(struct sst_dsp *ctx, u16 mod_id, u8 *mod_name); |
123 | int (*unload_mod)(struct sst_dsp *ctx, u16 mod_id); | 141 | int (*unload_mod)(struct sst_dsp *ctx, u16 mod_id); |
@@ -158,14 +176,26 @@ int skl_cldma_prepare(struct sst_dsp *ctx); | |||
158 | void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state); | 176 | void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state); |
159 | struct sst_dsp *skl_dsp_ctx_init(struct device *dev, | 177 | struct sst_dsp *skl_dsp_ctx_init(struct device *dev, |
160 | struct sst_dsp_device *sst_dev, int irq); | 178 | struct sst_dsp_device *sst_dev, int irq); |
161 | int skl_dsp_enable_core(struct sst_dsp *ctx); | ||
162 | int skl_dsp_disable_core(struct sst_dsp *ctx); | ||
163 | bool is_skl_dsp_running(struct sst_dsp *ctx); | 179 | bool is_skl_dsp_running(struct sst_dsp *ctx); |
180 | |||
181 | unsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx); | ||
182 | void skl_dsp_init_core_state(struct sst_dsp *ctx); | ||
183 | int skl_dsp_enable_core(struct sst_dsp *ctx, unsigned int core_mask); | ||
184 | int skl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core_mask); | ||
185 | int skl_dsp_core_power_up(struct sst_dsp *ctx, unsigned int core_mask); | ||
186 | int skl_dsp_core_power_down(struct sst_dsp *ctx, unsigned int core_mask); | ||
187 | int skl_dsp_core_unset_reset_state(struct sst_dsp *ctx, | ||
188 | unsigned int core_mask); | ||
189 | int skl_dsp_start_core(struct sst_dsp *ctx, unsigned int core_mask); | ||
190 | |||
164 | irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id); | 191 | irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id); |
165 | int skl_dsp_wake(struct sst_dsp *ctx); | 192 | int skl_dsp_wake(struct sst_dsp *ctx); |
166 | int skl_dsp_sleep(struct sst_dsp *ctx); | 193 | int skl_dsp_sleep(struct sst_dsp *ctx); |
167 | void skl_dsp_free(struct sst_dsp *dsp); | 194 | void skl_dsp_free(struct sst_dsp *dsp); |
168 | 195 | ||
196 | int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id); | ||
197 | int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id); | ||
198 | |||
169 | int skl_dsp_boot(struct sst_dsp *ctx); | 199 | int skl_dsp_boot(struct sst_dsp *ctx); |
170 | int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | 200 | int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, |
171 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, | 201 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, |
@@ -182,7 +212,5 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset); | |||
182 | void skl_freeup_uuid_list(struct skl_sst *ctx); | 212 | void skl_freeup_uuid_list(struct skl_sst *ctx); |
183 | 213 | ||
184 | int skl_dsp_strip_extended_manifest(struct firmware *fw); | 214 | int skl_dsp_strip_extended_manifest(struct firmware *fw); |
185 | int skl_dsp_start_core(struct sst_dsp *ctx); | ||
186 | int skl_dsp_core_power_up(struct sst_dsp *ctx); | ||
187 | 215 | ||
188 | #endif /*__SKL_SST_DSP_H__*/ | 216 | #endif /*__SKL_SST_DSP_H__*/ |
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h index 5102c7b415fe..2e3d4e80ef97 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.h +++ b/sound/soc/intel/skylake/skl-sst-ipc.h | |||
@@ -45,6 +45,14 @@ struct skl_ipc_header { | |||
45 | u32 extension; | 45 | u32 extension; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | #define SKL_DSP_CORES_MAX 2 | ||
49 | |||
50 | struct skl_dsp_cores { | ||
51 | unsigned int count; | ||
52 | enum skl_dsp_states state[SKL_DSP_CORES_MAX]; | ||
53 | int usage_count[SKL_DSP_CORES_MAX]; | ||
54 | }; | ||
55 | |||
48 | struct skl_sst { | 56 | struct skl_sst { |
49 | struct device *dev; | 57 | struct device *dev; |
50 | struct sst_dsp *dsp; | 58 | struct sst_dsp *dsp; |
@@ -66,6 +74,9 @@ struct skl_sst { | |||
66 | 74 | ||
67 | /* Is firmware loaded */ | 75 | /* Is firmware loaded */ |
68 | bool fw_loaded; | 76 | bool fw_loaded; |
77 | |||
78 | /* multi-core */ | ||
79 | struct skl_dsp_cores cores; | ||
69 | }; | 80 | }; |
70 | 81 | ||
71 | struct skl_ipc_init_instance_msg { | 82 | struct skl_ipc_init_instance_msg { |
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c index eaf0c9d19782..ecaca94d2a96 100644 --- a/sound/soc/intel/skylake/skl-sst.c +++ b/sound/soc/intel/skylake/skl-sst.c | |||
@@ -84,10 +84,8 @@ static int skl_load_base_firmware(struct sst_dsp *ctx) | |||
84 | ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev); | 84 | ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev); |
85 | if (ret < 0) { | 85 | if (ret < 0) { |
86 | dev_err(ctx->dev, "Request firmware failed %d\n", ret); | 86 | dev_err(ctx->dev, "Request firmware failed %d\n", ret); |
87 | skl_dsp_disable_core(ctx); | ||
88 | return -EIO; | 87 | return -EIO; |
89 | } | 88 | } |
90 | |||
91 | } | 89 | } |
92 | 90 | ||
93 | ret = snd_skl_parse_uuids(ctx, SKL_ADSP_FW_BIN_HDR_OFFSET); | 91 | ret = snd_skl_parse_uuids(ctx, SKL_ADSP_FW_BIN_HDR_OFFSET); |
@@ -95,7 +93,7 @@ static int skl_load_base_firmware(struct sst_dsp *ctx) | |||
95 | dev_err(ctx->dev, | 93 | dev_err(ctx->dev, |
96 | "UUID parsing err: %d\n", ret); | 94 | "UUID parsing err: %d\n", ret); |
97 | release_firmware(ctx->fw); | 95 | release_firmware(ctx->fw); |
98 | skl_dsp_disable_core(ctx); | 96 | skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); |
99 | return ret; | 97 | return ret; |
100 | } | 98 | } |
101 | 99 | ||
@@ -159,13 +157,13 @@ static int skl_load_base_firmware(struct sst_dsp *ctx) | |||
159 | transfer_firmware_failed: | 157 | transfer_firmware_failed: |
160 | ctx->cl_dev.ops.cl_cleanup_controller(ctx); | 158 | ctx->cl_dev.ops.cl_cleanup_controller(ctx); |
161 | skl_load_base_firmware_failed: | 159 | skl_load_base_firmware_failed: |
162 | skl_dsp_disable_core(ctx); | 160 | skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); |
163 | release_firmware(ctx->fw); | 161 | release_firmware(ctx->fw); |
164 | ctx->fw = NULL; | 162 | ctx->fw = NULL; |
165 | return ret; | 163 | return ret; |
166 | } | 164 | } |
167 | 165 | ||
168 | static int skl_set_dsp_D0(struct sst_dsp *ctx) | 166 | static int skl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) |
169 | { | 167 | { |
170 | int ret; | 168 | int ret; |
171 | 169 | ||
@@ -180,7 +178,7 @@ static int skl_set_dsp_D0(struct sst_dsp *ctx) | |||
180 | return ret; | 178 | return ret; |
181 | } | 179 | } |
182 | 180 | ||
183 | static int skl_set_dsp_D3(struct sst_dsp *ctx) | 181 | static int skl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) |
184 | { | 182 | { |
185 | int ret; | 183 | int ret; |
186 | struct skl_ipc_dxstate_info dx; | 184 | struct skl_ipc_dxstate_info dx; |
@@ -207,7 +205,7 @@ static int skl_set_dsp_D3(struct sst_dsp *ctx) | |||
207 | skl_ipc_op_int_disable(ctx); | 205 | skl_ipc_op_int_disable(ctx); |
208 | skl_ipc_int_disable(ctx); | 206 | skl_ipc_int_disable(ctx); |
209 | 207 | ||
210 | ret = skl_dsp_disable_core(ctx); | 208 | ret = skl_dsp_disable_core(ctx, core_id); |
211 | if (ret < 0) { | 209 | if (ret < 0) { |
212 | dev_err(ctx->dev, "disable dsp core failed ret: %d\n", ret); | 210 | dev_err(ctx->dev, "disable dsp core failed ret: %d\n", ret); |
213 | ret = -EIO; | 211 | ret = -EIO; |
@@ -466,12 +464,16 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | |||
466 | if (ret) | 464 | if (ret) |
467 | return ret; | 465 | return ret; |
468 | 466 | ||
467 | skl->cores.count = 2; | ||
468 | |||
469 | ret = sst->fw_ops.load_fw(sst); | 469 | ret = sst->fw_ops.load_fw(sst); |
470 | if (ret < 0) { | 470 | if (ret < 0) { |
471 | dev_err(dev, "Load base fw failed : %d", ret); | 471 | dev_err(dev, "Load base fw failed : %d", ret); |
472 | goto cleanup; | 472 | goto cleanup; |
473 | } | 473 | } |
474 | 474 | ||
475 | skl_dsp_init_core_state(sst); | ||
476 | |||
475 | if (dsp) | 477 | if (dsp) |
476 | *dsp = skl; | 478 | *dsp = skl; |
477 | 479 | ||