Unverified Commit 093184a3 authored by Venkata Prasad Potturu's avatar Venkata Prasad Potturu Committed by Mark Brown
Browse files

ASoC: amd: acp: Refactor I2S dai driver



All I2S instances are connected to different powertile form acp6.0
onwards, refactor dai driver to support all I2S instances for all acp
platforms.

Signed-off-by: default avatarVenkata Prasad Potturu <venkataprasad.potturu@amd.com>
Link: https://patch.msgid.link/20240903113427.182997-3-venkataprasad.potturu@amd.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent cd60dec8
Loading
Loading
Loading
Loading
+25 −24
Original line number Diff line number Diff line
@@ -339,16 +339,16 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			switch (dai->driver->id) {
			case I2S_BT_INSTANCE:
				water_val = ACP_BT_TX_INTR_WATERMARK_SIZE;
				water_val = ACP_BT_TX_INTR_WATERMARK_SIZE(adata);
				reg_val = ACP_BTTDM_ITER;
				ier_val = ACP_BTTDM_IER;
				buf_reg = ACP_BT_TX_RINGBUFSIZE;
				buf_reg = ACP_BT_TX_RINGBUFSIZE(adata);
				break;
			case I2S_SP_INSTANCE:
				water_val = ACP_I2S_TX_INTR_WATERMARK_SIZE;
				water_val = ACP_I2S_TX_INTR_WATERMARK_SIZE(adata);
				reg_val = ACP_I2STDM_ITER;
				ier_val = ACP_I2STDM_IER;
				buf_reg = ACP_I2S_TX_RINGBUFSIZE;
				buf_reg = ACP_I2S_TX_RINGBUFSIZE(adata);
				break;
			case I2S_HS_INSTANCE:
				water_val = ACP_HS_TX_INTR_WATERMARK_SIZE;
@@ -363,16 +363,16 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
		} else {
			switch (dai->driver->id) {
			case I2S_BT_INSTANCE:
				water_val = ACP_BT_RX_INTR_WATERMARK_SIZE;
				water_val = ACP_BT_RX_INTR_WATERMARK_SIZE(adata);
				reg_val = ACP_BTTDM_IRER;
				ier_val = ACP_BTTDM_IER;
				buf_reg = ACP_BT_RX_RINGBUFSIZE;
				buf_reg = ACP_BT_RX_RINGBUFSIZE(adata);
				break;
			case I2S_SP_INSTANCE:
				water_val = ACP_I2S_RX_INTR_WATERMARK_SIZE;
				water_val = ACP_I2S_RX_INTR_WATERMARK_SIZE(adata);
				reg_val = ACP_I2STDM_IRER;
				ier_val = ACP_I2STDM_IER;
				buf_reg = ACP_I2S_RX_RINGBUFSIZE;
				buf_reg = ACP_I2S_RX_RINGBUFSIZE(adata);
				break;
			case I2S_HS_INSTANCE:
				water_val = ACP_HS_RX_INTR_WATERMARK_SIZE;
@@ -385,6 +385,7 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
				return -EINVAL;
			}
		}

		writel(period_bytes, adata->acp_base + water_val);
		writel(buf_size, adata->acp_base + buf_reg);
		if (rsrc->soc_mclk)
