1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * AMD ALSA SoC Pink Sardine SoundWire DMA Driver 4 * 5 * Copyright 2023 Advanced Micro Devices, Inc. 6 */ 7 8 #include <linux/err.h> 9 #include <linux/io.h> 10 #include <linux/module.h> 11 #include <linux/platform_device.h> 12 #include <sound/pcm_params.h> 13 #include <sound/soc.h> 14 #include <sound/soc-dai.h> 15 #include <linux/pm_runtime.h> 16 #include <linux/soundwire/sdw_amd.h> 17 #include "acp63.h" 18 19 #define DRV_NAME "amd_ps_sdw_dma" 20 21 static struct sdw_dma_ring_buf_reg sdw0_dma_ring_buf_reg[ACP63_SDW0_DMA_MAX_STREAMS] = { 22 {ACP_AUDIO0_TX_DMA_SIZE, ACP_AUDIO0_TX_FIFOADDR, ACP_AUDIO0_TX_FIFOSIZE, 23 ACP_AUDIO0_TX_RINGBUFSIZE, ACP_AUDIO0_TX_RINGBUFADDR, ACP_AUDIO0_TX_INTR_WATERMARK_SIZE, 24 ACP_AUDIO0_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_TX_LINEARPOSITIONCNTR_HIGH}, 25 {ACP_AUDIO1_TX_DMA_SIZE, ACP_AUDIO1_TX_FIFOADDR, ACP_AUDIO1_TX_FIFOSIZE, 26 ACP_AUDIO1_TX_RINGBUFSIZE, ACP_AUDIO1_TX_RINGBUFADDR, ACP_AUDIO1_TX_INTR_WATERMARK_SIZE, 27 ACP_AUDIO1_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO1_TX_LINEARPOSITIONCNTR_HIGH}, 28 {ACP_AUDIO2_TX_DMA_SIZE, ACP_AUDIO2_TX_FIFOADDR, ACP_AUDIO2_TX_FIFOSIZE, 29 ACP_AUDIO2_TX_RINGBUFSIZE, ACP_AUDIO2_TX_RINGBUFADDR, ACP_AUDIO2_TX_INTR_WATERMARK_SIZE, 30 ACP_AUDIO2_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO2_TX_LINEARPOSITIONCNTR_HIGH}, 31 {ACP_AUDIO0_RX_DMA_SIZE, ACP_AUDIO0_RX_FIFOADDR, ACP_AUDIO0_RX_FIFOSIZE, 32 ACP_AUDIO0_RX_RINGBUFSIZE, ACP_AUDIO0_RX_RINGBUFADDR, ACP_AUDIO0_RX_INTR_WATERMARK_SIZE, 33 ACP_AUDIO0_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_TX_LINEARPOSITIONCNTR_HIGH}, 34 {ACP_AUDIO1_RX_DMA_SIZE, ACP_AUDIO1_RX_FIFOADDR, ACP_AUDIO1_RX_FIFOSIZE, 35 ACP_AUDIO1_RX_RINGBUFSIZE, ACP_AUDIO1_RX_RINGBUFADDR, ACP_AUDIO1_RX_INTR_WATERMARK_SIZE, 36 ACP_AUDIO1_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH}, 37 {ACP_AUDIO2_RX_DMA_SIZE, ACP_AUDIO2_RX_FIFOADDR, ACP_AUDIO2_RX_FIFOSIZE, 38 ACP_AUDIO2_RX_RINGBUFSIZE, ACP_AUDIO2_RX_RINGBUFADDR, ACP_AUDIO2_RX_INTR_WATERMARK_SIZE, 39 ACP_AUDIO2_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO2_RX_LINEARPOSITIONCNTR_HIGH} 40 }; 41 42 static struct sdw_dma_ring_buf_reg sdw1_dma_ring_buf_reg[ACP63_SDW1_DMA_MAX_STREAMS] = { 43 {ACP_P1_AUDIO1_TX_DMA_SIZE, ACP_P1_AUDIO1_TX_FIFOADDR, ACP_P1_AUDIO1_TX_FIFOSIZE, 44 ACP_P1_AUDIO1_TX_RINGBUFSIZE, ACP_P1_AUDIO1_TX_RINGBUFADDR, 45 ACP_P1_AUDIO1_TX_INTR_WATERMARK_SIZE, 46 ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR_HIGH}, 47 {ACP_P1_AUDIO1_RX_DMA_SIZE, ACP_P1_AUDIO1_RX_FIFOADDR, ACP_P1_AUDIO1_RX_FIFOSIZE, 48 ACP_P1_AUDIO1_RX_RINGBUFSIZE, ACP_P1_AUDIO1_RX_RINGBUFADDR, 49 ACP_P1_AUDIO1_RX_INTR_WATERMARK_SIZE, 50 ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH}, 51 }; 52 53 static u32 sdw0_dma_enable_reg[ACP63_SDW0_DMA_MAX_STREAMS] = { 54 ACP_SW0_AUDIO0_TX_EN, 55 ACP_SW0_AUDIO1_TX_EN, 56 ACP_SW0_AUDIO2_TX_EN, 57 ACP_SW0_AUDIO0_RX_EN, 58 ACP_SW0_AUDIO1_RX_EN, 59 ACP_SW0_AUDIO2_RX_EN, 60 }; 61 62 static u32 sdw1_dma_enable_reg[ACP63_SDW1_DMA_MAX_STREAMS] = { 63 ACP_SW1_AUDIO1_TX_EN, 64 ACP_SW1_AUDIO1_RX_EN, 65 }; 66 67 static const struct snd_pcm_hardware acp63_sdw_hardware_playback = { 68 .info = SNDRV_PCM_INFO_INTERLEAVED | 69 SNDRV_PCM_INFO_BLOCK_TRANSFER | 70 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | 71 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, 72 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 73 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, 74 .channels_min = 2, 75 .channels_max = 2, 76 .rates = SNDRV_PCM_RATE_48000, 77 .rate_min = 48000, 78 .rate_max = 48000, 79 .buffer_bytes_max = SDW_PLAYBACK_MAX_NUM_PERIODS * SDW_PLAYBACK_MAX_PERIOD_SIZE, 80 .period_bytes_min = SDW_PLAYBACK_MIN_PERIOD_SIZE, 81 .period_bytes_max = SDW_PLAYBACK_MAX_PERIOD_SIZE, 82 .periods_min = SDW_PLAYBACK_MIN_NUM_PERIODS, 83 .periods_max = SDW_PLAYBACK_MAX_NUM_PERIODS, 84 }; 85 86 static const struct snd_pcm_hardware acp63_sdw_hardware_capture = { 87 .info = SNDRV_PCM_INFO_INTERLEAVED | 88 SNDRV_PCM_INFO_BLOCK_TRANSFER | 89 SNDRV_PCM_INFO_MMAP | 90 SNDRV_PCM_INFO_MMAP_VALID | 91 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, 92 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 93 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, 94 .channels_min = 2, 95 .channels_max = 2, 96 .rates = SNDRV_PCM_RATE_48000, 97 .rate_min = 48000, 98 .rate_max = 48000, 99 .buffer_bytes_max = SDW_CAPTURE_MAX_NUM_PERIODS * SDW_CAPTURE_MAX_PERIOD_SIZE, 100 .period_bytes_min = SDW_CAPTURE_MIN_PERIOD_SIZE, 101 .period_bytes_max = SDW_CAPTURE_MAX_PERIOD_SIZE, 102 .periods_min = SDW_CAPTURE_MIN_NUM_PERIODS, 103 .periods_max = SDW_CAPTURE_MAX_NUM_PERIODS, 104 }; 105 106 static void acp63_enable_disable_sdw_dma_interrupts(void __iomem *acp_base, bool enable) 107 { 108 u32 ext_intr_cntl, ext_intr_cntl1; 109 u32 irq_mask = ACP_SDW_DMA_IRQ_MASK; 110 u32 irq_mask1 = ACP_P1_SDW_DMA_IRQ_MASK; 111 112 if (enable) { 113 ext_intr_cntl = readl(acp_base + ACP_EXTERNAL_INTR_CNTL); 114 ext_intr_cntl |= irq_mask; 115 writel(ext_intr_cntl, acp_base + ACP_EXTERNAL_INTR_CNTL); 116 ext_intr_cntl1 = readl(acp_base + ACP_EXTERNAL_INTR_CNTL1); 117 ext_intr_cntl1 |= irq_mask1; 118 writel(ext_intr_cntl1, acp_base + ACP_EXTERNAL_INTR_CNTL1); 119 } else { 120 ext_intr_cntl = readl(acp_base + ACP_EXTERNAL_INTR_CNTL); 121 ext_intr_cntl &= ~irq_mask; 122 writel(ext_intr_cntl, acp_base + ACP_EXTERNAL_INTR_CNTL); 123 ext_intr_cntl1 = readl(acp_base + ACP_EXTERNAL_INTR_CNTL1); 124 ext_intr_cntl1 &= ~irq_mask1; 125 writel(ext_intr_cntl1, acp_base + ACP_EXTERNAL_INTR_CNTL1); 126 } 127 } 128 129 static void acp63_config_dma(struct acp_sdw_dma_stream *stream, void __iomem *acp_base, 130 u32 stream_id) 131 { 132 u16 page_idx; 133 u32 low, high, val; 134 u32 sdw_dma_pte_offset; 135 dma_addr_t addr; 136 137 addr = stream->dma_addr; 138 sdw_dma_pte_offset = SDW_PTE_OFFSET(stream->instance); 139 val = sdw_dma_pte_offset + (stream_id * ACP_SDW_PTE_OFFSET); 140 141 /* Group Enable */ 142 writel(ACP_SDW_SRAM_PTE_OFFSET | BIT(31), acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_2); 143 writel(PAGE_SIZE_4K_ENABLE, acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2); 144 for (page_idx = 0; page_idx < stream->num_pages; page_idx++) { 145 /* Load the low address of page int ACP SRAM through SRBM */ 146 low = lower_32_bits(addr); 147 high = upper_32_bits(addr); 148 149 writel(low, acp_base + ACP_SCRATCH_REG_0 + val); 150 high |= BIT(31); 151 writel(high, acp_base + ACP_SCRATCH_REG_0 + val + 4); 152 val += 8; 153 addr += PAGE_SIZE; 154 } 155 writel(0x1, acp_base + ACPAXI2AXI_ATU_CTRL); 156 } 157 158 static int acp63_configure_sdw_ringbuffer(void __iomem *acp_base, u32 stream_id, u32 size, 159 u32 manager_instance) 160 { 161 u32 reg_dma_size; 162 u32 reg_fifo_addr; 163 u32 reg_fifo_size; 164 u32 reg_ring_buf_size; 165 u32 reg_ring_buf_addr; 166 u32 sdw_fifo_addr; 167 u32 sdw_fifo_offset; 168 u32 sdw_ring_buf_addr; 169 u32 sdw_ring_buf_size; 170 u32 sdw_mem_window_offset; 171 172 switch (manager_instance) { 173 case ACP_SDW0: 174 reg_dma_size = sdw0_dma_ring_buf_reg[stream_id].reg_dma_size; 175 reg_fifo_addr = sdw0_dma_ring_buf_reg[stream_id].reg_fifo_addr; 176 reg_fifo_size = sdw0_dma_ring_buf_reg[stream_id].reg_fifo_size; 177 reg_ring_buf_size = sdw0_dma_ring_buf_reg[stream_id].reg_ring_buf_size; 178 reg_ring_buf_addr = sdw0_dma_ring_buf_reg[stream_id].reg_ring_buf_addr; 179 break; 180 case ACP_SDW1: 181 reg_dma_size = sdw1_dma_ring_buf_reg[stream_id].reg_dma_size; 182 reg_fifo_addr = sdw1_dma_ring_buf_reg[stream_id].reg_fifo_addr; 183 reg_fifo_size = sdw1_dma_ring_buf_reg[stream_id].reg_fifo_size; 184 reg_ring_buf_size = sdw1_dma_ring_buf_reg[stream_id].reg_ring_buf_size; 185 reg_ring_buf_addr = sdw1_dma_ring_buf_reg[stream_id].reg_ring_buf_addr; 186 break; 187 default: 188 return -EINVAL; 189 } 190 sdw_fifo_offset = ACP_SDW_FIFO_OFFSET(manager_instance); 191 sdw_mem_window_offset = SDW_MEM_WINDOW_START(manager_instance); 192 sdw_fifo_addr = sdw_fifo_offset + (stream_id * SDW_FIFO_OFFSET); 193 sdw_ring_buf_addr = sdw_mem_window_offset + (stream_id * ACP_SDW_RING_BUFF_ADDR_OFFSET); 194 sdw_ring_buf_size = size; 195 writel(sdw_ring_buf_size, acp_base + reg_ring_buf_size); 196 writel(sdw_ring_buf_addr, acp_base + reg_ring_buf_addr); 197 writel(sdw_fifo_addr, acp_base + reg_fifo_addr); 198 writel(SDW_DMA_SIZE, acp_base + reg_dma_size); 199 writel(SDW_FIFO_SIZE, acp_base + reg_fifo_size); 200 return 0; 201 } 202 203 static int acp63_sdw_dma_open(struct snd_soc_component *component, 204 struct snd_pcm_substream *substream) 205 { 206 struct snd_pcm_runtime *runtime; 207 struct acp_sdw_dma_stream *stream; 208 struct snd_soc_dai *cpu_dai; 209 struct amd_sdw_manager *amd_manager; 210 struct snd_soc_pcm_runtime *prtd = substream->private_data; 211 int ret; 212 213 runtime = substream->runtime; 214 cpu_dai = asoc_rtd_to_cpu(prtd, 0); 215 amd_manager = snd_soc_dai_get_drvdata(cpu_dai); 216 stream = kzalloc(sizeof(*stream), GFP_KERNEL); 217 if (!stream) 218 return -ENOMEM; 219 220 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 221 runtime->hw = acp63_sdw_hardware_playback; 222 else 223 runtime->hw = acp63_sdw_hardware_capture; 224 ret = snd_pcm_hw_constraint_integer(runtime, 225 SNDRV_PCM_HW_PARAM_PERIODS); 226 if (ret < 0) { 227 dev_err(component->dev, "set integer constraint failed\n"); 228 kfree(stream); 229 return ret; 230 } 231 232 stream->stream_id = cpu_dai->id; 233 stream->instance = amd_manager->instance; 234 runtime->private_data = stream; 235 return ret; 236 } 237 238 static int acp63_sdw_dma_hw_params(struct snd_soc_component *component, 239 struct snd_pcm_substream *substream, 240 struct snd_pcm_hw_params *params) 241 { 242 struct acp_sdw_dma_stream *stream; 243 struct sdw_dma_dev_data *sdw_data; 244 u32 period_bytes; 245 u32 water_mark_size_reg; 246 u32 irq_mask, ext_intr_ctrl; 247 u64 size; 248 u32 stream_id; 249 u32 acp_ext_intr_cntl_reg; 250 int ret; 251 252 sdw_data = dev_get_drvdata(component->dev); 253 stream = substream->runtime->private_data; 254 if (!stream) 255 return -EINVAL; 256 stream_id = stream->stream_id; 257 switch (stream->instance) { 258 case ACP_SDW0: 259 sdw_data->sdw0_dma_stream[stream_id] = substream; 260 water_mark_size_reg = sdw0_dma_ring_buf_reg[stream_id].water_mark_size_reg; 261 acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL; 262 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 263 irq_mask = BIT(SDW0_DMA_TX_IRQ_MASK(stream_id)); 264 else 265 irq_mask = BIT(SDW0_DMA_RX_IRQ_MASK(stream_id)); 266 break; 267 case ACP_SDW1: 268 sdw_data->sdw1_dma_stream[stream_id] = substream; 269 acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL1; 270 water_mark_size_reg = sdw1_dma_ring_buf_reg[stream_id].water_mark_size_reg; 271 irq_mask = BIT(SDW1_DMA_IRQ_MASK(stream_id)); 272 break; 273 default: 274 return -EINVAL; 275 } 276 size = params_buffer_bytes(params); 277 period_bytes = params_period_bytes(params); 278 stream->dma_addr = substream->runtime->dma_addr; 279 stream->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); 280 acp63_config_dma(stream, sdw_data->acp_base, stream_id); 281 ret = acp63_configure_sdw_ringbuffer(sdw_data->acp_base, stream_id, size, 282 stream->instance); 283 if (ret) { 284 dev_err(component->dev, "Invalid DMA channel\n"); 285 return -EINVAL; 286 } 287 ext_intr_ctrl = readl(sdw_data->acp_base + acp_ext_intr_cntl_reg); 288 ext_intr_ctrl |= irq_mask; 289 writel(ext_intr_ctrl, sdw_data->acp_base + acp_ext_intr_cntl_reg); 290 writel(period_bytes, sdw_data->acp_base + water_mark_size_reg); 291 return 0; 292 } 293 294 static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __iomem *acp_base) 295 { 296 union acp_sdw_dma_count byte_count; 297 u32 pos_low_reg, pos_high_reg; 298 299 byte_count.bytescount = 0; 300 switch (stream->instance) { 301 case ACP_SDW0: 302 pos_low_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_low_reg; 303 pos_high_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_high_reg; 304 break; 305 case ACP_SDW1: 306 pos_low_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_low_reg; 307 pos_high_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_high_reg; 308 break; 309 default: 310 return -EINVAL; 311 } 312 if (pos_low_reg) { 313 byte_count.bcount.high = readl(acp_base + pos_high_reg); 314 byte_count.bcount.low = readl(acp_base + pos_low_reg); 315 } 316 return byte_count.bytescount; 317 } 318 319 static snd_pcm_uframes_t acp63_sdw_dma_pointer(struct snd_soc_component *comp, 320 struct snd_pcm_substream *substream) 321 { 322 struct sdw_dma_dev_data *sdw_data; 323 struct acp_sdw_dma_stream *stream; 324 u32 pos, buffersize; 325 u64 bytescount; 326 327 sdw_data = dev_get_drvdata(comp->dev); 328 stream = substream->runtime->private_data; 329 buffersize = frames_to_bytes(substream->runtime, 330 substream->runtime->buffer_size); 331 bytescount = acp63_sdw_get_byte_count(stream, sdw_data->acp_base); 332 if (bytescount > stream->bytescount) 333 bytescount -= stream->bytescount; 334 pos = do_div(bytescount, buffersize); 335 return bytes_to_frames(substream->runtime, pos); 336 } 337 338 static int acp63_sdw_dma_new(struct snd_soc_component *component, 339 struct snd_soc_pcm_runtime *rtd) 340 { 341 struct device *parent = component->dev->parent; 342 343 snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, 344 parent, SDW_MIN_BUFFER, SDW_MAX_BUFFER); 345 return 0; 346 } 347 348 static int acp63_sdw_dma_close(struct snd_soc_component *component, 349 struct snd_pcm_substream *substream) 350 { 351 struct sdw_dma_dev_data *sdw_data; 352 struct acp_sdw_dma_stream *stream; 353 354 sdw_data = dev_get_drvdata(component->dev); 355 stream = substream->runtime->private_data; 356 if (!stream) 357 return -EINVAL; 358 switch (stream->instance) { 359 case ACP_SDW0: 360 sdw_data->sdw0_dma_stream[stream->stream_id] = NULL; 361 break; 362 case ACP_SDW1: 363 sdw_data->sdw1_dma_stream[stream->stream_id] = NULL; 364 break; 365 default: 366 return -EINVAL; 367 } 368 kfree(stream); 369 return 0; 370 } 371 372 static int acp63_sdw_dma_enable(struct snd_pcm_substream *substream, 373 void __iomem *acp_base, bool sdw_dma_enable) 374 { 375 struct acp_sdw_dma_stream *stream; 376 u32 stream_id; 377 u32 sdw_dma_en_reg; 378 u32 sdw_dma_en_stat_reg; 379 u32 sdw_dma_stat; 380 u32 dma_enable; 381 382 stream = substream->runtime->private_data; 383 stream_id = stream->stream_id; 384 switch (stream->instance) { 385 case ACP_SDW0: 386 sdw_dma_en_reg = sdw0_dma_enable_reg[stream_id]; 387 break; 388 case ACP_SDW1: 389 sdw_dma_en_reg = sdw1_dma_enable_reg[stream_id]; 390 break; 391 default: 392 return -EINVAL; 393 } 394 sdw_dma_en_stat_reg = sdw_dma_en_reg + 4; 395 dma_enable = sdw_dma_enable; 396 writel(dma_enable, acp_base + sdw_dma_en_reg); 397 return readl_poll_timeout(acp_base + sdw_dma_en_stat_reg, sdw_dma_stat, 398 (sdw_dma_stat == dma_enable), ACP_DELAY_US, ACP_COUNTER); 399 } 400 401 static int acp63_sdw_dma_trigger(struct snd_soc_component *comp, 402 struct snd_pcm_substream *substream, 403 int cmd) 404 { 405 struct sdw_dma_dev_data *sdw_data; 406 int ret; 407 408 sdw_data = dev_get_drvdata(comp->dev); 409 switch (cmd) { 410 case SNDRV_PCM_TRIGGER_START: 411 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 412 case SNDRV_PCM_TRIGGER_RESUME: 413 ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, true); 414 break; 415 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 416 case SNDRV_PCM_TRIGGER_SUSPEND: 417 case SNDRV_PCM_TRIGGER_STOP: 418 ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, false); 419 break; 420 default: 421 ret = -EINVAL; 422 } 423 if (ret) 424 dev_err(comp->dev, "trigger %d failed: %d", cmd, ret); 425 return ret; 426 } 427 428 static const struct snd_soc_component_driver acp63_sdw_component = { 429 .name = DRV_NAME, 430 .open = acp63_sdw_dma_open, 431 .close = acp63_sdw_dma_close, 432 .hw_params = acp63_sdw_dma_hw_params, 433 .trigger = acp63_sdw_dma_trigger, 434 .pointer = acp63_sdw_dma_pointer, 435 .pcm_construct = acp63_sdw_dma_new, 436 }; 437 438 static int acp63_sdw_platform_probe(struct platform_device *pdev) 439 { 440 struct resource *res; 441 struct sdw_dma_dev_data *sdw_data; 442 struct acp63_dev_data *acp_data; 443 struct device *parent; 444 int status; 445 446 parent = pdev->dev.parent; 447 acp_data = dev_get_drvdata(parent); 448 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 449 if (!res) { 450 dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n"); 451 return -ENODEV; 452 } 453 454 sdw_data = devm_kzalloc(&pdev->dev, sizeof(*sdw_data), GFP_KERNEL); 455 if (!sdw_data) 456 return -ENOMEM; 457 458 sdw_data->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); 459 if (!sdw_data->acp_base) 460 return -ENOMEM; 461 462 sdw_data->acp_lock = &acp_data->acp_lock; 463 dev_set_drvdata(&pdev->dev, sdw_data); 464 status = devm_snd_soc_register_component(&pdev->dev, 465 &acp63_sdw_component, 466 NULL, 0); 467 if (status) { 468 dev_err(&pdev->dev, "Fail to register sdw dma component\n"); 469 return status; 470 } 471 pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS); 472 pm_runtime_use_autosuspend(&pdev->dev); 473 pm_runtime_mark_last_busy(&pdev->dev); 474 pm_runtime_set_active(&pdev->dev); 475 pm_runtime_enable(&pdev->dev); 476 return 0; 477 } 478 479 static int acp63_sdw_platform_remove(struct platform_device *pdev) 480 { 481 pm_runtime_disable(&pdev->dev); 482 return 0; 483 } 484 485 static int acp_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data) 486 { 487 struct acp_sdw_dma_stream *stream; 488 struct snd_pcm_substream *substream; 489 struct snd_pcm_runtime *runtime; 490 u32 period_bytes, buf_size, water_mark_size_reg; 491 u32 stream_count; 492 int index, instance, ret; 493 494 for (instance = 0; instance < AMD_SDW_MAX_MANAGERS; instance++) { 495 if (instance == ACP_SDW0) 496 stream_count = ACP63_SDW0_DMA_MAX_STREAMS; 497 else 498 stream_count = ACP63_SDW1_DMA_MAX_STREAMS; 499 500 for (index = 0; index < stream_count; index++) { 501 if (instance == ACP_SDW0) { 502 substream = sdw_data->sdw0_dma_stream[index]; 503 water_mark_size_reg = 504 sdw0_dma_ring_buf_reg[index].water_mark_size_reg; 505 } else { 506 substream = sdw_data->sdw1_dma_stream[index]; 507 water_mark_size_reg = 508 sdw1_dma_ring_buf_reg[index].water_mark_size_reg; 509 } 510 511 if (substream && substream->runtime) { 512 runtime = substream->runtime; 513 stream = runtime->private_data; 514 period_bytes = frames_to_bytes(runtime, runtime->period_size); 515 buf_size = frames_to_bytes(runtime, runtime->buffer_size); 516 acp63_config_dma(stream, sdw_data->acp_base, index); 517 ret = acp63_configure_sdw_ringbuffer(sdw_data->acp_base, index, 518 buf_size, instance); 519 if (ret) 520 return ret; 521 writel(period_bytes, sdw_data->acp_base + water_mark_size_reg); 522 } 523 } 524 } 525 acp63_enable_disable_sdw_dma_interrupts(sdw_data->acp_base, true); 526 return 0; 527 } 528 529 static int __maybe_unused acp63_sdw_pcm_resume(struct device *dev) 530 { 531 struct sdw_dma_dev_data *sdw_data; 532 533 sdw_data = dev_get_drvdata(dev); 534 return acp_restore_sdw_dma_config(sdw_data); 535 } 536 537 static const struct dev_pm_ops acp63_pm_ops = { 538 SET_SYSTEM_SLEEP_PM_OPS(NULL, acp63_sdw_pcm_resume) 539 }; 540 541 static struct platform_driver acp63_sdw_dma_driver = { 542 .probe = acp63_sdw_platform_probe, 543 .remove = acp63_sdw_platform_remove, 544 .driver = { 545 .name = "amd_ps_sdw_dma", 546 .pm = &acp63_pm_ops, 547 }, 548 }; 549 550 module_platform_driver(acp63_sdw_dma_driver); 551 552 MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); 553 MODULE_DESCRIPTION("AMD ACP6.3 PS SDW DMA Driver"); 554 MODULE_LICENSE("GPL"); 555 MODULE_ALIAS("platform:" DRV_NAME); 556