Lines Matching +full:use +full:- +full:iram
1 // SPDX-License-Identifier: GPL-2.0-only
3 * sst.c - Intel SST Driver for audio engine
5 * Copyright (C) 2008-14 Intel Corp
28 #include "../sst-mfld-platform.h"
57 isr.full = sst_shim_read64(drv->shim, SST_ISRX); in intel_sst_interrupt_mrfld()
61 spin_lock(&drv->ipc_spin_lock); in intel_sst_interrupt_mrfld()
62 header.full = sst_shim_read64(drv->shim, in intel_sst_interrupt_mrfld()
63 drv->ipc_reg.ipcx); in intel_sst_interrupt_mrfld()
65 sst_shim_write64(drv->shim, drv->ipc_reg.ipcx, header.full); in intel_sst_interrupt_mrfld()
69 sst_shim_write64(drv->shim, SST_ISRX, isr.full); in intel_sst_interrupt_mrfld()
70 spin_unlock(&drv->ipc_spin_lock); in intel_sst_interrupt_mrfld()
73 queue_work(drv->post_msg_wq, &drv->ipc_post_msg_wq); in intel_sst_interrupt_mrfld()
79 spin_lock(&drv->ipc_spin_lock); in intel_sst_interrupt_mrfld()
80 imr.full = sst_shim_read64(drv->shim, SST_IMRX); in intel_sst_interrupt_mrfld()
82 sst_shim_write64(drv->shim, SST_IMRX, imr.full); in intel_sst_interrupt_mrfld()
83 spin_unlock(&drv->ipc_spin_lock); in intel_sst_interrupt_mrfld()
84 header.full = sst_shim_read64(drv->shim, drv->ipc_reg.ipcd); in intel_sst_interrupt_mrfld()
87 drv->ops->clear_interrupt(drv); in intel_sst_interrupt_mrfld()
94 memcpy_fromio(msg->mailbox_data, in intel_sst_interrupt_mrfld()
95 drv->mailbox + drv->mailbox_recv_offset, size); in intel_sst_interrupt_mrfld()
97 dev_err(drv->dev, in intel_sst_interrupt_mrfld()
103 msg->mrfld_header = header; in intel_sst_interrupt_mrfld()
104 msg->is_process_reply = in intel_sst_interrupt_mrfld()
106 spin_lock(&drv->rx_msg_lock); in intel_sst_interrupt_mrfld()
107 list_add_tail(&msg->node, &drv->rx_list); in intel_sst_interrupt_mrfld()
108 spin_unlock(&drv->rx_msg_lock); in intel_sst_interrupt_mrfld()
109 drv->ops->clear_interrupt(drv); in intel_sst_interrupt_mrfld()
121 spin_lock_irqsave(&drv->rx_msg_lock, irq_flags); in intel_sst_irq_thread_mrfld()
122 if (list_empty(&drv->rx_list)) { in intel_sst_irq_thread_mrfld()
123 spin_unlock_irqrestore(&drv->rx_msg_lock, irq_flags); in intel_sst_irq_thread_mrfld()
127 list_for_each_entry_safe(msg, __msg, &drv->rx_list, node) { in intel_sst_irq_thread_mrfld()
128 list_del(&msg->node); in intel_sst_irq_thread_mrfld()
129 spin_unlock_irqrestore(&drv->rx_msg_lock, irq_flags); in intel_sst_irq_thread_mrfld()
130 if (msg->is_process_reply) in intel_sst_irq_thread_mrfld()
131 drv->ops->process_message(msg); in intel_sst_irq_thread_mrfld()
133 drv->ops->process_reply(drv, msg); in intel_sst_irq_thread_mrfld()
135 if (msg->is_large) in intel_sst_irq_thread_mrfld()
136 kfree(msg->mailbox_data); in intel_sst_irq_thread_mrfld()
138 spin_lock_irqsave(&drv->rx_msg_lock, irq_flags); in intel_sst_irq_thread_mrfld()
140 spin_unlock_irqrestore(&drv->rx_msg_lock, irq_flags); in intel_sst_irq_thread_mrfld()
153 dev_err(sst->dev, "not suspending FW!!, Err: %d\n", ret); in sst_save_dsp_context_v2()
154 return -EIO; in sst_save_dsp_context_v2()
177 switch (sst->dev_id) { in sst_driver_ops()
181 sst->tstamp = SST_TIME_STAMP_MRFLD; in sst_driver_ops()
182 sst->ops = &mrfld_ops; in sst_driver_ops()
186 dev_err(sst->dev, in sst_driver_ops()
188 sst->dev_id); in sst_driver_ops()
189 return -EINVAL; in sst_driver_ops()
198 ctx->ops->post_message(ctx, NULL, false); in sst_process_pending_msg()
203 INIT_LIST_HEAD(&ctx->memcpy_list); in sst_workqueue_init()
204 INIT_LIST_HEAD(&ctx->rx_list); in sst_workqueue_init()
205 INIT_LIST_HEAD(&ctx->ipc_dispatch_list); in sst_workqueue_init()
206 INIT_LIST_HEAD(&ctx->block_list); in sst_workqueue_init()
207 INIT_WORK(&ctx->ipc_post_msg_wq, sst_process_pending_msg); in sst_workqueue_init()
208 init_waitqueue_head(&ctx->wait_queue); in sst_workqueue_init()
210 ctx->post_msg_wq = in sst_workqueue_init()
212 if (!ctx->post_msg_wq) in sst_workqueue_init()
213 return -EBUSY; in sst_workqueue_init()
219 mutex_init(&ctx->sst_lock); in sst_init_locks()
220 spin_lock_init(&ctx->rx_msg_lock); in sst_init_locks()
221 spin_lock_init(&ctx->ipc_spin_lock); in sst_init_locks()
222 spin_lock_init(&ctx->block_lock); in sst_init_locks()
226 * Driver handles PCI IDs in ACPI - sst_acpi_probe() - and we are using only
235 return -ENOMEM; in sst_alloc_drv_context()
237 (*ctx)->dev = dev; in sst_alloc_drv_context()
238 (*ctx)->dev_id = dev_id; in sst_alloc_drv_context()
249 if (ctx->fw_version.type == 0 && ctx->fw_version.major == 0 && in firmware_version_show()
250 ctx->fw_version.minor == 0 && ctx->fw_version.build == 0) in firmware_version_show()
254 ctx->fw_version.type, ctx->fw_version.major, in firmware_version_show()
255 ctx->fw_version.minor, ctx->fw_version.build); in firmware_version_show()
274 if (!ctx->pdata) in sst_context_init()
275 return -EINVAL; in sst_context_init()
277 if (!ctx->pdata->probe_data) in sst_context_init()
278 return -EINVAL; in sst_context_init()
280 memcpy(&ctx->info, ctx->pdata->probe_data, sizeof(ctx->info)); in sst_context_init()
284 return -EINVAL; in sst_context_init()
290 ctx->pvt_id = 1; in sst_context_init()
291 ctx->stream_cnt = 0; in sst_context_init()
292 ctx->fw_in_mem = NULL; in sst_context_init()
293 /* we use memcpy, so set to 0 */ in sst_context_init()
294 ctx->use_dma = 0; in sst_context_init()
295 ctx->use_lli = 0; in sst_context_init()
298 return -EINVAL; in sst_context_init()
300 ctx->mailbox_recv_offset = ctx->pdata->ipc_info->mbox_recv_off; in sst_context_init()
301 ctx->ipc_reg.ipcx = SST_IPCX + ctx->pdata->ipc_info->ipc_offset; in sst_context_init()
302 ctx->ipc_reg.ipcd = SST_IPCD + ctx->pdata->ipc_info->ipc_offset; in sst_context_init()
304 dev_info(ctx->dev, "Got drv data max stream %d\n", in sst_context_init()
305 ctx->info.max_streams); in sst_context_init()
307 for (i = 1; i <= ctx->info.max_streams; i++) { in sst_context_init()
308 struct stream_info *stream = &ctx->streams[i]; in sst_context_init()
311 stream->pipe_id = PIPE_RSVD; in sst_context_init()
312 mutex_init(&stream->lock); in sst_context_init()
316 ret = devm_request_threaded_irq(ctx->dev, ctx->irq_num, ctx->ops->interrupt, in sst_context_init()
317 ctx->ops->irq_thread, 0, SST_DRV_NAME, in sst_context_init()
322 dev_dbg(ctx->dev, "Registered IRQ %#x\n", ctx->irq_num); in sst_context_init()
325 sst_shim_write64(ctx->shim, SST_IMRX, 0xFFFF0038); in sst_context_init()
327 ctx->qos = devm_kzalloc(ctx->dev, in sst_context_init()
329 if (!ctx->qos) { in sst_context_init()
330 ret = -ENOMEM; in sst_context_init()
333 cpu_latency_qos_add_request(ctx->qos, PM_QOS_DEFAULT_VALUE); in sst_context_init()
335 dev_dbg(ctx->dev, "Requesting FW %s now...\n", ctx->firmware_name); in sst_context_init()
336 ret = request_firmware_nowait(THIS_MODULE, true, ctx->firmware_name, in sst_context_init()
337 ctx->dev, GFP_KERNEL, ctx, sst_firmware_load_cb); in sst_context_init()
339 dev_err(ctx->dev, "Firmware download failed:%d\n", ret); in sst_context_init()
343 ret = sysfs_create_group(&ctx->dev->kobj, in sst_context_init()
346 dev_err(ctx->dev, in sst_context_init()
351 sst_register(ctx->dev); in sst_context_init()
354 sysfs_remove_group(&ctx->dev->kobj, &sst_fw_version_attr_group); in sst_context_init()
357 destroy_workqueue(ctx->post_msg_wq); in sst_context_init()
364 pm_runtime_get_noresume(ctx->dev); in sst_context_cleanup()
365 pm_runtime_disable(ctx->dev); in sst_context_cleanup()
366 sst_unregister(ctx->dev); in sst_context_cleanup()
368 sysfs_remove_group(&ctx->dev->kobj, &sst_fw_version_attr_group); in sst_context_cleanup()
369 destroy_workqueue(ctx->post_msg_wq); in sst_context_cleanup()
370 cpu_latency_qos_remove_request(ctx->qos); in sst_context_cleanup()
371 kfree(ctx->fw_sg_list.src); in sst_context_cleanup()
372 kfree(ctx->fw_sg_list.dst); in sst_context_cleanup()
373 ctx->fw_sg_list.list_len = 0; in sst_context_cleanup()
374 kfree(ctx->fw_in_mem); in sst_context_cleanup()
375 ctx->fw_in_mem = NULL; in sst_context_cleanup()
382 pm_runtime_set_autosuspend_delay(ctx->dev, SST_SUSPEND_DELAY); in sst_configure_runtime_pm()
383 pm_runtime_use_autosuspend(ctx->dev); in sst_configure_runtime_pm()
391 pm_runtime_set_active(ctx->dev); in sst_configure_runtime_pm()
393 pm_runtime_enable(ctx->dev); in sst_configure_runtime_pm()
396 pm_runtime_set_active(ctx->dev); in sst_configure_runtime_pm()
398 pm_runtime_put_noidle(ctx->dev); in sst_configure_runtime_pm()
407 if (ctx->sst_state == SST_RESET) { in intel_sst_runtime_suspend()
412 if (ctx->ops->save_dsp_context(ctx)) in intel_sst_runtime_suspend()
413 return -EBUSY; in intel_sst_runtime_suspend()
418 synchronize_irq(ctx->irq_num); in intel_sst_runtime_suspend()
419 flush_workqueue(ctx->post_msg_wq); in intel_sst_runtime_suspend()
421 ctx->ops->reset(ctx); in intel_sst_runtime_suspend()
433 if (ctx->sst_state == SST_RESET) in intel_sst_suspend()
440 for (i = 1; i <= ctx->info.max_streams; i++) { in intel_sst_suspend()
441 struct stream_info *stream = &ctx->streams[i]; in intel_sst_suspend()
443 if (stream->status == STREAM_RUNNING) { in intel_sst_suspend()
445 return -EBUSY; in intel_sst_suspend()
448 if (ctx->pdata->streams_lost_on_suspend) { in intel_sst_suspend()
449 stream->resume_status = stream->status; in intel_sst_suspend()
450 stream->resume_prev = stream->prev; in intel_sst_suspend()
451 if (stream->status != STREAM_UN_INIT) in intel_sst_suspend()
455 synchronize_irq(ctx->irq_num); in intel_sst_suspend()
456 flush_workqueue(ctx->post_msg_wq); in intel_sst_suspend()
462 if (ctx->ops->save_dsp_context(ctx)) in intel_sst_suspend()
463 return -EBUSY; in intel_sst_suspend()
468 return -ENOMEM; in intel_sst_suspend()
469 fw_save->iram = kvzalloc(ctx->iram_end - ctx->iram_base, GFP_KERNEL); in intel_sst_suspend()
470 if (!fw_save->iram) { in intel_sst_suspend()
471 ret = -ENOMEM; in intel_sst_suspend()
472 goto iram; in intel_sst_suspend()
474 fw_save->dram = kvzalloc(ctx->dram_end - ctx->dram_base, GFP_KERNEL); in intel_sst_suspend()
475 if (!fw_save->dram) { in intel_sst_suspend()
476 ret = -ENOMEM; in intel_sst_suspend()
479 fw_save->sram = kvzalloc(SST_MAILBOX_SIZE, GFP_KERNEL); in intel_sst_suspend()
480 if (!fw_save->sram) { in intel_sst_suspend()
481 ret = -ENOMEM; in intel_sst_suspend()
485 fw_save->ddr = kvzalloc(ctx->ddr_end - ctx->ddr_base, GFP_KERNEL); in intel_sst_suspend()
486 if (!fw_save->ddr) { in intel_sst_suspend()
487 ret = -ENOMEM; in intel_sst_suspend()
491 memcpy32_fromio(fw_save->iram, ctx->iram, ctx->iram_end - ctx->iram_base); in intel_sst_suspend()
492 memcpy32_fromio(fw_save->dram, ctx->dram, ctx->dram_end - ctx->dram_base); in intel_sst_suspend()
493 memcpy32_fromio(fw_save->sram, ctx->mailbox, SST_MAILBOX_SIZE); in intel_sst_suspend()
494 memcpy32_fromio(fw_save->ddr, ctx->ddr, ctx->ddr_end - ctx->ddr_base); in intel_sst_suspend()
496 ctx->fw_save = fw_save; in intel_sst_suspend()
497 ctx->ops->reset(ctx); in intel_sst_suspend()
500 kvfree(fw_save->sram); in intel_sst_suspend()
502 kvfree(fw_save->dram); in intel_sst_suspend()
504 kvfree(fw_save->iram); in intel_sst_suspend()
505 iram: in intel_sst_suspend()
513 struct sst_fw_save *fw_save = ctx->fw_save; in intel_sst_resume()
523 ctx->ops->reset(ctx); in intel_sst_resume()
525 ctx->fw_save = NULL; in intel_sst_resume()
527 memcpy32_toio(ctx->iram, fw_save->iram, ctx->iram_end - ctx->iram_base); in intel_sst_resume()
528 memcpy32_toio(ctx->dram, fw_save->dram, ctx->dram_end - ctx->dram_base); in intel_sst_resume()
529 memcpy32_toio(ctx->mailbox, fw_save->sram, SST_MAILBOX_SIZE); in intel_sst_resume()
530 memcpy32_toio(ctx->ddr, fw_save->ddr, ctx->ddr_end - ctx->ddr_base); in intel_sst_resume()
532 kvfree(fw_save->sram); in intel_sst_resume()
533 kvfree(fw_save->dram); in intel_sst_resume()
534 kvfree(fw_save->iram); in intel_sst_resume()
535 kvfree(fw_save->ddr); in intel_sst_resume()
540 return -ENOMEM; in intel_sst_resume()
544 ctx->ops->start(ctx); in intel_sst_resume()
547 dev_err(ctx->dev, "fw download failed %d\n", ret); in intel_sst_resume()
549 ret = -EBUSY; in intel_sst_resume()
555 if (ctx->pdata->streams_lost_on_suspend) { in intel_sst_resume()
556 for (i = 1; i <= ctx->info.max_streams; i++) { in intel_sst_resume()
557 struct stream_info *stream = &ctx->streams[i]; in intel_sst_resume()
559 if (stream->resume_status != STREAM_UN_INIT) { in intel_sst_resume()
560 dev_dbg(ctx->dev, "Re-allocing stream %d status %d prev %d\n", in intel_sst_resume()
561 i, stream->resume_status, in intel_sst_resume()
562 stream->resume_prev); in intel_sst_resume()
564 stream->status = stream->resume_status; in intel_sst_resume()
565 stream->prev = stream->resume_prev; in intel_sst_resume()