@@ -463,43 +464,43 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
	switch (dai->driver->id) {
	case I2S_SP_INSTANCE:
		if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
			reg_dma_size = ACP_I2S_TX_DMA_SIZE;
			reg_dma_size = ACP_I2S_TX_DMA_SIZE(adata);
			acp_fifo_addr = rsrc->sram_pte_offset +
						SP_PB_FIFO_ADDR_OFFSET;
			reg_fifo_addr =	ACP_I2S_TX_FIFOADDR;
			reg_fifo_size = ACP_I2S_TX_FIFOSIZE;
			reg_fifo_addr =	ACP_I2S_TX_FIFOADDR(adata);
			reg_fifo_size = ACP_I2S_TX_FIFOSIZE(adata);

			phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR);
			writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR(adata));
		} else {
			reg_dma_size = ACP_I2S_RX_DMA_SIZE;
			reg_dma_size = ACP_I2S_RX_DMA_SIZE(adata);
			acp_fifo_addr = rsrc->sram_pte_offset +
						SP_CAPT_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_I2S_RX_FIFOADDR;
			reg_fifo_size = ACP_I2S_RX_FIFOSIZE;
			reg_fifo_addr = ACP_I2S_RX_FIFOADDR(adata);
			reg_fifo_size = ACP_I2S_RX_FIFOSIZE(adata);
			phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR);
			writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR(adata));
		}
		break;
	case I2S_BT_INSTANCE:
		if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
			reg_dma_size = ACP_BT_TX_DMA_SIZE;
			reg_dma_size = ACP_BT_TX_DMA_SIZE(adata);
			acp_fifo_addr = rsrc->sram_pte_offset +
						BT_PB_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_BT_TX_FIFOADDR;
			reg_fifo_size = ACP_BT_TX_FIFOSIZE;
			reg_fifo_addr = ACP_BT_TX_FIFOADDR(adata);
			reg_fifo_size = ACP_BT_TX_FIFOSIZE(adata);

			phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR);
			writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR(adata));
		} else {
			reg_dma_size = ACP_BT_RX_DMA_SIZE;
			reg_dma_size = ACP_BT_RX_DMA_SIZE(adata);
			acp_fifo_addr = rsrc->sram_pte_offset +
						BT_CAPT_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_BT_RX_FIFOADDR;
			reg_fifo_size = ACP_BT_RX_FIFOSIZE;
			reg_fifo_addr = ACP_BT_RX_FIFOADDR(adata);
			reg_fifo_size = ACP_BT_RX_FIFOSIZE(adata);

			phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR);
			writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR(adata));
		}
		break;
	case I2S_HS_INSTANCE:
+16 −16
Original line number Diff line number Diff line
@@ -113,40 +113,40 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream,
	switch (dai->driver->id) {
	case I2S_SP_INSTANCE:
		if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
			reg_dma_size = ACP_I2S_TX_DMA_SIZE;
			reg_dma_size = ACP_I2S_TX_DMA_SIZE(adata);
			acp_fifo_addr = rsrc->sram_pte_offset +
					SP_PB_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_I2S_TX_FIFOADDR;
			reg_fifo_size = ACP_I2S_TX_FIFOSIZE;
			reg_fifo_addr = ACP_I2S_TX_FIFOADDR(adata);
			reg_fifo_size = ACP_I2S_TX_FIFOSIZE(adata);
			phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR);
			writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR(adata));
		} else {
			reg_dma_size = ACP_I2S_RX_DMA_SIZE;
			reg_dma_size = ACP_I2S_RX_DMA_SIZE(adata);
			acp_fifo_addr = rsrc->sram_pte_offset +
					SP_CAPT_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_I2S_RX_FIFOADDR;
			reg_fifo_size = ACP_I2S_RX_FIFOSIZE;
			reg_fifo_addr = ACP_I2S_RX_FIFOADDR(adata);
			reg_fifo_size = ACP_I2S_RX_FIFOSIZE(adata);
			phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR);
			writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR(adata));
		}
		break;
	case I2S_BT_INSTANCE:
		if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
			reg_dma_size = ACP_BT_TX_DMA_SIZE;
			reg_dma_size = ACP_BT_TX_DMA_SIZE(adata);
			acp_fifo_addr = rsrc->sram_pte_offset +
					BT_PB_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_BT_TX_FIFOADDR;
			reg_fifo_size = ACP_BT_TX_FIFOSIZE;
			reg_fifo_addr = ACP_BT_TX_FIFOADDR(adata);
			reg_fifo_size = ACP_BT_TX_FIFOSIZE(adata);
			phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR);
			writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR(adata));
		} else {
			reg_dma_size = ACP_BT_RX_DMA_SIZE;
			reg_dma_size = ACP_BT_RX_DMA_SIZE(adata);
			acp_fifo_addr = rsrc->sram_pte_offset +
					BT_CAPT_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_BT_RX_FIFOADDR;
			reg_fifo_size = ACP_BT_RX_FIFOSIZE;
			reg_fifo_addr = ACP_BT_RX_FIFOADDR(adata);
			reg_fifo_size = ACP_BT_RX_FIFOSIZE(adata);
			phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR);
			writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR(adata));
		}
		break;
	case I2S_HS_INSTANCE:
+8 −8
Original line number Diff line number Diff line
@@ -259,12 +259,12 @@ static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int
	if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
		switch (dai_id) {
		case I2S_BT_INSTANCE:
			high = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_HIGH);
			low = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_LOW);
			high = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_HIGH(adata));
			low = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_LOW(adata));
			break;
		case I2S_SP_INSTANCE:
			high = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH);
			low = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_LOW);
			high = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH(adata));
			low = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_LOW(adata));
			break;
		case I2S_HS_INSTANCE:
			high = readl(adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_HIGH);
