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>
31 #include <linux/acpi.h>
32 #include <acpi/acpi_bus.h>
35 #include "sst-dsp-priv.h"
36 #include "sst-haswell-ipc.h"
38 #include <trace/events/hswadsp.h>
40 #define SST_HSW_FW_SIGNATURE_SIZE 4
41 #define SST_HSW_FW_SIGN "$SST"
42 #define SST_HSW_FW_LIB_SIGN "$LIB"
44 #define SST_WPT_SHIM_OFFSET 0xFB000
45 #define SST_LP_SHIM_OFFSET 0xE7000
46 #define SST_WPT_IRAM_OFFSET 0xA0000
47 #define SST_LP_IRAM_OFFSET 0x80000
49 #define SST_SHIM_PM_REG 0x84
51 #define SST_HSW_IRAM 1
52 #define SST_HSW_DRAM 2
53 #define SST_HSW_REGS 3
55 struct dma_block_info
{
56 __le32 type
; /* IRAM/DRAM */
57 __le32 size
; /* Bytes */
58 __le32 ram_offset
; /* Offset in I/DRAM */
59 __le32 rsvd
; /* Reserved field */
60 } __attribute__((packed
));
62 struct fw_module_info
{
63 __le32 persistent_size
;
65 } __attribute__((packed
));
68 unsigned char signature
[SST_HSW_FW_SIGNATURE_SIZE
]; /* FW signature */
69 __le32 file_size
; /* size of fw minus this header */
70 __le32 modules
; /* # of modules */
71 __le32 file_format
; /* version of header format */
73 } __attribute__((packed
));
75 struct fw_module_header
{
76 unsigned char signature
[SST_HSW_FW_SIGNATURE_SIZE
]; /* module signature */
77 __le32 mod_size
; /* size of module */
78 __le32 blocks
; /* # of blocks */
80 __le16 type
; /* codec type, pp lib */
82 struct fw_module_info info
;
83 } __attribute__((packed
));
85 static void hsw_free(struct sst_dsp
*sst
);
87 static int hsw_parse_module(struct sst_dsp
*dsp
, struct sst_fw
*fw
,
88 struct fw_module_header
*module
)
90 struct dma_block_info
*block
;
91 struct sst_module
*mod
;
92 struct sst_module_data block_data
;
93 struct sst_module_template
template;
97 /* TODO: allowed module types need to be configurable */
98 if (module
->type
!= SST_HSW_MODULE_BASE_FW
99 && module
->type
!= SST_HSW_MODULE_PCM_SYSTEM
100 && module
->type
!= SST_HSW_MODULE_PCM
101 && module
->type
!= SST_HSW_MODULE_PCM_REFERENCE
102 && module
->type
!= SST_HSW_MODULE_PCM_CAPTURE
103 && module
->type
!= SST_HSW_MODULE_LPAL
)
106 dev_dbg(dsp
->dev
, "new module sign 0x%s size 0x%x blocks 0x%x type 0x%x\n",
107 module
->signature
, module
->mod_size
,
108 module
->blocks
, module
->type
);
109 dev_dbg(dsp
->dev
, " entrypoint 0x%x\n", module
->entry_point
);
110 dev_dbg(dsp
->dev
, " persistent 0x%x scratch 0x%x\n",
111 module
->info
.persistent_size
, module
->info
.scratch_size
);
113 memset(&template, 0, sizeof(template));
114 template.id
= module
->type
;
115 template.entry
= module
->entry_point
;
116 template.p
.size
= module
->info
.persistent_size
;
117 template.p
.type
= SST_MEM_DRAM
;
118 template.p
.data_type
= SST_DATA_P
;
119 template.s
.size
= module
->info
.scratch_size
;
120 template.s
.type
= SST_MEM_DRAM
;
121 template.s
.data_type
= SST_DATA_S
;
123 mod
= sst_module_new(fw
, &template, NULL
);
127 block
= (void *)module
+ sizeof(*module
);
129 for (count
= 0; count
< module
->blocks
; count
++) {
131 if (block
->size
<= 0) {
133 "error: block %d size invalid\n", count
);
134 sst_module_free(mod
);
138 switch (block
->type
) {
142 block
->ram_offset
+ dsp
->addr
.iram_offset
;
143 block_data
.type
= SST_MEM_IRAM
;
147 block_data
.offset
= block
->ram_offset
;
148 block_data
.type
= SST_MEM_DRAM
;
151 dev_err(dsp
->dev
, "error: bad type 0x%x for block 0x%x\n",
153 sst_module_free(mod
);
157 block_data
.size
= block
->size
;
158 block_data
.data_type
= SST_DATA_M
;
159 block_data
.data
= (void *)block
+ sizeof(*block
);
160 block_data
.data_offset
= block_data
.data
- fw
->dma_buf
;
162 dev_dbg(dsp
->dev
, "copy firmware block %d type 0x%x "
163 "size 0x%x ==> ram %p offset 0x%x\n",
164 count
, block
->type
, block
->size
, ram
,
167 sst_module_insert_fixed_block(mod
, &block_data
);
169 block
= (void *)block
+ sizeof(*block
) + block
->size
;
174 static int hsw_parse_fw_image(struct sst_fw
*sst_fw
)
176 struct fw_header
*header
;
177 struct sst_module
*scratch
;
178 struct fw_module_header
*module
;
179 struct sst_dsp
*dsp
= sst_fw
->dsp
;
180 struct sst_hsw
*hsw
= sst_fw
->private;
183 /* Read the header information from the data pointer */
184 header
= (struct fw_header
*)sst_fw
->dma_buf
;
187 if ((strncmp(header
->signature
, SST_HSW_FW_SIGN
, 4) != 0) ||
188 (sst_fw
->size
!= header
->file_size
+ sizeof(*header
))) {
189 dev_err(dsp
->dev
, "error: invalid fw sign/filesize mismatch\n");
193 dev_dbg(dsp
->dev
, "header size=0x%x modules=0x%x fmt=0x%x size=%zu\n",
194 header
->file_size
, header
->modules
,
195 header
->file_format
, sizeof(*header
));
197 /* parse each module */
198 module
= (void *)sst_fw
->dma_buf
+ sizeof(*header
);
199 for (count
= 0; count
< header
->modules
; count
++) {
202 ret
= hsw_parse_module(dsp
, sst_fw
, module
);
204 dev_err(dsp
->dev
, "error: invalid module %d\n", count
);
207 module
= (void *)module
+ sizeof(*module
) + module
->mod_size
;
210 /* allocate persistent/scratch mem regions */
211 scratch
= sst_mem_block_alloc_scratch(dsp
);
215 sst_hsw_set_scratch_module(hsw
, scratch
);
220 static irqreturn_t
hsw_irq(int irq
, void *context
)
222 struct sst_dsp
*sst
= (struct sst_dsp
*) context
;
226 spin_lock(&sst
->spinlock
);
228 /* Interrupt arrived, check src */
229 isr
= sst_dsp_shim_read_unlocked(sst
, SST_ISRX
);
230 if (isr
& SST_ISRX_DONE
) {
231 trace_sst_irq_done(isr
,
232 sst_dsp_shim_read_unlocked(sst
, SST_IMRX
));
234 /* Mask Done interrupt before return */
235 sst_dsp_shim_update_bits_unlocked(sst
, SST_IMRX
,
236 SST_IMRX_DONE
, SST_IMRX_DONE
);
237 ret
= IRQ_WAKE_THREAD
;
240 if (isr
& SST_ISRX_BUSY
) {
241 trace_sst_irq_busy(isr
,
242 sst_dsp_shim_read_unlocked(sst
, SST_IMRX
));
244 /* Mask Busy interrupt before return */
245 sst_dsp_shim_update_bits_unlocked(sst
, SST_IMRX
,
246 SST_IMRX_BUSY
, SST_IMRX_BUSY
);
247 ret
= IRQ_WAKE_THREAD
;
250 spin_unlock(&sst
->spinlock
);
254 static void hsw_boot(struct sst_dsp
*sst
)
256 /* select SSP1 19.2MHz base clock, SSP clock 0, turn off Low Power Clock */
257 sst_dsp_shim_update_bits_unlocked(sst
, SST_CSR
,
258 SST_CSR_S1IOCS
| SST_CSR_SBCS1
| SST_CSR_LPCS
, 0x0);
260 /* stall DSP core, set clk to 192/96Mhz */
261 sst_dsp_shim_update_bits_unlocked(sst
,
262 SST_CSR
, SST_CSR_STALL
| SST_CSR_DCS_MASK
,
263 SST_CSR_STALL
| SST_CSR_DCS(4));
265 /* Set 24MHz MCLK, prevent local clock gating, enable SSP0 clock */
266 sst_dsp_shim_update_bits_unlocked(sst
, SST_CLKCTL
,
267 SST_CLKCTL_MASK
| SST_CLKCTL_DCPLCG
| SST_CLKCTL_SCOE0
,
268 SST_CLKCTL_MASK
| SST_CLKCTL_DCPLCG
| SST_CLKCTL_SCOE0
);
270 /* disable DMA finish function for SSP0 & SSP1 */
271 sst_dsp_shim_update_bits_unlocked(sst
, SST_CSR2
, SST_CSR2_SDFD_SSP1
,
274 /* enable DMA engine 0,1 all channels to access host memory */
275 sst_dsp_shim_update_bits_unlocked(sst
, SST_HDMC
,
276 SST_HDMC_HDDA1(0xff) | SST_HDMC_HDDA0(0xff),
277 SST_HDMC_HDDA1(0xff) | SST_HDMC_HDDA0(0xff));
279 /* disable all clock gating */
280 writel(0x0, sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
283 sst_dsp_shim_update_bits_unlocked(sst
, SST_CSR
, SST_CSR_STALL
, 0x0);
286 static void hsw_reset(struct sst_dsp
*sst
)
288 /* put DSP into reset and stall */
289 sst_dsp_shim_update_bits_unlocked(sst
, SST_CSR
,
290 SST_CSR_RST
| SST_CSR_STALL
, SST_CSR_RST
| SST_CSR_STALL
);
292 /* keep in reset for 10ms */
295 /* take DSP out of reset and keep stalled for FW loading */
296 sst_dsp_shim_update_bits_unlocked(sst
, SST_CSR
,
297 SST_CSR_RST
| SST_CSR_STALL
, SST_CSR_STALL
);
300 struct sst_adsp_memregion
{
304 enum sst_mem_type type
;
307 /* lynx point ADSP mem regions */
308 static const struct sst_adsp_memregion lp_region
[] = {
309 {0x00000, 0x40000, 8, SST_MEM_DRAM
}, /* D-SRAM0 - 8 * 32kB */
310 {0x40000, 0x80000, 8, SST_MEM_DRAM
}, /* D-SRAM1 - 8 * 32kB */
311 {0x80000, 0xE0000, 12, SST_MEM_IRAM
}, /* I-SRAM - 12 * 32kB */
314 /* wild cat point ADSP mem regions */
315 static const struct sst_adsp_memregion wpt_region
[] = {
316 {0x00000, 0x40000, 8, SST_MEM_DRAM
}, /* D-SRAM0 - 8 * 32kB */
317 {0x40000, 0x80000, 8, SST_MEM_DRAM
}, /* D-SRAM1 - 8 * 32kB */
318 {0x80000, 0xA0000, 4, SST_MEM_DRAM
}, /* D-SRAM2 - 4 * 32kB */
319 {0xA0000, 0xF0000, 10, SST_MEM_IRAM
}, /* I-SRAM - 10 * 32kB */
322 static int hsw_acpi_resource_map(struct sst_dsp
*sst
, struct sst_pdata
*pdata
)
324 /* ADSP DRAM & IRAM */
325 sst
->addr
.lpe_base
= pdata
->lpe_base
;
326 sst
->addr
.lpe
= ioremap(pdata
->lpe_base
, pdata
->lpe_size
);
330 /* ADSP PCI MMIO config space */
331 sst
->addr
.pci_cfg
= ioremap(pdata
->pcicfg_base
, pdata
->pcicfg_size
);
332 if (!sst
->addr
.pci_cfg
) {
333 iounmap(sst
->addr
.lpe
);
338 sst
->addr
.shim
= sst
->addr
.lpe
+ sst
->addr
.shim_offset
;
342 static u32
hsw_block_get_bit(struct sst_mem_block
*block
)
344 u32 bit
= 0, shift
= 0;
346 switch (block
->type
) {
357 bit
= 1 << (block
->index
+ shift
);
362 /* enable 32kB memory block - locks held by caller */
363 static int hsw_block_enable(struct sst_mem_block
*block
)
365 struct sst_dsp
*sst
= block
->dsp
;
368 if (block
->users
++ > 0)
371 dev_dbg(block
->dsp
->dev
, " enabled block %d:%d at offset 0x%x\n",
372 block
->type
, block
->index
, block
->offset
);
374 val
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
375 bit
= hsw_block_get_bit(block
);
376 writel(val
& ~bit
, sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
378 /* wait 18 DSP clock ticks */
384 /* disable 32kB memory block - locks held by caller */
385 static int hsw_block_disable(struct sst_mem_block
*block
)
387 struct sst_dsp
*sst
= block
->dsp
;
390 if (--block
->users
> 0)
393 dev_dbg(block
->dsp
->dev
, " disabled block %d:%d at offset 0x%x\n",
394 block
->type
, block
->index
, block
->offset
);
396 val
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
397 bit
= hsw_block_get_bit(block
);
398 writel(val
| bit
, sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
403 static struct sst_block_ops sst_hsw_ops
= {
404 .enable
= hsw_block_enable
,
405 .disable
= hsw_block_disable
,
408 static int hsw_enable_shim(struct sst_dsp
*sst
)
414 reg
= readl(sst
->addr
.pci_cfg
+ SST_SHIM_PM_REG
);
415 writel(reg
& ~0x3, sst
->addr
.pci_cfg
+ SST_SHIM_PM_REG
);
417 /* check that ADSP shim is enabled */
419 reg
= sst_dsp_shim_read_unlocked(sst
, SST_CSR
);
420 if (reg
!= 0xffffffff)
429 static int hsw_init(struct sst_dsp
*sst
, struct sst_pdata
*pdata
)
431 const struct sst_adsp_memregion
*region
;
433 int ret
= -ENODEV
, i
, j
, region_count
;
439 case SST_DEV_ID_LYNX_POINT
:
441 region_count
= ARRAY_SIZE(lp_region
);
442 sst
->addr
.iram_offset
= SST_LP_IRAM_OFFSET
;
443 sst
->addr
.shim_offset
= SST_LP_SHIM_OFFSET
;
445 case SST_DEV_ID_WILDCAT_POINT
:
447 region_count
= ARRAY_SIZE(wpt_region
);
448 sst
->addr
.iram_offset
= SST_WPT_IRAM_OFFSET
;
449 sst
->addr
.shim_offset
= SST_WPT_SHIM_OFFSET
;
452 dev_err(dev
, "error: failed to get mem resources\n");
456 ret
= hsw_acpi_resource_map(sst
, pdata
);
458 dev_err(dev
, "error: failed to map resources\n");
462 /* enable the DSP SHIM */
463 ret
= hsw_enable_shim(sst
);
465 dev_err(dev
, "error: failed to set DSP D0 and reset SHIM\n");
469 ret
= dma_coerce_mask_and_coherent(dev
, DMA_BIT_MASK(31));
473 /* Enable Interrupt from both sides */
474 sst_dsp_shim_update_bits_unlocked(sst
, SST_IMRX
, 0x3, 0x0);
475 sst_dsp_shim_update_bits_unlocked(sst
, SST_IMRD
,
476 (0x3 | 0x1 << 16 | 0x3 << 21), 0x0);
478 /* register DSP memory blocks - ideally we should get this from ACPI */
479 for (i
= 0; i
< region_count
; i
++) {
480 offset
= region
[i
].start
;
481 size
= (region
[i
].end
- region
[i
].start
) / region
[i
].blocks
;
483 /* register individual memory blocks */
484 for (j
= 0; j
< region
[i
].blocks
; j
++) {
485 sst_mem_block_register(sst
, offset
, size
,
486 region
[i
].type
, &sst_hsw_ops
, j
, sst
);
491 /* set default power gating mask */
492 writel(0x0, sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
497 static void hsw_free(struct sst_dsp
*sst
)
499 sst_mem_block_unregister_all(sst
);
500 iounmap(sst
->addr
.lpe
);
501 iounmap(sst
->addr
.pci_cfg
);
504 struct sst_ops haswell_ops
= {
507 .write
= sst_shim32_write
,
508 .read
= sst_shim32_read
,
509 .write64
= sst_shim32_write64
,
510 .read64
= sst_shim32_read64
,
511 .ram_read
= sst_memcpy_fromio_32
,
512 .ram_write
= sst_memcpy_toio_32
,
513 .irq_handler
= hsw_irq
,
516 .parse_fw
= hsw_parse_fw_image
,