2 * sst.c - Intel SST Driver for audio engine
4 * Copyright (C) 2008-14 Intel Corp
5 * Authors: Vinod Koul <vinod.koul@intel.com>
6 * Harsha Priya <priya.harsha@intel.com>
7 * Dharageswari R <dharageswari.r@intel.com>
8 * KP Jeeja <jeeja.kp@intel.com>
9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2 of the License.
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22 #include <linux/module.h>
23 #include <linux/pci.h>
25 #include <linux/interrupt.h>
26 #include <linux/firmware.h>
27 #include <linux/pm_runtime.h>
28 #include <linux/pm_qos.h>
29 #include <linux/async.h>
30 #include <linux/delay.h>
31 #include <linux/acpi.h>
32 #include <sound/core.h>
33 #include <sound/pcm.h>
34 #include <sound/soc.h>
35 #include <sound/compress_driver.h>
36 #include <asm/intel-mid.h>
37 #include <asm/platform_sst_audio.h>
38 #include "../sst-mfld-platform.h"
40 #include "../sst-dsp.h"
42 MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
43 MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
44 MODULE_DESCRIPTION("Intel (R) SST(R) Audio Engine Driver");
45 MODULE_LICENSE("GPL v2");
47 static inline bool sst_is_process_reply(u32 msg_id
)
49 return ((msg_id
& PROCESS_MSG
) ? true : false);
52 static inline bool sst_validate_mailbox_size(unsigned int size
)
54 return ((size
<= SST_MAILBOX_SIZE
) ? true : false);
57 static irqreturn_t
intel_sst_interrupt_mrfld(int irq
, void *context
)
59 union interrupt_reg_mrfld isr
;
60 union ipc_header_mrfld header
;
61 union sst_imr_reg_mrfld imr
;
62 struct ipc_post
*msg
= NULL
;
63 unsigned int size
= 0;
64 struct intel_sst_drv
*drv
= (struct intel_sst_drv
*) context
;
65 irqreturn_t retval
= IRQ_HANDLED
;
67 /* Interrupt arrived, check src */
68 isr
.full
= sst_shim_read64(drv
->shim
, SST_ISRX
);
70 if (isr
.part
.done_interrupt
) {
72 spin_lock(&drv
->ipc_spin_lock
);
73 header
.full
= sst_shim_read64(drv
->shim
,
75 header
.p
.header_high
.part
.done
= 0;
76 sst_shim_write64(drv
->shim
, drv
->ipc_reg
.ipcx
, header
.full
);
78 /* write 1 to clear status register */;
79 isr
.part
.done_interrupt
= 1;
80 sst_shim_write64(drv
->shim
, SST_ISRX
, isr
.full
);
81 spin_unlock(&drv
->ipc_spin_lock
);
83 /* we can send more messages to DSP so trigger work */
84 queue_work(drv
->post_msg_wq
, &drv
->ipc_post_msg_wq
);
88 if (isr
.part
.busy_interrupt
) {
89 /* message from dsp so copy that */
90 spin_lock(&drv
->ipc_spin_lock
);
91 imr
.full
= sst_shim_read64(drv
->shim
, SST_IMRX
);
92 imr
.part
.busy_interrupt
= 1;
93 sst_shim_write64(drv
->shim
, SST_IMRX
, imr
.full
);
94 spin_unlock(&drv
->ipc_spin_lock
);
95 header
.full
= sst_shim_read64(drv
->shim
, drv
->ipc_reg
.ipcd
);
97 if (sst_create_ipc_msg(&msg
, header
.p
.header_high
.part
.large
)) {
98 drv
->ops
->clear_interrupt(drv
);
102 if (header
.p
.header_high
.part
.large
) {
103 size
= header
.p
.header_low_payload
;
104 if (sst_validate_mailbox_size(size
)) {
105 memcpy_fromio(msg
->mailbox_data
,
106 drv
->mailbox
+ drv
->mailbox_recv_offset
, size
);
109 "Mailbox not copied, payload size is: %u\n", size
);
110 header
.p
.header_low_payload
= 0;
114 msg
->mrfld_header
= header
;
115 msg
->is_process_reply
=
116 sst_is_process_reply(header
.p
.header_high
.part
.msg_id
);
117 spin_lock(&drv
->rx_msg_lock
);
118 list_add_tail(&msg
->node
, &drv
->rx_list
);
119 spin_unlock(&drv
->rx_msg_lock
);
120 drv
->ops
->clear_interrupt(drv
);
121 retval
= IRQ_WAKE_THREAD
;
126 static irqreturn_t
intel_sst_irq_thread_mrfld(int irq
, void *context
)
128 struct intel_sst_drv
*drv
= (struct intel_sst_drv
*) context
;
129 struct ipc_post
*__msg
, *msg
= NULL
;
130 unsigned long irq_flags
;
132 spin_lock_irqsave(&drv
->rx_msg_lock
, irq_flags
);
133 if (list_empty(&drv
->rx_list
)) {
134 spin_unlock_irqrestore(&drv
->rx_msg_lock
, irq_flags
);
138 list_for_each_entry_safe(msg
, __msg
, &drv
->rx_list
, node
) {
139 list_del(&msg
->node
);
140 spin_unlock_irqrestore(&drv
->rx_msg_lock
, irq_flags
);
141 if (msg
->is_process_reply
)
142 drv
->ops
->process_message(msg
);
144 drv
->ops
->process_reply(drv
, msg
);
147 kfree(msg
->mailbox_data
);
149 spin_lock_irqsave(&drv
->rx_msg_lock
, irq_flags
);
151 spin_unlock_irqrestore(&drv
->rx_msg_lock
, irq_flags
);
155 static struct intel_sst_ops mrfld_ops
= {
156 .interrupt
= intel_sst_interrupt_mrfld
,
157 .irq_thread
= intel_sst_irq_thread_mrfld
,
158 .clear_interrupt
= intel_sst_clear_intr_mrfld
,
159 .start
= sst_start_mrfld
,
160 .reset
= intel_sst_reset_dsp_mrfld
,
161 .post_message
= sst_post_message_mrfld
,
162 .process_reply
= sst_process_reply_mrfld
,
163 .alloc_stream
= sst_alloc_stream_mrfld
,
164 .post_download
= sst_post_download_mrfld
,
167 int sst_driver_ops(struct intel_sst_drv
*sst
)
170 switch (sst
->pci_id
) {
171 case SST_MRFLD_PCI_ID
:
172 sst
->tstamp
= SST_TIME_STAMP_MRFLD
;
173 sst
->ops
= &mrfld_ops
;
178 "SST Driver capablities missing for pci_id: %x", sst
->pci_id
);
183 void sst_process_pending_msg(struct work_struct
*work
)
185 struct intel_sst_drv
*ctx
= container_of(work
,
186 struct intel_sst_drv
, ipc_post_msg_wq
);
188 ctx
->ops
->post_message(ctx
, NULL
, false);
192 * intel_sst_probe - PCI probe function
194 * @pci: PCI device structure
195 * @pci_id: PCI device ID structure
198 static int intel_sst_probe(struct pci_dev
*pci
,
199 const struct pci_device_id
*pci_id
)
202 struct intel_sst_drv
*sst_drv_ctx
;
203 struct intel_sst_ops
*ops
;
204 struct sst_platform_info
*sst_pdata
= pci
->dev
.platform_data
;
207 dev_dbg(&pci
->dev
, "Probe for DID %x\n", pci
->device
);
208 sst_drv_ctx
= devm_kzalloc(&pci
->dev
, sizeof(*sst_drv_ctx
), GFP_KERNEL
);
212 sst_drv_ctx
->dev
= &pci
->dev
;
213 sst_drv_ctx
->pci_id
= pci
->device
;
217 sst_drv_ctx
->pdata
= sst_pdata
;
218 if (!sst_drv_ctx
->pdata
->probe_data
)
221 memcpy(&sst_drv_ctx
->info
, sst_drv_ctx
->pdata
->probe_data
,
222 sizeof(sst_drv_ctx
->info
));
224 if (0 != sst_driver_ops(sst_drv_ctx
))
227 ops
= sst_drv_ctx
->ops
;
228 mutex_init(&sst_drv_ctx
->sst_lock
);
230 /* pvt_id 0 reserved for async messages */
231 sst_drv_ctx
->pvt_id
= 1;
232 sst_drv_ctx
->stream_cnt
= 0;
233 sst_drv_ctx
->fw_in_mem
= NULL
;
235 /* we use memcpy, so set to 0 */
236 sst_drv_ctx
->use_dma
= 0;
237 sst_drv_ctx
->use_lli
= 0;
239 INIT_LIST_HEAD(&sst_drv_ctx
->memcpy_list
);
240 INIT_LIST_HEAD(&sst_drv_ctx
->ipc_dispatch_list
);
241 INIT_LIST_HEAD(&sst_drv_ctx
->block_list
);
242 INIT_LIST_HEAD(&sst_drv_ctx
->rx_list
);
244 sst_drv_ctx
->post_msg_wq
=
245 create_singlethread_workqueue("sst_post_msg_wq");
246 if (!sst_drv_ctx
->post_msg_wq
) {
248 goto do_free_drv_ctx
;
250 INIT_WORK(&sst_drv_ctx
->ipc_post_msg_wq
, sst_process_pending_msg
);
251 init_waitqueue_head(&sst_drv_ctx
->wait_queue
);
253 spin_lock_init(&sst_drv_ctx
->ipc_spin_lock
);
254 spin_lock_init(&sst_drv_ctx
->block_lock
);
255 spin_lock_init(&sst_drv_ctx
->rx_msg_lock
);
257 dev_info(sst_drv_ctx
->dev
, "Got drv data max stream %d\n",
258 sst_drv_ctx
->info
.max_streams
);
259 for (i
= 1; i
<= sst_drv_ctx
->info
.max_streams
; i
++) {
260 struct stream_info
*stream
= &sst_drv_ctx
->streams
[i
];
262 memset(stream
, 0, sizeof(*stream
));
263 stream
->pipe_id
= PIPE_RSVD
;
264 mutex_init(&stream
->lock
);
267 /* Init the device */
268 ret
= pcim_enable_device(pci
);
270 dev_err(sst_drv_ctx
->dev
,
271 "device can't be enabled. Returned err: %d\n", ret
);
274 sst_drv_ctx
->pci
= pci_dev_get(pci
);
275 ret
= pci_request_regions(pci
, SST_DRV_NAME
);
281 if (sst_drv_ctx
->pci_id
== SST_MRFLD_PCI_ID
) {
282 sst_drv_ctx
->ddr_base
= pci_resource_start(pci
, 0);
283 /* check that the relocated IMR base matches with FW Binary */
284 ddr_base
= relocate_imr_addr_mrfld(sst_drv_ctx
->ddr_base
);
285 if (!sst_drv_ctx
->pdata
->lib_info
) {
286 dev_err(sst_drv_ctx
->dev
, "lib_info pointer NULL\n");
288 goto do_release_regions
;
290 if (ddr_base
!= sst_drv_ctx
->pdata
->lib_info
->mod_base
) {
291 dev_err(sst_drv_ctx
->dev
,
292 "FW LSP DDR BASE does not match with IFWI\n");
294 goto do_release_regions
;
296 sst_drv_ctx
->ddr_end
= pci_resource_end(pci
, 0);
298 sst_drv_ctx
->ddr
= pcim_iomap(pci
, 0,
299 pci_resource_len(pci
, 0));
300 if (!sst_drv_ctx
->ddr
) {
302 goto do_release_regions
;
304 dev_dbg(sst_drv_ctx
->dev
, "sst: DDR Ptr %p\n", sst_drv_ctx
->ddr
);
306 sst_drv_ctx
->ddr
= NULL
;
310 sst_drv_ctx
->shim_phy_add
= pci_resource_start(pci
, 1);
311 sst_drv_ctx
->shim
= pcim_iomap(pci
, 1, pci_resource_len(pci
, 1));
312 if (!sst_drv_ctx
->shim
) {
314 goto do_release_regions
;
316 dev_dbg(sst_drv_ctx
->dev
, "SST Shim Ptr %p\n", sst_drv_ctx
->shim
);
319 sst_drv_ctx
->mailbox_add
= pci_resource_start(pci
, 2);
320 sst_drv_ctx
->mailbox
= pcim_iomap(pci
, 2, pci_resource_len(pci
, 2));
321 if (!sst_drv_ctx
->mailbox
) {
323 goto do_release_regions
;
325 dev_dbg(sst_drv_ctx
->dev
, "SRAM Ptr %p\n", sst_drv_ctx
->mailbox
);
328 sst_drv_ctx
->iram_end
= pci_resource_end(pci
, 3);
329 sst_drv_ctx
->iram_base
= pci_resource_start(pci
, 3);
330 sst_drv_ctx
->iram
= pcim_iomap(pci
, 3, pci_resource_len(pci
, 3));
331 if (!sst_drv_ctx
->iram
) {
333 goto do_release_regions
;
335 dev_dbg(sst_drv_ctx
->dev
, "IRAM Ptr %p\n", sst_drv_ctx
->iram
);
338 sst_drv_ctx
->dram_end
= pci_resource_end(pci
, 4);
339 sst_drv_ctx
->dram_base
= pci_resource_start(pci
, 4);
340 sst_drv_ctx
->dram
= pcim_iomap(pci
, 4, pci_resource_len(pci
, 4));
341 if (!sst_drv_ctx
->dram
) {
343 goto do_release_regions
;
345 dev_dbg(sst_drv_ctx
->dev
, "DRAM Ptr %p\n", sst_drv_ctx
->dram
);
348 sst_set_fw_state_locked(sst_drv_ctx
, SST_RESET
);
349 sst_drv_ctx
->irq_num
= pci
->irq
;
350 /* Register the ISR */
351 ret
= devm_request_threaded_irq(&pci
->dev
, pci
->irq
,
352 sst_drv_ctx
->ops
->interrupt
,
353 sst_drv_ctx
->ops
->irq_thread
, 0, SST_DRV_NAME
,
356 goto do_release_regions
;
357 dev_dbg(sst_drv_ctx
->dev
, "Registered IRQ 0x%x\n", pci
->irq
);
359 /* default intr are unmasked so set this as masked */
360 if (sst_drv_ctx
->pci_id
== SST_MRFLD_PCI_ID
)
361 sst_shim_write64(sst_drv_ctx
->shim
, SST_IMRX
, 0xFFFF0038);
363 pci_set_drvdata(pci
, sst_drv_ctx
);
364 pm_runtime_set_autosuspend_delay(sst_drv_ctx
->dev
, SST_SUSPEND_DELAY
);
365 pm_runtime_use_autosuspend(sst_drv_ctx
->dev
);
366 pm_runtime_allow(sst_drv_ctx
->dev
);
367 pm_runtime_put_noidle(sst_drv_ctx
->dev
);
368 sst_register(sst_drv_ctx
->dev
);
369 sst_drv_ctx
->qos
= devm_kzalloc(&pci
->dev
,
370 sizeof(struct pm_qos_request
), GFP_KERNEL
);
371 if (!sst_drv_ctx
->qos
) {
373 goto do_release_regions
;
375 pm_qos_add_request(sst_drv_ctx
->qos
, PM_QOS_CPU_DMA_LATENCY
,
376 PM_QOS_DEFAULT_VALUE
);
381 pci_release_regions(pci
);
383 destroy_workqueue(sst_drv_ctx
->post_msg_wq
);
385 dev_err(sst_drv_ctx
->dev
, "Probe failed with %d\n", ret
);
390 * intel_sst_remove - PCI remove function
392 * @pci: PCI device structure
394 * This function is called by OS when a device is unloaded
395 * This frees the interrupt etc
397 static void intel_sst_remove(struct pci_dev
*pci
)
399 struct intel_sst_drv
*sst_drv_ctx
= pci_get_drvdata(pci
);
401 pm_runtime_get_noresume(sst_drv_ctx
->dev
);
402 pm_runtime_forbid(sst_drv_ctx
->dev
);
403 sst_unregister(sst_drv_ctx
->dev
);
404 pci_dev_put(sst_drv_ctx
->pci
);
405 sst_set_fw_state_locked(sst_drv_ctx
, SST_SHUTDOWN
);
407 flush_scheduled_work();
408 destroy_workqueue(sst_drv_ctx
->post_msg_wq
);
409 pm_qos_remove_request(sst_drv_ctx
->qos
);
410 kfree(sst_drv_ctx
->fw_sg_list
.src
);
411 kfree(sst_drv_ctx
->fw_sg_list
.dst
);
412 sst_drv_ctx
->fw_sg_list
.list_len
= 0;
413 kfree(sst_drv_ctx
->fw_in_mem
);
414 sst_drv_ctx
->fw_in_mem
= NULL
;
415 sst_memcpy_free_resources(sst_drv_ctx
);
417 pci_release_regions(pci
);
418 pci_set_drvdata(pci
, NULL
);
422 static struct pci_device_id intel_sst_ids
[] = {
423 { PCI_VDEVICE(INTEL
, SST_MRFLD_PCI_ID
), 0},
427 static struct pci_driver sst_driver
= {
428 .name
= SST_DRV_NAME
,
429 .id_table
= intel_sst_ids
,
430 .probe
= intel_sst_probe
,
431 .remove
= intel_sst_remove
,
434 module_pci_driver(sst_driver
);