@@ -277,12 +277,12 @@ static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int
	} else {
		switch (dai_id) {
		case I2S_BT_INSTANCE:
			high = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_HIGH);
			low = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_LOW);
			high = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_HIGH(adata));
			low = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_LOW(adata));
			break;
		case I2S_SP_INSTANCE:
			high = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH);
			low = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW);
			high = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH(adata));
			low = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW(adata));
			break;
		case I2S_HS_INSTANCE:
			high = readl(adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_HIGH);
+41 −36
Original line number Diff line number Diff line
@@ -32,42 +32,47 @@

/* Registers from ACP_AUDIO_BUFFERS block */

#define ACP_I2S_RX_RINGBUFADDR                        0x2000
#define ACP_I2S_RX_RINGBUFSIZE                        0x2004
#define ACP_I2S_RX_LINKPOSITIONCNTR                   0x2008
#define ACP_I2S_RX_FIFOADDR                           0x200C
#define ACP_I2S_RX_FIFOSIZE                           0x2010
#define ACP_I2S_RX_DMA_SIZE                           0x2014
#define ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH            0x2018
#define ACP_I2S_RX_LINEARPOSITIONCNTR_LOW             0x201C
#define ACP_I2S_RX_INTR_WATERMARK_SIZE                0x2020
#define ACP_I2S_TX_RINGBUFADDR                        0x2024
#define ACP_I2S_TX_RINGBUFSIZE                        0x2028
#define ACP_I2S_TX_LINKPOSITIONCNTR                   0x202C
#define ACP_I2S_TX_FIFOADDR                           0x2030
#define ACP_I2S_TX_FIFOSIZE                           0x2034
#define ACP_I2S_TX_DMA_SIZE                           0x2038
#define ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH            0x203C
#define ACP_I2S_TX_LINEARPOSITIONCNTR_LOW             0x2040
#define ACP_I2S_TX_INTR_WATERMARK_SIZE                0x2044
#define ACP_BT_RX_RINGBUFADDR                         0x2048
#define ACP_BT_RX_RINGBUFSIZE                         0x204C
#define ACP_BT_RX_LINKPOSITIONCNTR                    0x2050
#define ACP_BT_RX_FIFOADDR                            0x2054
#define ACP_BT_RX_FIFOSIZE                            0x2058
#define ACP_BT_RX_DMA_SIZE                            0x205C
#define ACP_BT_RX_LINEARPOSITIONCNTR_HIGH             0x2060
#define ACP_BT_RX_LINEARPOSITIONCNTR_LOW              0x2064
#define ACP_BT_RX_INTR_WATERMARK_SIZE                 0x2068
#define ACP_BT_TX_RINGBUFADDR                         0x206C
#define ACP_BT_TX_RINGBUFSIZE                         0x2070
#define ACP_BT_TX_LINKPOSITIONCNTR                    0x2074
#define ACP_BT_TX_FIFOADDR                            0x2078
#define ACP_BT_TX_FIFOSIZE                            0x207C
#define ACP_BT_TX_DMA_SIZE                            0x2080
#define ACP_BT_TX_LINEARPOSITIONCNTR_HIGH             0x2084
#define ACP_BT_TX_LINEARPOSITIONCNTR_LOW              0x2088
#define ACP_BT_TX_INTR_WATERMARK_SIZE                 0x208C
#define ACP_I2S_REG_ADDR(acp_adata, addr) \
			 ((addr) + (acp_adata->rsrc->irqp_used * \
			 acp_adata->rsrc->irq_reg_offset))

