[alsa-devel] [PATCH 0/8] Enablement of BT I2S controller instance for AMD APUs
This patch set updates Audio CoProcessor (ACP) audio drivers to enable BT I2S controller instance. In Audio Coprocessor, There are three I2S controllers can be configured/enabled.(I2S SP, I2S MICSP, BT I2S) Default enabled I2S controller instance is I2S SP instance. There is a requirement to enable BT I2S controller Instance along with I2S SP controller instance. This patch set bring up functionality to render & capture on BT I2S controller instance.
The current patch set also includes a new dependent patch.
The current code is based on asoc-next, but I'm happy to rebase on whatever tree this ends up going through if there are any problems applying.
Vijendar Mukunda (8): ASoC: dwc: I2S Controller instance param added ASoC: amd: dma driver changes for BT I2S controller instance ASoC: amd: dma descriptor changes for BT I2S Instance ASoC: amd: Interrupt handler changes for BT I2S instance ASoC: amd: prepare callback modifications for bt i2s instance ASoC: amd: pointer and trigger callback modifications for bt i2s ASoC: amd: 16bit resolution support for bt i2s instance ASoC: amd: enabling bt i2s config after acp reset
include/sound/designware_i2s.h | 6 + sound/soc/amd/acp-pcm-dma.c | 531 +++++++++++++++++++++++++++++++++-------- sound/soc/amd/acp.h | 50 +++- sound/soc/dwc/dwc-i2s.c | 1 + sound/soc/dwc/local.h | 1 + 5 files changed, 481 insertions(+), 108 deletions(-)
When multiple I2S controller instances created, i2s_instance parameter refers to i2s controller instance value.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com --- include/sound/designware_i2s.h | 6 ++++++ sound/soc/dwc/dwc-i2s.c | 1 + sound/soc/dwc/local.h | 1 + 3 files changed, 8 insertions(+)
diff --git a/include/sound/designware_i2s.h b/include/sound/designware_i2s.h index 830f5ca..8113759 100644 --- a/include/sound/designware_i2s.h +++ b/include/sound/designware_i2s.h @@ -44,6 +44,10 @@ struct i2s_platform_data { int channel; u32 snd_fmts; u32 snd_rates; + /* i2s_instance parameter returns I2S controller instance value + * when multiple I2S controllers instantiated + */ + u32 i2s_instance;
#define DW_I2S_QUIRK_COMP_REG_OFFSET (1 << 0) #define DW_I2S_QUIRK_COMP_PARAM1 (1 << 1) @@ -74,5 +78,7 @@ struct i2s_dma_data { #define FOUR_CHANNEL_SUPPORT 4 /* up to 3.1 */ #define SIX_CHANNEL_SUPPORT 6 /* up to 5.1 */ #define EIGHT_CHANNEL_SUPPORT 8 /* up to 7.1 */ +#define I2S_SP_INSTANCE 1 +#define I2S_BT_INSTANCE 2
#endif /* __SOUND_DESIGNWARE_I2S_H */ diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c index e27e21f..20145c0 100644 --- a/sound/soc/dwc/dwc-i2s.c +++ b/sound/soc/dwc/dwc-i2s.c @@ -549,6 +549,7 @@ static int dw_configure_dai_by_pd(struct dw_i2s_dev *dev,
if (dev->quirks & DW_I2S_QUIRK_16BIT_IDX_OVERRIDE) idx = 1; + dev->i2s_instance = pdata->i2s_instance; /* Set DMA slaves info */ dev->play_dma_data.pd.data = pdata->play_dma_data; dev->capture_dma_data.pd.data = pdata->capture_dma_data; diff --git a/sound/soc/dwc/local.h b/sound/soc/dwc/local.h index 91dc70a..e89e464 100644 --- a/sound/soc/dwc/local.h +++ b/sound/soc/dwc/local.h @@ -98,6 +98,7 @@ struct dw_i2s_dev { u32 ccr; u32 xfer_resolution; u32 fifo_th; + u32 i2s_instance;
/* data related to DMA transfers b/w i2s and DMAC */ union dw_i2s_snd_dma_data play_dma_data;
With in ACP, There are three I2S controllers can be configured/enabled ( I2S SP, I2S MICSP, I2S BT). Default enabled I2S controller instance is I2S SP. This patch provides required changes to support I2S BT controller Instance.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com Signed-off-by: Akshu Agrawal akshu.agrawal@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com --- sound/soc/amd/acp-pcm-dma.c | 106 +++++++++++++++++++++++++++++++++++--------- sound/soc/amd/acp.h | 7 +++ 2 files changed, 91 insertions(+), 22 deletions(-)
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 540088d..a61c4e0 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -697,6 +697,7 @@ static int acp_dma_open(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *prtd = substream->private_data; struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, DRV_NAME); struct audio_drv_data *intr_data = dev_get_drvdata(component->dev); + struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(prtd->cpu_dai); struct audio_substream_data *adata = kzalloc(sizeof(struct audio_substream_data), GFP_KERNEL); if (adata == NULL) @@ -710,7 +711,21 @@ static int acp_dma_open(struct snd_pcm_substream *substream) default: runtime->hw = acp_pcm_hardware_playback; } + adata->i2s_play_instance = dev->i2s_instance; + if (adata->i2s_play_instance == I2S_SP_INSTANCE) + adata->i2ssp_renderbytescount = 0; + else if (adata->i2s_play_instance == I2S_BT_INSTANCE) + adata->i2sbt_renderbytescount = 0; + else + return -EINVAL; } else { + adata->i2s_capture_instance = dev->i2s_instance; + if (adata->i2s_capture_instance == I2S_SP_INSTANCE) + adata->i2ssp_capturebytescount = 0; + else if (adata->i2s_capture_instance == I2S_BT_INSTANCE) + adata->i2sbt_capturebytescount = 0; + else + return -EINVAL; switch (intr_data->asic_type) { case CHIP_STONEY: runtime->hw = acp_st_pcm_hardware_capture; @@ -736,11 +751,20 @@ static int acp_dma_open(struct snd_pcm_substream *substream) * This enablement is not required for another stream, if current * stream is not closed */ - if (!intr_data->play_i2ssp_stream && !intr_data->capture_i2ssp_stream) + if (!intr_data->play_i2ssp_stream && !intr_data->capture_i2ssp_stream && + !intr_data->play_i2sbt_stream && + !intr_data->capture_i2sbt_stream) acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - intr_data->play_i2ssp_stream = substream; + switch (adata->i2s_play_instance) { + case I2S_BT_INSTANCE: + intr_data->play_i2sbt_stream = substream; + break; + case I2S_SP_INSTANCE: + default: + intr_data->play_i2ssp_stream = substream; + } /* For Stoney, Memory gating is disabled,i.e SRAM Banks * won't be turned off. The default state for SRAM banks is ON. * Setting SRAM bank state code skipped for STONEY platform. @@ -751,7 +775,14 @@ static int acp_dma_open(struct snd_pcm_substream *substream) bank, true); } } else { - intr_data->capture_i2ssp_stream = substream; + switch (adata->i2s_capture_instance) { + case I2S_BT_INSTANCE: + intr_data->capture_i2sbt_stream = substream; + break; + case I2S_SP_INSTANCE: + default: + intr_data->capture_i2ssp_stream = substream; + } if (intr_data->asic_type != CHIP_STONEY) { for (bank = 5; bank <= 8; bank++) acp_set_sram_bank_state(intr_data->acp_mmio, @@ -1010,34 +1041,49 @@ static int acp_dma_close(struct snd_pcm_substream *substream) struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, DRV_NAME); struct audio_drv_data *adata = dev_get_drvdata(component->dev);
- kfree(rtd); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - adata->play_i2ssp_stream = NULL; - /* For Stoney, Memory gating is disabled,i.e SRAM Banks - * won't be turned off. The default state for SRAM banks is ON. - * Setting SRAM bank state code skipped for STONEY platform. - * added condition checks for Carrizo platform only - */ - if (adata->asic_type != CHIP_STONEY) { - for (bank = 1; bank <= 4; bank++) - acp_set_sram_bank_state(adata->acp_mmio, bank, - false); + switch (rtd->i2s_play_instance) { + case I2S_BT_INSTANCE: + adata->play_i2sbt_stream = NULL; + break; + case I2S_SP_INSTANCE: + default: + adata->play_i2ssp_stream = NULL; + /* For Stoney, Memory gating is disabled,i.e SRAM Banks + * won't be turned off. The default state for SRAM banks + * is ON.Setting SRAM bank state code skipped for STONEY + * platform.Added condition checks for Carrizo platform + * only. + */ + if (adata->asic_type != CHIP_STONEY) { + for (bank = 1; bank <= 4; bank++) + acp_set_sram_bank_state(adata->acp_mmio, + bank, false); + } } } else { - adata->capture_i2ssp_stream = NULL; - if (adata->asic_type != CHIP_STONEY) { - for (bank = 5; bank <= 8; bank++) - acp_set_sram_bank_state(adata->acp_mmio, bank, - false); + switch (rtd->i2s_capture_instance) { + case I2S_BT_INSTANCE: + adata->capture_i2sbt_stream = NULL; + break; + case I2S_SP_INSTANCE: + default: + adata->capture_i2ssp_stream = NULL; + if (adata->asic_type != CHIP_STONEY) { + for (bank = 5; bank <= 8; bank++) + acp_set_sram_bank_state(adata->acp_mmio, + bank, false); + } } }
/* Disable ACP irq, when the current stream is being closed and * another stream is also not active. - */ - if (!adata->play_i2ssp_stream && !adata->capture_i2ssp_stream) + */ + if (!adata->play_i2ssp_stream && !adata->capture_i2ssp_stream && + !adata->play_i2sbt_stream && !adata->capture_i2sbt_stream) acp_reg_write(0, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB); + kfree(rtd);
return 0; } @@ -1089,6 +1135,8 @@ static int acp_audio_probe(struct platform_device *pdev)
audio_drv_data->play_i2ssp_stream = NULL; audio_drv_data->capture_i2ssp_stream = NULL; + audio_drv_data->play_i2sbt_stream = NULL; + audio_drv_data->capture_i2sbt_stream = NULL;
audio_drv_data->asic_type = *pdata;
@@ -1177,6 +1225,20 @@ static int acp_pcm_resume(struct device *dev) adata->capture_i2ssp_stream->runtime->private_data, adata->asic_type); } + if (adata->asic_type != CHIP_CARRIZO) { + if (adata->play_i2sbt_stream && + adata->play_i2sbt_stream->runtime) { + config_acp_dma(adata->acp_mmio, + adata->play_i2sbt_stream->runtime->private_data, + adata->asic_type); + } + if (adata->capture_i2sbt_stream && + adata->capture_i2sbt_stream->runtime) { + config_acp_dma(adata->acp_mmio, + adata->capture_i2sbt_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 ba01510..c86bef4 100644 --- a/sound/soc/amd/acp.h +++ b/sound/soc/amd/acp.h @@ -4,6 +4,7 @@
#include "include/acp_2_2_d.h" #include "include/acp_2_2_sh_mask.h" +#include "../dwc/local.h"
#define ACP_PAGE_SIZE_4K_ENABLE 0x02
@@ -88,12 +89,18 @@ struct audio_substream_data { uint64_t size; u64 i2ssp_renderbytescount; u64 i2ssp_capturebytescount; + u64 i2sbt_renderbytescount; + u64 i2sbt_capturebytescount; void __iomem *acp_mmio; + u16 i2s_play_instance; + u16 i2s_capture_instance; };
struct audio_drv_data { struct snd_pcm_substream *play_i2ssp_stream; struct snd_pcm_substream *capture_i2ssp_stream; + struct snd_pcm_substream *play_i2sbt_stream; + struct snd_pcm_substream *capture_i2sbt_stream; void __iomem *acp_mmio; u32 asic_type; };
Hi Vijendar,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on asoc/for-next] [also build test ERROR on next-20180327] [cannot apply to v4.16-rc7] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Vijendar-Mukunda/ASoC-dwc-I2S-Contr... base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next config: x86_64-randconfig-s1-03281558 (attached as .config) compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026 reproduce: # save the attached .config to linux build tree make ARCH=x86_64
All errors (new ones prefixed by >>):
sound/soc/dwc/dwc-i2s.o: In function `dw_pcm_push_tx':
sound/soc/dwc/dwc-i2s.c:721: multiple definition of `dw_pcm_push_tx'
sound/soc/amd/acp-pcm-dma.o:sound/soc/amd/acp-pcm-dma.c:933: first defined here sound/soc/dwc/dwc-i2s.o: In function `dw_pcm_pop_rx':
sound/soc/dwc/local.h:129: multiple definition of `dw_pcm_pop_rx'
sound/soc/amd/acp-pcm-dma.o:sound/soc/amd/../dwc/local.h:129: first defined here sound/soc/dwc/dwc-i2s.o: In function `dw_pcm_register':
sound/soc/dwc/local.h:131: multiple definition of `dw_pcm_register'
sound/soc/amd/acp-pcm-dma.o:sound/soc/amd/../dwc/local.h:131: first defined here
vim +129 sound/soc/dwc/local.h
79361b2b Jose Abreu 2016-06-09 122 79361b2b Jose Abreu 2016-06-09 123 #if IS_ENABLED(CONFIG_SND_DESIGNWARE_PCM) 79361b2b Jose Abreu 2016-06-09 124 void dw_pcm_push_tx(struct dw_i2s_dev *dev); e2f748e0 Jose Abreu 2016-12-27 125 void dw_pcm_pop_rx(struct dw_i2s_dev *dev); 79361b2b Jose Abreu 2016-06-09 126 int dw_pcm_register(struct platform_device *pdev); 79361b2b Jose Abreu 2016-06-09 127 #else 79361b2b Jose Abreu 2016-06-09 128 void dw_pcm_push_tx(struct dw_i2s_dev *dev) { } e2f748e0 Jose Abreu 2016-12-27 @129 void dw_pcm_pop_rx(struct dw_i2s_dev *dev) { } 79361b2b Jose Abreu 2016-06-09 130 int dw_pcm_register(struct platform_device *pdev) 79361b2b Jose Abreu 2016-06-09 @131 { 79361b2b Jose Abreu 2016-06-09 132 return -EINVAL; 79361b2b Jose Abreu 2016-06-09 133 } 79361b2b Jose Abreu 2016-06-09 134 #endif 79361b2b Jose Abreu 2016-06-09 135
:::::: The code at line 129 was first introduced by commit :::::: e2f748e06db389d9fd51413df23ff8d3615a47db ASoC: dwc: Add record capability in PIO mode
:::::: TO: Jose Abreu Jose.Abreu@synopsys.com :::::: CC: Mark Brown broonie@kernel.org
--- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
On Wednesday 28 March 2018 04:53 PM, kbuild test robot wrote:
Hi Vijendar,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on asoc/for-next] [also build test ERROR on next-20180327] [cannot apply to v4.16-rc7] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Vijendar-Mukunda/ASoC-dwc-I2S-Contr... base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next config: x86_64-randconfig-s1-03281558 (attached as .config) compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026 reproduce: # save the attached .config to linux build tree make ARCH=x86_64
All errors (new ones prefixed by >>):
sound/soc/dwc/dwc-i2s.o: In function `dw_pcm_push_tx':
sound/soc/dwc/dwc-i2s.c:721: multiple definition of `dw_pcm_push_tx'
sound/soc/amd/acp-pcm-dma.o:sound/soc/amd/acp-pcm-dma.c:933: first defined here sound/soc/dwc/dwc-i2s.o: In function `dw_pcm_pop_rx':
sound/soc/dwc/local.h:129: multiple definition of `dw_pcm_pop_rx'
sound/soc/amd/acp-pcm-dma.o:sound/soc/amd/../dwc/local.h:129: first defined here sound/soc/dwc/dwc-i2s.o: In function `dw_pcm_register':
sound/soc/dwc/local.h:131: multiple definition of `dw_pcm_register'
sound/soc/amd/acp-pcm-dma.o:sound/soc/amd/../dwc/local.h:131: first defined here
vim +129 sound/soc/dwc/local.h
79361b2b Jose Abreu 2016-06-09 122 79361b2b Jose Abreu 2016-06-09 123 #if IS_ENABLED(CONFIG_SND_DESIGNWARE_PCM) 79361b2b Jose Abreu 2016-06-09 124 void dw_pcm_push_tx(struct dw_i2s_dev *dev); e2f748e0 Jose Abreu 2016-12-27 125 void dw_pcm_pop_rx(struct dw_i2s_dev *dev); 79361b2b Jose Abreu 2016-06-09 126 int dw_pcm_register(struct platform_device *pdev); 79361b2b Jose Abreu 2016-06-09 127 #else 79361b2b Jose Abreu 2016-06-09 128 void dw_pcm_push_tx(struct dw_i2s_dev *dev) { } e2f748e0 Jose Abreu 2016-12-27 @129 void dw_pcm_pop_rx(struct dw_i2s_dev *dev) { } 79361b2b Jose Abreu 2016-06-09 130 int dw_pcm_register(struct platform_device *pdev) 79361b2b Jose Abreu 2016-06-09 @131 { 79361b2b Jose Abreu 2016-06-09 132 return -EINVAL; 79361b2b Jose Abreu 2016-06-09 133 } 79361b2b Jose Abreu 2016-06-09 134 #endif 79361b2b Jose Abreu 2016-06-09 135
:::::: The code at line 129 was first introduced by commit :::::: e2f748e06db389d9fd51413df23ff8d3615a47db ASoC: dwc: Add record capability in PIO mode
:::::: TO: Jose Abreu Jose.Abreu@synopsys.com :::::: CC: Mark Brown broonie@kernel.org
0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
posted patch as V2 after fixing kbuild errors.
Below is the link.
As Stoney has SRAM memory limitation ,to support playback & capture on both the I2S controller instances audio buffer size is reduced to 8k.
For playback on I2S SP instance sram bank 1 will be used. For capture on I2S SP instance sram bank 2 will be used. For playback on I2S BT instance sram bank 3 will be used. For capture on I2S BT instance sram bank 4 will be used.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com --- sound/soc/amd/acp-pcm-dma.c | 106 ++++++++++++++++++++++++++++++++++---------- sound/soc/amd/acp.h | 41 +++++++++++++++-- 2 files changed, 120 insertions(+), 27 deletions(-)
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index a61c4e0..6da54ab 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -37,7 +37,7 @@ #define MAX_BUFFER (PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS) #define MIN_BUFFER MAX_BUFFER
-#define ST_PLAYBACK_MAX_PERIOD_SIZE 8192 +#define ST_PLAYBACK_MAX_PERIOD_SIZE 4096 #define ST_CAPTURE_MAX_PERIOD_SIZE ST_PLAYBACK_MAX_PERIOD_SIZE #define ST_MAX_BUFFER (ST_PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS) #define ST_MIN_BUFFER ST_MAX_BUFFER @@ -320,42 +320,99 @@ static void config_acp_dma(void __iomem *acp_mmio, u16 ch1, ch2, destination, dma_dscr_idx;
if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) { - pte_offset = ACP_PLAYBACK_PTE_OFFSET; - ch1 = SYSRAM_TO_ACP_CH_NUM; - ch2 = ACP_TO_I2S_DMA_CH_NUM; - sram_bank = ACP_SHARED_RAM_BANK_1_ADDRESS; - destination = TO_ACP_I2S_1; - - } else { - pte_offset = ACP_CAPTURE_PTE_OFFSET; - ch1 = SYSRAM_TO_ACP_CH_NUM; - ch2 = ACP_TO_I2S_DMA_CH_NUM; - switch (asic_type) { - case CHIP_STONEY: + switch (audio_config->i2s_play_instance) { + case I2S_BT_INSTANCE: + pte_offset = ACP_ST_I2S_BT_PLAYBACK_PTE_OFFSET; + ch1 = SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM; + ch2 = ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM; sram_bank = ACP_SHARED_RAM_BANK_3_ADDRESS; + destination = TO_BLUETOOTH; break; + case I2S_SP_INSTANCE: default: - sram_bank = ACP_SHARED_RAM_BANK_5_ADDRESS; + switch (asic_type) { + case CHIP_STONEY: + pte_offset = ACP_ST_I2S_SP_PLAYBACK_PTE_OFFSET; + break; + default: + pte_offset = ACP_PLAYBACK_PTE_OFFSET; + } + ch1 = SYSRAM_TO_ACP_CH_NUM; + ch2 = ACP_TO_I2S_DMA_CH_NUM; + sram_bank = ACP_SHARED_RAM_BANK_1_ADDRESS; + destination = TO_ACP_I2S_1; + } + } else { + switch (audio_config->i2s_capture_instance) { + case I2S_BT_INSTANCE: + pte_offset = ACP_ST_I2S_BT_CAPTURE_PTE_OFFSET; + ch1 = ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM; + ch2 = I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM; + sram_bank = ACP_SHARED_RAM_BANK_4_ADDRESS; + destination = FROM_BLUETOOTH; + break; + case I2S_SP_INSTANCE: + default: + pte_offset = ACP_CAPTURE_PTE_OFFSET; + ch1 = SYSRAM_TO_ACP_CH_NUM; + ch2 = ACP_TO_I2S_DMA_CH_NUM; + switch (asic_type) { + case CHIP_STONEY: + sram_bank = ACP_SHARED_RAM_BANK_2_ADDRESS; + break; + default: + sram_bank = ACP_SHARED_RAM_BANK_5_ADDRESS; + } + destination = FROM_ACP_I2S_1; } - destination = FROM_ACP_I2S_1; }
acp_pte_config(acp_mmio, audio_config->pg, audio_config->num_of_pages, pte_offset); - if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) - dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12; - else - dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH14; + if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) { + switch (audio_config->i2s_play_instance) { + case I2S_BT_INSTANCE: + dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH8; + break; + case I2S_SP_INSTANCE: + default: + dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12; + } + } else { + switch (audio_config->i2s_capture_instance) { + case I2S_BT_INSTANCE: + dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH10; + break; + case I2S_SP_INSTANCE: + default: + dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH14; + } + }
/* Configure System memory <-> ACP SRAM DMA descriptors */ set_acp_sysmem_dma_descriptors(acp_mmio, audio_config->size, audio_config->direction, pte_offset, ch1, sram_bank, dma_dscr_idx, asic_type);
- if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) - dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH13; - else - dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH15; + if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) { + switch (audio_config->i2s_play_instance) { + case I2S_BT_INSTANCE: + dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH9; + break; + case I2S_SP_INSTANCE: + default: + dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH13; + } + } else { + switch (audio_config->i2s_capture_instance) { + case I2S_BT_INSTANCE: + dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH11; + break; + case I2S_SP_INSTANCE: + default: + dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH15; + } + } /* Configure ACP SRAM <-> I2S DMA descriptors */ set_acp_to_i2s_dma_descriptors(acp_mmio, audio_config->size, audio_config->direction, sram_bank, @@ -385,6 +442,9 @@ static void acp_dma_start(void __iomem *acp_mmio, case ACP_TO_I2S_DMA_CH_NUM: case ACP_TO_SYSRAM_CH_NUM: case I2S_TO_ACP_DMA_CH_NUM: + case ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM: + case ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM: + case I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM: dma_ctrl |= ACP_DMA_CNTL_0__DMAChIOCEn_MASK; break; default: diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h index c86bef4..b697dcb 100644 --- a/sound/soc/amd/acp.h +++ b/sound/soc/amd/acp.h @@ -11,17 +11,29 @@ #define ACP_PLAYBACK_PTE_OFFSET 10 #define ACP_CAPTURE_PTE_OFFSET 0
+/* Playback and Capture Offset for Stoney */ +#define ACP_ST_I2S_SP_PLAYBACK_PTE_OFFSET 0x04 +#define ACP_ST_I2S_SP_CAPTURE_PTE_OFFSET 0x00 +#define ACP_ST_I2S_BT_PLAYBACK_PTE_OFFSET 0x08 +#define ACP_ST_I2S_BT_CAPTURE_PTE_OFFSET 0x0c + #define ACP_GARLIC_CNTL_DEFAULT 0x00000FB4 #define ACP_ONION_CNTL_DEFAULT 0x00000FB4
#define ACP_PHYSICAL_BASE 0x14000
-/* Playback SRAM address (as a destination in dma descriptor) */ +/* In case of I2S SP controller instance, Stoney uses SRAM bank 1 for + * playback and SRAM Bank 2 for capture where as in case of BT I2S + * Instance ,Stoney uses SRAM Bank 3 for playback & SRAM Bank 4 will + * be used for capture.Carrizo uses I2S SP controller instance.SRAM Banks + * 1,2,3,4 will be used for playback & SRAM Banks 5,6,7,8 will be used + * for capture scenario. + */ #define ACP_SHARED_RAM_BANK_1_ADDRESS 0x4002000 - -/* Capture SRAM address (as a source in dma descriptor) */ -#define ACP_SHARED_RAM_BANK_5_ADDRESS 0x400A000 +#define ACP_SHARED_RAM_BANK_2_ADDRESS 0x4004000 #define ACP_SHARED_RAM_BANK_3_ADDRESS 0x4006000 +#define ACP_SHARED_RAM_BANK_4_ADDRESS 0x4008000 +#define ACP_SHARED_RAM_BANK_5_ADDRESS 0x400A000
#define ACP_DMA_RESET_TIME 10000 #define ACP_CLOCK_EN_TIME_OUT_VALUE 0x000000FF @@ -36,8 +48,10 @@
#define TO_ACP_I2S_1 0x2 #define TO_ACP_I2S_2 0x4 +#define TO_BLUETOOTH 0x3 #define FROM_ACP_I2S_1 0xa #define FROM_ACP_I2S_2 0xb +#define FROM_BLUETOOTH 0xb
#define ACP_TILE_ON_MASK 0x03 #define ACP_TILE_OFF_MASK 0x02 @@ -58,6 +72,14 @@ #define ACP_TO_SYSRAM_CH_NUM 14 #define I2S_TO_ACP_DMA_CH_NUM 15
+/* Playback DMA Channels for I2S BT instance */ +#define SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM 8 +#define ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM 9 + +/* Capture DMA Channels for I2S BT Instance */ +#define ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM 10 +#define I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM 11 + #define NUM_DSCRS_PER_CHANNEL 2
#define PLAYBACK_START_DMA_DESCR_CH12 0 @@ -70,6 +92,17 @@ #define CAPTURE_START_DMA_DESCR_CH15 6 #define CAPTURE_END_DMA_DESCR_CH15 7
+/* I2S BT Instance DMA Descriptors */ +#define PLAYBACK_START_DMA_DESCR_CH8 8 +#define PLAYBACK_END_DMA_DESCR_CH8 9 +#define PLAYBACK_START_DMA_DESCR_CH9 10 +#define PLAYBACK_END_DMA_DESCR_CH9 11 + +#define CAPTURE_START_DMA_DESCR_CH10 12 +#define CAPTURE_END_DMA_DESCR_CH10 13 +#define CAPTURE_START_DMA_DESCR_CH11 14 +#define CAPTURE_END_DMA_DESCR_CH11 15 + #define mmACP_I2S_16BIT_RESOLUTION_EN 0x5209 #define ACP_I2S_MIC_16BIT_RESOLUTION_EN 0x01 #define ACP_I2S_SP_16BIT_RESOLUTION_EN 0x02
Interrupt handler changes for BT I2S instance.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com --- sound/soc/amd/acp-pcm-dma.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 6da54ab..9bd12bd 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -721,6 +721,24 @@ static irqreturn_t dma_irq_handler(int irq, void *arg) acp_mmio, mmACP_EXTERNAL_INTR_STAT); }
+ if ((intr_flag & BIT(ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM)) != 0) { + valid_irq = true; + if (acp_reg_read(acp_mmio, mmACP_DMA_CUR_DSCR_9) == + PLAYBACK_START_DMA_DESCR_CH9) + dscr_idx = PLAYBACK_END_DMA_DESCR_CH8; + else + dscr_idx = PLAYBACK_START_DMA_DESCR_CH8; + config_acp_dma_channel(acp_mmio, + SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM, + dscr_idx, 1, 0); + acp_dma_start(acp_mmio, SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM, + false); + snd_pcm_period_elapsed(irq_data->play_i2sbt_stream); + acp_reg_write((intr_flag & + BIT(ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM)) << 16, + acp_mmio, mmACP_EXTERNAL_INTR_STAT); + } + if ((intr_flag & BIT(I2S_TO_ACP_DMA_CH_NUM)) != 0) { valid_irq = true; if (acp_reg_read(acp_mmio, mmACP_DMA_CUR_DSCR_15) == @@ -743,6 +761,31 @@ static irqreturn_t dma_irq_handler(int irq, void *arg) acp_mmio, mmACP_EXTERNAL_INTR_STAT); }
+ if ((intr_flag & BIT(I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM)) != 0) { + valid_irq = true; + if (acp_reg_read(acp_mmio, mmACP_DMA_CUR_DSCR_11) == + CAPTURE_START_DMA_DESCR_CH11) + dscr_idx = CAPTURE_END_DMA_DESCR_CH10; + else + dscr_idx = CAPTURE_START_DMA_DESCR_CH10; + config_acp_dma_channel(acp_mmio, + ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM, + dscr_idx, 1, 0); + acp_dma_start(acp_mmio, ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM, + false); + acp_reg_write((intr_flag & + BIT(I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM)) << 16, + acp_mmio, mmACP_EXTERNAL_INTR_STAT); + } + + if ((intr_flag & BIT(ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM)) != 0) { + valid_irq = true; + snd_pcm_period_elapsed(irq_data->capture_i2sbt_stream); + acp_reg_write((intr_flag & + BIT(ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM)) << 16, + acp_mmio, mmACP_EXTERNAL_INTR_STAT); + } + if (valid_irq) return IRQ_HANDLED; else
modified prepare callback for configuring dma channels for BT instance.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/acp-pcm-dma.c | 53 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 8 deletions(-)
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 9bd12bd..86d2287 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -1012,25 +1012,62 @@ static int acp_dma_mmap(struct snd_pcm_substream *substream,
static int acp_dma_prepare(struct snd_pcm_substream *substream) { + u16 start_dscr_idx; struct snd_pcm_runtime *runtime = substream->runtime; struct audio_substream_data *rtd = runtime->private_data;
if (!rtd) return -EINVAL; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - config_acp_dma_channel(rtd->acp_mmio, SYSRAM_TO_ACP_CH_NUM, - PLAYBACK_START_DMA_DESCR_CH12, + switch (rtd->i2s_play_instance) { + case I2S_BT_INSTANCE: + start_dscr_idx = PLAYBACK_START_DMA_DESCR_CH8; + config_acp_dma_channel(rtd->acp_mmio, + SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM, + start_dscr_idx, NUM_DSCRS_PER_CHANNEL, 0); - config_acp_dma_channel(rtd->acp_mmio, ACP_TO_I2S_DMA_CH_NUM, - PLAYBACK_START_DMA_DESCR_CH13, + config_acp_dma_channel(rtd->acp_mmio, + ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM, + start_dscr_idx + 2, NUM_DSCRS_PER_CHANNEL, 0); + break; + case I2S_SP_INSTANCE: + default: + start_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12; + config_acp_dma_channel(rtd->acp_mmio, + SYSRAM_TO_ACP_CH_NUM, + start_dscr_idx, + NUM_DSCRS_PER_CHANNEL, 0); + config_acp_dma_channel(rtd->acp_mmio, + ACP_TO_I2S_DMA_CH_NUM, + start_dscr_idx + 2, + NUM_DSCRS_PER_CHANNEL, 0); + } } else { - config_acp_dma_channel(rtd->acp_mmio, ACP_TO_SYSRAM_CH_NUM, - CAPTURE_START_DMA_DESCR_CH14, + switch (rtd->i2s_capture_instance) { + case I2S_BT_INSTANCE: + start_dscr_idx = CAPTURE_START_DMA_DESCR_CH10; + config_acp_dma_channel(rtd->acp_mmio, + ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM, + start_dscr_idx, NUM_DSCRS_PER_CHANNEL, 0); - config_acp_dma_channel(rtd->acp_mmio, I2S_TO_ACP_DMA_CH_NUM, - CAPTURE_START_DMA_DESCR_CH15, + config_acp_dma_channel(rtd->acp_mmio, + I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM, + start_dscr_idx + 2, NUM_DSCRS_PER_CHANNEL, 0); + break; + case I2S_SP_INSTANCE: + default: + start_dscr_idx = CAPTURE_START_DMA_DESCR_CH14; + config_acp_dma_channel(rtd->acp_mmio, + ACP_TO_SYSRAM_CH_NUM, + start_dscr_idx, + NUM_DSCRS_PER_CHANNEL, 0); + config_acp_dma_channel(rtd->acp_mmio, + I2S_TO_ACP_DMA_CH_NUM, + start_dscr_idx + 2, + NUM_DSCRS_PER_CHANNEL, 0); + } } return 0; }
modified trigger and pointer callbacks for bt i2s instance.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/acp-pcm-dma.c | 189 +++++++++++++++++++++++++++++++++----------- 1 file changed, 144 insertions(+), 45 deletions(-)
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 86d2287..c695e42 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -956,23 +956,43 @@ static int acp_dma_hw_free(struct snd_pcm_substream *substream) return snd_pcm_lib_free_pages(substream); }
-static u64 acp_get_byte_count(void __iomem *acp_mmio, int stream) +static u64 acp_get_byte_count(void __iomem *acp_mmio, u16 instance, int stream) { union acp_dma_count playback_dma_count; union acp_dma_count capture_dma_count; u64 bytescount = 0;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - playback_dma_count.bcount.high = acp_reg_read(acp_mmio, + switch (instance) { + case I2S_BT_INSTANCE: + playback_dma_count.bcount.high = acp_reg_read(acp_mmio, + mmACP_I2S_BT_TRANSMIT_BYTE_CNT_HIGH); + playback_dma_count.bcount.low = acp_reg_read(acp_mmio, + mmACP_I2S_BT_TRANSMIT_BYTE_CNT_LOW); + break; + case I2S_SP_INSTANCE: + default: + playback_dma_count.bcount.high = acp_reg_read(acp_mmio, mmACP_I2S_TRANSMIT_BYTE_CNT_HIGH); - playback_dma_count.bcount.low = acp_reg_read(acp_mmio, + playback_dma_count.bcount.low = acp_reg_read(acp_mmio, mmACP_I2S_TRANSMIT_BYTE_CNT_LOW); + } bytescount = playback_dma_count.bytescount; } else { - capture_dma_count.bcount.high = acp_reg_read(acp_mmio, + switch (instance) { + case I2S_BT_INSTANCE: + capture_dma_count.bcount.high = acp_reg_read(acp_mmio, + mmACP_I2S_BT_RECEIVE_BYTE_CNT_HIGH); + capture_dma_count.bcount.low = acp_reg_read(acp_mmio, + mmACP_I2S_BT_RECEIVE_BYTE_CNT_LOW); + break; + case I2S_SP_INSTANCE: + default: + capture_dma_count.bcount.high = acp_reg_read(acp_mmio, mmACP_I2S_RECEIVED_BYTE_CNT_HIGH); - capture_dma_count.bcount.low = acp_reg_read(acp_mmio, + capture_dma_count.bcount.low = acp_reg_read(acp_mmio, mmACP_I2S_RECEIVED_BYTE_CNT_LOW); + } bytescount = capture_dma_count.bytescount; } return bytescount; @@ -991,14 +1011,38 @@ static snd_pcm_uframes_t acp_dma_pointer(struct snd_pcm_substream *substream) return -EINVAL;
buffersize = frames_to_bytes(runtime, runtime->buffer_size); - bytescount = acp_get_byte_count(rtd->acp_mmio, substream->stream); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (bytescount > rtd->i2ssp_renderbytescount) - bytescount = bytescount - rtd->i2ssp_renderbytescount; + bytescount = acp_get_byte_count(rtd->acp_mmio, + rtd->i2s_play_instance, + substream->stream); + switch (rtd->i2s_play_instance) { + case I2S_BT_INSTANCE: + if (bytescount > rtd->i2sbt_renderbytescount) + bytescount = bytescount - + rtd->i2sbt_renderbytescount; + break; + case I2S_SP_INSTANCE: + default: + if (bytescount > rtd->i2ssp_renderbytescount) + bytescount = bytescount - + rtd->i2ssp_renderbytescount; + } } else { - if (bytescount > rtd->i2ssp_capturebytescount) - bytescount = bytescount - rtd->i2ssp_capturebytescount; + bytescount = acp_get_byte_count(rtd->acp_mmio, + rtd->i2s_capture_instance, + substream->stream); + switch (rtd->i2s_capture_instance) { + case I2S_BT_INSTANCE: + if (bytescount > rtd->i2sbt_capturebytescount) + bytescount = bytescount - + rtd->i2sbt_capturebytescount; + break; + case I2S_SP_INSTANCE: + default: + if (bytescount > rtd->i2ssp_capturebytescount) + bytescount = bytescount - + rtd->i2ssp_capturebytescount; + } } pos = do_div(bytescount, buffersize); return bytes_to_frames(runtime, pos); @@ -1089,54 +1133,109 @@ static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: - bytescount = acp_get_byte_count(rtd->acp_mmio, - substream->stream); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (rtd->i2ssp_renderbytescount == 0) - rtd->i2ssp_renderbytescount = bytescount; - acp_dma_start(rtd->acp_mmio, - SYSRAM_TO_ACP_CH_NUM, false); - while (acp_reg_read(rtd->acp_mmio, mmACP_DMA_CH_STS) & - BIT(SYSRAM_TO_ACP_CH_NUM)) { - if (!loops--) { - dev_err(component->dev, - "acp dma start timeout\n"); - return -ETIMEDOUT; + bytescount = acp_get_byte_count(rtd->acp_mmio, + rtd->i2s_play_instance, + substream->stream); + switch (rtd->i2s_play_instance) { + case I2S_BT_INSTANCE: + if (rtd->i2sbt_renderbytescount == 0) + rtd->i2sbt_renderbytescount = bytescount; + acp_dma_start(rtd->acp_mmio, + SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM, + false); + while (acp_reg_read(rtd->acp_mmio, + mmACP_DMA_CH_STS) & + BIT(SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM)) { + if (!loops--) { + dev_err(component->dev, + "acp dma start timeout\n"); + return -ETIMEDOUT; + } + cpu_relax(); } - cpu_relax(); - } - - acp_dma_start(rtd->acp_mmio, + acp_dma_start(rtd->acp_mmio, + ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM, + true); + break; + case I2S_SP_INSTANCE: + default: + if (rtd->i2ssp_renderbytescount == 0) + rtd->i2ssp_renderbytescount = bytescount; + acp_dma_start(rtd->acp_mmio, + SYSRAM_TO_ACP_CH_NUM, false); + while (acp_reg_read(rtd->acp_mmio, + mmACP_DMA_CH_STS) & + BIT(SYSRAM_TO_ACP_CH_NUM)) { + if (!loops--) { + dev_err(component->dev, + "acp dma start timeout\n"); + return -ETIMEDOUT; + } + cpu_relax(); + } + acp_dma_start(rtd->acp_mmio, ACP_TO_I2S_DMA_CH_NUM, true); - + } } else { - if (rtd->i2ssp_capturebytescount == 0) - rtd->i2ssp_capturebytescount = bytescount; - acp_dma_start(rtd->acp_mmio, - I2S_TO_ACP_DMA_CH_NUM, true); + bytescount = acp_get_byte_count(rtd->acp_mmio, + rtd->i2s_capture_instance, + substream->stream); + switch (rtd->i2s_capture_instance) { + case I2S_BT_INSTANCE: + if (rtd->i2sbt_capturebytescount == 0) + rtd->i2sbt_capturebytescount = 0; + acp_dma_start(rtd->acp_mmio, + I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM, + true); + break; + case I2S_SP_INSTANCE: + default: + if (rtd->i2ssp_capturebytescount == 0) + rtd->i2ssp_capturebytescount = bytescount; + acp_dma_start(rtd->acp_mmio, + I2S_TO_ACP_DMA_CH_NUM, true); + } } ret = 0; break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: - /* Need to stop only circular DMA channels : - * ACP_TO_I2S_DMA_CH_NUM / I2S_TO_ACP_DMA_CH_NUM. Non-circular - * channels will stopped automatically after its transfer - * completes : SYSRAM_TO_ACP_CH_NUM / ACP_TO_SYSRAM_CH_NUM - */ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = acp_dma_stop(rtd->acp_mmio, + switch (rtd->i2s_play_instance) { + case I2S_BT_INSTANCE: + ret = acp_dma_stop(rtd->acp_mmio, + SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM); + ret = acp_dma_stop(rtd->acp_mmio, + ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM); + rtd->i2sbt_renderbytescount = 0; + break; + case I2S_SP_INSTANCE: + default: + ret = acp_dma_stop(rtd->acp_mmio, SYSRAM_TO_ACP_CH_NUM); - ret = acp_dma_stop(rtd->acp_mmio, - ACP_TO_I2S_DMA_CH_NUM); - rtd->i2ssp_renderbytescount = 0; + ret = acp_dma_stop(rtd->acp_mmio, + ACP_TO_I2S_DMA_CH_NUM); + rtd->i2ssp_renderbytescount = 0; + } } else { - ret = acp_dma_stop(rtd->acp_mmio, - I2S_TO_ACP_DMA_CH_NUM); - ret = acp_dma_stop(rtd->acp_mmio, + switch (rtd->i2s_capture_instance) { + case I2S_BT_INSTANCE: + ret = acp_dma_stop(rtd->acp_mmio, + I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM); + ret = acp_dma_stop(rtd->acp_mmio, + ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM); + rtd->i2sbt_capturebytescount = 0; + break; + case I2S_SP_INSTANCE: + default: + ret = acp_dma_stop(rtd->acp_mmio, + I2S_TO_ACP_DMA_CH_NUM); + ret = acp_dma_stop(rtd->acp_mmio, ACP_TO_SYSRAM_CH_NUM); - rtd->i2ssp_capturebytescount = 0; + rtd->i2ssp_capturebytescount = 0; + } } break; default:
added 16bit resolution support for bt i2s instance for stoney.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/acp-pcm-dma.c | 29 +++++++++++++++++++++++------ sound/soc/amd/acp.h | 1 + 2 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index c695e42..92b163a 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -916,12 +916,29 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream, return -EINVAL;
if (adata->asic_type == CHIP_STONEY) { - val = acp_reg_read(adata->acp_mmio, mmACP_I2S_16BIT_RESOLUTION_EN); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - val |= ACP_I2S_SP_16BIT_RESOLUTION_EN; - else - val |= ACP_I2S_MIC_16BIT_RESOLUTION_EN; - acp_reg_write(val, adata->acp_mmio, mmACP_I2S_16BIT_RESOLUTION_EN); + val = acp_reg_read(adata->acp_mmio, + mmACP_I2S_16BIT_RESOLUTION_EN); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + switch (rtd->i2s_play_instance) { + case I2S_BT_INSTANCE: + val |= ACP_I2S_BT_16BIT_RESOLUTION_EN; + break; + case I2S_SP_INSTANCE: + default: + val |= ACP_I2S_SP_16BIT_RESOLUTION_EN; + } + } else { + switch (rtd->i2s_capture_instance) { + case I2S_BT_INSTANCE: + val |= ACP_I2S_BT_16BIT_RESOLUTION_EN; + break; + case I2S_SP_INSTANCE: + default: + val |= ACP_I2S_MIC_16BIT_RESOLUTION_EN; + } + } + acp_reg_write(val, adata->acp_mmio, + mmACP_I2S_16BIT_RESOLUTION_EN); } size = params_buffer_bytes(params); status = snd_pcm_lib_malloc_pages(substream, size); diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h index b697dcb..a91f0a9 100644 --- a/sound/soc/amd/acp.h +++ b/sound/soc/amd/acp.h @@ -106,6 +106,7 @@ #define mmACP_I2S_16BIT_RESOLUTION_EN 0x5209 #define ACP_I2S_MIC_16BIT_RESOLUTION_EN 0x01 #define ACP_I2S_SP_16BIT_RESOLUTION_EN 0x02 +#define ACP_I2S_BT_16BIT_RESOLUTION_EN 0x04 enum acp_dma_priority_level { /* 0x0 Specifies the DMA channel is given normal priority */ ACP_DMA_PRIORITY_LEVEL_NORMAL = 0x0,
after acp reset , it requires to reprogram bt i2s config mux pins to enable bt i2s instance. added bt i2s enablement sequence during acp init.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com --- sound/soc/amd/acp-pcm-dma.c | 5 +++++ sound/soc/amd/acp.h | 1 + 2 files changed, 6 insertions(+)
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 92b163a..3ebba00 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -604,6 +604,11 @@ static int acp_init(void __iomem *acp_mmio, u32 asic_type) val &= ~ACP_SOFT_RESET__SoftResetAud_MASK; acp_reg_write(val, acp_mmio, mmACP_SOFT_RESET);
+ /* For BT instance change pins from UART to BT */ + val = acp_reg_read(acp_mmio, mmACP_BT_UART_PAD_SEL); + val |= ACP_BT_UART_PAD_SELECT_MASK; + acp_reg_write(val, acp_mmio, mmACP_BT_UART_PAD_SEL); + /* initiailize Onion control DAGB register */ acp_reg_write(ACP_ONION_CNTL_DEFAULT, acp_mmio, mmACP_AXI2DAGB_ONION_CNTL); diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h index a91f0a9..aa3e07b 100644 --- a/sound/soc/amd/acp.h +++ b/sound/soc/amd/acp.h @@ -107,6 +107,7 @@ #define ACP_I2S_MIC_16BIT_RESOLUTION_EN 0x01 #define ACP_I2S_SP_16BIT_RESOLUTION_EN 0x02 #define ACP_I2S_BT_16BIT_RESOLUTION_EN 0x04 +#define ACP_BT_UART_PAD_SELECT_MASK 0x1 enum acp_dma_priority_level { /* 0x0 Specifies the DMA channel is given normal priority */ ACP_DMA_PRIORITY_LEVEL_NORMAL = 0x0,
On Monday 26 March 2018 06:42 PM, Vijendar Mukunda wrote:
This patch set updates Audio CoProcessor (ACP) audio drivers to enable BT I2S controller instance. In Audio Coprocessor, There are three I2S controllers can be configured/enabled.(I2S SP, I2S MICSP, BT I2S) Default enabled I2S controller instance is I2S SP instance. There is a requirement to enable BT I2S controller Instance along with I2S SP controller instance. This patch set bring up functionality to render & capture on BT I2S controller instance.
The current patch set also includes a new dependent patch.
The current code is based on asoc-next, but I'm happy to rebase on whatever tree this ends up going through if there are any problems applying.
Vijendar Mukunda (8): ASoC: dwc: I2S Controller instance param added ASoC: amd: dma driver changes for BT I2S controller instance ASoC: amd: dma descriptor changes for BT I2S Instance ASoC: amd: Interrupt handler changes for BT I2S instance ASoC: amd: prepare callback modifications for bt i2s instance ASoC: amd: pointer and trigger callback modifications for bt i2s ASoC: amd: 16bit resolution support for bt i2s instance ASoC: amd: enabling bt i2s config after acp reset
include/sound/designware_i2s.h | 6 + sound/soc/amd/acp-pcm-dma.c | 531 +++++++++++++++++++++++++++++++++-------- sound/soc/amd/acp.h | 50 +++- sound/soc/dwc/dwc-i2s.c | 1 + sound/soc/dwc/local.h | 1 + 5 files changed, 481 insertions(+), 108 deletions(-)
Hi Mark,
Could you please review the entire patch set. Only for [PATCH 2/8] ASoC: amd: dma driver changes for BT I2S controller instance, Posted a V2 patch which fixes kbuild errors. https://patchwork.kernel.org/patch/10316177/
Thanks, Vijendar
participants (3)
-
kbuild test robot
-
Mukunda,Vijendar
-
Vijendar Mukunda