2 * Intel Haswell SST DSP driver
4 * Copyright (C) 2013, Intel Corporation. All rights reserved.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 #include <linux/delay.h>
19 #include <linux/slab.h>
20 #include <linux/device.h>
21 #include <linux/sched.h>
22 #include <linux/export.h>
23 #include <linux/interrupt.h>
24 #include <linux/module.h>
25 #include <linux/dma-mapping.h>
26 #include <linux/platform_device.h>
27 #include <linux/pci.h>
28 #include <linux/firmware.h>
29 #include <linux/pm_runtime.h>
32 #include "sst-dsp-priv.h"
33 #include "sst-haswell-ipc.h"
35 #include <trace/events/hswadsp.h>
37 #define SST_HSW_FW_SIGNATURE_SIZE 4
38 #define SST_HSW_FW_SIGN "$SST"
39 #define SST_HSW_FW_LIB_SIGN "$LIB"
41 #define SST_WPT_SHIM_OFFSET 0xFB000
42 #define SST_LP_SHIM_OFFSET 0xE7000
43 #define SST_WPT_IRAM_OFFSET 0xA0000
44 #define SST_LP_IRAM_OFFSET 0x80000
46 #define SST_SHIM_PM_REG 0x84
48 #define SST_HSW_IRAM 1
49 #define SST_HSW_DRAM 2
50 #define SST_HSW_REGS 3
52 struct dma_block_info
{
53 __le32 type
; /* IRAM/DRAM */
54 __le32 size
; /* Bytes */
55 __le32 ram_offset
; /* Offset in I/DRAM */
56 __le32 rsvd
; /* Reserved field */
57 } __attribute__((packed
));
59 struct fw_module_info
{
60 __le32 persistent_size
;
62 } __attribute__((packed
));
65 unsigned char signature
[SST_HSW_FW_SIGNATURE_SIZE
]; /* FW signature */
66 __le32 file_size
; /* size of fw minus this header */
67 __le32 modules
; /* # of modules */
68 __le32 file_format
; /* version of header format */
70 } __attribute__((packed
));
72 struct fw_module_header
{
73 unsigned char signature
[SST_HSW_FW_SIGNATURE_SIZE
]; /* module signature */
74 __le32 mod_size
; /* size of module */
75 __le32 blocks
; /* # of blocks */
77 __le16 type
; /* codec type, pp lib */
79 struct fw_module_info info
;
80 } __attribute__((packed
));
82 static void hsw_free(struct sst_dsp
*sst
);
84 static int hsw_parse_module(struct sst_dsp
*dsp
, struct sst_fw
*fw
,
85 struct fw_module_header
*module
)
87 struct dma_block_info
*block
;
88 struct sst_module
*mod
;
89 struct sst_module_data block_data
;
90 struct sst_module_template
template;
94 /* TODO: allowed module types need to be configurable */
95 if (module
->type
!= SST_HSW_MODULE_BASE_FW
96 && module
->type
!= SST_HSW_MODULE_PCM_SYSTEM
97 && module
->type
!= SST_HSW_MODULE_PCM
98 && module
->type
!= SST_HSW_MODULE_PCM_REFERENCE
99 && module
->type
!= SST_HSW_MODULE_PCM_CAPTURE
100 && module
->type
!= SST_HSW_MODULE_LPAL
)
103 dev_dbg(dsp
->dev
, "new module sign 0x%s size 0x%x blocks 0x%x type 0x%x\n",
104 module
->signature
, module
->mod_size
,
105 module
->blocks
, module
->type
);
106 dev_dbg(dsp
->dev
, " entrypoint 0x%x\n", module
->entry_point
);
107 dev_dbg(dsp
->dev
, " persistent 0x%x scratch 0x%x\n",
108 module
->info
.persistent_size
, module
->info
.scratch_size
);
110 memset(&template, 0, sizeof(template));
111 template.id
= module
->type
;
112 template.entry
= module
->entry_point
;
113 template.p
.size
= module
->info
.persistent_size
;
114 template.p
.type
= SST_MEM_DRAM
;
115 template.p
.data_type
= SST_DATA_P
;
116 template.s
.size
= module
->info
.scratch_size
;
117 template.s
.type
= SST_MEM_DRAM
;
118 template.s
.data_type
= SST_DATA_S
;
120 mod
= sst_module_new(fw
, &template, NULL
);
124 block
= (void *)module
+ sizeof(*module
);
126 for (count
= 0; count
< module
->blocks
; count
++) {
128 if (block
->size
<= 0) {
130 "error: block %d size invalid\n", count
);
131 sst_module_free(mod
);
135 switch (block
->type
) {
139 block
->ram_offset
+ dsp
->addr
.iram_offset
;
140 block_data
.type
= SST_MEM_IRAM
;
144 block_data
.offset
= block
->ram_offset
;
145 block_data
.type
= SST_MEM_DRAM
;
148 dev_err(dsp
->dev
, "error: bad type 0x%x for block 0x%x\n",
150 sst_module_free(mod
);
154 block_data
.size
= block
->size
;
155 block_data
.data_type
= SST_DATA_M
;
156 block_data
.data
= (void *)block
+ sizeof(*block
);
157 block_data
.data_offset
= block_data
.data
- fw
->dma_buf
;
159 dev_dbg(dsp
->dev
, "copy firmware block %d type 0x%x "
160 "size 0x%x ==> ram %p offset 0x%x\n",
161 count
, block
->type
, block
->size
, ram
,
164 sst_module_insert_fixed_block(mod
, &block_data
);
166 block
= (void *)block
+ sizeof(*block
) + block
->size
;
171 static int hsw_parse_fw_image(struct sst_fw
*sst_fw
)
173 struct fw_header
*header
;
174 struct sst_module
*scratch
;
175 struct fw_module_header
*module
;
176 struct sst_dsp
*dsp
= sst_fw
->dsp
;
177 struct sst_hsw
*hsw
= sst_fw
->private;
180 /* Read the header information from the data pointer */
181 header
= (struct fw_header
*)sst_fw
->dma_buf
;
184 if ((strncmp(header
->signature
, SST_HSW_FW_SIGN
, 4) != 0) ||
185 (sst_fw
->size
!= header
->file_size
+ sizeof(*header
))) {
186 dev_err(dsp
->dev
, "error: invalid fw sign/filesize mismatch\n");
190 dev_dbg(dsp
->dev
, "header size=0x%x modules=0x%x fmt=0x%x size=%zu\n",
191 header
->file_size
, header
->modules
,
192 header
->file_format
, sizeof(*header
));
194 /* parse each module */
195 module
= (void *)sst_fw
->dma_buf
+ sizeof(*header
);
196 for (count
= 0; count
< header
->modules
; count
++) {
199 ret
= hsw_parse_module(dsp
, sst_fw
, module
);
201 dev_err(dsp
->dev
, "error: invalid module %d\n", count
);
204 module
= (void *)module
+ sizeof(*module
) + module
->mod_size
;
207 /* allocate persistent/scratch mem regions */
208 scratch
= sst_mem_block_alloc_scratch(dsp
);
212 sst_hsw_set_scratch_module(hsw
, scratch
);
217 static irqreturn_t
hsw_irq(int irq
, void *context
)
219 struct sst_dsp
*sst
= (struct sst_dsp
*) context
;
223 spin_lock(&sst
->spinlock
);
225 /* Interrupt arrived, check src */
226 isr
= sst_dsp_shim_read_unlocked(sst
, SST_ISRX
);
227 if (isr
& SST_ISRX_DONE
) {
228 trace_sst_irq_done(isr
,
229 sst_dsp_shim_read_unlocked(sst
, SST_IMRX
));
231 /* Mask Done interrupt before return */
232 sst_dsp_shim_update_bits_unlocked(sst
, SST_IMRX
,
233 SST_IMRX_DONE
, SST_IMRX_DONE
);
234 ret
= IRQ_WAKE_THREAD
;
237 if (isr
& SST_ISRX_BUSY
) {
238 trace_sst_irq_busy(isr
,
239 sst_dsp_shim_read_unlocked(sst
, SST_IMRX
));
241 /* Mask Busy interrupt before return */
242 sst_dsp_shim_update_bits_unlocked(sst
, SST_IMRX
,
243 SST_IMRX_BUSY
, SST_IMRX_BUSY
);
244 ret
= IRQ_WAKE_THREAD
;
247 spin_unlock(&sst
->spinlock
);
251 static void hsw_boot(struct sst_dsp
*sst
)
253 /* select SSP1 19.2MHz base clock, SSP clock 0, turn off Low Power Clock */
254 sst_dsp_shim_update_bits_unlocked(sst
, SST_CSR
,
255 SST_CSR_S1IOCS
| SST_CSR_SBCS1
| SST_CSR_LPCS
, 0x0);
257 /* stall DSP core, set clk to 192/96Mhz */
258 sst_dsp_shim_update_bits_unlocked(sst
,
259 SST_CSR
, SST_CSR_STALL
| SST_CSR_DCS_MASK
,
260 SST_CSR_STALL
| SST_CSR_DCS(4));
262 /* Set 24MHz MCLK, prevent local clock gating, enable SSP0 clock */
263 sst_dsp_shim_update_bits_unlocked(sst
, SST_CLKCTL
,
264 SST_CLKCTL_MASK
| SST_CLKCTL_DCPLCG
| SST_CLKCTL_SCOE0
,
265 SST_CLKCTL_MASK
| SST_CLKCTL_DCPLCG
| SST_CLKCTL_SCOE0
);
267 /* disable DMA finish function for SSP0 & SSP1 */
268 sst_dsp_shim_update_bits_unlocked(sst
, SST_CSR2
, SST_CSR2_SDFD_SSP1
,
271 /* enable DMA engine 0,1 all channels to access host memory */
272 sst_dsp_shim_update_bits_unlocked(sst
, SST_HMDC
,
273 SST_HMDC_HDDA1(0xff) | SST_HMDC_HDDA0(0xff),
274 SST_HMDC_HDDA1(0xff) | SST_HMDC_HDDA0(0xff));
276 /* disable all clock gating */
277 writel(0x0, sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
280 sst_dsp_shim_update_bits_unlocked(sst
, SST_CSR
, SST_CSR_STALL
, 0x0);
283 static void hsw_reset(struct sst_dsp
*sst
)
285 /* put DSP into reset and stall */
286 sst_dsp_shim_update_bits_unlocked(sst
, SST_CSR
,
287 SST_CSR_RST
| SST_CSR_STALL
, SST_CSR_RST
| SST_CSR_STALL
);
289 /* keep in reset for 10ms */
292 /* take DSP out of reset and keep stalled for FW loading */
293 sst_dsp_shim_update_bits_unlocked(sst
, SST_CSR
,
294 SST_CSR_RST
| SST_CSR_STALL
, SST_CSR_STALL
);
297 struct sst_adsp_memregion
{
301 enum sst_mem_type type
;
304 /* lynx point ADSP mem regions */
305 static const struct sst_adsp_memregion lp_region
[] = {
306 {0x00000, 0x40000, 8, SST_MEM_DRAM
}, /* D-SRAM0 - 8 * 32kB */
307 {0x40000, 0x80000, 8, SST_MEM_DRAM
}, /* D-SRAM1 - 8 * 32kB */
308 {0x80000, 0xE0000, 12, SST_MEM_IRAM
}, /* I-SRAM - 12 * 32kB */
311 /* wild cat point ADSP mem regions */
312 static const struct sst_adsp_memregion wpt_region
[] = {
313 {0x00000, 0xA0000, 20, SST_MEM_DRAM
}, /* D-SRAM0,D-SRAM1,D-SRAM2 - 20 * 32kB */
314 {0xA0000, 0xF0000, 10, SST_MEM_IRAM
}, /* I-SRAM - 10 * 32kB */
317 static int hsw_acpi_resource_map(struct sst_dsp
*sst
, struct sst_pdata
*pdata
)
319 /* ADSP DRAM & IRAM */
320 sst
->addr
.lpe_base
= pdata
->lpe_base
;
321 sst
->addr
.lpe
= ioremap(pdata
->lpe_base
, pdata
->lpe_size
);
325 /* ADSP PCI MMIO config space */
326 sst
->addr
.pci_cfg
= ioremap(pdata
->pcicfg_base
, pdata
->pcicfg_size
);
327 if (!sst
->addr
.pci_cfg
) {
328 iounmap(sst
->addr
.lpe
);
333 sst
->addr
.shim
= sst
->addr
.lpe
+ sst
->addr
.shim_offset
;
337 struct sst_sram_shift
{
338 u32 dev_id
; /* SST Device IDs */
343 static const struct sst_sram_shift sram_shift
[] = {
344 {SST_DEV_ID_LYNX_POINT
, 6, 16}, /* lp */
345 {SST_DEV_ID_WILDCAT_POINT
, 2, 12}, /* wpt */
347 static u32
hsw_block_get_bit(struct sst_mem_block
*block
)
349 u32 bit
= 0, shift
= 0, index
;
350 struct sst_dsp
*sst
= block
->dsp
;
352 for (index
= 0; index
< ARRAY_SIZE(sram_shift
); index
++) {
353 if (sram_shift
[index
].dev_id
== sst
->id
)
357 if (index
< ARRAY_SIZE(sram_shift
)) {
358 switch (block
->type
) {
360 shift
= sram_shift
[index
].dram_shift
;
363 shift
= sram_shift
[index
].iram_shift
;
371 bit
= 1 << (block
->index
+ shift
);
376 /*dummy read a SRAM block.*/
377 static void sst_mem_block_dummy_read(struct sst_mem_block
*block
)
381 struct sst_dsp
*sst
= block
->dsp
;
383 size
= block
->size
> 4 ? 4 : block
->size
;
384 memcpy_fromio(tmp_buf
, sst
->addr
.lpe
+ block
->offset
, size
);
387 /* enable 32kB memory block - locks held by caller */
388 static int hsw_block_enable(struct sst_mem_block
*block
)
390 struct sst_dsp
*sst
= block
->dsp
;
393 if (block
->users
++ > 0)
396 dev_dbg(block
->dsp
->dev
, " enabled block %d:%d at offset 0x%x\n",
397 block
->type
, block
->index
, block
->offset
);
399 val
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
400 bit
= hsw_block_get_bit(block
);
401 writel(val
& ~bit
, sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
403 /* wait 18 DSP clock ticks */
406 /*add a dummy read before the SRAM block is written, otherwise the writing may miss bytes sometimes.*/
407 sst_mem_block_dummy_read(block
);
411 /* disable 32kB memory block - locks held by caller */
412 static int hsw_block_disable(struct sst_mem_block
*block
)
414 struct sst_dsp
*sst
= block
->dsp
;
417 if (--block
->users
> 0)
420 dev_dbg(block
->dsp
->dev
, " disabled block %d:%d at offset 0x%x\n",
421 block
->type
, block
->index
, block
->offset
);
423 val
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
424 bit
= hsw_block_get_bit(block
);
425 writel(val
| bit
, sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
430 static struct sst_block_ops sst_hsw_ops
= {
431 .enable
= hsw_block_enable
,
432 .disable
= hsw_block_disable
,
435 static int hsw_enable_shim(struct sst_dsp
*sst
)
441 reg
= readl(sst
->addr
.pci_cfg
+ SST_SHIM_PM_REG
);
442 writel(reg
& ~0x3, sst
->addr
.pci_cfg
+ SST_SHIM_PM_REG
);
444 /* check that ADSP shim is enabled */
446 reg
= sst_dsp_shim_read_unlocked(sst
, SST_CSR
);
447 if (reg
!= 0xffffffff)
456 static int hsw_init(struct sst_dsp
*sst
, struct sst_pdata
*pdata
)
458 const struct sst_adsp_memregion
*region
;
460 int ret
= -ENODEV
, i
, j
, region_count
;
466 case SST_DEV_ID_LYNX_POINT
:
468 region_count
= ARRAY_SIZE(lp_region
);
469 sst
->addr
.iram_offset
= SST_LP_IRAM_OFFSET
;
470 sst
->addr
.shim_offset
= SST_LP_SHIM_OFFSET
;
472 case SST_DEV_ID_WILDCAT_POINT
:
474 region_count
= ARRAY_SIZE(wpt_region
);
475 sst
->addr
.iram_offset
= SST_WPT_IRAM_OFFSET
;
476 sst
->addr
.shim_offset
= SST_WPT_SHIM_OFFSET
;
479 dev_err(dev
, "error: failed to get mem resources\n");
483 ret
= hsw_acpi_resource_map(sst
, pdata
);
485 dev_err(dev
, "error: failed to map resources\n");
489 /* enable the DSP SHIM */
490 ret
= hsw_enable_shim(sst
);
492 dev_err(dev
, "error: failed to set DSP D0 and reset SHIM\n");
496 ret
= dma_coerce_mask_and_coherent(dev
, DMA_BIT_MASK(31));
500 /* Enable Interrupt from both sides */
501 sst_dsp_shim_update_bits_unlocked(sst
, SST_IMRX
, 0x3, 0x0);
502 sst_dsp_shim_update_bits_unlocked(sst
, SST_IMRD
,
503 (0x3 | 0x1 << 16 | 0x3 << 21), 0x0);
505 /* register DSP memory blocks - ideally we should get this from ACPI */
506 for (i
= 0; i
< region_count
; i
++) {
507 offset
= region
[i
].start
;
508 size
= (region
[i
].end
- region
[i
].start
) / region
[i
].blocks
;
510 /* register individual memory blocks */
511 for (j
= 0; j
< region
[i
].blocks
; j
++) {
512 sst_mem_block_register(sst
, offset
, size
,
513 region
[i
].type
, &sst_hsw_ops
, j
, sst
);
518 /* set default power gating control, enable power gating control for all blocks. that is,
519 can't be accessed, please enable each block before accessing. */
520 writel(0xffffffff, sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
525 static void hsw_free(struct sst_dsp
*sst
)
527 sst_mem_block_unregister_all(sst
);
528 iounmap(sst
->addr
.lpe
);
529 iounmap(sst
->addr
.pci_cfg
);
532 struct sst_ops haswell_ops
= {
535 .write
= sst_shim32_write
,
536 .read
= sst_shim32_read
,
537 .write64
= sst_shim32_write64
,
538 .read64
= sst_shim32_read64
,
539 .ram_read
= sst_memcpy_fromio_32
,
540 .ram_write
= sst_memcpy_toio_32
,
541 .irq_handler
= hsw_irq
,
544 .parse_fw
= hsw_parse_fw_image
,