1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * bxt-sst.c - DSP library functions for BXT platform 4 * 5 * Copyright (C) 2015-16 Intel Corp 6 * Author:Rafal Redzimski <rafal.f.redzimski@intel.com> 7 * Jeeja KP <jeeja.kp@intel.com> 8 */ 9 10 #include <linux/module.h> 11 #include <linux/delay.h> 12 #include <linux/firmware.h> 13 #include <linux/device.h> 14 15 #include "../common/sst-dsp.h" 16 #include "../common/sst-dsp-priv.h" 17 #include "skl.h" 18 19 #define BXT_BASEFW_TIMEOUT 3000 20 #define BXT_INIT_TIMEOUT 300 21 #define BXT_ROM_INIT_TIMEOUT 70 22 #define BXT_IPC_PURGE_FW 0x01004000 23 24 #define BXT_ROM_INIT 0x5 25 #define BXT_ADSP_SRAM0_BASE 0x80000 26 27 /* Firmware status window */ 28 #define BXT_ADSP_FW_STATUS BXT_ADSP_SRAM0_BASE 29 #define BXT_ADSP_ERROR_CODE (BXT_ADSP_FW_STATUS + 0x4) 30 31 #define BXT_ADSP_SRAM1_BASE 0xA0000 32 33 #define BXT_INSTANCE_ID 0 34 #define BXT_BASE_FW_MODULE_ID 0 35 36 #define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000 37 38 /* Delay before scheduling D0i3 entry */ 39 #define BXT_D0I3_DELAY 5000 40 41 #define BXT_FW_ROM_INIT_RETRY 3 42 43 static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) 44 { 45 return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE); 46 } 47 48 static int 49 bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count) 50 { 51 struct snd_dma_buffer dmab; 52 struct skl_dev *skl = ctx->thread_context; 53 struct firmware stripped_fw; 54 int ret = 0, i, dma_id, stream_tag; 55 56 /* library indices start from 1 to N. 0 represents base FW */ 57 for (i = 1; i < lib_count; i++) { 58 ret = skl_prepare_lib_load(skl, &skl->lib_info[i], &stripped_fw, 59 BXT_ADSP_FW_BIN_HDR_OFFSET, i); 60 if (ret < 0) 61 goto load_library_failed; 62 63 stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, 64 stripped_fw.size, &dmab); 65 if (stream_tag <= 0) { 66 dev_err(ctx->dev, "Lib prepare DMA err: %x\n", 67 stream_tag); 68 ret = stream_tag; 69 goto load_library_failed; 70 } 71 72 dma_id = stream_tag - 1; 73 memcpy(dmab.area, stripped_fw.data, stripped_fw.size); 74 75 ctx->dsp_ops.trigger(ctx->dev, true, stream_tag); 76 ret = skl_sst_ipc_load_library(&skl->ipc, dma_id, i, true); 77 if (ret < 0) 78 dev_err(ctx->dev, "IPC Load Lib for %s fail: %d\n", 79 linfo[i].name, ret); 80 81 ctx->dsp_ops.trigger(ctx->dev, false, stream_tag); 82 ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag); 83 } 84 85 return ret; 86 87 load_library_failed: 88 skl_release_library(linfo, lib_count); 89 return ret; 90 } 91 92 /* 93 * First boot sequence has some extra steps. Core 0 waits for power 94 * status on core 1, so power up core 1 also momentarily, keep it in 95 * reset/stall and then turn it off 96 */ 97 static int sst_bxt_prepare_fw(struct sst_dsp *ctx, 98 const void *fwdata, u32 fwsize) 99 { 100 int stream_tag, ret; 101 102 stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, fwsize, &ctx->dmab); 103 if (stream_tag <= 0) { 104 dev_err(ctx->dev, "Failed to prepare DMA FW loading err: %x\n", 105 stream_tag); 106 return stream_tag; 107 } 108 109 ctx->dsp_ops.stream_tag = stream_tag; 110 memcpy(ctx->dmab.area, fwdata, fwsize); 111 112 /* Step 1: Power up core 0 and core1 */ 113 ret = skl_dsp_core_power_up(ctx, SKL_DSP_CORE0_MASK | 114 SKL_DSP_CORE_MASK(1)); 115 if (ret < 0) { 116 dev_err(ctx->dev, "dsp core0/1 power up failed\n"); 117 goto base_fw_load_failed; 118 } 119 120 /* Step 2: Purge FW request */ 121 sst_dsp_shim_write(ctx, SKL_ADSP_REG_HIPCI, SKL_ADSP_REG_HIPCI_BUSY | 122 (BXT_IPC_PURGE_FW | ((stream_tag - 1) << 9))); 123 124 /* Step 3: Unset core0 reset state & unstall/run core0 */ 125 ret = skl_dsp_start_core(ctx, SKL_DSP_CORE0_MASK); 126 if (ret < 0) { 127 dev_err(ctx->dev, "Start dsp core failed ret: %d\n", ret); 128 ret = -EIO; 129 goto base_fw_load_failed; 130 } 131 132 /* Step 4: Wait for DONE Bit */ 133 ret = sst_dsp_register_poll(ctx, SKL_ADSP_REG_HIPCIE, 134 SKL_ADSP_REG_HIPCIE_DONE, 135 SKL_ADSP_REG_HIPCIE_DONE, 136 BXT_INIT_TIMEOUT, "HIPCIE Done"); 137 if (ret < 0) { 138 dev_err(ctx->dev, "Timeout for Purge Request%d\n", ret); 139 goto base_fw_load_failed; 140 } 141 142 /* Step 5: power down core1 */ 143 ret = skl_dsp_core_power_down(ctx, SKL_DSP_CORE_MASK(1)); 144 if (ret < 0) { 145 dev_err(ctx->dev, "dsp core1 power down failed\n"); 146 goto base_fw_load_failed; 147 } 148 149 /* Step 6: Enable Interrupt */ 150 skl_ipc_int_enable(ctx); 151 skl_ipc_op_int_enable(ctx); 152 153 /* Step 7: Wait for ROM init */ 154 ret = sst_dsp_register_poll(ctx, BXT_ADSP_FW_STATUS, SKL_FW_STS_MASK, 155 SKL_FW_INIT, BXT_ROM_INIT_TIMEOUT, "ROM Load"); 156 if (ret < 0) { 157 dev_err(ctx->dev, "Timeout for ROM init, ret:%d\n", ret); 158 goto base_fw_load_failed; 159 } 160 161 return ret; 162 163 base_fw_load_failed: 164 ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, stream_tag); 165 skl_dsp_core_power_down(ctx, SKL_DSP_CORE_MASK(1)); 166 skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); 167 return ret; 168 } 169 170 static int sst_transfer_fw_host_dma(struct sst_dsp *ctx) 171 { 172 int ret; 173 174 ctx->dsp_ops.trigger(ctx->dev, true, ctx->dsp_ops.stream_tag); 175 ret = sst_dsp_register_poll(ctx, BXT_ADSP_FW_STATUS, SKL_FW_STS_MASK, 176 BXT_ROM_INIT, BXT_BASEFW_TIMEOUT, "Firmware boot"); 177 178 ctx->dsp_ops.trigger(ctx->dev, false, ctx->dsp_ops.stream_tag); 179 ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, ctx->dsp_ops.stream_tag); 180 181 return ret; 182 } 183 184 static int bxt_load_base_firmware(struct sst_dsp *ctx) 185 { 186 struct firmware stripped_fw; 187 struct skl_dev *skl = ctx->thread_context; 188 int ret, i; 189 190 if (ctx->fw == NULL) { 191 ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev); 192 if (ret < 0) { 193 dev_err(ctx->dev, "Request firmware failed %d\n", ret); 194 return ret; 195 } 196 } 197 198 /* prase uuids on first boot */ 199 if (skl->is_first_boot) { 200 ret = snd_skl_parse_uuids(ctx, ctx->fw, BXT_ADSP_FW_BIN_HDR_OFFSET, 0); 201 if (ret < 0) 202 goto sst_load_base_firmware_failed; 203 } 204 205 stripped_fw.data = ctx->fw->data; 206 stripped_fw.size = ctx->fw->size; 207 skl_dsp_strip_extended_manifest(&stripped_fw); 208 209 210 for (i = 0; i < BXT_FW_ROM_INIT_RETRY; i++) { 211 ret = sst_bxt_prepare_fw(ctx, stripped_fw.data, stripped_fw.size); 212 if (ret == 0) 213 break; 214 } 215 216 if (ret < 0) { 217 dev_err(ctx->dev, "Error code=0x%x: FW status=0x%x\n", 218 sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE), 219 sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS)); 220 221 dev_err(ctx->dev, "Core En/ROM load fail:%d\n", ret); 222 goto sst_load_base_firmware_failed; 223 } 224 225 ret = sst_transfer_fw_host_dma(ctx); 226 if (ret < 0) { 227 dev_err(ctx->dev, "Transfer firmware failed %d\n", ret); 228 dev_info(ctx->dev, "Error code=0x%x: FW status=0x%x\n", 229 sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE), 230 sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS)); 231 232 skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); 233 } else { 234 dev_dbg(ctx->dev, "Firmware download successful\n"); 235 ret = wait_event_timeout(skl->boot_wait, skl->boot_complete, 236 msecs_to_jiffies(SKL_IPC_BOOT_MSECS)); 237 if (ret == 0) { 238 dev_err(ctx->dev, "DSP boot fail, FW Ready timeout\n"); 239 skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); 240 ret = -EIO; 241 } else { 242 ret = 0; 243 skl->fw_loaded = true; 244 } 245 } 246 247 return ret; 248 249 sst_load_base_firmware_failed: 250 release_firmware(ctx->fw); 251 ctx->fw = NULL; 252 return ret; 253 } 254 255 /* 256 * Decide the D0i3 state that can be targeted based on the usecase 257 * ref counts and DSP state 258 * 259 * Decision Matrix: (X= dont care; state = target state) 260 * 261 * DSP state != SKL_DSP_RUNNING ; state = no d0i3 262 * 263 * DSP state == SKL_DSP_RUNNING , the following matrix applies 264 * non_d0i3 >0; streaming =X; non_streaming =X; state = no d0i3 265 * non_d0i3 =X; streaming =0; non_streaming =0; state = no d0i3 266 * non_d0i3 =0; streaming >0; non_streaming =X; state = streaming d0i3 267 * non_d0i3 =0; streaming =0; non_streaming =X; state = non-streaming d0i3 268 */ 269 static int bxt_d0i3_target_state(struct sst_dsp *ctx) 270 { 271 struct skl_dev *skl = ctx->thread_context; 272 struct skl_d0i3_data *d0i3 = &skl->d0i3; 273 274 if (skl->cores.state[SKL_DSP_CORE0_ID] != SKL_DSP_RUNNING) 275 return SKL_DSP_D0I3_NONE; 276 277 if (d0i3->non_d0i3) 278 return SKL_DSP_D0I3_NONE; 279 else if (d0i3->streaming) 280 return SKL_DSP_D0I3_STREAMING; 281 else if (d0i3->non_streaming) 282 return SKL_DSP_D0I3_NON_STREAMING; 283 else 284 return SKL_DSP_D0I3_NONE; 285 } 286 287 static void bxt_set_dsp_D0i3(struct work_struct *work) 288 { 289 int ret; 290 struct skl_ipc_d0ix_msg msg; 291 struct skl_dev *skl = container_of(work, 292 struct skl_dev, d0i3.work.work); 293 struct sst_dsp *ctx = skl->dsp; 294 struct skl_d0i3_data *d0i3 = &skl->d0i3; 295 int target_state; 296 297 dev_dbg(ctx->dev, "In %s:\n", __func__); 298 299 /* D0i3 entry allowed only if core 0 alone is running */ 300 if (skl_dsp_get_enabled_cores(ctx) != SKL_DSP_CORE0_MASK) { 301 dev_warn(ctx->dev, 302 "D0i3 allowed when only core0 running:Exit\n"); 303 return; 304 } 305 306 target_state = bxt_d0i3_target_state(ctx); 307 if (target_state == SKL_DSP_D0I3_NONE) 308 return; 309 310 msg.instance_id = 0; 311 msg.module_id = 0; 312 msg.wake = 1; 313 msg.streaming = 0; 314 if (target_state == SKL_DSP_D0I3_STREAMING) 315 msg.streaming = 1; 316 317 ret = skl_ipc_set_d0ix(&skl->ipc, &msg); 318 319 if (ret < 0) { 320 dev_err(ctx->dev, "Failed to set DSP to D0i3 state\n"); 321 return; 322 } 323 324 /* Set Vendor specific register D0I3C.I3 to enable D0i3*/ 325 if (skl->update_d0i3c) 326 skl->update_d0i3c(skl->dev, true); 327 328 d0i3->state = target_state; 329 skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING_D0I3; 330 } 331 332 static int bxt_schedule_dsp_D0i3(struct sst_dsp *ctx) 333 { 334 struct skl_dev *skl = ctx->thread_context; 335 struct skl_d0i3_data *d0i3 = &skl->d0i3; 336 337 /* Schedule D0i3 only if the usecase ref counts are appropriate */ 338 if (bxt_d0i3_target_state(ctx) != SKL_DSP_D0I3_NONE) { 339 340 dev_dbg(ctx->dev, "%s: Schedule D0i3\n", __func__); 341 342 schedule_delayed_work(&d0i3->work, 343 msecs_to_jiffies(BXT_D0I3_DELAY)); 344 } 345 346 return 0; 347 } 348 349 static int bxt_set_dsp_D0i0(struct sst_dsp *ctx) 350 { 351 int ret; 352 struct skl_ipc_d0ix_msg msg; 353 struct skl_dev *skl = ctx->thread_context; 354 355 dev_dbg(ctx->dev, "In %s:\n", __func__); 356 357 /* First Cancel any pending attempt to put DSP to D0i3 */ 358 cancel_delayed_work_sync(&skl->d0i3.work); 359 360 /* If DSP is currently in D0i3, bring it to D0i0 */ 361 if (skl->cores.state[SKL_DSP_CORE0_ID] != SKL_DSP_RUNNING_D0I3) 362 return 0; 363 364 dev_dbg(ctx->dev, "Set DSP to D0i0\n"); 365 366 msg.instance_id = 0; 367 msg.module_id = 0; 368 msg.streaming = 0; 369 msg.wake = 0; 370 371 if (skl->d0i3.state == SKL_DSP_D0I3_STREAMING) 372 msg.streaming = 1; 373 374 /* Clear Vendor specific register D0I3C.I3 to disable D0i3*/ 375 if (skl->update_d0i3c) 376 skl->update_d0i3c(skl->dev, false); 377 378 ret = skl_ipc_set_d0ix(&skl->ipc, &msg); 379 if (ret < 0) { 380 dev_err(ctx->dev, "Failed to set DSP to D0i0\n"); 381 return ret; 382 } 383 384 skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING; 385 skl->d0i3.state = SKL_DSP_D0I3_NONE; 386 387 return 0; 388 } 389 390 static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) 391 { 392 struct skl_dev *skl = ctx->thread_context; 393 int ret; 394 struct skl_ipc_dxstate_info dx; 395 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); 396 397 if (skl->fw_loaded == false) { 398 skl->boot_complete = false; 399 ret = bxt_load_base_firmware(ctx); 400 if (ret < 0) { 401 dev_err(ctx->dev, "reload fw failed: %d\n", ret); 402 return ret; 403 } 404 405 if (skl->lib_count > 1) { 406 ret = bxt_load_library(ctx, skl->lib_info, 407 skl->lib_count); 408 if (ret < 0) { 409 dev_err(ctx->dev, "reload libs failed: %d\n", ret); 410 return ret; 411 } 412 } 413 skl->cores.state[core_id] = SKL_DSP_RUNNING; 414 return ret; 415 } 416 417 /* If core 0 is being turned on, turn on core 1 as well */ 418 if (core_id == SKL_DSP_CORE0_ID) 419 ret = skl_dsp_core_power_up(ctx, core_mask | 420 SKL_DSP_CORE_MASK(1)); 421 else 422 ret = skl_dsp_core_power_up(ctx, core_mask); 423 424 if (ret < 0) 425 goto err; 426 427 if (core_id == SKL_DSP_CORE0_ID) { 428 429 /* 430 * Enable interrupt after SPA is set and before 431 * DSP is unstalled 432 */ 433 skl_ipc_int_enable(ctx); 434 skl_ipc_op_int_enable(ctx); 435 skl->boot_complete = false; 436 } 437 438 ret = skl_dsp_start_core(ctx, core_mask); 439 if (ret < 0) 440 goto err; 441 442 if (core_id == SKL_DSP_CORE0_ID) { 443 ret = wait_event_timeout(skl->boot_wait, 444 skl->boot_complete, 445 msecs_to_jiffies(SKL_IPC_BOOT_MSECS)); 446 447 /* If core 1 was turned on for booting core 0, turn it off */ 448 skl_dsp_core_power_down(ctx, SKL_DSP_CORE_MASK(1)); 449 if (ret == 0) { 450 dev_err(ctx->dev, "%s: DSP boot timeout\n", __func__); 451 dev_err(ctx->dev, "Error code=0x%x: FW status=0x%x\n", 452 sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE), 453 sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS)); 454 dev_err(ctx->dev, "Failed to set core0 to D0 state\n"); 455 ret = -EIO; 456 goto err; 457 } 458 } 459 460 /* Tell FW if additional core in now On */ 461 462 if (core_id != SKL_DSP_CORE0_ID) { 463 dx.core_mask = core_mask; 464 dx.dx_mask = core_mask; 465 466 ret = skl_ipc_set_dx(&skl->ipc, BXT_INSTANCE_ID, 467 BXT_BASE_FW_MODULE_ID, &dx); 468 if (ret < 0) { 469 dev_err(ctx->dev, "IPC set_dx for core %d fail: %d\n", 470 core_id, ret); 471 goto err; 472 } 473 } 474 475 skl->cores.state[core_id] = SKL_DSP_RUNNING; 476 return 0; 477 err: 478 if (core_id == SKL_DSP_CORE0_ID) 479 core_mask |= SKL_DSP_CORE_MASK(1); 480 skl_dsp_disable_core(ctx, core_mask); 481 482 return ret; 483 } 484 485 static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) 486 { 487 int ret; 488 struct skl_ipc_dxstate_info dx; 489 struct skl_dev *skl = ctx->thread_context; 490 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); 491 492 dx.core_mask = core_mask; 493 dx.dx_mask = SKL_IPC_D3_MASK; 494 495 dev_dbg(ctx->dev, "core mask=%x dx_mask=%x\n", 496 dx.core_mask, dx.dx_mask); 497 498 ret = skl_ipc_set_dx(&skl->ipc, BXT_INSTANCE_ID, 499 BXT_BASE_FW_MODULE_ID, &dx); 500 if (ret < 0) { 501 dev_err(ctx->dev, 502 "Failed to set DSP to D3:core id = %d;Continue reset\n", 503 core_id); 504 /* 505 * In case of D3 failure, re-download the firmware, so set 506 * fw_loaded to false. 507 */ 508 skl->fw_loaded = false; 509 } 510 511 if (core_id == SKL_DSP_CORE0_ID) { 512 /* disable Interrupt */ 513 skl_ipc_op_int_disable(ctx); 514 skl_ipc_int_disable(ctx); 515 } 516 ret = skl_dsp_disable_core(ctx, core_mask); 517 if (ret < 0) { 518 dev_err(ctx->dev, "Failed to disable core %d\n", ret); 519 return ret; 520 } 521 skl->cores.state[core_id] = SKL_DSP_RESET; 522 return 0; 523 } 524 525 static const struct skl_dsp_fw_ops bxt_fw_ops = { 526 .set_state_D0 = bxt_set_dsp_D0, 527 .set_state_D3 = bxt_set_dsp_D3, 528 .set_state_D0i3 = bxt_schedule_dsp_D0i3, 529 .set_state_D0i0 = bxt_set_dsp_D0i0, 530 .load_fw = bxt_load_base_firmware, 531 .get_fw_errcode = bxt_get_errorcode, 532 .load_library = bxt_load_library, 533 }; 534 535 static struct sst_ops skl_ops = { 536 .irq_handler = skl_dsp_sst_interrupt, 537 .write = sst_shim32_write, 538 .read = sst_shim32_read, 539 .ram_read = sst_memcpy_fromio_32, 540 .ram_write = sst_memcpy_toio_32, 541 .free = skl_dsp_free, 542 }; 543 544 static struct sst_dsp_device skl_dev = { 545 .thread = skl_dsp_irq_thread_handler, 546 .ops = &skl_ops, 547 }; 548 549 int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 550 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 551 struct skl_dev **dsp) 552 { 553 struct skl_dev *skl; 554 struct sst_dsp *sst; 555 int ret; 556 557 ret = skl_sst_ctx_init(dev, irq, fw_name, dsp_ops, dsp, &skl_dev); 558 if (ret < 0) { 559 dev_err(dev, "%s: no device\n", __func__); 560 return ret; 561 } 562 563 skl = *dsp; 564 sst = skl->dsp; 565 sst->fw_ops = bxt_fw_ops; 566 sst->addr.lpe = mmio_base; 567 sst->addr.shim = mmio_base; 568 sst->addr.sram0_base = BXT_ADSP_SRAM0_BASE; 569 sst->addr.sram1_base = BXT_ADSP_SRAM1_BASE; 570 sst->addr.w0_stat_sz = SKL_ADSP_W0_STAT_SZ; 571 sst->addr.w0_up_sz = SKL_ADSP_W0_UP_SZ; 572 573 sst_dsp_mailbox_init(sst, (BXT_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), 574 SKL_ADSP_W0_UP_SZ, BXT_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ); 575 576 ret = skl_ipc_init(dev, skl); 577 if (ret) { 578 skl_dsp_free(sst); 579 return ret; 580 } 581 582 /* set the D0i3 check */ 583 skl->ipc.ops.check_dsp_lp_on = skl_ipc_check_D0i0; 584 585 skl->boot_complete = false; 586 init_waitqueue_head(&skl->boot_wait); 587 INIT_DELAYED_WORK(&skl->d0i3.work, bxt_set_dsp_D0i3); 588 skl->d0i3.state = SKL_DSP_D0I3_NONE; 589 590 return skl_dsp_acquire_irq(sst); 591 } 592 EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); 593 594 int bxt_sst_init_fw(struct device *dev, struct skl_dev *skl) 595 { 596 int ret; 597 struct sst_dsp *sst = skl->dsp; 598 599 ret = sst->fw_ops.load_fw(sst); 600 if (ret < 0) { 601 dev_err(dev, "Load base fw failed: %x\n", ret); 602 return ret; 603 } 604 605 skl_dsp_init_core_state(sst); 606 607 if (skl->lib_count > 1) { 608 ret = sst->fw_ops.load_library(sst, skl->lib_info, 609 skl->lib_count); 610 if (ret < 0) { 611 dev_err(dev, "Load Library failed : %x\n", ret); 612 return ret; 613 } 614 } 615 skl->is_first_boot = false; 616 617 return 0; 618 } 619 EXPORT_SYMBOL_GPL(bxt_sst_init_fw); 620 621 void bxt_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl) 622 { 623 624 skl_release_library(skl->lib_info, skl->lib_count); 625 if (skl->dsp->fw) 626 release_firmware(skl->dsp->fw); 627 skl_freeup_uuid_list(skl); 628 skl_ipc_free(&skl->ipc); 629 skl->dsp->ops->free(skl->dsp); 630 } 631 EXPORT_SYMBOL_GPL(bxt_sst_dsp_cleanup); 632 633 MODULE_LICENSE("GPL v2"); 634 MODULE_DESCRIPTION("Intel Broxton IPC driver"); 635