sst-baytrail-dsp.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. /*
  2. * Intel Baytrail SST DSP driver
  3. * Copyright (c) 2014, Intel Corporation.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms and conditions of the GNU General Public License,
  7. * version 2, as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. */
  14. #include <linux/delay.h>
  15. #include <linux/fs.h>
  16. #include <linux/slab.h>
  17. #include <linux/device.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/module.h>
  20. #include <linux/dma-mapping.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/firmware.h>
  23. #include "../common/sst-dsp.h"
  24. #include "../common/sst-dsp-priv.h"
  25. #include "sst-baytrail-ipc.h"
  26. #define SST_BYT_FW_SIGNATURE_SIZE 4
  27. #define SST_BYT_FW_SIGN "$SST"
  28. #define SST_BYT_IRAM_OFFSET 0xC0000
  29. #define SST_BYT_DRAM_OFFSET 0x100000
  30. #define SST_BYT_SHIM_OFFSET 0x140000
  31. enum sst_ram_type {
  32. SST_BYT_IRAM = 1,
  33. SST_BYT_DRAM = 2,
  34. SST_BYT_CACHE = 3,
  35. };
  36. struct dma_block_info {
  37. enum sst_ram_type type; /* IRAM/DRAM */
  38. u32 size; /* Bytes */
  39. u32 ram_offset; /* Offset in I/DRAM */
  40. u32 rsvd; /* Reserved field */
  41. };
  42. struct fw_header {
  43. unsigned char signature[SST_BYT_FW_SIGNATURE_SIZE];
  44. u32 file_size; /* size of fw minus this header */
  45. u32 modules; /* # of modules */
  46. u32 file_format; /* version of header format */
  47. u32 reserved[4];
  48. };
  49. struct sst_byt_fw_module_header {
  50. unsigned char signature[SST_BYT_FW_SIGNATURE_SIZE];
  51. u32 mod_size; /* size of module */
  52. u32 blocks; /* # of blocks */
  53. u32 type; /* codec type, pp lib */
  54. u32 entry_point;
  55. };
  56. static int sst_byt_parse_module(struct sst_dsp *dsp, struct sst_fw *fw,
  57. struct sst_byt_fw_module_header *module)
  58. {
  59. struct dma_block_info *block;
  60. struct sst_module *mod;
  61. struct sst_module_template template;
  62. int count;
  63. memset(&template, 0, sizeof(template));
  64. template.id = module->type;
  65. template.entry = module->entry_point;
  66. mod = sst_module_new(fw, &template, NULL);
  67. if (mod == NULL)
  68. return -ENOMEM;
  69. block = (void *)module + sizeof(*module);
  70. for (count = 0; count < module->blocks; count++) {
  71. if (block->size <= 0) {
  72. dev_err(dsp->dev, "block %d size invalid\n", count);
  73. return -EINVAL;
  74. }
  75. switch (block->type) {
  76. case SST_BYT_IRAM:
  77. mod->offset = block->ram_offset +
  78. dsp->addr.iram_offset;
  79. mod->type = SST_MEM_IRAM;
  80. break;
  81. case SST_BYT_DRAM:
  82. mod->offset = block->ram_offset +
  83. dsp->addr.dram_offset;
  84. mod->type = SST_MEM_DRAM;
  85. break;
  86. case SST_BYT_CACHE:
  87. mod->offset = block->ram_offset +
  88. (dsp->addr.fw_ext - dsp->addr.lpe);
  89. mod->type = SST_MEM_CACHE;
  90. break;
  91. default:
  92. dev_err(dsp->dev, "wrong ram type 0x%x in block0x%x\n",
  93. block->type, count);
  94. return -EINVAL;
  95. }
  96. mod->size = block->size;
  97. mod->data = (void *)block + sizeof(*block);
  98. sst_module_alloc_blocks(mod);
  99. block = (void *)block + sizeof(*block) + block->size;
  100. }
  101. return 0;
  102. }
  103. static int sst_byt_parse_fw_image(struct sst_fw *sst_fw)
  104. {
  105. struct fw_header *header;
  106. struct sst_byt_fw_module_header *module;
  107. struct sst_dsp *dsp = sst_fw->dsp;
  108. int ret, count;
  109. /* Read the header information from the data pointer */
  110. header = (struct fw_header *)sst_fw->dma_buf;
  111. /* verify FW */
  112. if ((strncmp(header->signature, SST_BYT_FW_SIGN, 4) != 0) ||
  113. (sst_fw->size != header->file_size + sizeof(*header))) {
  114. /* Invalid FW signature */
  115. dev_err(dsp->dev, "Invalid FW sign/filesize mismatch\n");
  116. return -EINVAL;
  117. }
  118. dev_dbg(dsp->dev,
  119. "header sign=%4s size=0x%x modules=0x%x fmt=0x%x size=%zu\n",
  120. header->signature, header->file_size, header->modules,
  121. header->file_format, sizeof(*header));
  122. module = (void *)sst_fw->dma_buf + sizeof(*header);
  123. for (count = 0; count < header->modules; count++) {
  124. /* module */
  125. ret = sst_byt_parse_module(dsp, sst_fw, module);
  126. if (ret < 0) {
  127. dev_err(dsp->dev, "invalid module %d\n", count);
  128. return ret;
  129. }
  130. module = (void *)module + sizeof(*module) + module->mod_size;
  131. }
  132. return 0;
  133. }
  134. static void sst_byt_dump_shim(struct sst_dsp *sst)
  135. {
  136. int i;
  137. u64 reg;
  138. for (i = 0; i <= 0xF0; i += 8) {
  139. reg = sst_dsp_shim_read64_unlocked(sst, i);
  140. if (reg)
  141. dev_dbg(sst->dev, "shim 0x%2.2x value 0x%16.16llx\n",
  142. i, reg);
  143. }
  144. for (i = 0x00; i <= 0xff; i += 4) {
  145. reg = readl(sst->addr.pci_cfg + i);
  146. if (reg)
  147. dev_dbg(sst->dev, "pci 0x%2.2x value 0x%8.8x\n",
  148. i, (u32)reg);
  149. }
  150. }
  151. static irqreturn_t sst_byt_irq(int irq, void *context)
  152. {
  153. struct sst_dsp *sst = (struct sst_dsp *) context;
  154. u64 isrx;
  155. irqreturn_t ret = IRQ_NONE;
  156. spin_lock(&sst->spinlock);
  157. isrx = sst_dsp_shim_read64_unlocked(sst, SST_ISRX);
  158. if (isrx & SST_ISRX_DONE) {
  159. /* ADSP has processed the message request from IA */
  160. sst_dsp_shim_update_bits64_unlocked(sst, SST_IPCX,
  161. SST_BYT_IPCX_DONE, 0);
  162. ret = IRQ_WAKE_THREAD;
  163. }
  164. if (isrx & SST_BYT_ISRX_REQUEST) {
  165. /* mask message request from ADSP and do processing later */
  166. sst_dsp_shim_update_bits64_unlocked(sst, SST_IMRX,
  167. SST_BYT_IMRX_REQUEST,
  168. SST_BYT_IMRX_REQUEST);
  169. ret = IRQ_WAKE_THREAD;
  170. }
  171. spin_unlock(&sst->spinlock);
  172. return ret;
  173. }
  174. static void sst_byt_boot(struct sst_dsp *sst)
  175. {
  176. int tries = 10;
  177. /*
  178. * save the physical address of extended firmware block in the first
  179. * 4 bytes of the mailbox
  180. */
  181. memcpy_toio(sst->addr.lpe + SST_BYT_MAILBOX_OFFSET,
  182. &sst->pdata->fw_base, sizeof(u32));
  183. /* release stall and wait to unstall */
  184. sst_dsp_shim_update_bits64(sst, SST_CSR, SST_BYT_CSR_STALL, 0x0);
  185. while (tries--) {
  186. if (!(sst_dsp_shim_read64(sst, SST_CSR) &
  187. SST_BYT_CSR_PWAITMODE))
  188. break;
  189. msleep(100);
  190. }
  191. if (tries < 0) {
  192. dev_err(sst->dev, "unable to start DSP\n");
  193. sst_byt_dump_shim(sst);
  194. }
  195. }
  196. static void sst_byt_reset(struct sst_dsp *sst)
  197. {
  198. /* put DSP into reset, set reset vector and stall */
  199. sst_dsp_shim_update_bits64(sst, SST_CSR,
  200. SST_BYT_CSR_RST | SST_BYT_CSR_VECTOR_SEL | SST_BYT_CSR_STALL,
  201. SST_BYT_CSR_RST | SST_BYT_CSR_VECTOR_SEL | SST_BYT_CSR_STALL);
  202. udelay(10);
  203. /* take DSP out of reset and keep stalled for FW loading */
  204. sst_dsp_shim_update_bits64(sst, SST_CSR, SST_BYT_CSR_RST, 0);
  205. }
  206. struct sst_adsp_memregion {
  207. u32 start;
  208. u32 end;
  209. int blocks;
  210. enum sst_mem_type type;
  211. };
  212. /* BYT test stuff */
  213. static const struct sst_adsp_memregion byt_region[] = {
  214. {0xC0000, 0x100000, 8, SST_MEM_IRAM}, /* I-SRAM - 8 * 32kB */
  215. {0x100000, 0x140000, 8, SST_MEM_DRAM}, /* D-SRAM0 - 8 * 32kB */
  216. };
  217. static int sst_byt_resource_map(struct sst_dsp *sst, struct sst_pdata *pdata)
  218. {
  219. sst->addr.lpe_base = pdata->lpe_base;
  220. sst->addr.lpe = ioremap(pdata->lpe_base, pdata->lpe_size);
  221. if (!sst->addr.lpe)
  222. return -ENODEV;
  223. /* ADSP PCI MMIO config space */
  224. sst->addr.pci_cfg = ioremap(pdata->pcicfg_base, pdata->pcicfg_size);
  225. if (!sst->addr.pci_cfg) {
  226. iounmap(sst->addr.lpe);
  227. return -ENODEV;
  228. }
  229. /* SST Extended FW allocation */
  230. sst->addr.fw_ext = ioremap(pdata->fw_base, pdata->fw_size);
  231. if (!sst->addr.fw_ext) {
  232. iounmap(sst->addr.pci_cfg);
  233. iounmap(sst->addr.lpe);
  234. return -ENODEV;
  235. }
  236. /* SST Shim */
  237. sst->addr.shim = sst->addr.lpe + sst->addr.shim_offset;
  238. sst_dsp_mailbox_init(sst, SST_BYT_MAILBOX_OFFSET + 0x204,
  239. SST_BYT_IPC_MAX_PAYLOAD_SIZE,
  240. SST_BYT_MAILBOX_OFFSET,
  241. SST_BYT_IPC_MAX_PAYLOAD_SIZE);
  242. sst->irq = pdata->irq;
  243. return 0;
  244. }
  245. static int sst_byt_init(struct sst_dsp *sst, struct sst_pdata *pdata)
  246. {
  247. const struct sst_adsp_memregion *region;
  248. struct device *dev;
  249. int ret = -ENODEV, i, j, region_count;
  250. u32 offset, size;
  251. dev = sst->dev;
  252. switch (sst->id) {
  253. case SST_DEV_ID_BYT:
  254. region = byt_region;
  255. region_count = ARRAY_SIZE(byt_region);
  256. sst->addr.iram_offset = SST_BYT_IRAM_OFFSET;
  257. sst->addr.dram_offset = SST_BYT_DRAM_OFFSET;
  258. sst->addr.shim_offset = SST_BYT_SHIM_OFFSET;
  259. break;
  260. default:
  261. dev_err(dev, "failed to get mem resources\n");
  262. return ret;
  263. }
  264. ret = sst_byt_resource_map(sst, pdata);
  265. if (ret < 0) {
  266. dev_err(dev, "failed to map resources\n");
  267. return ret;
  268. }
  269. ret = dma_coerce_mask_and_coherent(sst->dma_dev, DMA_BIT_MASK(32));
  270. if (ret)
  271. return ret;
  272. /* enable Interrupt from both sides */
  273. sst_dsp_shim_update_bits64(sst, SST_IMRX, 0x3, 0x0);
  274. sst_dsp_shim_update_bits64(sst, SST_IMRD, 0x3, 0x0);
  275. /* register DSP memory blocks - ideally we should get this from ACPI */
  276. for (i = 0; i < region_count; i++) {
  277. offset = region[i].start;
  278. size = (region[i].end - region[i].start) / region[i].blocks;
  279. /* register individual memory blocks */
  280. for (j = 0; j < region[i].blocks; j++) {
  281. sst_mem_block_register(sst, offset, size,
  282. region[i].type, NULL, j, sst);
  283. offset += size;
  284. }
  285. }
  286. return 0;
  287. }
  288. static void sst_byt_free(struct sst_dsp *sst)
  289. {
  290. sst_mem_block_unregister_all(sst);
  291. iounmap(sst->addr.lpe);
  292. iounmap(sst->addr.pci_cfg);
  293. iounmap(sst->addr.fw_ext);
  294. }
  295. struct sst_ops sst_byt_ops = {
  296. .reset = sst_byt_reset,
  297. .boot = sst_byt_boot,
  298. .write = sst_shim32_write,
  299. .read = sst_shim32_read,
  300. .write64 = sst_shim32_write64,
  301. .read64 = sst_shim32_read64,
  302. .ram_read = sst_memcpy_fromio_32,
  303. .ram_write = sst_memcpy_toio_32,
  304. .irq_handler = sst_byt_irq,
  305. .init = sst_byt_init,
  306. .free = sst_byt_free,
  307. .parse_fw = sst_byt_parse_fw_image,
  308. };