2 * skl-sst-dsp.c - SKL SST library generic function
4 * Copyright (C) 2014-15, Intel Corporation.
5 * Author:Rafal Redzimski <rafal.f.redzimski@intel.com>
6 * Jeeja KP <jeeja.kp@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as version 2, as
11 * published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 #include <sound/pcm.h>
20 #include "../common/sst-dsp.h"
21 #include "../common/sst-ipc.h"
22 #include "../common/sst-dsp-priv.h"
23 #include "skl-sst-ipc.h"
25 /* various timeout values */
26 #define SKL_DSP_PU_TO 50
27 #define SKL_DSP_PD_TO 50
28 #define SKL_DSP_RESET_TO 50
30 void skl_dsp_set_state_locked(struct sst_dsp
*ctx
, int state
)
32 mutex_lock(&ctx
->mutex
);
33 ctx
->sst_state
= state
;
34 mutex_unlock(&ctx
->mutex
);
37 static int skl_dsp_core_set_reset_state(struct sst_dsp
*ctx
)
42 sst_dsp_shim_update_bits_unlocked(ctx
,
43 SKL_ADSP_REG_ADSPCS
, SKL_ADSPCS_CRST_MASK
,
44 SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK
));
46 /* poll with timeout to check if operation successful */
47 ret
= sst_dsp_register_poll(ctx
,
50 SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK
),
53 if ((sst_dsp_shim_read_unlocked(ctx
, SKL_ADSP_REG_ADSPCS
) &
54 SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK
)) !=
55 SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK
)) {
56 dev_err(ctx
->dev
, "Set reset state failed\n");
63 static int skl_dsp_core_unset_reset_state(struct sst_dsp
*ctx
)
67 dev_dbg(ctx
->dev
, "In %s\n", __func__
);
70 sst_dsp_shim_update_bits_unlocked(ctx
, SKL_ADSP_REG_ADSPCS
,
71 SKL_ADSPCS_CRST_MASK
, 0);
73 /* poll with timeout to check if operation successful */
74 ret
= sst_dsp_register_poll(ctx
,
81 if ((sst_dsp_shim_read_unlocked(ctx
, SKL_ADSP_REG_ADSPCS
) &
82 SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK
)) != 0) {
83 dev_err(ctx
->dev
, "Unset reset state failed\n");
90 static bool is_skl_dsp_core_enable(struct sst_dsp
*ctx
)
95 val
= sst_dsp_shim_read_unlocked(ctx
, SKL_ADSP_REG_ADSPCS
);
97 is_enable
= ((val
& SKL_ADSPCS_CPA(SKL_DSP_CORES_MASK
)) &&
98 (val
& SKL_ADSPCS_SPA(SKL_DSP_CORES_MASK
)) &&
99 !(val
& SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK
)) &&
100 !(val
& SKL_ADSPCS_CSTALL(SKL_DSP_CORES_MASK
)));
102 dev_dbg(ctx
->dev
, "DSP core is enabled=%d\n", is_enable
);
106 static int skl_dsp_reset_core(struct sst_dsp
*ctx
)
109 sst_dsp_shim_write_unlocked(ctx
, SKL_ADSP_REG_ADSPCS
,
110 sst_dsp_shim_read_unlocked(ctx
, SKL_ADSP_REG_ADSPCS
) &
111 SKL_ADSPCS_CSTALL(SKL_DSP_CORES_MASK
));
113 /* set reset state */
114 return skl_dsp_core_set_reset_state(ctx
);
117 static int skl_dsp_start_core(struct sst_dsp
*ctx
)
121 /* unset reset state */
122 ret
= skl_dsp_core_unset_reset_state(ctx
);
124 dev_dbg(ctx
->dev
, "dsp unset reset fails\n");
129 dev_dbg(ctx
->dev
, "run core...\n");
130 sst_dsp_shim_write_unlocked(ctx
, SKL_ADSP_REG_ADSPCS
,
131 sst_dsp_shim_read_unlocked(ctx
, SKL_ADSP_REG_ADSPCS
) &
132 ~SKL_ADSPCS_CSTALL(SKL_DSP_CORES_MASK
));
134 if (!is_skl_dsp_core_enable(ctx
)) {
135 skl_dsp_reset_core(ctx
);
136 dev_err(ctx
->dev
, "DSP core enable failed\n");
143 static int skl_dsp_core_power_up(struct sst_dsp
*ctx
)
148 sst_dsp_shim_update_bits_unlocked(ctx
, SKL_ADSP_REG_ADSPCS
,
149 SKL_ADSPCS_SPA_MASK
, SKL_ADSPCS_SPA(SKL_DSP_CORES_MASK
));
151 /* poll with timeout to check if operation successful */
152 ret
= sst_dsp_register_poll(ctx
,
155 SKL_ADSPCS_CPA(SKL_DSP_CORES_MASK
),
159 if ((sst_dsp_shim_read_unlocked(ctx
, SKL_ADSP_REG_ADSPCS
) &
160 SKL_ADSPCS_CPA(SKL_DSP_CORES_MASK
)) !=
161 SKL_ADSPCS_CPA(SKL_DSP_CORES_MASK
)) {
162 dev_err(ctx
->dev
, "DSP core power up failed\n");
169 static int skl_dsp_core_power_down(struct sst_dsp
*ctx
)
172 sst_dsp_shim_update_bits_unlocked(ctx
, SKL_ADSP_REG_ADSPCS
,
173 SKL_ADSPCS_SPA_MASK
, 0);
175 /* poll with timeout to check if operation successful */
176 return sst_dsp_register_poll(ctx
,
184 static int skl_dsp_enable_core(struct sst_dsp
*ctx
)
189 ret
= skl_dsp_core_power_up(ctx
);
191 dev_dbg(ctx
->dev
, "dsp core power up failed\n");
195 return skl_dsp_start_core(ctx
);
198 int skl_dsp_disable_core(struct sst_dsp
*ctx
)
202 ret
= skl_dsp_reset_core(ctx
);
204 dev_err(ctx
->dev
, "dsp core reset failed\n");
209 ret
= skl_dsp_core_power_down(ctx
);
211 dev_err(ctx
->dev
, "dsp core power down failed\n");
215 if (is_skl_dsp_core_enable(ctx
)) {
216 dev_err(ctx
->dev
, "DSP core disable failed\n");
223 int skl_dsp_boot(struct sst_dsp
*ctx
)
227 if (is_skl_dsp_core_enable(ctx
)) {
228 dev_dbg(ctx
->dev
, "dsp core is already enabled, so reset the dap core\n");
229 ret
= skl_dsp_reset_core(ctx
);
231 dev_err(ctx
->dev
, "dsp reset failed\n");
235 ret
= skl_dsp_start_core(ctx
);
237 dev_err(ctx
->dev
, "dsp start failed\n");
241 dev_dbg(ctx
->dev
, "disable and enable to make sure DSP is invalid state\n");
242 ret
= skl_dsp_disable_core(ctx
);
245 dev_err(ctx
->dev
, "dsp disable core failes\n");
248 ret
= skl_dsp_enable_core(ctx
);
254 irqreturn_t
skl_dsp_sst_interrupt(int irq
, void *dev_id
)
256 struct sst_dsp
*ctx
= dev_id
;
258 irqreturn_t result
= IRQ_NONE
;
260 spin_lock(&ctx
->spinlock
);
262 val
= sst_dsp_shim_read_unlocked(ctx
, SKL_ADSP_REG_ADSPIS
);
263 ctx
->intr_status
= val
;
265 if (val
== 0xffffffff) {
266 spin_unlock(&ctx
->spinlock
);
270 if (val
& SKL_ADSPIS_IPC
) {
271 skl_ipc_int_disable(ctx
);
272 result
= IRQ_WAKE_THREAD
;
275 if (val
& SKL_ADSPIS_CL_DMA
) {
276 skl_cldma_int_disable(ctx
);
277 result
= IRQ_WAKE_THREAD
;
280 spin_unlock(&ctx
->spinlock
);
285 int skl_dsp_wake(struct sst_dsp
*ctx
)
287 return ctx
->fw_ops
.set_state_D0(ctx
);
289 EXPORT_SYMBOL_GPL(skl_dsp_wake
);
291 int skl_dsp_sleep(struct sst_dsp
*ctx
)
293 return ctx
->fw_ops
.set_state_D3(ctx
);
295 EXPORT_SYMBOL_GPL(skl_dsp_sleep
);
297 struct sst_dsp
*skl_dsp_ctx_init(struct device
*dev
,
298 struct sst_dsp_device
*sst_dev
, int irq
)
303 sst
= devm_kzalloc(dev
, sizeof(*sst
), GFP_KERNEL
);
307 spin_lock_init(&sst
->spinlock
);
308 mutex_init(&sst
->mutex
);
310 sst
->sst_dev
= sst_dev
;
312 sst
->ops
= sst_dev
->ops
;
313 sst
->thread_context
= sst_dev
->thread_context
;
315 /* Initialise SST Audio DSP */
316 if (sst
->ops
->init
) {
317 ret
= sst
->ops
->init(sst
, NULL
);
322 /* Register the ISR */
323 ret
= request_threaded_irq(sst
->irq
, sst
->ops
->irq_handler
,
324 sst_dev
->thread
, IRQF_SHARED
, "AudioDSP", sst
);
326 dev_err(sst
->dev
, "unable to grab threaded IRQ %d, disabling device\n",
334 void skl_dsp_free(struct sst_dsp
*dsp
)
336 skl_ipc_int_disable(dsp
);
338 free_irq(dsp
->irq
, dsp
);
339 skl_dsp_disable_core(dsp
);
341 EXPORT_SYMBOL_GPL(skl_dsp_free
);
343 bool is_skl_dsp_running(struct sst_dsp
*ctx
)
345 return (ctx
->sst_state
== SKL_DSP_RUNNING
);
347 EXPORT_SYMBOL_GPL(is_skl_dsp_running
);