Unverified Commit 0fa0843d authored by Vijendar Mukunda's avatar Vijendar Mukunda Committed by Mark Brown
Browse files

ASoC: amd: ps: refactor soundwire dma driver code



Refactor existing SoundWire dma driver code by adding acp_rev check for
ACP6.3 platform.

Signed-off-by: default avatarVijendar Mukunda <Vijendar.Mukunda@amd.com>
Link: https://patch.msgid.link/20250207062819.1527184-10-Vijendar.Mukunda@amd.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent fcb75460
Loading
Loading
Loading
Loading
+89 −57
Original line number Diff line number Diff line
@@ -167,7 +167,7 @@ static void acp63_config_dma(struct acp_sdw_dma_stream *stream, void __iomem *ac
}

static int acp63_configure_sdw_ringbuffer(void __iomem *acp_base, u32 stream_id, u32 size,
					  u32 manager_instance)
					  u32 manager_instance, u32 acp_rev)
{
	u32 reg_dma_size;
	u32 reg_fifo_addr;
@@ -180,6 +180,8 @@ static int acp63_configure_sdw_ringbuffer(void __iomem *acp_base, u32 stream_id,
	u32 sdw_ring_buf_size;
	u32 sdw_mem_window_offset;

	switch (acp_rev) {
	case ACP63_PCI_REV:
		switch (manager_instance) {
		case ACP_SDW0:
			reg_dma_size = acp63_sdw0_dma_reg[stream_id].reg_dma_size;
@@ -198,6 +200,10 @@ static int acp63_configure_sdw_ringbuffer(void __iomem *acp_base, u32 stream_id,
		default:
			return -EINVAL;
		}
		break;
	default:
		return -EINVAL;
	}
	sdw_fifo_offset = ACP_SDW_FIFO_OFFSET(manager_instance);
	sdw_mem_window_offset = SDW_MEM_WINDOW_START(manager_instance);
	sdw_fifo_addr = sdw_fifo_offset + (stream_id * SDW_FIFO_OFFSET);
@@ -265,6 +271,8 @@ static int acp63_sdw_dma_hw_params(struct snd_soc_component *component,
	if (!stream)
		return -EINVAL;
	stream_id = stream->stream_id;
	switch (sdw_data->acp_rev) {
	case ACP63_PCI_REV:
		switch (stream->instance) {
		case ACP_SDW0:
			sdw_data->acp63_sdw0_dma_stream[stream_id] = substream;
@@ -284,13 +292,17 @@ static int acp63_sdw_dma_hw_params(struct snd_soc_component *component,
		default:
			return -EINVAL;
		}
		break;
	default:
		return -EINVAL;
	}
	size = params_buffer_bytes(params);
	period_bytes = params_period_bytes(params);
	stream->dma_addr = substream->runtime->dma_addr;
	stream->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
	acp63_config_dma(stream, sdw_data->acp_base, stream_id);
	ret = acp63_configure_sdw_ringbuffer(sdw_data->acp_base, stream_id, size,
					     stream->instance);
					     stream->instance, sdw_data->acp_rev);
	if (ret) {
		dev_err(component->dev, "Invalid DMA channel\n");
		return -EINVAL;
@@ -302,12 +314,15 @@ static int acp63_sdw_dma_hw_params(struct snd_soc_component *component,
	return 0;
}

static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __iomem *acp_base)
static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __iomem *acp_base,
				    u32 acp_rev)
{
	union acp_sdw_dma_count byte_count;
	u32 pos_low_reg, pos_high_reg;

	byte_count.bytescount = 0;
	switch (acp_rev) {
	case ACP63_PCI_REV:
		switch (stream->instance) {
		case ACP_SDW0:
			pos_low_reg = acp63_sdw0_dma_reg[stream->stream_id].pos_low_reg;
@@ -320,6 +335,10 @@ static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __io
		default:
			goto POINTER_RETURN_BYTES;
		}
		break;
	default:
		goto POINTER_RETURN_BYTES;
	}
	if (pos_low_reg) {
		byte_count.bcount.high = readl(acp_base + pos_high_reg);
		byte_count.bcount.low = readl(acp_base + pos_low_reg);
@@ -340,7 +359,7 @@ static snd_pcm_uframes_t acp63_sdw_dma_pointer(struct snd_soc_component *comp,
	stream = substream->runtime->private_data;
	buffersize = frames_to_bytes(substream->runtime,
				     substream->runtime->buffer_size);
	bytescount = acp63_sdw_get_byte_count(stream, sdw_data->acp_base);
	bytescount = acp63_sdw_get_byte_count(stream, sdw_data->acp_base, sdw_data->acp_rev);
	if (bytescount > stream->bytescount)
		bytescount -= stream->bytescount;
	pos = do_div(bytescount, buffersize);
@@ -367,6 +386,8 @@ static int acp63_sdw_dma_close(struct snd_soc_component *component,
	stream = substream->runtime->private_data;
	if (!stream)
		return -EINVAL;
	switch (sdw_data->acp_rev) {
	case ACP63_PCI_REV:
		switch (stream->instance) {
		case ACP_SDW0:
			sdw_data->acp63_sdw0_dma_stream[stream->stream_id] = NULL;
@@ -377,12 +398,16 @@ static int acp63_sdw_dma_close(struct snd_soc_component *component,
		default:
			return -EINVAL;
		}
		break;
	default:
		return -EINVAL;
	}
	kfree(stream);
	return 0;
}

static int acp63_sdw_dma_enable(struct snd_pcm_substream *substream,
				void __iomem *acp_base, bool sdw_dma_enable)
				void __iomem *acp_base, u32 acp_rev, bool sdw_dma_enable)
{
	struct acp_sdw_dma_stream *stream;
	u32 stream_id;
@@ -393,6 +418,8 @@ static int acp63_sdw_dma_enable(struct snd_pcm_substream *substream,

	stream = substream->runtime->private_data;
	stream_id = stream->stream_id;
	switch (acp_rev) {
	case ACP63_PCI_REV:
		switch (stream->instance) {
		case ACP_SDW0:
			sdw_dma_en_reg = acp63_sdw0_dma_enable_reg[stream_id];
@@ -403,6 +430,10 @@ static int acp63_sdw_dma_enable(struct snd_pcm_substream *substream,
		default:
			return -EINVAL;
		}
		break;
	default:
		return -EINVAL;
	}
	sdw_dma_en_stat_reg = sdw_dma_en_reg + 4;
	dma_enable = sdw_dma_enable;
	writel(dma_enable, acp_base + sdw_dma_en_reg);
@@ -422,12 +453,12 @@ static int acp63_sdw_dma_trigger(struct snd_soc_component *comp,
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
	case SNDRV_PCM_TRIGGER_RESUME:
		ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, true);
		ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, sdw_data->acp_rev, true);
		break;
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_STOP:
		ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, false);
		ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, sdw_data->acp_rev, false);
		break;
	default:
		ret = -EINVAL;
@@ -527,7 +558,8 @@ static int acp_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data)
				buf_size = frames_to_bytes(runtime, runtime->buffer_size);
				acp63_config_dma(stream, sdw_data->acp_base, index);
				ret = acp63_configure_sdw_ringbuffer(sdw_data->acp_base, index,
								     buf_size, instance);
								     buf_size, instance,
								     ACP63_PCI_REV);
				if (ret)
					return ret;
				writel(period_bytes, sdw_data->acp_base + water_mark_size_reg);