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 "../common/sst-dsp.h"
32 #include "../common/sst-dsp-priv.h"
33 #include "../haswell/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
45 #define SST_WPT_DSP_DRAM_OFFSET 0x400000
46 #define SST_WPT_DSP_IRAM_OFFSET 0x00000
47 #define SST_LPT_DSP_DRAM_OFFSET 0x400000
48 #define SST_LPT_DSP_IRAM_OFFSET 0x00000
50 #define SST_SHIM_PM_REG 0x84
52 #define SST_HSW_IRAM 1
53 #define SST_HSW_DRAM 2
54 #define SST_HSW_REGS 3
56 struct dma_block_info
{
57 __le32 type
; /* IRAM/DRAM */
58 __le32 size
; /* Bytes */
59 __le32 ram_offset
; /* Offset in I/DRAM */
60 __le32 rsvd
; /* Reserved field */
61 } __attribute__((packed
));
63 struct fw_module_info
{
64 __le32 persistent_size
;
66 } __attribute__((packed
));
69 unsigned char signature
[SST_HSW_FW_SIGNATURE_SIZE
]; /* FW signature */
70 __le32 file_size
; /* size of fw minus this header */
71 __le32 modules
; /* # of modules */
72 __le32 file_format
; /* version of header format */
74 } __attribute__((packed
));
76 struct fw_module_header
{
77 unsigned char signature
[SST_HSW_FW_SIGNATURE_SIZE
]; /* module signature */
78 __le32 mod_size
; /* size of module */
79 __le32 blocks
; /* # of blocks */
81 __le16 type
; /* codec type, pp lib */
83 struct fw_module_info info
;
84 } __attribute__((packed
));
86 static void hsw_free(struct sst_dsp
*sst
);
88 static int hsw_parse_module(struct sst_dsp
*dsp
, struct sst_fw
*fw
,
89 struct fw_module_header
*module
)
91 struct dma_block_info
*block
;
92 struct sst_module
*mod
;
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_WAVES
104 && module
->type
!= SST_HSW_MODULE_LPAL
)
107 dev_dbg(dsp
->dev
, "new module sign 0x%s size 0x%x blocks 0x%x type 0x%x\n",
108 module
->signature
, module
->mod_size
,
109 module
->blocks
, module
->type
);
110 dev_dbg(dsp
->dev
, " entrypoint 0x%x\n", module
->entry_point
);
111 dev_dbg(dsp
->dev
, " persistent 0x%x scratch 0x%x\n",
112 module
->info
.persistent_size
, module
->info
.scratch_size
);
114 memset(&template, 0, sizeof(template));
115 template.id
= module
->type
;
116 template.entry
= module
->entry_point
- 4;
117 template.persistent_size
= module
->info
.persistent_size
;
118 template.scratch_size
= module
->info
.scratch_size
;
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 mod
->type
= SST_MEM_IRAM
;
145 mod
->offset
= block
->ram_offset
;
146 mod
->type
= SST_MEM_DRAM
;
149 dev_err(dsp
->dev
, "error: bad type 0x%x for block 0x%x\n",
151 sst_module_free(mod
);
155 mod
->size
= block
->size
;
156 mod
->data
= (void *)block
+ sizeof(*block
);
157 mod
->data_offset
= mod
->data
- fw
->dma_buf
;
159 dev_dbg(dsp
->dev
, "module block %d type 0x%x "
160 "size 0x%x ==> ram %p offset 0x%x\n",
161 count
, mod
->type
, block
->size
, ram
,
164 ret
= sst_module_alloc_blocks(mod
);
166 dev_err(dsp
->dev
, "error: could not allocate blocks for module %d\n",
168 sst_module_free(mod
);
172 block
= (void *)block
+ sizeof(*block
) + block
->size
;
174 mod
->state
= SST_MODULE_STATE_LOADED
;
179 static int hsw_parse_fw_image(struct sst_fw
*sst_fw
)
181 struct fw_header
*header
;
182 struct fw_module_header
*module
;
183 struct sst_dsp
*dsp
= sst_fw
->dsp
;
186 /* Read the header information from the data pointer */
187 header
= (struct fw_header
*)sst_fw
->dma_buf
;
190 if ((strncmp(header
->signature
, SST_HSW_FW_SIGN
, 4) != 0) ||
191 (sst_fw
->size
!= header
->file_size
+ sizeof(*header
))) {
192 dev_err(dsp
->dev
, "error: invalid fw sign/filesize mismatch\n");
196 dev_dbg(dsp
->dev
, "header size=0x%x modules=0x%x fmt=0x%x size=%zu\n",
197 header
->file_size
, header
->modules
,
198 header
->file_format
, sizeof(*header
));
200 /* parse each module */
201 module
= (void *)sst_fw
->dma_buf
+ sizeof(*header
);
202 for (count
= 0; count
< header
->modules
; count
++) {
205 ret
= hsw_parse_module(dsp
, sst_fw
, module
);
207 dev_err(dsp
->dev
, "error: invalid module %d\n", count
);
210 module
= (void *)module
+ sizeof(*module
) + module
->mod_size
;
216 static irqreturn_t
hsw_irq(int irq
, void *context
)
218 struct sst_dsp
*sst
= (struct sst_dsp
*) context
;
222 spin_lock(&sst
->spinlock
);
224 /* Interrupt arrived, check src */
225 isr
= sst_dsp_shim_read_unlocked(sst
, SST_ISRX
);
226 if (isr
& SST_ISRX_DONE
) {
227 trace_sst_irq_done(isr
,
228 sst_dsp_shim_read_unlocked(sst
, SST_IMRX
));
230 /* Mask Done interrupt before return */
231 sst_dsp_shim_update_bits_unlocked(sst
, SST_IMRX
,
232 SST_IMRX_DONE
, SST_IMRX_DONE
);
233 ret
= IRQ_WAKE_THREAD
;
236 if (isr
& SST_ISRX_BUSY
) {
237 trace_sst_irq_busy(isr
,
238 sst_dsp_shim_read_unlocked(sst
, SST_IMRX
));
240 /* Mask Busy interrupt before return */
241 sst_dsp_shim_update_bits_unlocked(sst
, SST_IMRX
,
242 SST_IMRX_BUSY
, SST_IMRX_BUSY
);
243 ret
= IRQ_WAKE_THREAD
;
246 spin_unlock(&sst
->spinlock
);
250 static void hsw_set_dsp_D3(struct sst_dsp
*sst
)
255 /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
256 reg
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
257 reg
&= ~(SST_VDRTCL2_DCLCGE
| SST_VDRTCL2_DTCGE
);
258 writel(reg
, sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
260 /* enable power gating and switch off DRAM & IRAM blocks */
261 val
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
262 val
|= SST_VDRTCL0_DSRAMPGE_MASK
|
263 SST_VDRTCL0_ISRAMPGE_MASK
;
264 val
&= ~(SST_VDRTCL0_D3PGD
| SST_VDRTCL0_D3SRAMPGD
);
265 writel(val
, sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
267 /* switch off audio PLL */
268 val
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
269 val
|= SST_VDRTCL2_APLLSE_MASK
;
270 writel(val
, sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
272 /* disable MCLK(clkctl.smos = 0) */
273 sst_dsp_shim_update_bits_unlocked(sst
, SST_CLKCTL
,
276 /* Set D3 state, delay 50 us */
277 val
= readl(sst
->addr
.pci_cfg
+ SST_PMCS
);
278 val
|= SST_PMCS_PS_MASK
;
279 writel(val
, sst
->addr
.pci_cfg
+ SST_PMCS
);
282 /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */
283 reg
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
284 reg
|= SST_VDRTCL2_DCLCGE
| SST_VDRTCL2_DTCGE
;
285 writel(reg
, sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
291 static void hsw_reset(struct sst_dsp
*sst
)
293 /* put DSP into reset and stall */
294 sst_dsp_shim_update_bits_unlocked(sst
, SST_CSR
,
295 SST_CSR_RST
| SST_CSR_STALL
,
296 SST_CSR_RST
| SST_CSR_STALL
);
298 /* keep in reset for 10ms */
301 /* take DSP out of reset and keep stalled for FW loading */
302 sst_dsp_shim_update_bits_unlocked(sst
, SST_CSR
,
303 SST_CSR_RST
| SST_CSR_STALL
, SST_CSR_STALL
);
306 static int hsw_set_dsp_D0(struct sst_dsp
*sst
)
309 u32 reg
, fw_dump_bit
;
311 /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
312 reg
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
313 reg
&= ~(SST_VDRTCL2_DCLCGE
| SST_VDRTCL2_DTCGE
);
314 writel(reg
, sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
316 /* Disable D3PG (VDRTCTL0.D3PGD = 1) */
317 reg
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
318 reg
|= SST_VDRTCL0_D3PGD
;
319 writel(reg
, sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
322 reg
= readl(sst
->addr
.pci_cfg
+ SST_PMCS
);
323 reg
&= ~SST_PMCS_PS_MASK
;
324 writel(reg
, sst
->addr
.pci_cfg
+ SST_PMCS
);
326 /* check that ADSP shim is enabled */
328 reg
= readl(sst
->addr
.pci_cfg
+ SST_PMCS
) & SST_PMCS_PS_MASK
;
338 /* select SSP1 19.2MHz base clock, SSP clock 0, turn off Low Power Clock */
339 sst_dsp_shim_update_bits_unlocked(sst
, SST_CSR
,
340 SST_CSR_S1IOCS
| SST_CSR_SBCS1
| SST_CSR_LPCS
, 0x0);
342 /* stall DSP core, set clk to 192/96Mhz */
343 sst_dsp_shim_update_bits_unlocked(sst
,
344 SST_CSR
, SST_CSR_STALL
| SST_CSR_DCS_MASK
,
345 SST_CSR_STALL
| SST_CSR_DCS(4));
347 /* Set 24MHz MCLK, prevent local clock gating, enable SSP0 clock */
348 sst_dsp_shim_update_bits_unlocked(sst
, SST_CLKCTL
,
349 SST_CLKCTL_MASK
| SST_CLKCTL_DCPLCG
| SST_CLKCTL_SCOE0
,
350 SST_CLKCTL_MASK
| SST_CLKCTL_DCPLCG
| SST_CLKCTL_SCOE0
);
352 /* Stall and reset core, set CSR */
355 /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */
356 reg
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
357 reg
|= SST_VDRTCL2_DCLCGE
| SST_VDRTCL2_DTCGE
;
358 writel(reg
, sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
362 /* switch on audio PLL */
363 reg
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
364 reg
&= ~SST_VDRTCL2_APLLSE_MASK
;
365 writel(reg
, sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
367 /* set default power gating control, enable power gating control for all blocks. that is,
368 can't be accessed, please enable each block before accessing. */
369 reg
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
370 reg
|= SST_VDRTCL0_DSRAMPGE_MASK
| SST_VDRTCL0_ISRAMPGE_MASK
;
371 /* for D0, always enable the block(DSRAM[0]) used for FW dump */
372 fw_dump_bit
= 1 << SST_VDRTCL0_DSRAMPGE_SHIFT
;
373 writel(reg
& ~fw_dump_bit
, sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
376 /* disable DMA finish function for SSP0 & SSP1 */
377 sst_dsp_shim_update_bits_unlocked(sst
, SST_CSR2
, SST_CSR2_SDFD_SSP1
,
380 /* set on-demond mode on engine 0,1 for all channels */
381 sst_dsp_shim_update_bits(sst
, SST_HMDC
,
382 SST_HMDC_HDDA_E0_ALLCH
| SST_HMDC_HDDA_E1_ALLCH
,
383 SST_HMDC_HDDA_E0_ALLCH
| SST_HMDC_HDDA_E1_ALLCH
);
385 /* Enable Interrupt from both sides */
386 sst_dsp_shim_update_bits(sst
, SST_IMRX
, (SST_IMRX_BUSY
| SST_IMRX_DONE
),
388 sst_dsp_shim_update_bits(sst
, SST_IMRD
, (SST_IMRD_DONE
| SST_IMRD_BUSY
|
389 SST_IMRD_SSP0
| SST_IMRD_DMAC
), 0x0);
391 /* clear IPC registers */
392 sst_dsp_shim_write(sst
, SST_IPCX
, 0x0);
393 sst_dsp_shim_write(sst
, SST_IPCD
, 0x0);
394 sst_dsp_shim_write(sst
, 0x80, 0x6);
395 sst_dsp_shim_write(sst
, 0xe0, 0x300a);
400 static void hsw_boot(struct sst_dsp
*sst
)
402 /* set oportunistic mode on engine 0,1 for all channels */
403 sst_dsp_shim_update_bits(sst
, SST_HMDC
,
404 SST_HMDC_HDDA_E0_ALLCH
| SST_HMDC_HDDA_E1_ALLCH
, 0);
407 sst_dsp_shim_update_bits_unlocked(sst
, SST_CSR
, SST_CSR_STALL
, 0x0);
410 static void hsw_stall(struct sst_dsp
*sst
)
413 sst_dsp_shim_update_bits(sst
, SST_CSR
,
414 SST_CSR_24MHZ_LPCS
| SST_CSR_STALL
,
415 SST_CSR_STALL
| SST_CSR_24MHZ_LPCS
);
418 static void hsw_sleep(struct sst_dsp
*sst
)
420 dev_dbg(sst
->dev
, "HSW_PM dsp runtime suspend\n");
422 /* put DSP into reset and stall */
423 sst_dsp_shim_update_bits(sst
, SST_CSR
,
424 SST_CSR_24MHZ_LPCS
| SST_CSR_RST
| SST_CSR_STALL
,
425 SST_CSR_RST
| SST_CSR_STALL
| SST_CSR_24MHZ_LPCS
);
428 dev_dbg(sst
->dev
, "HSW_PM dsp runtime suspend exit\n");
431 static int hsw_wake(struct sst_dsp
*sst
)
435 dev_dbg(sst
->dev
, "HSW_PM dsp runtime resume\n");
437 ret
= hsw_set_dsp_D0(sst
);
441 dev_dbg(sst
->dev
, "HSW_PM dsp runtime resume exit\n");
446 struct sst_adsp_memregion
{
450 enum sst_mem_type type
;
453 /* lynx point ADSP mem regions */
454 static const struct sst_adsp_memregion lp_region
[] = {
455 {0x00000, 0x40000, 8, SST_MEM_DRAM
}, /* D-SRAM0 - 8 * 32kB */
456 {0x40000, 0x80000, 8, SST_MEM_DRAM
}, /* D-SRAM1 - 8 * 32kB */
457 {0x80000, 0xE0000, 12, SST_MEM_IRAM
}, /* I-SRAM - 12 * 32kB */
460 /* wild cat point ADSP mem regions */
461 static const struct sst_adsp_memregion wpt_region
[] = {
462 {0x00000, 0xA0000, 20, SST_MEM_DRAM
}, /* D-SRAM0,D-SRAM1,D-SRAM2 - 20 * 32kB */
463 {0xA0000, 0xF0000, 10, SST_MEM_IRAM
}, /* I-SRAM - 10 * 32kB */
466 static int hsw_acpi_resource_map(struct sst_dsp
*sst
, struct sst_pdata
*pdata
)
468 /* ADSP DRAM & IRAM */
469 sst
->addr
.lpe_base
= pdata
->lpe_base
;
470 sst
->addr
.lpe
= ioremap(pdata
->lpe_base
, pdata
->lpe_size
);
474 /* ADSP PCI MMIO config space */
475 sst
->addr
.pci_cfg
= ioremap(pdata
->pcicfg_base
, pdata
->pcicfg_size
);
476 if (!sst
->addr
.pci_cfg
) {
477 iounmap(sst
->addr
.lpe
);
482 sst
->addr
.shim
= sst
->addr
.lpe
+ sst
->addr
.shim_offset
;
486 struct sst_sram_shift
{
487 u32 dev_id
; /* SST Device IDs */
492 static const struct sst_sram_shift sram_shift
[] = {
493 {SST_DEV_ID_LYNX_POINT
, 6, 16}, /* lp */
494 {SST_DEV_ID_WILDCAT_POINT
, 2, 12}, /* wpt */
497 static u32
hsw_block_get_bit(struct sst_mem_block
*block
)
499 u32 bit
= 0, shift
= 0, index
;
500 struct sst_dsp
*sst
= block
->dsp
;
502 for (index
= 0; index
< ARRAY_SIZE(sram_shift
); index
++) {
503 if (sram_shift
[index
].dev_id
== sst
->id
)
507 if (index
< ARRAY_SIZE(sram_shift
)) {
508 switch (block
->type
) {
510 shift
= sram_shift
[index
].dram_shift
;
513 shift
= sram_shift
[index
].iram_shift
;
521 bit
= 1 << (block
->index
+ shift
);
526 /*dummy read a SRAM block.*/
527 static void sst_mem_block_dummy_read(struct sst_mem_block
*block
)
531 struct sst_dsp
*sst
= block
->dsp
;
533 size
= block
->size
> 4 ? 4 : block
->size
;
534 memcpy_fromio(tmp_buf
, sst
->addr
.lpe
+ block
->offset
, size
);
537 /* enable 32kB memory block - locks held by caller */
538 static int hsw_block_enable(struct sst_mem_block
*block
)
540 struct sst_dsp
*sst
= block
->dsp
;
543 if (block
->users
++ > 0)
546 dev_dbg(block
->dsp
->dev
, " enabled block %d:%d at offset 0x%x\n",
547 block
->type
, block
->index
, block
->offset
);
549 /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
550 val
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
551 val
&= ~SST_VDRTCL2_DCLCGE
;
552 writel(val
, sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
554 val
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
555 bit
= hsw_block_get_bit(block
);
556 writel(val
& ~bit
, sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
558 /* wait 18 DSP clock ticks */
561 /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */
562 val
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
563 val
|= SST_VDRTCL2_DCLCGE
;
564 writel(val
, sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
568 /*add a dummy read before the SRAM block is written, otherwise the writing may miss bytes sometimes.*/
569 sst_mem_block_dummy_read(block
);
573 /* disable 32kB memory block - locks held by caller */
574 static int hsw_block_disable(struct sst_mem_block
*block
)
576 struct sst_dsp
*sst
= block
->dsp
;
579 if (--block
->users
> 0)
582 dev_dbg(block
->dsp
->dev
, " disabled block %d:%d at offset 0x%x\n",
583 block
->type
, block
->index
, block
->offset
);
585 /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
586 val
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
587 val
&= ~SST_VDRTCL2_DCLCGE
;
588 writel(val
, sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
591 val
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
592 bit
= hsw_block_get_bit(block
);
593 /* don't disable DSRAM[0], keep it always enable for FW dump*/
594 if (bit
!= (1 << SST_VDRTCL0_DSRAMPGE_SHIFT
))
595 writel(val
| bit
, sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
597 /* wait 18 DSP clock ticks */
600 /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */
601 val
= readl(sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
602 val
|= SST_VDRTCL2_DCLCGE
;
603 writel(val
, sst
->addr
.pci_cfg
+ SST_VDRTCTL2
);
610 static const struct sst_block_ops sst_hsw_ops
= {
611 .enable
= hsw_block_enable
,
612 .disable
= hsw_block_disable
,
615 static int hsw_init(struct sst_dsp
*sst
, struct sst_pdata
*pdata
)
617 const struct sst_adsp_memregion
*region
;
619 int ret
= -ENODEV
, i
, j
, region_count
;
620 u32 offset
, size
, fw_dump_bit
;
625 case SST_DEV_ID_LYNX_POINT
:
627 region_count
= ARRAY_SIZE(lp_region
);
628 sst
->addr
.iram_offset
= SST_LP_IRAM_OFFSET
;
629 sst
->addr
.dsp_iram_offset
= SST_LPT_DSP_IRAM_OFFSET
;
630 sst
->addr
.dsp_dram_offset
= SST_LPT_DSP_DRAM_OFFSET
;
631 sst
->addr
.shim_offset
= SST_LP_SHIM_OFFSET
;
633 case SST_DEV_ID_WILDCAT_POINT
:
635 region_count
= ARRAY_SIZE(wpt_region
);
636 sst
->addr
.iram_offset
= SST_WPT_IRAM_OFFSET
;
637 sst
->addr
.dsp_iram_offset
= SST_WPT_DSP_IRAM_OFFSET
;
638 sst
->addr
.dsp_dram_offset
= SST_WPT_DSP_DRAM_OFFSET
;
639 sst
->addr
.shim_offset
= SST_WPT_SHIM_OFFSET
;
642 dev_err(dev
, "error: failed to get mem resources\n");
646 ret
= hsw_acpi_resource_map(sst
, pdata
);
648 dev_err(dev
, "error: failed to map resources\n");
652 /* enable the DSP SHIM */
653 ret
= hsw_set_dsp_D0(sst
);
655 dev_err(dev
, "error: failed to set DSP D0 and reset SHIM\n");
659 ret
= dma_coerce_mask_and_coherent(dev
, DMA_BIT_MASK(31));
664 /* register DSP memory blocks - ideally we should get this from ACPI */
665 for (i
= 0; i
< region_count
; i
++) {
666 offset
= region
[i
].start
;
667 size
= (region
[i
].end
- region
[i
].start
) / region
[i
].blocks
;
669 /* register individual memory blocks */
670 for (j
= 0; j
< region
[i
].blocks
; j
++) {
671 sst_mem_block_register(sst
, offset
, size
,
672 region
[i
].type
, &sst_hsw_ops
, j
, sst
);
677 /* always enable the block(DSRAM[0]) used for FW dump */
678 fw_dump_bit
= 1 << SST_VDRTCL0_DSRAMPGE_SHIFT
;
679 /* set default power gating control, enable power gating control for all blocks. that is,
680 can't be accessed, please enable each block before accessing. */
681 writel(0xffffffff & ~fw_dump_bit
, sst
->addr
.pci_cfg
+ SST_VDRTCTL0
);
686 static void hsw_free(struct sst_dsp
*sst
)
688 sst_mem_block_unregister_all(sst
);
689 iounmap(sst
->addr
.lpe
);
690 iounmap(sst
->addr
.pci_cfg
);
693 struct sst_ops haswell_ops
= {
699 .write
= sst_shim32_write
,
700 .read
= sst_shim32_read
,
701 .write64
= sst_shim32_write64
,
702 .read64
= sst_shim32_read64
,
703 .ram_read
= sst_memcpy_fromio_32
,
704 .ram_write
= sst_memcpy_toio_32
,
705 .irq_handler
= hsw_irq
,
708 .parse_fw
= hsw_parse_fw_image
,