[PATCH 5/8] ASoC: AMD: DMA driver changes for Stoney Platform

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Vijendar Mukunda <Vijendar.Mukunda@xxxxxxx>

Added DMA driver changes for Stoney platform.
Below are the key differences between Stoney and CZ:
- Memory Gating is disabled
- SRAM Banks won't be turned off
- No Of SRAM Banks reduced to 6
- DAGB Garlic Interface used
- 16 bit resolution is supported.
- SRAM bank 1 & SRAM bank 2 will be used for playback scenario.
- SRAM Bank 3 & SRAM Bank 4 will be used for Capture scenario.

Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda at amd.com>
Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
 sound/soc/amd/acp-pcm-dma.c | 81 +++++++++++++++++++++++++++++++++------------
 sound/soc/amd/acp.h         |  2 ++
 2 files changed, 61 insertions(+), 22 deletions(-)

diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c
index e48ae5d..5b5e95d 100644
--- a/sound/soc/amd/acp-pcm-dma.c
+++ b/sound/soc/amd/acp-pcm-dma.c
@@ -139,8 +139,8 @@ static void config_dma_descriptor_in_sram(void __iomem *acp_mmio,
  * system memory <-> ACP SRAM
  */
 static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio,
-					   u32 size, int direction,
-					   u32 pte_offset)
+					u32 size, int direction,
+					u32 pte_offset, u32 asic_type)
 {
 	u16 i;
 	u16 dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12;
@@ -154,20 +154,38 @@ static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio,
 					(size / 2) - (i * (size/2));
 			dmadscr[i].src = ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS
 				+ (pte_offset * SZ_4K) + (i * (size/2));
-			dmadscr[i].xfer_val |=
-			(ACP_DMA_ATTRIBUTES_DAGB_ONION_TO_SHAREDMEM << 16) |
-			(size / 2);
+			if (asic_type == CHIP_STONEY) {
+				dmadscr[i].xfer_val |=
+				(ACP_DMA_ATTRIBUTES_DAGB_GARLIC_TO_SHAREDMEM  << 16) |
+				(size / 2);
+			} else {
+				dmadscr[i].xfer_val |=
+				(ACP_DMA_ATTRIBUTES_DAGB_ONION_TO_SHAREDMEM  << 16) |
+				(size / 2);
+			}
 		} else {
 			dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH14 + i;
-			dmadscr[i].src = ACP_SHARED_RAM_BANK_5_ADDRESS +
-					(i * (size/2));
-			dmadscr[i].dest = ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS
-						+ (pte_offset * SZ_4K) +
-						(i * (size/2));
-			dmadscr[i].xfer_val |=
-			BIT(22) |
-			(ACP_DMA_ATTRIBUTES_SHAREDMEM_TO_DAGB_ONION << 16) |
-			(size / 2);
+			if (asic_type == CHIP_STONEY) {
+				dmadscr[i].src = ACP_SHARED_RAM_BANK_3_ADDRESS +
+				(i * (size/2));
+				dmadscr[i].dest =
+				ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS +
+				(pte_offset * SZ_4K) + (i * (size/2));
+				dmadscr[i].xfer_val |=
+				BIT(22) |
+				(ACP_DMA_ATTRIBUTES_SHARED_MEM_TO_DAGB_GARLIC << 16) |
+				(size / 2);
+			} else {
+				dmadscr[i].src = ACP_SHARED_RAM_BANK_5_ADDRESS +
+				(i * (size/2));
+				dmadscr[i].dest =
+				 ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS +
+				(pte_offset * SZ_4K) + (i * (size/2));
+				dmadscr[i].xfer_val |=
+				BIT(22) |
+				(ACP_DMA_ATTRIBUTES_SHAREDMEM_TO_DAGB_ONION << 16) |
+				(size / 2);
+			}
 		}
 		config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx,
 						&dmadscr[i]);
@@ -188,7 +206,8 @@ static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio,
  * ACP SRAM <-> I2S
  */
 static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio,
-					   u32 size, int direction)
+					u32 size, int direction,
+					u32 asic_type)
 {
 
 	u16 i;
@@ -209,8 +228,15 @@ static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio,
 			dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH15 + i;
 			/* dmadscr[i].src is unused by hardware. */
 			dmadscr[i].src = 0;
-			dmadscr[i].dest = ACP_SHARED_RAM_BANK_5_ADDRESS +
+			if (asic_type == CHIP_STONEY) {
+				dmadscr[i].dest =
+					 ACP_SHARED_RAM_BANK_3_ADDRESS +
 					(i * (size / 2));
+			} else {
+				dmadscr[i].dest =
+					 ACP_SHARED_RAM_BANK_5_ADDRESS +
+					(i * (size / 2));
+			}
 			dmadscr[i].xfer_val |= BIT(22) |
 					(FROM_ACP_I2S_1 << 16) | (size / 2);
 		}
