ASoC: Intel: Skylake: Shield against no-NHLT configurations
[sfrench/cifs-2.6.git] / sound / soc / intel / skylake / skl-sst-dsp.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * skl-sst-dsp.c - SKL SST library generic function
4  *
5  * Copyright (C) 2014-15, Intel Corporation.
6  * Author:Rafal Redzimski <rafal.f.redzimski@intel.com>
7  *      Jeeja KP <jeeja.kp@intel.com>
8  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9  */
10 #include <sound/pcm.h>
11
12 #include "../common/sst-dsp.h"
13 #include "../common/sst-ipc.h"
14 #include "../common/sst-dsp-priv.h"
15 #include "skl.h"
16
17 /* various timeout values */
18 #define SKL_DSP_PU_TO           50
19 #define SKL_DSP_PD_TO           50
20 #define SKL_DSP_RESET_TO        50
21
22 void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state)
23 {
24         mutex_lock(&ctx->mutex);
25         ctx->sst_state = state;
26         mutex_unlock(&ctx->mutex);
27 }
28
29 /*
30  * Initialize core power state and usage count. To be called after
31  * successful first boot. Hence core 0 will be running and other cores
32  * will be reset
33  */
34 void skl_dsp_init_core_state(struct sst_dsp *ctx)
35 {
36         struct skl_dev *skl = ctx->thread_context;
37         int i;
38
39         skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING;
40         skl->cores.usage_count[SKL_DSP_CORE0_ID] = 1;
41
42         for (i = SKL_DSP_CORE0_ID + 1; i < skl->cores.count; i++) {
43                 skl->cores.state[i] = SKL_DSP_RESET;
44                 skl->cores.usage_count[i] = 0;
45         }
46 }
47
48 /* Get the mask for all enabled cores */
49 unsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx)
50 {
51         struct skl_dev *skl = ctx->thread_context;
52         unsigned int core_mask, en_cores_mask;
53         u32 val;
54
55         core_mask = SKL_DSP_CORES_MASK(skl->cores.count);
56
57         val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS);
58
59         /* Cores having CPA bit set */
60         en_cores_mask = (val & SKL_ADSPCS_CPA_MASK(core_mask)) >>
61                         SKL_ADSPCS_CPA_SHIFT;
62
63         /* And cores having CRST bit cleared */
64         en_cores_mask &= (~val & SKL_ADSPCS_CRST_MASK(core_mask)) >>
65                         SKL_ADSPCS_CRST_SHIFT;
66
67         /* And cores having CSTALL bit cleared */
68         en_cores_mask &= (~val & SKL_ADSPCS_CSTALL_MASK(core_mask)) >>
69                         SKL_ADSPCS_CSTALL_SHIFT;
70         en_cores_mask &= core_mask;
71
72         dev_dbg(ctx->dev, "DSP enabled cores mask = %x\n", en_cores_mask);
73
74         return en_cores_mask;
75 }
76
77 static int
78 skl_dsp_core_set_reset_state(struct sst_dsp *ctx, unsigned int core_mask)
79 {
80         int ret;
81
82         /* update bits */
83         sst_dsp_shim_update_bits_unlocked(ctx,
84                         SKL_ADSP_REG_ADSPCS, SKL_ADSPCS_CRST_MASK(core_mask),
85                         SKL_ADSPCS_CRST_MASK(core_mask));
86
87         /* poll with timeout to check if operation successful */
88         ret = sst_dsp_register_poll(ctx,
89                         SKL_ADSP_REG_ADSPCS,
90                         SKL_ADSPCS_CRST_MASK(core_mask),
91                         SKL_ADSPCS_CRST_MASK(core_mask),
92                         SKL_DSP_RESET_TO,
93                         "Set reset");
94         if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) &
95                                 SKL_ADSPCS_CRST_MASK(core_mask)) !=
96                                 SKL_ADSPCS_CRST_MASK(core_mask)) {
97                 dev_err(ctx->dev, "Set reset state failed: core_mask %x\n",
98                                                         core_mask);
99                 ret = -EIO;
100         }
101
102         return ret;
103 }
104
105 int skl_dsp_core_unset_reset_state(
106                 struct sst_dsp *ctx, unsigned int core_mask)
107 {
108         int ret;
109
110         dev_dbg(ctx->dev, "In %s\n", __func__);
111
112         /* update bits */
113         sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
114                                 SKL_ADSPCS_CRST_MASK(core_mask), 0);
115
116         /* poll with timeout to check if operation successful */
117         ret = sst_dsp_register_poll(ctx,
118                         SKL_ADSP_REG_ADSPCS,
119                         SKL_ADSPCS_CRST_MASK(core_mask),
120                         0,
121                         SKL_DSP_RESET_TO,
122                         "Unset reset");
123
124         if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) &
125                                 SKL_ADSPCS_CRST_MASK(core_mask)) != 0) {
126                 dev_err(ctx->dev, "Unset reset state failed: core_mask %x\n",
127                                 core_mask);
128                 ret = -EIO;
129         }
130
131         return ret;
132 }
133
134 static bool
135 is_skl_dsp_core_enable(struct sst_dsp *ctx, unsigned int core_mask)
136 {
137         int val;
138         bool is_enable;
139
140         val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS);
141
142         is_enable = ((val & SKL_ADSPCS_CPA_MASK(core_mask)) &&
143                         (val & SKL_ADSPCS_SPA_MASK(core_mask)) &&
144                         !(val & SKL_ADSPCS_CRST_MASK(core_mask)) &&
145                         !(val & SKL_ADSPCS_CSTALL_MASK(core_mask)));
146
147         dev_dbg(ctx->dev, "DSP core(s) enabled? %d : core_mask %x\n",
148                                                 is_enable, core_mask);
149
150         return is_enable;
151 }
152
153 static int skl_dsp_reset_core(struct sst_dsp *ctx, unsigned int core_mask)
154 {
155         /* stall core */
156         sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
157                         SKL_ADSPCS_CSTALL_MASK(core_mask),
158                         SKL_ADSPCS_CSTALL_MASK(core_mask));
159
160         /* set reset state */
161         return skl_dsp_core_set_reset_state(ctx, core_mask);
162 }
163
164 int skl_dsp_start_core(struct sst_dsp *ctx, unsigned int core_mask)
165 {
166         int ret;
167
168         /* unset reset state */
169         ret = skl_dsp_core_unset_reset_state(ctx, core_mask);
170         if (ret < 0)
171                 return ret;
172
173         /* run core */
174         dev_dbg(ctx->dev, "unstall/run core: core_mask = %x\n", core_mask);
175         sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
176                         SKL_ADSPCS_CSTALL_MASK(core_mask), 0);
177
178         if (!is_skl_dsp_core_enable(ctx, core_mask)) {
179                 skl_dsp_reset_core(ctx, core_mask);
180                 dev_err(ctx->dev, "DSP start core failed: core_mask %x\n",
181                                                         core_mask);
182                 ret = -EIO;
183         }
184
185         return ret;
186 }
187
188 int skl_dsp_core_power_up(struct sst_dsp *ctx, unsigned int core_mask)
189 {
190         int ret;
191
192         /* update bits */
193         sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
194                         SKL_ADSPCS_SPA_MASK(core_mask),
195                         SKL_ADSPCS_SPA_MASK(core_mask));
196
197         /* poll with timeout to check if operation successful */
198         ret = sst_dsp_register_poll(ctx,
199                         SKL_ADSP_REG_ADSPCS,
200                         SKL_ADSPCS_CPA_MASK(core_mask),
201                         SKL_ADSPCS_CPA_MASK(core_mask),
202                         SKL_DSP_PU_TO,
203                         "Power up");
204
205         if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) &
206                         SKL_ADSPCS_CPA_MASK(core_mask)) !=
207                         SKL_ADSPCS_CPA_MASK(core_mask)) {
208                 dev_err(ctx->dev, "DSP core power up failed: core_mask %x\n",
209                                 core_mask);
210                 ret = -EIO;
211         }
212
213         return ret;
214 }
215
216 int skl_dsp_core_power_down(struct sst_dsp  *ctx, unsigned int core_mask)
217 {
218         /* update bits */
219         sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
220                                 SKL_ADSPCS_SPA_MASK(core_mask), 0);
221
222         /* poll with timeout to check if operation successful */
223         return sst_dsp_register_poll(ctx,
224                         SKL_ADSP_REG_ADSPCS,
225                         SKL_ADSPCS_CPA_MASK(core_mask),
226                         0,
227                         SKL_DSP_PD_TO,
228                         "Power down");
229 }
230
231 int skl_dsp_enable_core(struct sst_dsp  *ctx, unsigned int core_mask)
232 {
233         int ret;
234
235         /* power up */
236         ret = skl_dsp_core_power_up(ctx, core_mask);
237         if (ret < 0) {
238                 dev_err(ctx->dev, "dsp core power up failed: core_mask %x\n",
239                                                         core_mask);
240                 return ret;
241         }
242
243         return skl_dsp_start_core(ctx, core_mask);
244 }
245
246 int skl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core_mask)
247 {
248         int ret;
249
250         ret = skl_dsp_reset_core(ctx, core_mask);
251         if (ret < 0) {
252                 dev_err(ctx->dev, "dsp core reset failed: core_mask %x\n",
253                                                         core_mask);
254                 return ret;
255         }
256
257         /* power down core*/
258         ret = skl_dsp_core_power_down(ctx, core_mask);
259         if (ret < 0) {
260                 dev_err(ctx->dev, "dsp core power down fail mask %x: %d\n",
261                                                         core_mask, ret);
262                 return ret;
263         }
264
265         if (is_skl_dsp_core_enable(ctx, core_mask)) {
266                 dev_err(ctx->dev, "dsp core disable fail mask %x: %d\n",
267                                                         core_mask, ret);
268                 ret = -EIO;
269         }
270
271         return ret;
272 }
273
274 int skl_dsp_boot(struct sst_dsp *ctx)
275 {
276         int ret;
277
278         if (is_skl_dsp_core_enable(ctx, SKL_DSP_CORE0_MASK)) {
279                 ret = skl_dsp_reset_core(ctx, SKL_DSP_CORE0_MASK);
280                 if (ret < 0) {
281                         dev_err(ctx->dev, "dsp core0 reset fail: %d\n", ret);
282                         return ret;
283                 }
284
285                 ret = skl_dsp_start_core(ctx, SKL_DSP_CORE0_MASK);
286                 if (ret < 0) {
287                         dev_err(ctx->dev, "dsp core0 start fail: %d\n", ret);
288                         return ret;
289                 }
290         } else {
291                 ret = skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
292                 if (ret < 0) {
293                         dev_err(ctx->dev, "dsp core0 disable fail: %d\n", ret);
294                         return ret;
295                 }
296                 ret = skl_dsp_enable_core(ctx, SKL_DSP_CORE0_MASK);
297         }
298
299         return ret;
300 }
301
302 irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id)
303 {
304         struct sst_dsp *ctx = dev_id;
305         u32 val;
306         irqreturn_t result = IRQ_NONE;
307
308         spin_lock(&ctx->spinlock);
309
310         val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPIS);
311         ctx->intr_status = val;
312
313         if (val == 0xffffffff) {
314                 spin_unlock(&ctx->spinlock);
315                 return IRQ_NONE;
316         }
317
318         if (val & SKL_ADSPIS_IPC) {
319                 skl_ipc_int_disable(ctx);
320                 result = IRQ_WAKE_THREAD;
321         }
322
323         if (val & SKL_ADSPIS_CL_DMA) {
324                 skl_cldma_int_disable(ctx);
325                 result = IRQ_WAKE_THREAD;
326         }
327
328         spin_unlock(&ctx->spinlock);
329
330         return result;
331 }
332 /*
333  * skl_dsp_get_core/skl_dsp_put_core will be called inside DAPM context
334  * within the dapm mutex. Hence no separate lock is used.
335  */
336 int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id)
337 {
338         struct skl_dev *skl = ctx->thread_context;
339         int ret = 0;
340
341         if (core_id >= skl->cores.count) {
342                 dev_err(ctx->dev, "invalid core id: %d\n", core_id);
343                 return -EINVAL;
344         }
345
346         skl->cores.usage_count[core_id]++;
347
348         if (skl->cores.state[core_id] == SKL_DSP_RESET) {
349                 ret = ctx->fw_ops.set_state_D0(ctx, core_id);
350                 if (ret < 0) {
351                         dev_err(ctx->dev, "unable to get core%d\n", core_id);
352                         goto out;
353                 }
354         }
355
356 out:
357         dev_dbg(ctx->dev, "core id %d state %d usage_count %d\n",
358                         core_id, skl->cores.state[core_id],
359                         skl->cores.usage_count[core_id]);
360
361         return ret;
362 }
363 EXPORT_SYMBOL_GPL(skl_dsp_get_core);
364
365 int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id)
366 {
367         struct skl_dev *skl = ctx->thread_context;
368         int ret = 0;
369
370         if (core_id >= skl->cores.count) {
371                 dev_err(ctx->dev, "invalid core id: %d\n", core_id);
372                 return -EINVAL;
373         }
374
375         if ((--skl->cores.usage_count[core_id] == 0) &&
376                 (skl->cores.state[core_id] != SKL_DSP_RESET)) {
377                 ret = ctx->fw_ops.set_state_D3(ctx, core_id);
378                 if (ret < 0) {
379                         dev_err(ctx->dev, "unable to put core %d: %d\n",
380                                         core_id, ret);
381                         skl->cores.usage_count[core_id]++;
382                 }
383         }
384
385         dev_dbg(ctx->dev, "core id %d state %d usage_count %d\n",
386                         core_id, skl->cores.state[core_id],
387                         skl->cores.usage_count[core_id]);
388
389         return ret;
390 }
391 EXPORT_SYMBOL_GPL(skl_dsp_put_core);
392
393 int skl_dsp_wake(struct sst_dsp *ctx)
394 {
395         return skl_dsp_get_core(ctx, SKL_DSP_CORE0_ID);
396 }
397 EXPORT_SYMBOL_GPL(skl_dsp_wake);
398
399 int skl_dsp_sleep(struct sst_dsp *ctx)
400 {
401         return skl_dsp_put_core(ctx, SKL_DSP_CORE0_ID);
402 }
403 EXPORT_SYMBOL_GPL(skl_dsp_sleep);
404
405 struct sst_dsp *skl_dsp_ctx_init(struct device *dev,
406                 struct sst_dsp_device *sst_dev, int irq)
407 {
408         int ret;
409         struct sst_dsp *sst;
410
411         sst = devm_kzalloc(dev, sizeof(*sst), GFP_KERNEL);
412         if (sst == NULL)
413                 return NULL;
414
415         spin_lock_init(&sst->spinlock);
416         mutex_init(&sst->mutex);
417         sst->dev = dev;
418         sst->sst_dev = sst_dev;
419         sst->irq = irq;
420         sst->ops = sst_dev->ops;
421         sst->thread_context = sst_dev->thread_context;
422
423         /* Initialise SST Audio DSP */
424         if (sst->ops->init) {
425                 ret = sst->ops->init(sst, NULL);
426                 if (ret < 0)
427                         return NULL;
428         }
429
430         return sst;
431 }
432
433 int skl_dsp_acquire_irq(struct sst_dsp *sst)
434 {
435         struct sst_dsp_device *sst_dev = sst->sst_dev;
436         int ret;
437
438         /* Register the ISR */
439         ret = request_threaded_irq(sst->irq, sst->ops->irq_handler,
440                 sst_dev->thread, IRQF_SHARED, "AudioDSP", sst);
441         if (ret)
442                 dev_err(sst->dev, "unable to grab threaded IRQ %d, disabling device\n",
443                                sst->irq);
444
445         return ret;
446 }
447
448 void skl_dsp_free(struct sst_dsp *dsp)
449 {
450         skl_ipc_int_disable(dsp);
451
452         free_irq(dsp->irq, dsp);
453         skl_ipc_op_int_disable(dsp);
454         skl_dsp_disable_core(dsp, SKL_DSP_CORE0_MASK);
455 }
456 EXPORT_SYMBOL_GPL(skl_dsp_free);
457
458 bool is_skl_dsp_running(struct sst_dsp *ctx)
459 {
460         return (ctx->sst_state == SKL_DSP_RUNNING);
461 }
462 EXPORT_SYMBOL_GPL(is_skl_dsp_running);