#define ACP_I2S_RX_RINGBUFADDR(adata)               ACP_I2S_REG_ADDR(adata, 0x2000)
#define ACP_I2S_RX_RINGBUFSIZE(adata)               ACP_I2S_REG_ADDR(adata, 0x2004)
#define ACP_I2S_RX_LINKPOSITIONCNTR(adata)          ACP_I2S_REG_ADDR(adata, 0x2008)
#define ACP_I2S_RX_FIFOADDR(adata)                  ACP_I2S_REG_ADDR(adata, 0x200C)
#define ACP_I2S_RX_FIFOSIZE(adata)                  ACP_I2S_REG_ADDR(adata, 0x2010)
#define ACP_I2S_RX_DMA_SIZE(adata)                  ACP_I2S_REG_ADDR(adata, 0x2014)
#define ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH(adata)   ACP_I2S_REG_ADDR(adata, 0x2018)
#define ACP_I2S_RX_LINEARPOSITIONCNTR_LOW(adata)    ACP_I2S_REG_ADDR(adata, 0x201C)
#define ACP_I2S_RX_INTR_WATERMARK_SIZE(adata)       ACP_I2S_REG_ADDR(adata, 0x2020)
#define ACP_I2S_TX_RINGBUFADDR(adata)               ACP_I2S_REG_ADDR(adata, 0x2024)
#define ACP_I2S_TX_RINGBUFSIZE(adata)               ACP_I2S_REG_ADDR(adata, 0x2028)
#define ACP_I2S_TX_LINKPOSITIONCNTR(adata)          ACP_I2S_REG_ADDR(adata, 0x202C)
#define ACP_I2S_TX_FIFOADDR(adata)                  ACP_I2S_REG_ADDR(adata, 0x2030)
#define ACP_I2S_TX_FIFOSIZE(adata)                  ACP_I2S_REG_ADDR(adata, 0x2034)
#define ACP_I2S_TX_DMA_SIZE(adata)                  ACP_I2S_REG_ADDR(adata, 0x2038)
#define ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH(adata)   ACP_I2S_REG_ADDR(adata, 0x203C)
#define ACP_I2S_TX_LINEARPOSITIONCNTR_LOW(adata)    ACP_I2S_REG_ADDR(adata, 0x2040)
#define ACP_I2S_TX_INTR_WATERMARK_SIZE(adata)       ACP_I2S_REG_ADDR(adata, 0x2044)
#define ACP_BT_RX_RINGBUFADDR(adata)                ACP_I2S_REG_ADDR(adata, 0x2048)
#define ACP_BT_RX_RINGBUFSIZE(adata)                ACP_I2S_REG_ADDR(adata, 0x204C)
#define ACP_BT_RX_LINKPOSITIONCNTR(adata)           ACP_I2S_REG_ADDR(adata, 0x2050)
#define ACP_BT_RX_FIFOADDR(adata)                   ACP_I2S_REG_ADDR(adata, 0x2054)
#define ACP_BT_RX_FIFOSIZE(adata)                   ACP_I2S_REG_ADDR(adata, 0x2058)
#define ACP_BT_RX_DMA_SIZE(adata)                   ACP_I2S_REG_ADDR(adata, 0x205C)
#define ACP_BT_RX_LINEARPOSITIONCNTR_HIGH(adata)    ACP_I2S_REG_ADDR(adata, 0x2060)
#define ACP_BT_RX_LINEARPOSITIONCNTR_LOW(adata)     ACP_I2S_REG_ADDR(adata, 0x2064)
#define ACP_BT_RX_INTR_WATERMARK_SIZE(adata)        ACP_I2S_REG_ADDR(adata, 0x2068)
#define ACP_BT_TX_RINGBUFADDR(adata)                ACP_I2S_REG_ADDR(adata, 0x206C)
#define ACP_BT_TX_RINGBUFSIZE(adata)                ACP_I2S_REG_ADDR(adata, 0x2070)
#define ACP_BT_TX_LINKPOSITIONCNTR(adata)           ACP_I2S_REG_ADDR(adata, 0x2074)
#define ACP_BT_TX_FIFOADDR(adata)                   ACP_I2S_REG_ADDR(adata, 0x2078)
#define ACP_BT_TX_FIFOSIZE(adata)                   ACP_I2S_REG_ADDR(adata, 0x207C)
#define ACP_BT_TX_DMA_SIZE(adata)                   ACP_I2S_REG_ADDR(adata, 0x2080)
#define ACP_BT_TX_LINEARPOSITIONCNTR_HIGH(adata)    ACP_I2S_REG_ADDR(adata, 0x2084)
#define ACP_BT_TX_LINEARPOSITIONCNTR_LOW(adata)     ACP_I2S_REG_ADDR(adata, 0x2088)
#define ACP_BT_TX_INTR_WATERMARK_SIZE(adata)        ACP_I2S_REG_ADDR(adata, 0x208C)

#define ACP_HS_RX_RINGBUFADDR			      0x3A90
#define ACP_HS_RX_RINGBUFSIZE			      0x3A94
#define ACP_HS_RX_LINKPOSITIONCNTR		      0x3A98