.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * cnl-sst.c - DSP library functions for CNL platform |
---|
3 | 4 | * |
---|
.. | .. |
---|
11 | 12 | * |
---|
12 | 13 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
13 | 14 | * |
---|
14 | | - * This program is free software; you can redistribute it and/or modify |
---|
15 | | - * it under the terms of the GNU General Public License as version 2, as |
---|
16 | | - * published by the Free Software Foundation. |
---|
17 | | - * |
---|
18 | | - * This program is distributed in the hope that it will be useful, but |
---|
19 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
20 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
21 | | - * General Public License for more details. |
---|
22 | | - * |
---|
23 | 15 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
24 | 16 | */ |
---|
25 | 17 | |
---|
.. | .. |
---|
32 | 24 | #include "../common/sst-dsp-priv.h" |
---|
33 | 25 | #include "../common/sst-ipc.h" |
---|
34 | 26 | #include "cnl-sst-dsp.h" |
---|
35 | | -#include "skl-sst-dsp.h" |
---|
36 | | -#include "skl-sst-ipc.h" |
---|
| 27 | +#include "skl.h" |
---|
37 | 28 | |
---|
38 | 29 | #define CNL_FW_ROM_INIT 0x1 |
---|
39 | 30 | #define CNL_FW_INIT 0x5 |
---|
.. | .. |
---|
66 | 57 | ctx->dsp_ops.stream_tag = stream_tag; |
---|
67 | 58 | memcpy(ctx->dmab.area, fwdata, fwsize); |
---|
68 | 59 | |
---|
| 60 | + ret = skl_dsp_core_power_up(ctx, SKL_DSP_CORE0_MASK); |
---|
| 61 | + if (ret < 0) { |
---|
| 62 | + dev_err(ctx->dev, "dsp core0 power up failed\n"); |
---|
| 63 | + ret = -EIO; |
---|
| 64 | + goto base_fw_load_failed; |
---|
| 65 | + } |
---|
| 66 | + |
---|
69 | 67 | /* purge FW request */ |
---|
70 | 68 | sst_dsp_shim_write(ctx, CNL_ADSP_REG_HIPCIDR, |
---|
71 | 69 | CNL_ADSP_REG_HIPCIDR_BUSY | (CNL_IPC_PURGE | |
---|
72 | 70 | ((stream_tag - 1) << CNL_ROM_CTRL_DMA_ID))); |
---|
73 | 71 | |
---|
74 | | - ret = cnl_dsp_enable_core(ctx, SKL_DSP_CORE0_MASK); |
---|
| 72 | + ret = skl_dsp_start_core(ctx, SKL_DSP_CORE0_MASK); |
---|
75 | 73 | if (ret < 0) { |
---|
76 | | - dev_err(ctx->dev, "dsp boot core failed ret: %d\n", ret); |
---|
| 74 | + dev_err(ctx->dev, "Start dsp core failed ret: %d\n", ret); |
---|
77 | 75 | ret = -EIO; |
---|
| 76 | + goto base_fw_load_failed; |
---|
| 77 | + } |
---|
| 78 | + |
---|
| 79 | + ret = sst_dsp_register_poll(ctx, CNL_ADSP_REG_HIPCIDA, |
---|
| 80 | + CNL_ADSP_REG_HIPCIDA_DONE, |
---|
| 81 | + CNL_ADSP_REG_HIPCIDA_DONE, |
---|
| 82 | + BXT_INIT_TIMEOUT, "HIPCIDA Done"); |
---|
| 83 | + if (ret < 0) { |
---|
| 84 | + dev_err(ctx->dev, "timeout for purge request: %d\n", ret); |
---|
78 | 85 | goto base_fw_load_failed; |
---|
79 | 86 | } |
---|
80 | 87 | |
---|
.. | .. |
---|
117 | 124 | static int cnl_load_base_firmware(struct sst_dsp *ctx) |
---|
118 | 125 | { |
---|
119 | 126 | struct firmware stripped_fw; |
---|
120 | | - struct skl_sst *cnl = ctx->thread_context; |
---|
121 | | - int ret; |
---|
| 127 | + struct skl_dev *cnl = ctx->thread_context; |
---|
| 128 | + int ret, i; |
---|
122 | 129 | |
---|
123 | 130 | if (!ctx->fw) { |
---|
124 | 131 | ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev); |
---|
.. | .. |
---|
140 | 147 | stripped_fw.size = ctx->fw->size; |
---|
141 | 148 | skl_dsp_strip_extended_manifest(&stripped_fw); |
---|
142 | 149 | |
---|
143 | | - ret = cnl_prepare_fw(ctx, stripped_fw.data, stripped_fw.size); |
---|
144 | | - if (ret < 0) { |
---|
145 | | - dev_err(ctx->dev, "prepare firmware failed: %d\n", ret); |
---|
146 | | - goto cnl_load_base_firmware_failed; |
---|
| 150 | + for (i = 0; i < BXT_FW_ROM_INIT_RETRY; i++) { |
---|
| 151 | + ret = cnl_prepare_fw(ctx, stripped_fw.data, stripped_fw.size); |
---|
| 152 | + if (!ret) |
---|
| 153 | + break; |
---|
| 154 | + dev_dbg(ctx->dev, "prepare firmware failed: %d\n", ret); |
---|
147 | 155 | } |
---|
| 156 | + |
---|
| 157 | + if (ret < 0) |
---|
| 158 | + goto cnl_load_base_firmware_failed; |
---|
148 | 159 | |
---|
149 | 160 | ret = sst_transfer_fw_host_dma(ctx); |
---|
150 | 161 | if (ret < 0) { |
---|
.. | .. |
---|
167 | 178 | return 0; |
---|
168 | 179 | |
---|
169 | 180 | cnl_load_base_firmware_failed: |
---|
| 181 | + dev_err(ctx->dev, "firmware load failed: %d\n", ret); |
---|
170 | 182 | release_firmware(ctx->fw); |
---|
171 | 183 | ctx->fw = NULL; |
---|
172 | 184 | |
---|
.. | .. |
---|
175 | 187 | |
---|
176 | 188 | static int cnl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) |
---|
177 | 189 | { |
---|
178 | | - struct skl_sst *cnl = ctx->thread_context; |
---|
| 190 | + struct skl_dev *cnl = ctx->thread_context; |
---|
179 | 191 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); |
---|
180 | 192 | struct skl_ipc_dxstate_info dx; |
---|
181 | 193 | int ret; |
---|
.. | .. |
---|
238 | 250 | |
---|
239 | 251 | static int cnl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) |
---|
240 | 252 | { |
---|
241 | | - struct skl_sst *cnl = ctx->thread_context; |
---|
| 253 | + struct skl_dev *cnl = ctx->thread_context; |
---|
242 | 254 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); |
---|
243 | 255 | struct skl_ipc_dxstate_info dx; |
---|
244 | 256 | int ret; |
---|
.. | .. |
---|
289 | 301 | .irq_handler = cnl_dsp_sst_interrupt, |
---|
290 | 302 | .write = sst_shim32_write, |
---|
291 | 303 | .read = sst_shim32_read, |
---|
292 | | - .ram_read = sst_memcpy_fromio_32, |
---|
293 | | - .ram_write = sst_memcpy_toio_32, |
---|
294 | 304 | .free = cnl_dsp_free, |
---|
295 | 305 | }; |
---|
296 | 306 | |
---|
.. | .. |
---|
302 | 312 | static irqreturn_t cnl_dsp_irq_thread_handler(int irq, void *context) |
---|
303 | 313 | { |
---|
304 | 314 | struct sst_dsp *dsp = context; |
---|
305 | | - struct skl_sst *cnl = sst_dsp_get_thread_context(dsp); |
---|
| 315 | + struct skl_dev *cnl = dsp->thread_context; |
---|
306 | 316 | struct sst_generic_ipc *ipc = &cnl->ipc; |
---|
307 | 317 | struct skl_ipc_header header = {0}; |
---|
308 | 318 | u32 hipcida, hipctdr, hipctdd; |
---|
.. | .. |
---|
314 | 324 | |
---|
315 | 325 | hipcida = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCIDA); |
---|
316 | 326 | hipctdr = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCTDR); |
---|
| 327 | + hipctdd = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCTDD); |
---|
317 | 328 | |
---|
318 | 329 | /* reply message from dsp */ |
---|
319 | 330 | if (hipcida & CNL_ADSP_REG_HIPCIDA_DONE) { |
---|
.. | .. |
---|
333 | 344 | |
---|
334 | 345 | /* new message from dsp */ |
---|
335 | 346 | if (hipctdr & CNL_ADSP_REG_HIPCTDR_BUSY) { |
---|
336 | | - hipctdd = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCTDD); |
---|
337 | 347 | header.primary = hipctdr; |
---|
338 | 348 | header.extension = hipctdd; |
---|
339 | 349 | dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x", |
---|
.. | .. |
---|
376 | 386 | |
---|
377 | 387 | static void cnl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) |
---|
378 | 388 | { |
---|
379 | | - struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->header); |
---|
| 389 | + struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->tx.header); |
---|
380 | 390 | |
---|
381 | | - if (msg->tx_size) |
---|
382 | | - sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); |
---|
| 391 | + if (msg->tx.size) |
---|
| 392 | + sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size); |
---|
383 | 393 | sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDD, |
---|
384 | 394 | header->extension); |
---|
385 | 395 | sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDR, |
---|
.. | .. |
---|
395 | 405 | return (hipcidr & CNL_ADSP_REG_HIPCIDR_BUSY); |
---|
396 | 406 | } |
---|
397 | 407 | |
---|
398 | | -static int cnl_ipc_init(struct device *dev, struct skl_sst *cnl) |
---|
| 408 | +static int cnl_ipc_init(struct device *dev, struct skl_dev *cnl) |
---|
399 | 409 | { |
---|
400 | 410 | struct sst_generic_ipc *ipc; |
---|
401 | 411 | int err; |
---|
.. | .. |
---|
424 | 434 | |
---|
425 | 435 | int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, |
---|
426 | 436 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, |
---|
427 | | - struct skl_sst **dsp) |
---|
| 437 | + struct skl_dev **dsp) |
---|
428 | 438 | { |
---|
429 | | - struct skl_sst *cnl; |
---|
| 439 | + struct skl_dev *cnl; |
---|
430 | 440 | struct sst_dsp *sst; |
---|
431 | 441 | int ret; |
---|
432 | 442 | |
---|
.. | .. |
---|
463 | 473 | } |
---|
464 | 474 | EXPORT_SYMBOL_GPL(cnl_sst_dsp_init); |
---|
465 | 475 | |
---|
466 | | -int cnl_sst_init_fw(struct device *dev, struct skl_sst *ctx) |
---|
| 476 | +int cnl_sst_init_fw(struct device *dev, struct skl_dev *skl) |
---|
467 | 477 | { |
---|
468 | 478 | int ret; |
---|
469 | | - struct sst_dsp *sst = ctx->dsp; |
---|
| 479 | + struct sst_dsp *sst = skl->dsp; |
---|
470 | 480 | |
---|
471 | | - ret = ctx->dsp->fw_ops.load_fw(sst); |
---|
| 481 | + ret = skl->dsp->fw_ops.load_fw(sst); |
---|
472 | 482 | if (ret < 0) { |
---|
473 | 483 | dev_err(dev, "load base fw failed: %d", ret); |
---|
474 | 484 | return ret; |
---|
.. | .. |
---|
476 | 486 | |
---|
477 | 487 | skl_dsp_init_core_state(sst); |
---|
478 | 488 | |
---|
479 | | - ctx->is_first_boot = false; |
---|
| 489 | + skl->is_first_boot = false; |
---|
480 | 490 | |
---|
481 | 491 | return 0; |
---|
482 | 492 | } |
---|
483 | 493 | EXPORT_SYMBOL_GPL(cnl_sst_init_fw); |
---|
484 | 494 | |
---|
485 | | -void cnl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) |
---|
| 495 | +void cnl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl) |
---|
486 | 496 | { |
---|
487 | | - if (ctx->dsp->fw) |
---|
488 | | - release_firmware(ctx->dsp->fw); |
---|
| 497 | + if (skl->dsp->fw) |
---|
| 498 | + release_firmware(skl->dsp->fw); |
---|
489 | 499 | |
---|
490 | | - skl_freeup_uuid_list(ctx); |
---|
491 | | - cnl_ipc_free(&ctx->ipc); |
---|
| 500 | + skl_freeup_uuid_list(skl); |
---|
| 501 | + cnl_ipc_free(&skl->ipc); |
---|
492 | 502 | |
---|
493 | | - ctx->dsp->ops->free(ctx->dsp); |
---|
| 503 | + skl->dsp->ops->free(skl->dsp); |
---|
494 | 504 | } |
---|
495 | 505 | EXPORT_SYMBOL_GPL(cnl_sst_dsp_cleanup); |
---|
496 | 506 | |
---|