aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/intel/skylake/bxt-sst.c22
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.c253
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.h96
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h11
-rw-r--r--sound/soc/intel/skylake/skl-sst.c16
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
119base_fw_load_failed: 119base_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
207static int bxt_set_dsp_D0(struct sst_dsp *ctx) 208static 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
246static int bxt_set_dsp_D3(struct sst_dsp *ctx) 247static 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
37static 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 */
42void 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 */
57unsigned 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
85static int
86skl_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
63static int skl_dsp_core_unset_reset_state(struct sst_dsp *ctx) 113int 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
90static bool is_skl_dsp_core_enable(struct sst_dsp *ctx) 142static bool
143is_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
106static int skl_dsp_reset_core(struct sst_dsp *ctx) 161static 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
117int skl_dsp_start_core(struct sst_dsp *ctx) 172int 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
142int skl_dsp_core_power_up(struct sst_dsp *ctx) 196int 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
168static int skl_dsp_core_power_down(struct sst_dsp *ctx) 224int 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
183int skl_dsp_enable_core(struct sst_dsp *ctx) 239int 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
197int skl_dsp_disable_core(struct sst_dsp *ctx) 254int 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 */
344int 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}
370EXPORT_SYMBOL_GPL(skl_dsp_get_core);
371
372int 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}
397EXPORT_SYMBOL_GPL(skl_dsp_put_core);
283 398
284int skl_dsp_wake(struct sst_dsp *ctx) 399int 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}
288EXPORT_SYMBOL_GPL(skl_dsp_wake); 403EXPORT_SYMBOL_GPL(skl_dsp_wake);
289 404
290int skl_dsp_sleep(struct sst_dsp *ctx) 405int 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}
294EXPORT_SYMBOL_GPL(skl_dsp_sleep); 409EXPORT_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}
343EXPORT_SYMBOL_GPL(skl_dsp_free); 456EXPORT_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
110enum skl_dsp_states { 128enum 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);
158void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state); 176void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state);
159struct sst_dsp *skl_dsp_ctx_init(struct device *dev, 177struct 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);
161int skl_dsp_enable_core(struct sst_dsp *ctx);
162int skl_dsp_disable_core(struct sst_dsp *ctx);
163bool is_skl_dsp_running(struct sst_dsp *ctx); 179bool is_skl_dsp_running(struct sst_dsp *ctx);
180
181unsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx);
182void skl_dsp_init_core_state(struct sst_dsp *ctx);
183int skl_dsp_enable_core(struct sst_dsp *ctx, unsigned int core_mask);
184int skl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core_mask);
185int skl_dsp_core_power_up(struct sst_dsp *ctx, unsigned int core_mask);
186int skl_dsp_core_power_down(struct sst_dsp *ctx, unsigned int core_mask);
187int skl_dsp_core_unset_reset_state(struct sst_dsp *ctx,
188 unsigned int core_mask);
189int skl_dsp_start_core(struct sst_dsp *ctx, unsigned int core_mask);
190
164irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id); 191irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id);
165int skl_dsp_wake(struct sst_dsp *ctx); 192int skl_dsp_wake(struct sst_dsp *ctx);
166int skl_dsp_sleep(struct sst_dsp *ctx); 193int skl_dsp_sleep(struct sst_dsp *ctx);
167void skl_dsp_free(struct sst_dsp *dsp); 194void skl_dsp_free(struct sst_dsp *dsp);
168 195
196int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id);
197int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id);
198
169int skl_dsp_boot(struct sst_dsp *ctx); 199int skl_dsp_boot(struct sst_dsp *ctx);
170int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 200int 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);
182void skl_freeup_uuid_list(struct skl_sst *ctx); 212void skl_freeup_uuid_list(struct skl_sst *ctx);
183 213
184int skl_dsp_strip_extended_manifest(struct firmware *fw); 214int skl_dsp_strip_extended_manifest(struct firmware *fw);
185int skl_dsp_start_core(struct sst_dsp *ctx);
186int 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
50struct 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
48struct skl_sst { 56struct 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
71struct skl_ipc_init_instance_msg { 82struct 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)
159transfer_firmware_failed: 157transfer_firmware_failed:
160 ctx->cl_dev.ops.cl_cleanup_controller(ctx); 158 ctx->cl_dev.ops.cl_cleanup_controller(ctx);
161skl_load_base_firmware_failed: 159skl_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
168static int skl_set_dsp_D0(struct sst_dsp *ctx) 166static 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
183static int skl_set_dsp_D3(struct sst_dsp *ctx) 181static 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