Lines Matching +full:ddr +full:- +full:config
1 // SPDX-License-Identifier: GPL-2.0
4 #include <linux/dma-mapping.h>
6 #include <linux/dma/sprd-dma.h>
14 #include "sprd-pcm-dma.h"
31 #define SPRD_COMPR_IRAM_LINKLIST_SIZE (1024 - SPRD_COMPR_IRAM_INFO_SIZE)
36 /* Stage 1 DDR buffer size definition */
52 * The Spreadtrum Audio compress offload mode will use 2-stage DMA transfer to
58 * For 2-stage DMA transfer, we can allocate 2 buffers: IRAM buffer (always
59 * power-on) and DDR buffer. The source channel will transfer data from IRAM
62 * DDR buffer to IRAM buffer.
64 * Since the DSP fifo is only 512B, IRAM buffer is allocated by 32K, and DDR
66 * done, we can wake up the AP system to transfer data from DDR to IRAM, and
79 /* Stage 1 DDR buffer */
93 /* Stage 1 DDR buffer received data size */
95 /* Stage 1 DDR buffer pointer */
106 struct snd_compr_runtime *runtime = cstream->runtime; in sprd_platform_compr_drain_notify()
107 struct sprd_compr_stream *stream = runtime->private_data; in sprd_platform_compr_drain_notify()
109 memset(stream->info_area, 0, sizeof(struct sprd_compr_playinfo)); in sprd_platform_compr_drain_notify()
117 struct snd_compr_runtime *runtime = cstream->runtime; in sprd_platform_compr_dma_complete()
118 struct sprd_compr_stream *stream = runtime->private_data; in sprd_platform_compr_dma_complete()
119 struct sprd_compr_dma *dma = &stream->dma[1]; in sprd_platform_compr_dma_complete()
122 stream->copied_total += dma->trans_len; in sprd_platform_compr_dma_complete()
123 if (stream->copied_total > stream->received_total) in sprd_platform_compr_dma_complete()
124 stream->copied_total = stream->received_total; in sprd_platform_compr_dma_complete()
134 struct snd_compr_runtime *runtime = cstream->runtime; in sprd_platform_compr_dma_config()
135 struct sprd_compr_stream *stream = runtime->private_data; in sprd_platform_compr_dma_config()
136 struct snd_soc_pcm_runtime *rtd = cstream->private_data; in sprd_platform_compr_dma_config()
137 struct device *dev = component->dev; in sprd_platform_compr_dma_config()
139 struct sprd_pcm_dma_params *dma_params = data->dma_params; in sprd_platform_compr_dma_config()
140 struct sprd_compr_dma *dma = &stream->dma[channel]; in sprd_platform_compr_dma_config()
141 struct dma_slave_config config = { }; in sprd_platform_compr_dma_config() local
153 return -EINVAL; in sprd_platform_compr_dma_config()
156 dma->chan = dma_request_slave_channel(dev, in sprd_platform_compr_dma_config()
157 dma_params->chan_name[channel]); in sprd_platform_compr_dma_config()
158 if (!dma->chan) { in sprd_platform_compr_dma_config()
160 return -ENODEV; in sprd_platform_compr_dma_config()
165 ret = -ENOMEM; in sprd_platform_compr_dma_config()
172 period = (SPRD_COMPR_MCDT_FIFO_SIZE - SPRD_COMPR_MCDT_EMPTY_WMK) * 4; in sprd_platform_compr_dma_config()
173 period_cnt = params->buffer.fragment_size / period; in sprd_platform_compr_dma_config()
174 src_addr = stream->iram_buffer.addr; in sprd_platform_compr_dma_config()
175 dst_addr = dma_params->dev_phys[channel]; in sprd_platform_compr_dma_config()
184 period = params->buffer.fragment_size; in sprd_platform_compr_dma_config()
185 period_cnt = params->buffer.fragments; in sprd_platform_compr_dma_config()
186 src_addr = stream->compr_buffer.addr; in sprd_platform_compr_dma_config()
187 dst_addr = stream->iram_buffer.addr; in sprd_platform_compr_dma_config()
195 ret = -EINVAL; in sprd_platform_compr_dma_config()
199 dma->trans_len = period * period_cnt; in sprd_platform_compr_dma_config()
201 config.src_maxburst = period; in sprd_platform_compr_dma_config()
202 config.src_addr_width = bus_width; in sprd_platform_compr_dma_config()
203 config.dst_addr_width = bus_width; in sprd_platform_compr_dma_config()
204 if (cstream->direction == SND_COMPRESS_PLAYBACK) { in sprd_platform_compr_dma_config()
205 config.src_addr = src_addr; in sprd_platform_compr_dma_config()
206 config.dst_addr = dst_addr; in sprd_platform_compr_dma_config()
209 config.src_addr = dst_addr; in sprd_platform_compr_dma_config()
210 config.dst_addr = src_addr; in sprd_platform_compr_dma_config()
216 sg_dma_len(sgt) = dma->trans_len; in sprd_platform_compr_dma_config()
221 * Configure the link-list address for the DMA engine link-list in sprd_platform_compr_dma_config()
224 link.virt_addr = (unsigned long)dma->virt; in sprd_platform_compr_dma_config()
225 link.phy_addr = dma->phys; in sprd_platform_compr_dma_config()
227 ret = dmaengine_slave_config(dma->chan, &config); in sprd_platform_compr_dma_config()
238 dma->desc = dma->chan->device->device_prep_slave_sg(dma->chan, sg, in sprd_platform_compr_dma_config()
241 if (!dma->desc) { in sprd_platform_compr_dma_config()
243 ret = -ENOMEM; in sprd_platform_compr_dma_config()
248 if (!params->no_wake_mode && channel == 1) { in sprd_platform_compr_dma_config()
249 dma->desc->callback = sprd_platform_compr_dma_complete; in sprd_platform_compr_dma_config()
250 dma->desc->callback_param = cstream; in sprd_platform_compr_dma_config()
260 dma_release_channel(dma->chan); in sprd_platform_compr_dma_config()
268 struct snd_compr_runtime *runtime = cstream->runtime; in sprd_platform_compr_set_params()
269 struct sprd_compr_stream *stream = runtime->private_data; in sprd_platform_compr_set_params()
270 struct device *dev = component->dev; in sprd_platform_compr_set_params()
275 * Configure the DMA engine 2-stage transfer mode. Channel 1 set as the in sprd_platform_compr_set_params()
282 dev_err(dev, "failed to config stage 1 DMA: %d\n", ret); in sprd_platform_compr_set_params()
288 dev_err(dev, "failed to config stage 0 DMA: %d\n", ret); in sprd_platform_compr_set_params()
292 compr_params.direction = cstream->direction; in sprd_platform_compr_set_params()
293 compr_params.sample_rate = params->codec.sample_rate; in sprd_platform_compr_set_params()
294 compr_params.channels = stream->num_channels; in sprd_platform_compr_set_params()
295 compr_params.info_phys = stream->info_phys; in sprd_platform_compr_set_params()
296 compr_params.info_size = stream->info_size; in sprd_platform_compr_set_params()
297 compr_params.rate = params->codec.bit_rate; in sprd_platform_compr_set_params()
298 compr_params.format = params->codec.id; in sprd_platform_compr_set_params()
300 ret = stream->compr_ops->set_params(cstream->direction, &compr_params); in sprd_platform_compr_set_params()
309 dma_release_channel(stream->dma[0].chan); in sprd_platform_compr_set_params()
311 dma_release_channel(stream->dma[1].chan); in sprd_platform_compr_set_params()
318 struct snd_compr_runtime *runtime = cstream->runtime; in sprd_platform_compr_open()
319 struct snd_soc_pcm_runtime *rtd = cstream->private_data; in sprd_platform_compr_open()
320 struct device *dev = component->dev; in sprd_platform_compr_open()
324 int stream_id = cstream->direction, ret; in sprd_platform_compr_open()
332 return -ENOMEM; in sprd_platform_compr_open()
334 stream->cstream = cstream; in sprd_platform_compr_open()
335 stream->num_channels = 2; in sprd_platform_compr_open()
336 stream->compr_ops = data->ops; in sprd_platform_compr_open()
340 * link-list size and play information of DSP address size. in sprd_platform_compr_open()
343 SPRD_COMPR_IRAM_SIZE, &stream->iram_buffer); in sprd_platform_compr_open()
347 /* Use to save link-list configuration for DMA 0. */ in sprd_platform_compr_open()
348 stream->dma[0].virt = stream->iram_buffer.area + SPRD_COMPR_IRAM_SIZE; in sprd_platform_compr_open()
349 stream->dma[0].phys = stream->iram_buffer.addr + SPRD_COMPR_IRAM_SIZE; in sprd_platform_compr_open()
352 stream->info_phys = stream->iram_buffer.addr + SPRD_COMPR_IRAM_SIZE + in sprd_platform_compr_open()
354 stream->info_area = stream->iram_buffer.area + SPRD_COMPR_IRAM_SIZE + in sprd_platform_compr_open()
356 stream->info_size = SPRD_COMPR_IRAM_INFO_SIZE; in sprd_platform_compr_open()
359 * Allocate the stage 1 DDR buffer size, including the DMA 1 link-list in sprd_platform_compr_open()
363 SPRD_COMPR_AREA_SIZE, &stream->compr_buffer); in sprd_platform_compr_open()
367 /* Use to save link-list configuration for DMA 1. */ in sprd_platform_compr_open()
368 stream->dma[1].virt = stream->compr_buffer.area + SPRD_COMPR_AREA_SIZE; in sprd_platform_compr_open()
369 stream->dma[1].phys = stream->compr_buffer.addr + SPRD_COMPR_AREA_SIZE; in sprd_platform_compr_open()
373 ret = stream->compr_ops->open(stream_id, &cb); in sprd_platform_compr_open()
379 runtime->private_data = stream; in sprd_platform_compr_open()
383 snd_dma_free_pages(&stream->compr_buffer); in sprd_platform_compr_open()
385 snd_dma_free_pages(&stream->iram_buffer); in sprd_platform_compr_open()
395 struct snd_compr_runtime *runtime = cstream->runtime; in sprd_platform_compr_free()
396 struct sprd_compr_stream *stream = runtime->private_data; in sprd_platform_compr_free()
397 struct device *dev = component->dev; in sprd_platform_compr_free()
398 int stream_id = cstream->direction, i; in sprd_platform_compr_free()
400 for (i = 0; i < stream->num_channels; i++) { in sprd_platform_compr_free()
401 struct sprd_compr_dma *dma = &stream->dma[i]; in sprd_platform_compr_free()
403 if (dma->chan) { in sprd_platform_compr_free()
404 dma_release_channel(dma->chan); in sprd_platform_compr_free()
405 dma->chan = NULL; in sprd_platform_compr_free()
409 snd_dma_free_pages(&stream->compr_buffer); in sprd_platform_compr_free()
410 snd_dma_free_pages(&stream->iram_buffer); in sprd_platform_compr_free()
412 stream->compr_ops->close(stream_id); in sprd_platform_compr_free()
422 struct snd_compr_runtime *runtime = cstream->runtime; in sprd_platform_compr_trigger()
423 struct sprd_compr_stream *stream = runtime->private_data; in sprd_platform_compr_trigger()
424 struct device *dev = component->dev; in sprd_platform_compr_trigger()
425 int channels = stream->num_channels, ret = 0, i; in sprd_platform_compr_trigger()
426 int stream_id = cstream->direction; in sprd_platform_compr_trigger()
428 if (cstream->direction != SND_COMPRESS_PLAYBACK) { in sprd_platform_compr_trigger()
430 return -EINVAL; in sprd_platform_compr_trigger()
435 for (i = channels - 1; i >= 0; i--) { in sprd_platform_compr_trigger()
436 struct sprd_compr_dma *dma = &stream->dma[i]; in sprd_platform_compr_trigger()
438 if (!dma->desc) in sprd_platform_compr_trigger()
441 dma->cookie = dmaengine_submit(dma->desc); in sprd_platform_compr_trigger()
442 ret = dma_submit_error(dma->cookie); in sprd_platform_compr_trigger()
450 for (i = channels - 1; i >= 0; i--) { in sprd_platform_compr_trigger()
451 struct sprd_compr_dma *dma = &stream->dma[i]; in sprd_platform_compr_trigger()
453 if (dma->chan) in sprd_platform_compr_trigger()
454 dma_async_issue_pending(dma->chan); in sprd_platform_compr_trigger()
457 ret = stream->compr_ops->start(stream_id); in sprd_platform_compr_trigger()
461 for (i = channels - 1; i >= 0; i--) { in sprd_platform_compr_trigger()
462 struct sprd_compr_dma *dma = &stream->dma[i]; in sprd_platform_compr_trigger()
464 if (dma->chan) in sprd_platform_compr_trigger()
465 dmaengine_terminate_async(dma->chan); in sprd_platform_compr_trigger()
468 stream->copied_total = 0; in sprd_platform_compr_trigger()
469 stream->stage1_pointer = 0; in sprd_platform_compr_trigger()
470 stream->received_total = 0; in sprd_platform_compr_trigger()
471 stream->received_stage0 = 0; in sprd_platform_compr_trigger()
472 stream->received_stage1 = 0; in sprd_platform_compr_trigger()
474 ret = stream->compr_ops->stop(stream_id); in sprd_platform_compr_trigger()
479 for (i = channels - 1; i >= 0; i--) { in sprd_platform_compr_trigger()
480 struct sprd_compr_dma *dma = &stream->dma[i]; in sprd_platform_compr_trigger()
482 if (dma->chan) in sprd_platform_compr_trigger()
483 dmaengine_pause(dma->chan); in sprd_platform_compr_trigger()
486 ret = stream->compr_ops->pause(stream_id); in sprd_platform_compr_trigger()
491 for (i = channels - 1; i >= 0; i--) { in sprd_platform_compr_trigger()
492 struct sprd_compr_dma *dma = &stream->dma[i]; in sprd_platform_compr_trigger()
494 if (dma->chan) in sprd_platform_compr_trigger()
495 dmaengine_resume(dma->chan); in sprd_platform_compr_trigger()
498 ret = stream->compr_ops->pause_release(stream_id); in sprd_platform_compr_trigger()
503 ret = stream->compr_ops->drain(stream->received_total); in sprd_platform_compr_trigger()
507 ret = -EINVAL; in sprd_platform_compr_trigger()
518 struct snd_compr_runtime *runtime = cstream->runtime; in sprd_platform_compr_pointer()
519 struct sprd_compr_stream *stream = runtime->private_data; in sprd_platform_compr_pointer()
521 (struct sprd_compr_playinfo *)stream->info_area; in sprd_platform_compr_pointer()
523 tstamp->copied_total = stream->copied_total; in sprd_platform_compr_pointer()
524 tstamp->pcm_io_frames = info->current_data_offset; in sprd_platform_compr_pointer()
533 struct snd_compr_runtime *runtime = cstream->runtime; in sprd_platform_compr_copy()
534 struct sprd_compr_stream *stream = runtime->private_data; in sprd_platform_compr_copy()
544 if (stream->received_stage0 < runtime->fragment_size) { in sprd_platform_compr_copy()
545 avail_bytes = runtime->fragment_size - stream->received_stage0; in sprd_platform_compr_copy()
546 dst = stream->iram_buffer.area + stream->received_stage0; in sprd_platform_compr_copy()
554 return -EFAULT; in sprd_platform_compr_copy()
556 stream->received_stage0 += data_count; in sprd_platform_compr_copy()
557 stream->copied_total += data_count; in sprd_platform_compr_copy()
564 * the left to the stage 1 DDR buffer. in sprd_platform_compr_copy()
567 return -EFAULT; in sprd_platform_compr_copy()
569 data_count -= avail_bytes; in sprd_platform_compr_copy()
570 stream->received_stage0 += avail_bytes; in sprd_platform_compr_copy()
571 stream->copied_total += avail_bytes; in sprd_platform_compr_copy()
577 * Copy data to the stage 1 DDR buffer if no spaces for the stage 0 IRAM in sprd_platform_compr_copy()
580 dst = stream->compr_buffer.area + stream->stage1_pointer; in sprd_platform_compr_copy()
581 if (data_count < stream->compr_buffer.bytes - stream->stage1_pointer) { in sprd_platform_compr_copy()
583 return -EFAULT; in sprd_platform_compr_copy()
585 stream->stage1_pointer += data_count; in sprd_platform_compr_copy()
587 avail_bytes = stream->compr_buffer.bytes - stream->stage1_pointer; in sprd_platform_compr_copy()
590 return -EFAULT; in sprd_platform_compr_copy()
592 if (copy_from_user(stream->compr_buffer.area, buf + avail_bytes, in sprd_platform_compr_copy()
593 data_count - avail_bytes)) in sprd_platform_compr_copy()
594 return -EFAULT; in sprd_platform_compr_copy()
596 stream->stage1_pointer = data_count - avail_bytes; in sprd_platform_compr_copy()
599 stream->received_stage1 += data_count; in sprd_platform_compr_copy()
603 stream->received_total += count; in sprd_platform_compr_copy()
611 caps->direction = cstream->direction; in sprd_platform_compr_get_caps()
612 caps->min_fragment_size = SPRD_COMPR_MIN_FRAGMENT_SIZE; in sprd_platform_compr_get_caps()
613 caps->max_fragment_size = SPRD_COMPR_MAX_FRAGMENT_SIZE; in sprd_platform_compr_get_caps()
614 caps->min_fragments = SPRD_COMPR_MIN_NUM_FRAGMENTS; in sprd_platform_compr_get_caps()
615 caps->max_fragments = SPRD_COMPR_MAX_NUM_FRAGMENTS; in sprd_platform_compr_get_caps()
616 caps->num_codecs = 2; in sprd_platform_compr_get_caps()
617 caps->codecs[0] = SND_AUDIOCODEC_MP3; in sprd_platform_compr_get_caps()
618 caps->codecs[1] = SND_AUDIOCODEC_AAC; in sprd_platform_compr_get_caps()
628 switch (codec->codec) { in sprd_platform_compr_get_codec_caps()
630 codec->num_descriptors = 2; in sprd_platform_compr_get_codec_caps()
631 codec->descriptor[0].max_ch = 2; in sprd_platform_compr_get_codec_caps()
632 codec->descriptor[0].bit_rate[0] = 320; in sprd_platform_compr_get_codec_caps()
633 codec->descriptor[0].bit_rate[1] = 128; in sprd_platform_compr_get_codec_caps()
634 codec->descriptor[0].num_bitrates = 2; in sprd_platform_compr_get_codec_caps()
635 codec->descriptor[0].profiles = 0; in sprd_platform_compr_get_codec_caps()
636 codec->descriptor[0].modes = SND_AUDIOCHANMODE_MP3_STEREO; in sprd_platform_compr_get_codec_caps()
637 codec->descriptor[0].formats = 0; in sprd_platform_compr_get_codec_caps()
641 codec->num_descriptors = 2; in sprd_platform_compr_get_codec_caps()
642 codec->descriptor[1].max_ch = 2; in sprd_platform_compr_get_codec_caps()
643 codec->descriptor[1].bit_rate[0] = 320; in sprd_platform_compr_get_codec_caps()
644 codec->descriptor[1].bit_rate[1] = 128; in sprd_platform_compr_get_codec_caps()
645 codec->descriptor[1].num_bitrates = 2; in sprd_platform_compr_get_codec_caps()
646 codec->descriptor[1].profiles = 0; in sprd_platform_compr_get_codec_caps()
647 codec->descriptor[1].modes = 0; in sprd_platform_compr_get_codec_caps()
648 codec->descriptor[1].formats = 0; in sprd_platform_compr_get_codec_caps()
652 return -EINVAL; in sprd_platform_compr_get_codec_caps()
671 MODULE_ALIAS("platform:compress-platform");