root/sound/soc/intel/haswell/sst-haswell-dsp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hsw_parse_module
  2. hsw_parse_fw_image
  3. hsw_irq
  4. hsw_set_dsp_D3
  5. hsw_reset
  6. hsw_set_dsp_D0
  7. hsw_boot
  8. hsw_stall
  9. hsw_sleep
  10. hsw_wake
  11. hsw_acpi_resource_map
  12. hsw_block_get_bit
  13. sst_mem_block_dummy_read
  14. hsw_block_enable
  15. hsw_block_disable
  16. hsw_init
  17. hsw_free

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Intel Haswell SST DSP driver
   4  *
   5  * Copyright (C) 2013, Intel Corporation. All rights reserved.
   6  */
   7 
   8 #include <linux/delay.h>
   9 #include <linux/fs.h>
  10 #include <linux/slab.h>
  11 #include <linux/device.h>
  12 #include <linux/sched.h>
  13 #include <linux/export.h>
  14 #include <linux/interrupt.h>
  15 #include <linux/module.h>
  16 #include <linux/dma-mapping.h>
  17 #include <linux/platform_device.h>
  18 #include <linux/pci.h>
  19 #include <linux/firmware.h>
  20 #include <linux/pm_runtime.h>
  21 
  22 #include "../common/sst-dsp.h"
  23 #include "../common/sst-dsp-priv.h"
  24 #include "../haswell/sst-haswell-ipc.h"
  25 
  26 #include <trace/events/hswadsp.h>
  27 
  28 #define SST_HSW_FW_SIGNATURE_SIZE       4
  29 #define SST_HSW_FW_SIGN                 "$SST"
  30 #define SST_HSW_FW_LIB_SIGN             "$LIB"
  31 
  32 #define SST_WPT_SHIM_OFFSET     0xFB000
  33 #define SST_LP_SHIM_OFFSET      0xE7000
  34 #define SST_WPT_IRAM_OFFSET     0xA0000
  35 #define SST_LP_IRAM_OFFSET      0x80000
  36 #define SST_WPT_DSP_DRAM_OFFSET 0x400000
  37 #define SST_WPT_DSP_IRAM_OFFSET 0x00000
  38 #define SST_LPT_DSP_DRAM_OFFSET 0x400000
  39 #define SST_LPT_DSP_IRAM_OFFSET 0x00000
  40 
  41 #define SST_SHIM_PM_REG         0x84
  42 
  43 #define SST_HSW_IRAM    1
  44 #define SST_HSW_DRAM    2
  45 #define SST_HSW_REGS    3
  46 
  47 struct dma_block_info {
  48         __le32 type;            /* IRAM/DRAM */
  49         __le32 size;            /* Bytes */
  50         __le32 ram_offset;      /* Offset in I/DRAM */
  51         __le32 rsvd;            /* Reserved field */
  52 } __attribute__((packed));
  53 
  54 struct fw_module_info {
  55         __le32 persistent_size;
  56         __le32 scratch_size;
  57 } __attribute__((packed));
  58 
  59 struct fw_header {
  60         unsigned char signature[SST_HSW_FW_SIGNATURE_SIZE]; /* FW signature */
  61         __le32 file_size;               /* size of fw minus this header */
  62         __le32 modules;         /*  # of modules */
  63         __le32 file_format;     /* version of header format */
  64         __le32 reserved[4];
  65 } __attribute__((packed));
  66 
  67 struct fw_module_header {
  68         unsigned char signature[SST_HSW_FW_SIGNATURE_SIZE]; /* module signature */
  69         __le32 mod_size;        /* size of module */
  70         __le32 blocks;  /* # of blocks */
  71         __le16 padding;
  72         __le16 type;    /* codec type, pp lib */
  73         __le32 entry_point;
  74         struct fw_module_info info;
  75 } __attribute__((packed));
  76 
  77 static void hsw_free(struct sst_dsp *sst);
  78 
  79 static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw,
  80         struct fw_module_header *module)
  81 {
  82         struct dma_block_info *block;
  83         struct sst_module *mod;
  84         struct sst_module_template template;
  85         int count, ret;
  86         void __iomem *ram;
  87         int type = le16_to_cpu(module->type);
  88         int entry_point = le32_to_cpu(module->entry_point);
  89 
  90         /* TODO: allowed module types need to be configurable */
  91         if (type != SST_HSW_MODULE_BASE_FW &&
  92             type != SST_HSW_MODULE_PCM_SYSTEM &&
  93             type != SST_HSW_MODULE_PCM &&
  94             type != SST_HSW_MODULE_PCM_REFERENCE &&
  95             type != SST_HSW_MODULE_PCM_CAPTURE &&
  96             type != SST_HSW_MODULE_WAVES &&
  97             type != SST_HSW_MODULE_LPAL)
  98                 return 0;
  99 
 100         dev_dbg(dsp->dev, "new module sign 0x%s size 0x%x blocks 0x%x type 0x%x\n",
 101                 module->signature, module->mod_size,
 102                 module->blocks, type);
 103         dev_dbg(dsp->dev, " entrypoint 0x%x\n", entry_point);
 104         dev_dbg(dsp->dev, " persistent 0x%x scratch 0x%x\n",
 105                 module->info.persistent_size, module->info.scratch_size);
 106 
 107         memset(&template, 0, sizeof(template));
 108         template.id = type;
 109         template.entry = entry_point - 4;
 110         template.persistent_size = le32_to_cpu(module->info.persistent_size);
 111         template.scratch_size = le32_to_cpu(module->info.scratch_size);
 112 
 113         mod = sst_module_new(fw, &template, NULL);
 114         if (mod == NULL)
 115                 return -ENOMEM;
 116 
 117         block = (void *)module + sizeof(*module);
 118 
 119         for (count = 0; count < le32_to_cpu(module->blocks); count++) {
 120 
 121                 if (le32_to_cpu(block->size) <= 0) {
 122                         dev_err(dsp->dev,
 123                                 "error: block %d size invalid\n", count);
 124                         sst_module_free(mod);
 125                         return -EINVAL;
 126                 }
 127 
 128                 switch (le32_to_cpu(block->type)) {
 129                 case SST_HSW_IRAM:
 130                         ram = dsp->addr.lpe;
 131                         mod->offset = le32_to_cpu(block->ram_offset) +
 132                                 dsp->addr.iram_offset;
 133                         mod->type = SST_MEM_IRAM;
 134                         break;
 135                 case SST_HSW_DRAM:
 136                 case SST_HSW_REGS:
 137                         ram = dsp->addr.lpe;
 138                         mod->offset = le32_to_cpu(block->ram_offset);
 139                         mod->type = SST_MEM_DRAM;
 140                         break;
 141                 default:
 142                         dev_err(dsp->dev, "error: bad type 0x%x for block 0x%x\n",
 143                                 block->type, count);
 144                         sst_module_free(mod);
 145                         return -EINVAL;
 146                 }
 147 
 148                 mod->size = le32_to_cpu(block->size);
 149                 mod->data = (void *)block + sizeof(*block);
 150                 mod->data_offset = mod->data - fw->dma_buf;
 151 
 152                 dev_dbg(dsp->dev, "module block %d type 0x%x "
 153                         "size 0x%x ==> ram %p offset 0x%x\n",
 154                         count, mod->type, block->size, ram,
 155                         block->ram_offset);
 156 
 157                 ret = sst_module_alloc_blocks(mod);
 158                 if (ret < 0) {
 159                         dev_err(dsp->dev, "error: could not allocate blocks for module %d\n",
 160                                 count);
 161                         sst_module_free(mod);
 162                         return ret;
 163                 }
 164 
 165                 block = (void *)block + sizeof(*block) +
 166                         le32_to_cpu(block->size);
 167         }
 168         mod->state = SST_MODULE_STATE_LOADED;
 169 
 170         return 0;
 171 }
 172 
 173 static int hsw_parse_fw_image(struct sst_fw *sst_fw)
 174 {
 175         struct fw_header *header;
 176         struct fw_module_header *module;
 177         struct sst_dsp *dsp = sst_fw->dsp;
 178         int ret, count;
 179 
 180         /* Read the header information from the data pointer */
 181         header = (struct fw_header *)sst_fw->dma_buf;
 182 
 183         /* verify FW */
 184         if ((strncmp(header->signature, SST_HSW_FW_SIGN, 4) != 0) ||
 185             (sst_fw->size !=
 186              le32_to_cpu(header->file_size) + sizeof(*header))) {
 187                 dev_err(dsp->dev, "error: invalid fw sign/filesize mismatch\n");
 188                 return -EINVAL;
 189         }
 190 
 191         dev_dbg(dsp->dev, "header size=0x%x modules=0x%x fmt=0x%x size=%zu\n",
 192                 header->file_size, header->modules,
 193                 header->file_format, sizeof(*header));
 194 
 195         /* parse each module */
 196         module = (void *)sst_fw->dma_buf + sizeof(*header);
 197         for (count = 0; count < le32_to_cpu(header->modules); count++) {
 198 
 199                 /* module */
 200                 ret = hsw_parse_module(dsp, sst_fw, module);
 201                 if (ret < 0) {
 202                         dev_err(dsp->dev, "error: invalid module %d\n", count);
 203                         return ret;
 204                 }
 205                 module = (void *)module + sizeof(*module) +
 206                         le32_to_cpu(module->mod_size);
 207         }
 208 
 209         return 0;
 210 }
 211 
 212 static irqreturn_t hsw_irq(int irq, void *context)
 213 {
 214         struct sst_dsp *sst = (struct sst_dsp *) context;
 215         u32 isr;
 216         int ret = IRQ_NONE;
 217 
 218         spin_lock(&sst->spinlock);
 219 
 220         /* Interrupt arrived, check src */
 221         isr = sst_dsp_shim_read_unlocked(sst, SST_ISRX);
 222         if (isr & SST_ISRX_DONE) {
 223                 trace_sst_irq_done(isr,
 224                         sst_dsp_shim_read_unlocked(sst, SST_IMRX));
 225 
 226                 /* Mask Done interrupt before return */
 227                 sst_dsp_shim_update_bits_unlocked(sst, SST_IMRX,
 228                         SST_IMRX_DONE, SST_IMRX_DONE);
 229                 ret = IRQ_WAKE_THREAD;
 230         }
 231 
 232         if (isr & SST_ISRX_BUSY) {
 233                 trace_sst_irq_busy(isr,
 234                         sst_dsp_shim_read_unlocked(sst, SST_IMRX));
 235 
 236                 /* Mask Busy interrupt before return */
 237                 sst_dsp_shim_update_bits_unlocked(sst, SST_IMRX,
 238                         SST_IMRX_BUSY, SST_IMRX_BUSY);
 239                 ret = IRQ_WAKE_THREAD;
 240         }
 241 
 242         spin_unlock(&sst->spinlock);
 243         return ret;
 244 }
 245 
 246 static void hsw_set_dsp_D3(struct sst_dsp *sst)
 247 {
 248         u32 val;
 249         u32 reg;
 250 
 251         /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
 252         reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
 253         reg &= ~(SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE);
 254         writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
 255 
 256         /* enable power gating and switch off DRAM & IRAM blocks */
 257         val = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
 258         val |= SST_VDRTCL0_DSRAMPGE_MASK |
 259                 SST_VDRTCL0_ISRAMPGE_MASK;
 260         val &= ~(SST_VDRTCL0_D3PGD | SST_VDRTCL0_D3SRAMPGD);
 261         writel(val, sst->addr.pci_cfg + SST_VDRTCTL0);
 262 
 263         /* switch off audio PLL */
 264         val = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
 265         val |= SST_VDRTCL2_APLLSE_MASK;
 266         writel(val, sst->addr.pci_cfg + SST_VDRTCTL2);
 267 
 268         /* disable MCLK(clkctl.smos = 0) */
 269         sst_dsp_shim_update_bits_unlocked(sst, SST_CLKCTL,
 270                 SST_CLKCTL_MASK, 0);
 271 
 272         /* Set D3 state, delay 50 us */
 273         val = readl(sst->addr.pci_cfg + SST_PMCS);
 274         val |= SST_PMCS_PS_MASK;
 275         writel(val, sst->addr.pci_cfg + SST_PMCS);
 276         udelay(50);
 277 
 278         /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */
 279         reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
 280         reg |= SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE;
 281         writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
 282 
 283         udelay(50);
 284 
 285 }
 286 
 287 static void hsw_reset(struct sst_dsp *sst)
 288 {
 289         /* put DSP into reset and stall */
 290         sst_dsp_shim_update_bits_unlocked(sst, SST_CSR,
 291                 SST_CSR_RST | SST_CSR_STALL,
 292                 SST_CSR_RST | SST_CSR_STALL);
 293 
 294         /* keep in reset for 10ms */
 295         mdelay(10);
 296 
 297         /* take DSP out of reset and keep stalled for FW loading */
 298         sst_dsp_shim_update_bits_unlocked(sst, SST_CSR,
 299                 SST_CSR_RST | SST_CSR_STALL, SST_CSR_STALL);
 300 }
 301 
 302 static int hsw_set_dsp_D0(struct sst_dsp *sst)
 303 {
 304         int tries = 10;
 305         u32 reg, fw_dump_bit;
 306 
 307         /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
 308         reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
 309         reg &= ~(SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE);
 310         writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
 311 
 312         /* Disable D3PG (VDRTCTL0.D3PGD = 1) */
 313         reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
 314         reg |= SST_VDRTCL0_D3PGD;
 315         writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0);
 316 
 317         /* Set D0 state */
 318         reg = readl(sst->addr.pci_cfg + SST_PMCS);
 319         reg &= ~SST_PMCS_PS_MASK;
 320         writel(reg, sst->addr.pci_cfg + SST_PMCS);
 321 
 322         /* check that ADSP shim is enabled */
 323         while (tries--) {
 324                 reg = readl(sst->addr.pci_cfg + SST_PMCS) & SST_PMCS_PS_MASK;
 325                 if (reg == 0)
 326                         goto finish;
 327 
 328                 msleep(1);
 329         }
 330 
 331         return -ENODEV;
 332 
 333 finish:
 334         /* select SSP1 19.2MHz base clock, SSP clock 0, turn off Low Power Clock */
 335         sst_dsp_shim_update_bits_unlocked(sst, SST_CSR,
 336                 SST_CSR_S1IOCS | SST_CSR_SBCS1 | SST_CSR_LPCS, 0x0);
 337 
 338         /* stall DSP core, set clk to 192/96Mhz */
 339         sst_dsp_shim_update_bits_unlocked(sst,
 340                 SST_CSR, SST_CSR_STALL | SST_CSR_DCS_MASK,
 341                 SST_CSR_STALL | SST_CSR_DCS(4));
 342 
 343         /* Set 24MHz MCLK, prevent local clock gating, enable SSP0 clock */
 344         sst_dsp_shim_update_bits_unlocked(sst, SST_CLKCTL,
 345                 SST_CLKCTL_MASK | SST_CLKCTL_DCPLCG | SST_CLKCTL_SCOE0,
 346                 SST_CLKCTL_MASK | SST_CLKCTL_DCPLCG | SST_CLKCTL_SCOE0);
 347 
 348         /* Stall and reset core, set CSR */
 349         hsw_reset(sst);
 350 
 351         /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */
 352         reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
 353         reg |= SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE;
 354         writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
 355 
 356         udelay(50);
 357 
 358         /* switch on audio PLL */
 359         reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
 360         reg &= ~SST_VDRTCL2_APLLSE_MASK;
 361         writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2);
 362 
 363         /* set default power gating control, enable power gating control for all blocks. that is,
 364         can't be accessed, please enable each block before accessing. */
 365         reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
 366         reg |= SST_VDRTCL0_DSRAMPGE_MASK | SST_VDRTCL0_ISRAMPGE_MASK;
 367         /* for D0, always enable the block(DSRAM[0]) used for FW dump */
 368         fw_dump_bit = 1 << SST_VDRTCL0_DSRAMPGE_SHIFT;
 369         writel(reg & ~fw_dump_bit, sst->addr.pci_cfg + SST_VDRTCTL0);
 370 
 371 
 372         /* disable DMA finish function for SSP0 & SSP1 */
 373         sst_dsp_shim_update_bits_unlocked(sst, SST_CSR2, SST_CSR2_SDFD_SSP1,
 374                 SST_CSR2_SDFD_SSP1);
 375 
 376         /* set on-demond mode on engine 0,1 for all channels */
 377         sst_dsp_shim_update_bits(sst, SST_HMDC,
 378                         SST_HMDC_HDDA_E0_ALLCH | SST_HMDC_HDDA_E1_ALLCH,
 379                         SST_HMDC_HDDA_E0_ALLCH | SST_HMDC_HDDA_E1_ALLCH);
 380 
 381         /* Enable Interrupt from both sides */
 382         sst_dsp_shim_update_bits(sst, SST_IMRX, (SST_IMRX_BUSY | SST_IMRX_DONE),
 383                                  0x0);
 384         sst_dsp_shim_update_bits(sst, SST_IMRD, (SST_IMRD_DONE | SST_IMRD_BUSY |
 385                                 SST_IMRD_SSP0 | SST_IMRD_DMAC), 0x0);
 386 
 387         /* clear IPC registers */
 388         sst_dsp_shim_write(sst, SST_IPCX, 0x0);
 389         sst_dsp_shim_write(sst, SST_IPCD, 0x0);
 390         sst_dsp_shim_write(sst, 0x80, 0x6);
 391         sst_dsp_shim_write(sst, 0xe0, 0x300a);
 392 
 393         return 0;
 394 }
 395 
 396 static void hsw_boot(struct sst_dsp *sst)
 397 {
 398         /* set oportunistic mode on engine 0,1 for all channels */
 399         sst_dsp_shim_update_bits(sst, SST_HMDC,
 400                         SST_HMDC_HDDA_E0_ALLCH | SST_HMDC_HDDA_E1_ALLCH, 0);
 401 
 402         /* set DSP to RUN */
 403         sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, SST_CSR_STALL, 0x0);
 404 }
 405 
 406 static void hsw_stall(struct sst_dsp *sst)
 407 {
 408         /* stall DSP */
 409         sst_dsp_shim_update_bits(sst, SST_CSR,
 410                 SST_CSR_24MHZ_LPCS | SST_CSR_STALL,
 411                 SST_CSR_STALL | SST_CSR_24MHZ_LPCS);
 412 }
 413 
 414 static void hsw_sleep(struct sst_dsp *sst)
 415 {
 416         dev_dbg(sst->dev, "HSW_PM dsp runtime suspend\n");
 417 
 418         /* put DSP into reset and stall */
 419         sst_dsp_shim_update_bits(sst, SST_CSR,
 420                 SST_CSR_24MHZ_LPCS | SST_CSR_RST | SST_CSR_STALL,
 421                 SST_CSR_RST | SST_CSR_STALL | SST_CSR_24MHZ_LPCS);
 422 
 423         hsw_set_dsp_D3(sst);
 424         dev_dbg(sst->dev, "HSW_PM dsp runtime suspend exit\n");
 425 }
 426 
 427 static int hsw_wake(struct sst_dsp *sst)
 428 {
 429         int ret;
 430 
 431         dev_dbg(sst->dev, "HSW_PM dsp runtime resume\n");
 432 
 433         ret = hsw_set_dsp_D0(sst);
 434         if (ret < 0)
 435                 return ret;
 436 
 437         dev_dbg(sst->dev, "HSW_PM dsp runtime resume exit\n");
 438 
 439         return 0;
 440 }
 441 
 442 struct sst_adsp_memregion {
 443         u32 start;
 444         u32 end;
 445         int blocks;
 446         enum sst_mem_type type;
 447 };
 448 
 449 /* lynx point ADSP mem regions */
 450 static const struct sst_adsp_memregion lp_region[] = {
 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 */
 454 };
 455 
 456 /* wild cat point ADSP mem regions */
 457 static const struct sst_adsp_memregion wpt_region[] = {
 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 */
 460 };
 461 
 462 static int hsw_acpi_resource_map(struct sst_dsp *sst, struct sst_pdata *pdata)
 463 {
 464         /* ADSP DRAM & IRAM */
 465         sst->addr.lpe_base = pdata->lpe_base;
 466         sst->addr.lpe = ioremap(pdata->lpe_base, pdata->lpe_size);
 467         if (!sst->addr.lpe)
 468                 return -ENODEV;
 469 
 470         /* ADSP PCI MMIO config space */
 471         sst->addr.pci_cfg = ioremap(pdata->pcicfg_base, pdata->pcicfg_size);
 472         if (!sst->addr.pci_cfg) {
 473                 iounmap(sst->addr.lpe);
 474                 return -ENODEV;
 475         }
 476 
 477         /* SST Shim */
 478         sst->addr.shim = sst->addr.lpe + sst->addr.shim_offset;
 479         return 0;
 480 }
 481 
 482 struct sst_sram_shift {
 483         u32 dev_id;     /* SST Device IDs  */
 484         u32 iram_shift;
 485         u32 dram_shift;
 486 };
 487 
 488 static const struct sst_sram_shift sram_shift[] = {
 489         {SST_DEV_ID_LYNX_POINT, 6, 16}, /* lp */
 490         {SST_DEV_ID_WILDCAT_POINT, 2, 12}, /* wpt */
 491 };
 492 
 493 static u32 hsw_block_get_bit(struct sst_mem_block *block)
 494 {
 495         u32 bit = 0, shift = 0, index;
 496         struct sst_dsp *sst = block->dsp;
 497 
 498         for (index = 0; index < ARRAY_SIZE(sram_shift); index++) {
 499                 if (sram_shift[index].dev_id == sst->id)
 500                         break;
 501         }
 502 
 503         if (index < ARRAY_SIZE(sram_shift)) {
 504                 switch (block->type) {
 505                 case SST_MEM_DRAM:
 506                         shift = sram_shift[index].dram_shift;
 507                         break;
 508                 case SST_MEM_IRAM:
 509                         shift = sram_shift[index].iram_shift;
 510                         break;
 511                 default:
 512                         shift = 0;
 513                 }
 514         } else
 515                 shift = 0;
 516 
 517         bit = 1 << (block->index + shift);
 518 
 519         return bit;
 520 }
 521 
 522 /*dummy read a SRAM block.*/
 523 static void sst_mem_block_dummy_read(struct sst_mem_block *block)
 524 {
 525         u32 size;
 526         u8 tmp_buf[4];
 527         struct sst_dsp *sst = block->dsp;
 528 
 529         size = block->size > 4 ? 4 : block->size;
 530         memcpy_fromio(tmp_buf, sst->addr.lpe + block->offset, size);
 531 }
 532 
 533 /* enable 32kB memory block - locks held by caller */
 534 static int hsw_block_enable(struct sst_mem_block *block)
 535 {
 536         struct sst_dsp *sst = block->dsp;
 537         u32 bit, val;
 538 
 539         if (block->users++ > 0)
 540                 return 0;
 541 
 542         dev_dbg(block->dsp->dev, " enabled block %d:%d at offset 0x%x\n",
 543                 block->type, block->index, block->offset);
 544 
 545         /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
 546         val = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
 547         val &= ~SST_VDRTCL2_DCLCGE;
 548         writel(val, sst->addr.pci_cfg + SST_VDRTCTL2);
 549 
 550         val = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
 551         bit = hsw_block_get_bit(block);
 552         writel(val & ~bit, sst->addr.pci_cfg + SST_VDRTCTL0);
 553 
 554         /* wait 18 DSP clock ticks */
 555         udelay(10);
 556 
 557         /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */
 558         val = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
 559         val |= SST_VDRTCL2_DCLCGE;
 560         writel(val, sst->addr.pci_cfg + SST_VDRTCTL2);
 561 
 562         udelay(50);
 563 
 564         /*add a dummy read before the SRAM block is written, otherwise the writing may miss bytes sometimes.*/
 565         sst_mem_block_dummy_read(block);
 566         return 0;
 567 }
 568 
 569 /* disable 32kB memory block - locks held by caller */
 570 static int hsw_block_disable(struct sst_mem_block *block)
 571 {
 572         struct sst_dsp *sst = block->dsp;
 573         u32 bit, val;
 574 
 575         if (--block->users > 0)
 576                 return 0;
 577 
 578         dev_dbg(block->dsp->dev, " disabled block %d:%d at offset 0x%x\n",
 579                 block->type, block->index, block->offset);
 580 
 581         /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
 582         val = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
 583         val &= ~SST_VDRTCL2_DCLCGE;
 584         writel(val, sst->addr.pci_cfg + SST_VDRTCTL2);
 585 
 586 
 587         val = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
 588         bit = hsw_block_get_bit(block);
 589         /* don't disable DSRAM[0], keep it always enable for FW dump*/
 590         if (bit != (1 << SST_VDRTCL0_DSRAMPGE_SHIFT))
 591                 writel(val | bit, sst->addr.pci_cfg + SST_VDRTCTL0);
 592 
 593         /* wait 18 DSP clock ticks */
 594         udelay(10);
 595 
 596         /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */
 597         val = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
 598         val |= SST_VDRTCL2_DCLCGE;
 599         writel(val, sst->addr.pci_cfg + SST_VDRTCTL2);
 600 
 601         udelay(50);
 602 
 603         return 0;
 604 }
 605 
 606 static const struct sst_block_ops sst_hsw_ops = {
 607         .enable = hsw_block_enable,
 608         .disable = hsw_block_disable,
 609 };
 610 
 611 static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata)
 612 {
 613         const struct sst_adsp_memregion *region;
 614         struct device *dev;
 615         int ret = -ENODEV, i, j, region_count;
 616         u32 offset, size, fw_dump_bit;
 617 
 618         dev = sst->dma_dev;
 619 
 620         switch (sst->id) {
 621         case SST_DEV_ID_LYNX_POINT:
 622                 region = lp_region;
 623                 region_count = ARRAY_SIZE(lp_region);
 624                 sst->addr.iram_offset = SST_LP_IRAM_OFFSET;
 625                 sst->addr.dsp_iram_offset = SST_LPT_DSP_IRAM_OFFSET;
 626                 sst->addr.dsp_dram_offset = SST_LPT_DSP_DRAM_OFFSET;
 627                 sst->addr.shim_offset = SST_LP_SHIM_OFFSET;
 628                 break;
 629         case SST_DEV_ID_WILDCAT_POINT:
 630                 region = wpt_region;
 631                 region_count = ARRAY_SIZE(wpt_region);
 632                 sst->addr.iram_offset = SST_WPT_IRAM_OFFSET;
 633                 sst->addr.dsp_iram_offset = SST_WPT_DSP_IRAM_OFFSET;
 634                 sst->addr.dsp_dram_offset = SST_WPT_DSP_DRAM_OFFSET;
 635                 sst->addr.shim_offset = SST_WPT_SHIM_OFFSET;
 636                 break;
 637         default:
 638                 dev_err(dev, "error: failed to get mem resources\n");
 639                 return ret;
 640         }
 641 
 642         ret = hsw_acpi_resource_map(sst, pdata);
 643         if (ret < 0) {
 644                 dev_err(dev, "error: failed to map resources\n");
 645                 return ret;
 646         }
 647 
 648         /* enable the DSP SHIM */
 649         ret = hsw_set_dsp_D0(sst);
 650         if (ret < 0) {
 651                 dev_err(dev, "error: failed to set DSP D0 and reset SHIM\n");
 652                 return ret;
 653         }
 654 
 655         ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(31));
 656         if (ret)
 657                 return ret;
 658 
 659 
 660         /* register DSP memory blocks - ideally we should get this from ACPI */
 661         for (i = 0; i < region_count; i++) {
 662                 offset = region[i].start;
 663                 size = (region[i].end - region[i].start) / region[i].blocks;
 664 
 665                 /* register individual memory blocks */
 666                 for (j = 0; j < region[i].blocks; j++) {
 667                         sst_mem_block_register(sst, offset, size,
 668                                 region[i].type, &sst_hsw_ops, j, sst);
 669                         offset += size;
 670                 }
 671         }
 672 
 673         /* always enable the block(DSRAM[0]) used for FW dump */
 674         fw_dump_bit = 1 << SST_VDRTCL0_DSRAMPGE_SHIFT;
 675         /* set default power gating control, enable power gating control for all blocks. that is,
 676         can't be accessed, please enable each block before accessing. */
 677         writel(0xffffffff & ~fw_dump_bit, sst->addr.pci_cfg + SST_VDRTCTL0);
 678 
 679         return 0;
 680 }
 681 
 682 static void hsw_free(struct sst_dsp *sst)
 683 {
 684         sst_mem_block_unregister_all(sst);
 685         iounmap(sst->addr.lpe);
 686         iounmap(sst->addr.pci_cfg);
 687 }
 688 
 689 struct sst_ops haswell_ops = {
 690         .reset = hsw_reset,
 691         .boot = hsw_boot,
 692         .stall = hsw_stall,
 693         .wake = hsw_wake,
 694         .sleep = hsw_sleep,
 695         .write = sst_shim32_write,
 696         .read = sst_shim32_read,
 697         .write64 = sst_shim32_write64,
 698         .read64 = sst_shim32_read64,
 699         .ram_read = sst_memcpy_fromio_32,
 700         .ram_write = sst_memcpy_toio_32,
 701         .irq_handler = hsw_irq,
 702         .init = hsw_init,
 703         .free = hsw_free,
 704         .parse_fw = hsw_parse_fw_image,
 705 };

/* [<][>][^][v][top][bottom][index][help] */