Lines Matching +full:reset +full:- +full:delay +full:- +full:us
1 // SPDX-License-Identifier: GPL-2.0-only
8 #include <linux/delay.h>
16 #include <linux/dma-mapping.h>
22 #include "../common/sst-dsp.h"
23 #include "../common/sst-dsp-priv.h"
24 #include "../haswell/sst-haswell-ipc.h"
87 int type = le16_to_cpu(module->type); in hsw_parse_module()
88 int entry_point = le32_to_cpu(module->entry_point); in hsw_parse_module()
100 dev_dbg(dsp->dev, "new module sign 0x%s size 0x%x blocks 0x%x type 0x%x\n", in hsw_parse_module()
101 module->signature, module->mod_size, in hsw_parse_module()
102 module->blocks, type); in hsw_parse_module()
103 dev_dbg(dsp->dev, " entrypoint 0x%x\n", entry_point); in hsw_parse_module()
104 dev_dbg(dsp->dev, " persistent 0x%x scratch 0x%x\n", in hsw_parse_module()
105 module->info.persistent_size, module->info.scratch_size); in hsw_parse_module()
109 template.entry = entry_point - 4; in hsw_parse_module()
110 template.persistent_size = le32_to_cpu(module->info.persistent_size); in hsw_parse_module()
111 template.scratch_size = le32_to_cpu(module->info.scratch_size); in hsw_parse_module()
115 return -ENOMEM; in hsw_parse_module()
119 for (count = 0; count < le32_to_cpu(module->blocks); count++) { in hsw_parse_module()
121 if (le32_to_cpu(block->size) <= 0) { in hsw_parse_module()
122 dev_err(dsp->dev, in hsw_parse_module()
125 return -EINVAL; in hsw_parse_module()
128 switch (le32_to_cpu(block->type)) { in hsw_parse_module()
130 ram = dsp->addr.lpe; in hsw_parse_module()
131 mod->offset = le32_to_cpu(block->ram_offset) + in hsw_parse_module()
132 dsp->addr.iram_offset; in hsw_parse_module()
133 mod->type = SST_MEM_IRAM; in hsw_parse_module()
137 ram = dsp->addr.lpe; in hsw_parse_module()
138 mod->offset = le32_to_cpu(block->ram_offset); in hsw_parse_module()
139 mod->type = SST_MEM_DRAM; in hsw_parse_module()
142 dev_err(dsp->dev, "error: bad type 0x%x for block 0x%x\n", in hsw_parse_module()
143 block->type, count); in hsw_parse_module()
145 return -EINVAL; in hsw_parse_module()
148 mod->size = le32_to_cpu(block->size); in hsw_parse_module()
149 mod->data = (void *)block + sizeof(*block); in hsw_parse_module()
150 mod->data_offset = mod->data - fw->dma_buf; in hsw_parse_module()
152 dev_dbg(dsp->dev, "module block %d type 0x%x " in hsw_parse_module()
154 count, mod->type, block->size, ram, in hsw_parse_module()
155 block->ram_offset); in hsw_parse_module()
159 dev_err(dsp->dev, "error: could not allocate blocks for module %d\n", in hsw_parse_module()
166 le32_to_cpu(block->size); in hsw_parse_module()
168 mod->state = SST_MODULE_STATE_LOADED; in hsw_parse_module()
177 struct sst_dsp *dsp = sst_fw->dsp; in hsw_parse_fw_image()
181 header = (struct fw_header *)sst_fw->dma_buf; in hsw_parse_fw_image()
184 if ((strncmp(header->signature, SST_HSW_FW_SIGN, 4) != 0) || in hsw_parse_fw_image()
185 (sst_fw->size != in hsw_parse_fw_image()
186 le32_to_cpu(header->file_size) + sizeof(*header))) { in hsw_parse_fw_image()
187 dev_err(dsp->dev, "error: invalid fw sign/filesize mismatch\n"); in hsw_parse_fw_image()
188 return -EINVAL; in hsw_parse_fw_image()
191 dev_dbg(dsp->dev, "header size=0x%x modules=0x%x fmt=0x%x size=%zu\n", in hsw_parse_fw_image()
192 header->file_size, header->modules, in hsw_parse_fw_image()
193 header->file_format, sizeof(*header)); in hsw_parse_fw_image()
196 module = (void *)sst_fw->dma_buf + sizeof(*header); in hsw_parse_fw_image()
197 for (count = 0; count < le32_to_cpu(header->modules); count++) { in hsw_parse_fw_image()
202 dev_err(dsp->dev, "error: invalid module %d\n", count); in hsw_parse_fw_image()
206 le32_to_cpu(module->mod_size); in hsw_parse_fw_image()
218 spin_lock(&sst->spinlock); in hsw_irq()
242 spin_unlock(&sst->spinlock); in hsw_irq()
252 reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_set_dsp_D3()
254 writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_set_dsp_D3()
257 val = readl(sst->addr.pci_cfg + SST_VDRTCTL0); in hsw_set_dsp_D3()
261 writel(val, sst->addr.pci_cfg + SST_VDRTCTL0); in hsw_set_dsp_D3()
264 val = readl(sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_set_dsp_D3()
266 writel(val, sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_set_dsp_D3()
272 /* Set D3 state, delay 50 us */ in hsw_set_dsp_D3()
273 val = readl(sst->addr.pci_cfg + SST_PMCS); in hsw_set_dsp_D3()
275 writel(val, sst->addr.pci_cfg + SST_PMCS); in hsw_set_dsp_D3()
278 /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */ in hsw_set_dsp_D3()
279 reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_set_dsp_D3()
281 writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_set_dsp_D3()
289 /* put DSP into reset and stall */ in hsw_reset()
294 /* keep in reset for 10ms */ in hsw_reset()
297 /* take DSP out of reset and keep stalled for FW loading */ in hsw_reset()
308 reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_set_dsp_D0()
310 writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_set_dsp_D0()
313 reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); in hsw_set_dsp_D0()
315 writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0); in hsw_set_dsp_D0()
318 reg = readl(sst->addr.pci_cfg + SST_PMCS); in hsw_set_dsp_D0()
320 writel(reg, sst->addr.pci_cfg + SST_PMCS); in hsw_set_dsp_D0()
323 while (tries--) { in hsw_set_dsp_D0()
324 reg = readl(sst->addr.pci_cfg + SST_PMCS) & SST_PMCS_PS_MASK; in hsw_set_dsp_D0()
331 return -ENODEV; in hsw_set_dsp_D0()
348 /* Stall and reset core, set CSR */ in hsw_set_dsp_D0()
351 /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */ in hsw_set_dsp_D0()
352 reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_set_dsp_D0()
354 writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_set_dsp_D0()
359 reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_set_dsp_D0()
361 writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_set_dsp_D0()
365 reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); in hsw_set_dsp_D0()
369 writel(reg & ~fw_dump_bit, sst->addr.pci_cfg + SST_VDRTCTL0); in hsw_set_dsp_D0()
376 /* set on-demond mode on engine 0,1 for all channels */ in hsw_set_dsp_D0()
416 dev_dbg(sst->dev, "HSW_PM dsp runtime suspend\n"); in hsw_sleep()
418 /* put DSP into reset and stall */ in hsw_sleep()
424 dev_dbg(sst->dev, "HSW_PM dsp runtime suspend exit\n"); in hsw_sleep()
431 dev_dbg(sst->dev, "HSW_PM dsp runtime resume\n"); in hsw_wake()
437 dev_dbg(sst->dev, "HSW_PM dsp runtime resume exit\n"); in hsw_wake()
451 {0x00000, 0x40000, 8, SST_MEM_DRAM}, /* D-SRAM0 - 8 * 32kB */
452 {0x40000, 0x80000, 8, SST_MEM_DRAM}, /* D-SRAM1 - 8 * 32kB */
453 {0x80000, 0xE0000, 12, SST_MEM_IRAM}, /* I-SRAM - 12 * 32kB */
458 {0x00000, 0xA0000, 20, SST_MEM_DRAM}, /* D-SRAM0,D-SRAM1,D-SRAM2 - 20 * 32kB */
459 {0xA0000, 0xF0000, 10, SST_MEM_IRAM}, /* I-SRAM - 10 * 32kB */
465 sst->addr.lpe_base = pdata->lpe_base; in hsw_acpi_resource_map()
466 sst->addr.lpe = ioremap(pdata->lpe_base, pdata->lpe_size); in hsw_acpi_resource_map()
467 if (!sst->addr.lpe) in hsw_acpi_resource_map()
468 return -ENODEV; in hsw_acpi_resource_map()
471 sst->addr.pci_cfg = ioremap(pdata->pcicfg_base, pdata->pcicfg_size); in hsw_acpi_resource_map()
472 if (!sst->addr.pci_cfg) { in hsw_acpi_resource_map()
473 iounmap(sst->addr.lpe); in hsw_acpi_resource_map()
474 return -ENODEV; in hsw_acpi_resource_map()
478 sst->addr.shim = sst->addr.lpe + sst->addr.shim_offset; in hsw_acpi_resource_map()
496 struct sst_dsp *sst = block->dsp; in hsw_block_get_bit()
499 if (sram_shift[index].dev_id == sst->id) in hsw_block_get_bit()
504 switch (block->type) { in hsw_block_get_bit()
517 bit = 1 << (block->index + shift); in hsw_block_get_bit()
527 struct sst_dsp *sst = block->dsp; in sst_mem_block_dummy_read()
529 size = block->size > 4 ? 4 : block->size; in sst_mem_block_dummy_read()
530 memcpy_fromio(tmp_buf, sst->addr.lpe + block->offset, size); in sst_mem_block_dummy_read()
533 /* enable 32kB memory block - locks held by caller */
536 struct sst_dsp *sst = block->dsp; in hsw_block_enable()
539 if (block->users++ > 0) in hsw_block_enable()
542 dev_dbg(block->dsp->dev, " enabled block %d:%d at offset 0x%x\n", in hsw_block_enable()
543 block->type, block->index, block->offset); in hsw_block_enable()
546 val = readl(sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_block_enable()
548 writel(val, sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_block_enable()
550 val = readl(sst->addr.pci_cfg + SST_VDRTCTL0); in hsw_block_enable()
552 writel(val & ~bit, sst->addr.pci_cfg + SST_VDRTCTL0); in hsw_block_enable()
557 /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */ in hsw_block_enable()
558 val = readl(sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_block_enable()
560 writel(val, sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_block_enable()
569 /* disable 32kB memory block - locks held by caller */
572 struct sst_dsp *sst = block->dsp; in hsw_block_disable()
575 if (--block->users > 0) in hsw_block_disable()
578 dev_dbg(block->dsp->dev, " disabled block %d:%d at offset 0x%x\n", in hsw_block_disable()
579 block->type, block->index, block->offset); in hsw_block_disable()
582 val = readl(sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_block_disable()
584 writel(val, sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_block_disable()
587 val = readl(sst->addr.pci_cfg + SST_VDRTCTL0); in hsw_block_disable()
591 writel(val | bit, sst->addr.pci_cfg + SST_VDRTCTL0); in hsw_block_disable()
596 /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */ in hsw_block_disable()
597 val = readl(sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_block_disable()
599 writel(val, sst->addr.pci_cfg + SST_VDRTCTL2); in hsw_block_disable()
615 int ret = -ENODEV, i, j, region_count; in hsw_init()
618 dev = sst->dma_dev; in hsw_init()
620 switch (sst->id) { in hsw_init()
624 sst->addr.iram_offset = SST_LP_IRAM_OFFSET; in hsw_init()
625 sst->addr.dsp_iram_offset = SST_LPT_DSP_IRAM_OFFSET; in hsw_init()
626 sst->addr.dsp_dram_offset = SST_LPT_DSP_DRAM_OFFSET; in hsw_init()
627 sst->addr.shim_offset = SST_LP_SHIM_OFFSET; in hsw_init()
632 sst->addr.iram_offset = SST_WPT_IRAM_OFFSET; in hsw_init()
633 sst->addr.dsp_iram_offset = SST_WPT_DSP_IRAM_OFFSET; in hsw_init()
634 sst->addr.dsp_dram_offset = SST_WPT_DSP_DRAM_OFFSET; in hsw_init()
635 sst->addr.shim_offset = SST_WPT_SHIM_OFFSET; in hsw_init()
651 dev_err(dev, "error: failed to set DSP D0 and reset SHIM\n"); in hsw_init()
660 /* register DSP memory blocks - ideally we should get this from ACPI */ in hsw_init()
663 size = (region[i].end - region[i].start) / region[i].blocks; in hsw_init()
677 writel(0xffffffff & ~fw_dump_bit, sst->addr.pci_cfg + SST_VDRTCTL0); in hsw_init()
685 iounmap(sst->addr.lpe); in hsw_free()
686 iounmap(sst->addr.pci_cfg); in hsw_free()
690 .reset = hsw_reset,