@@ -266,7 +292,8 @@ static void acp_pte_config(void __iomem *acp_mmio, struct page *pg,
 }
 
 static void config_acp_dma(void __iomem *acp_mmio,
-			   struct audio_substream_data *audio_config)
+				struct audio_substream_data *audio_config,
+				u32 asic_type)
 {
 	u32 pte_offset;
 
@@ -280,11 +307,12 @@ static void config_acp_dma(void __iomem *acp_mmio,
 
 	/* Configure System memory <-> ACP SRAM DMA descriptors */
 	set_acp_sysmem_dma_descriptors(acp_mmio, audio_config->size,
-				       audio_config->direction, pte_offset);
+					audio_config->direction, pte_offset,
+					asic_type);
 
 	/* Configure ACP SRAM <-> I2S DMA descriptors */
 	set_acp_to_i2s_dma_descriptors(acp_mmio, audio_config->size,
-					audio_config->direction);
+					audio_config->direction, asic_type);
 }
 
 /* Start a given DMA channel transfer */
@@ -500,6 +528,11 @@ static int acp_init(void __iomem *acp_mmio, u32 asic_type)
 		for (bank = 1; bank < 48; bank++)
 			acp_set_sram_bank_state(acp_mmio, bank, false);
 	}
+	if (asic_type == CHIP_STONEY) {
+		val = acp_reg_read(acp_mmio, mmACP_I2S_16BIT_RESOLUTION_EN);
+		val |= 0x03;
+		acp_reg_write(val, acp_mmio, mmACP_I2S_16BIT_RESOLUTION_EN);
+	}
 
 	return 0;
 }
@@ -675,6 +708,8 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
 	struct page *pg;
 	struct snd_pcm_runtime *runtime;
 	struct audio_substream_data *rtd;
+	struct snd_soc_pcm_runtime *prtd = substream->private_data;
+	struct audio_drv_data *adata = dev_get_drvdata(prtd->platform->dev);
 
 	runtime = substream->runtime;
 	rtd = runtime->private_data;
@@ -702,7 +737,7 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
 		rtd->num_of_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
 		rtd->direction = substream->stream;
 
-		config_acp_dma(rtd->acp_mmio, rtd);
+		config_acp_dma(rtd->acp_mmio, rtd, adata->asic_type);
 		status = 0;
 	} else {
 		status = -ENOMEM;
@@ -997,7 +1032,8 @@ static int acp_pcm_resume(struct device *dev)
 						true);
 		}
 		config_acp_dma(adata->acp_mmio,
-				adata->play_stream->runtime->private_data);
+				adata->play_stream->runtime->private_data,
+				adata->asic_type);
 	}
 	if (adata->capture_stream && adata->capture_stream->runtime) {
 		if (adata->asic_type == CHIP_CARRIZO) {
@@ -1006,7 +1042,8 @@ static int acp_pcm_resume(struct device *dev)
 						true);
 		}
 		config_acp_dma(adata->acp_mmio,
-				adata->capture_stream->runtime->private_data);
+				adata->capture_stream->runtime->private_data,
+				adata->asic_type);
 	}
 	acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
 	return 0;
diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h
index 28cf914..a330a99 100644
--- a/sound/soc/amd/acp.h
+++ b/sound/soc/amd/acp.h
@@ -19,6 +19,7 @@
 
 /* Capture SRAM address (as a source in dma descriptor) */
 #define ACP_SHARED_RAM_BANK_5_ADDRESS		0x400A000
+#define ACP_SHARED_RAM_BANK_3_ADDRESS		0x4006000
 
 #define ACP_DMA_RESET_TIME			10000
 #define ACP_CLOCK_EN_TIME_OUT_VALUE		0x000000FF
@@ -67,6 +68,7 @@
 #define CAPTURE_START_DMA_DESCR_CH15 6
 #define CAPTURE_END_DMA_DESCR_CH15 7
 
+#define mmACP_I2S_16BIT_RESOLUTION_EN       0x5209
 enum acp_dma_priority_level {
 	/* 0x0 Specifies the DMA channel is given normal priority */
 	ACP_DMA_PRIORITY_LEVEL_NORMAL = 0x0,
-- 
2.5.5



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux