ps-pdm-dma.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * AMD ALSA SoC Pink Sardine PDM Driver
  4. *
  5. * Copyright 2022 Advanced Micro Devices, Inc.
  6. */
  7. #include <linux/platform_device.h>
  8. #include <linux/module.h>
  9. #include <linux/err.h>
  10. #include <linux/io.h>
  11. #include <sound/pcm_params.h>
  12. #include <sound/soc.h>
  13. #include <sound/soc-dai.h>
  14. #include <linux/pm_runtime.h>
  15. #include "acp63.h"
  16. #define DRV_NAME "acp_ps_pdm_dma"
  17. static const struct snd_pcm_hardware acp63_pdm_hardware_capture = {
  18. .info = SNDRV_PCM_INFO_INTERLEAVED |
  19. SNDRV_PCM_INFO_BLOCK_TRANSFER |
  20. SNDRV_PCM_INFO_MMAP |
  21. SNDRV_PCM_INFO_MMAP_VALID |
  22. SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
  23. .formats = SNDRV_PCM_FMTBIT_S32_LE,
  24. .channels_min = 2,
  25. .channels_max = 2,
  26. .rates = SNDRV_PCM_RATE_48000,
  27. .rate_min = 48000,
  28. .rate_max = 48000,
  29. .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
  30. .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
  31. .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
  32. .periods_min = CAPTURE_MIN_NUM_PERIODS,
  33. .periods_max = CAPTURE_MAX_NUM_PERIODS,
  34. };
  35. static void acp63_init_pdm_ring_buffer(u32 physical_addr, u32 buffer_size,
  36. u32 watermark_size, void __iomem *acp_base)
  37. {
  38. acp63_writel(physical_addr, acp_base + ACP_WOV_RX_RINGBUFADDR);
  39. acp63_writel(buffer_size, acp_base + ACP_WOV_RX_RINGBUFSIZE);
  40. acp63_writel(watermark_size, acp_base + ACP_WOV_RX_INTR_WATERMARK_SIZE);
  41. acp63_writel(0x01, acp_base + ACPAXI2AXI_ATU_CTRL);
  42. }
  43. static void acp63_enable_pdm_clock(void __iomem *acp_base)
  44. {
  45. u32 pdm_clk_enable, pdm_ctrl;
  46. pdm_clk_enable = ACP_PDM_CLK_FREQ_MASK;
  47. pdm_ctrl = 0x00;
  48. acp63_writel(pdm_clk_enable, acp_base + ACP_WOV_CLK_CTRL);
  49. pdm_ctrl = acp63_readl(acp_base + ACP_WOV_MISC_CTRL);
  50. pdm_ctrl |= ACP_WOV_MISC_CTRL_MASK;
  51. acp63_writel(pdm_ctrl, acp_base + ACP_WOV_MISC_CTRL);
  52. }
  53. static void acp63_enable_pdm_interrupts(void __iomem *acp_base)
  54. {
  55. u32 ext_int_ctrl;
  56. ext_int_ctrl = acp63_readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
  57. ext_int_ctrl |= PDM_DMA_INTR_MASK;
  58. acp63_writel(ext_int_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
  59. }
  60. static void acp63_disable_pdm_interrupts(void __iomem *acp_base)
  61. {
  62. u32 ext_int_ctrl;
  63. ext_int_ctrl = acp63_readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
  64. ext_int_ctrl &= ~PDM_DMA_INTR_MASK;
  65. acp63_writel(ext_int_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
  66. }
  67. static bool acp63_check_pdm_dma_status(void __iomem *acp_base)
  68. {
  69. bool pdm_dma_status;
  70. u32 pdm_enable, pdm_dma_enable;
  71. pdm_dma_status = false;
  72. pdm_enable = acp63_readl(acp_base + ACP_WOV_PDM_ENABLE);
  73. pdm_dma_enable = acp63_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
  74. if ((pdm_enable & ACP_PDM_ENABLE) && (pdm_dma_enable & ACP_PDM_DMA_EN_STATUS))
  75. pdm_dma_status = true;
  76. return pdm_dma_status;
  77. }
  78. static int acp63_start_pdm_dma(void __iomem *acp_base)
  79. {
  80. u32 pdm_enable;
  81. u32 pdm_dma_enable;
  82. int timeout;
  83. pdm_enable = 0x01;
  84. pdm_dma_enable = 0x01;
  85. acp63_enable_pdm_clock(acp_base);
  86. acp63_writel(pdm_enable, acp_base + ACP_WOV_PDM_ENABLE);
  87. acp63_writel(pdm_dma_enable, acp_base + ACP_WOV_PDM_DMA_ENABLE);
  88. timeout = 0;
  89. while (++timeout < ACP_COUNTER) {
  90. pdm_dma_enable = acp63_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
  91. if ((pdm_dma_enable & 0x02) == ACP_PDM_DMA_EN_STATUS)
  92. return 0;
  93. udelay(DELAY_US);
  94. }
  95. return -ETIMEDOUT;
  96. }
  97. static int acp63_stop_pdm_dma(void __iomem *acp_base)
  98. {
  99. u32 pdm_enable, pdm_dma_enable;
  100. int timeout;
  101. pdm_enable = 0x00;
  102. pdm_dma_enable = 0x00;
  103. pdm_enable = acp63_readl(acp_base + ACP_WOV_PDM_ENABLE);
  104. pdm_dma_enable = acp63_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
  105. if (pdm_dma_enable & 0x01) {
  106. pdm_dma_enable = 0x02;
  107. acp63_writel(pdm_dma_enable, acp_base + ACP_WOV_PDM_DMA_ENABLE);
  108. timeout = 0;
  109. while (++timeout < ACP_COUNTER) {
  110. pdm_dma_enable = acp63_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
  111. if ((pdm_dma_enable & 0x02) == 0x00)
  112. break;
  113. udelay(DELAY_US);
  114. }
  115. if (timeout == ACP_COUNTER)
  116. return -ETIMEDOUT;
  117. }
  118. if (pdm_enable == ACP_PDM_ENABLE) {
  119. pdm_enable = ACP_PDM_DISABLE;
  120. acp63_writel(pdm_enable, acp_base + ACP_WOV_PDM_ENABLE);
  121. }
  122. acp63_writel(0x01, acp_base + ACP_WOV_PDM_FIFO_FLUSH);
  123. return 0;
  124. }
  125. static void acp63_config_dma(struct pdm_stream_instance *rtd, int direction)
  126. {
  127. u16 page_idx;
  128. u32 low, high, val;
  129. dma_addr_t addr;
  130. addr = rtd->dma_addr;
  131. val = PDM_PTE_OFFSET;
  132. /* Group Enable */
  133. acp63_writel(ACP_SRAM_PTE_OFFSET | BIT(31), rtd->acp63_base +
  134. ACPAXI2AXI_ATU_BASE_ADDR_GRP_1);
  135. acp63_writel(PAGE_SIZE_4K_ENABLE, rtd->acp63_base +
  136. ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1);
  137. for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) {
  138. /* Load the low address of page int ACP SRAM through SRBM */
  139. low = lower_32_bits(addr);
  140. high = upper_32_bits(addr);
  141. acp63_writel(low, rtd->acp63_base + ACP_SCRATCH_REG_0 + val);
  142. high |= BIT(31);
  143. acp63_writel(high, rtd->acp63_base + ACP_SCRATCH_REG_0 + val + 4);
  144. val += 8;
  145. addr += PAGE_SIZE;
  146. }
  147. }
  148. static int acp63_pdm_dma_open(struct snd_soc_component *component,
  149. struct snd_pcm_substream *substream)
  150. {
  151. struct snd_pcm_runtime *runtime;
  152. struct pdm_dev_data *adata;
  153. struct pdm_stream_instance *pdm_data;
  154. int ret;
  155. runtime = substream->runtime;
  156. adata = dev_get_drvdata(component->dev);
  157. pdm_data = kzalloc(sizeof(*pdm_data), GFP_KERNEL);
  158. if (!pdm_data)
  159. return -EINVAL;
  160. if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
  161. runtime->hw = acp63_pdm_hardware_capture;
  162. ret = snd_pcm_hw_constraint_integer(runtime,
  163. SNDRV_PCM_HW_PARAM_PERIODS);
  164. if (ret < 0) {
  165. dev_err(component->dev, "set integer constraint failed\n");
  166. kfree(pdm_data);
  167. return ret;
  168. }
  169. acp63_enable_pdm_interrupts(adata->acp63_base);
  170. if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
  171. adata->capture_stream = substream;
  172. pdm_data->acp63_base = adata->acp63_base;
  173. runtime->private_data = pdm_data;
  174. return ret;
  175. }
  176. static int acp63_pdm_dma_hw_params(struct snd_soc_component *component,
  177. struct snd_pcm_substream *substream,
  178. struct snd_pcm_hw_params *params)
  179. {
  180. struct pdm_stream_instance *rtd;
  181. size_t size, period_bytes;
  182. rtd = substream->runtime->private_data;
  183. if (!rtd)
  184. return -EINVAL;
  185. size = params_buffer_bytes(params);
  186. period_bytes = params_period_bytes(params);
  187. rtd->dma_addr = substream->runtime->dma_addr;
  188. rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
  189. acp63_config_dma(rtd, substream->stream);
  190. acp63_init_pdm_ring_buffer(PDM_MEM_WINDOW_START, size,
  191. period_bytes, rtd->acp63_base);
  192. return 0;
  193. }
  194. static u64 acp63_pdm_get_byte_count(struct pdm_stream_instance *rtd,
  195. int direction)
  196. {
  197. u32 high, low;
  198. u64 byte_count;
  199. high = acp63_readl(rtd->acp63_base + ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH);
  200. byte_count = high;
  201. low = acp63_readl(rtd->acp63_base + ACP_WOV_RX_LINEARPOSITIONCNTR_LOW);
  202. byte_count = (byte_count << 32) | low;
  203. return byte_count;
  204. }
  205. static snd_pcm_uframes_t acp63_pdm_dma_pointer(struct snd_soc_component *comp,
  206. struct snd_pcm_substream *stream)
  207. {
  208. struct pdm_stream_instance *rtd;
  209. u32 pos, buffersize;
  210. u64 bytescount;
  211. rtd = stream->runtime->private_data;
  212. buffersize = frames_to_bytes(stream->runtime,
  213. stream->runtime->buffer_size);
  214. bytescount = acp63_pdm_get_byte_count(rtd, stream->stream);
  215. if (bytescount > rtd->bytescount)
  216. bytescount -= rtd->bytescount;
  217. pos = do_div(bytescount, buffersize);
  218. return bytes_to_frames(stream->runtime, pos);
  219. }
  220. static int acp63_pdm_dma_new(struct snd_soc_component *component,
  221. struct snd_soc_pcm_runtime *rtd)
  222. {
  223. struct device *parent = component->dev->parent;
  224. snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
  225. parent, MIN_BUFFER, MAX_BUFFER);
  226. return 0;
  227. }
  228. static int acp63_pdm_dma_close(struct snd_soc_component *component,
  229. struct snd_pcm_substream *substream)
  230. {
  231. struct pdm_dev_data *adata = dev_get_drvdata(component->dev);
  232. struct snd_pcm_runtime *runtime = substream->runtime;
  233. acp63_disable_pdm_interrupts(adata->acp63_base);
  234. adata->capture_stream = NULL;
  235. kfree(runtime->private_data);
  236. return 0;
  237. }
  238. static int acp63_pdm_dai_trigger(struct snd_pcm_substream *substream,
  239. int cmd, struct snd_soc_dai *dai)
  240. {
  241. struct pdm_stream_instance *rtd;
  242. int ret;
  243. bool pdm_status;
  244. unsigned int ch_mask;
  245. rtd = substream->runtime->private_data;
  246. ret = 0;
  247. switch (substream->runtime->channels) {
  248. case TWO_CH:
  249. ch_mask = 0x00;
  250. break;
  251. default:
  252. return -EINVAL;
  253. }
  254. switch (cmd) {
  255. case SNDRV_PCM_TRIGGER_START:
  256. case SNDRV_PCM_TRIGGER_RESUME:
  257. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  258. acp63_writel(ch_mask, rtd->acp63_base + ACP_WOV_PDM_NO_OF_CHANNELS);
  259. acp63_writel(PDM_DECIMATION_FACTOR, rtd->acp63_base +
  260. ACP_WOV_PDM_DECIMATION_FACTOR);
  261. rtd->bytescount = acp63_pdm_get_byte_count(rtd, substream->stream);
  262. pdm_status = acp63_check_pdm_dma_status(rtd->acp63_base);
  263. if (!pdm_status)
  264. ret = acp63_start_pdm_dma(rtd->acp63_base);
  265. break;
  266. case SNDRV_PCM_TRIGGER_STOP:
  267. case SNDRV_PCM_TRIGGER_SUSPEND:
  268. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  269. pdm_status = acp63_check_pdm_dma_status(rtd->acp63_base);
  270. if (pdm_status)
  271. ret = acp63_stop_pdm_dma(rtd->acp63_base);
  272. break;
  273. default:
  274. ret = -EINVAL;
  275. break;
  276. }
  277. return ret;
  278. }
  279. static const struct snd_soc_dai_ops acp63_pdm_dai_ops = {
  280. .trigger = acp63_pdm_dai_trigger,
  281. };
  282. static struct snd_soc_dai_driver acp63_pdm_dai_driver = {
  283. .name = "acp_ps_pdm_dma.0",
  284. .capture = {
  285. .rates = SNDRV_PCM_RATE_48000,
  286. .formats = SNDRV_PCM_FMTBIT_S32_LE,
  287. .channels_min = 2,
  288. .channels_max = 2,
  289. .rate_min = 48000,
  290. .rate_max = 48000,
  291. },
  292. .ops = &acp63_pdm_dai_ops,
  293. };
  294. static const struct snd_soc_component_driver acp63_pdm_component = {
  295. .name = DRV_NAME,
  296. .open = acp63_pdm_dma_open,
  297. .close = acp63_pdm_dma_close,
  298. .hw_params = acp63_pdm_dma_hw_params,
  299. .pointer = acp63_pdm_dma_pointer,
  300. .pcm_construct = acp63_pdm_dma_new,
  301. };
  302. static int acp63_pdm_audio_probe(struct platform_device *pdev)
  303. {
  304. struct resource *res;
  305. struct pdm_dev_data *adata;
  306. int status;
  307. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  308. if (!res) {
  309. dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
  310. return -ENODEV;
  311. }
  312. adata = devm_kzalloc(&pdev->dev, sizeof(*adata), GFP_KERNEL);
  313. if (!adata)
  314. return -ENOMEM;
  315. adata->acp63_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
  316. if (!adata->acp63_base)
  317. return -ENOMEM;
  318. adata->capture_stream = NULL;
  319. dev_set_drvdata(&pdev->dev, adata);
  320. status = devm_snd_soc_register_component(&pdev->dev,
  321. &acp63_pdm_component,
  322. &acp63_pdm_dai_driver, 1);
  323. if (status) {
  324. dev_err(&pdev->dev, "Fail to register acp pdm dai\n");
  325. return -ENODEV;
  326. }
  327. pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
  328. pm_runtime_use_autosuspend(&pdev->dev);
  329. pm_runtime_enable(&pdev->dev);
  330. pm_runtime_allow(&pdev->dev);
  331. return 0;
  332. }
  333. static int acp63_pdm_audio_remove(struct platform_device *pdev)
  334. {
  335. pm_runtime_disable(&pdev->dev);
  336. return 0;
  337. }
  338. static int __maybe_unused acp63_pdm_resume(struct device *dev)
  339. {
  340. struct pdm_dev_data *adata;
  341. struct snd_pcm_runtime *runtime;
  342. struct pdm_stream_instance *rtd;
  343. u32 period_bytes, buffer_len;
  344. adata = dev_get_drvdata(dev);
  345. if (adata->capture_stream && adata->capture_stream->runtime) {
  346. runtime = adata->capture_stream->runtime;
  347. rtd = runtime->private_data;
  348. period_bytes = frames_to_bytes(runtime, runtime->period_size);
  349. buffer_len = frames_to_bytes(runtime, runtime->buffer_size);
  350. acp63_config_dma(rtd, SNDRV_PCM_STREAM_CAPTURE);
  351. acp63_init_pdm_ring_buffer(PDM_MEM_WINDOW_START, buffer_len,
  352. period_bytes, adata->acp63_base);
  353. }
  354. acp63_enable_pdm_interrupts(adata->acp63_base);
  355. return 0;
  356. }
  357. static int __maybe_unused acp63_pdm_suspend(struct device *dev)
  358. {
  359. struct pdm_dev_data *adata;
  360. adata = dev_get_drvdata(dev);
  361. acp63_disable_pdm_interrupts(adata->acp63_base);
  362. return 0;
  363. }
  364. static int __maybe_unused acp63_pdm_runtime_resume(struct device *dev)
  365. {
  366. struct pdm_dev_data *adata;
  367. adata = dev_get_drvdata(dev);
  368. acp63_enable_pdm_interrupts(adata->acp63_base);
  369. return 0;
  370. }
  371. static const struct dev_pm_ops acp63_pdm_pm_ops = {
  372. SET_RUNTIME_PM_OPS(acp63_pdm_suspend, acp63_pdm_runtime_resume, NULL)
  373. SET_SYSTEM_SLEEP_PM_OPS(acp63_pdm_suspend, acp63_pdm_resume)
  374. };
  375. static struct platform_driver acp63_pdm_dma_driver = {
  376. .probe = acp63_pdm_audio_probe,
  377. .remove = acp63_pdm_audio_remove,
  378. .driver = {
  379. .name = "acp_ps_pdm_dma",
  380. .pm = &acp63_pdm_pm_ops,
  381. },
  382. };
  383. module_platform_driver(acp63_pdm_dma_driver);
  384. MODULE_AUTHOR("[email protected]");
  385. MODULE_DESCRIPTION("AMD PINK SARDINE PDM Driver");
  386. MODULE_LICENSE("GPL v2");
  387. MODULE_ALIAS("platform:" DRV_NAME);