[PATCH V3 00/25] ASoC: amd: Add support for ACP7.0 & ACP7.1 platforms

This patch series includes the below changes - Refactor existing ACP6.3 platform ACP PCI driver, SoundWire DMA driver code. - Add Audio IO support for ACP7.0 and ACP7.1 platforms for SoundWire IO and ACP PDM controller combination. - Add SoundWire generic machine driver changes for legacy stack (No DSP enabled) for ACP7.0 & ACP7.1 platforms. - Add SoundWire machines for ACP7.0 & ACP7.1 platforms.
Changes since v2: - As per Mark's comment, to avoid code duplication drop separate folder(acp70) for ACP7.0 & ACP7.1 platforms and refactor existing ACP6.3 platform ACP PCI driver, SoundWire DMA driver code and add support for ACP7.0 & ACP7.1 platforms. - Add ACP PCI driver hw_ops for ACP6.3, ACP7.0 & ACP7.1 platforms. - Implement platform specific code in Soundwire DMA driver by adding acp pci revision id checks for ACP6.3/ACP7.0/ACP7.1 platforms. - Refactor existing ACP PCI driver Interrupt handler code. - Add new Soundwire machine for RT1320 Speaker + RT722 multi function codec combination. - Add machine driver quirks for Dell SKU's.
Changes since v1: - Change the code sequence for handling SoundWire wake interrupts. - Add new patch to restore host wake interrupt mask - Add new patch to enable ACP PME during ACP init sequence. - Change ACP PCI driver PM ops code sequence.
Vijendar Mukunda (25): ASoC: amd: ps: rename structure names, variable and other macros ASoC: amd: ps: use macro for ACP6.3 pci revision id ASoC: amd: ps: add acp pci driver hw_ops for acp6.3 platform ASoC: amd: ps: add callback functions for acp pci driver pm ops ASoC: amd: ps: add callback to read acp pin configuration ASoC: amd: ps: add soundwire dma irq thread callback ASoC: amd: ps: refactor soundwire dma interrupt handling ASoC: amd: ps: store acp revision id in SoundWire dma driver private data ASoC: amd: ps: refactor soundwire dma driver code ASoC: amd: ps: refactor soundwire dma interrupts enable/disable sequence ASoC: amd: ps: rename acp_restore_sdw_dma_config() function ASoC: amd: ps: add pci driver hw_ops for ACP7.0 & ACP7.1 variants ASoC: amd: ps: add pm ops related hw_ops for ACP7.0 & ACP7.1 platforms ASoC: amd: ps: add ACP7.0 & ACP7.1 specific soundwire dma driver changes ASoC: amd: ps: implement function to restore dma config for ACP7.0 platform ASoC: amd: ps: add soundwire dma interrupts handling for ACP7.0 platform ASoC: amd: ps: add soundwire wake interrupt handling ASoC: amd: ps: update module description ASoC: amd: ps: update file description and copyright year ASoC: amd: update Pink Sardine platform Kconfig description ASoC: amd: acp: add machine driver changes for ACP7.0 and ACP7.1 platforms ASoC: amd: acp: add RT711, RT714 & RT1316 support for ACP7.0 platform ASoC: amd: acp: amd-acp70-acpi-match: Add rt722 support ASoC: amd: acp: amd-acp70-acpi-match: Add RT1320 & RT722 combination soundwire machine ASoC: amd: amd_sdw: Add quirks for Dell SKU's
sound/soc/amd/Kconfig | 10 +- sound/soc/amd/acp/Kconfig | 1 + sound/soc/amd/acp/Makefile | 2 +- sound/soc/amd/acp/acp-sdw-legacy-mach.c | 45 +++ sound/soc/amd/acp/acp-sdw-mach-common.c | 34 ++ sound/soc/amd/acp/amd-acp70-acpi-match.c | 160 ++++++++ sound/soc/amd/acp/soc_amd_sdw_common.h | 12 + sound/soc/amd/mach-config.h | 1 + sound/soc/amd/ps/Makefile | 2 +- sound/soc/amd/ps/acp63.h | 246 ++++++++++-- sound/soc/amd/ps/pci-ps.c | 422 +++++++++----------- sound/soc/amd/ps/ps-common.c | 475 +++++++++++++++++++++++ sound/soc/amd/ps/ps-pdm-dma.c | 6 +- sound/soc/amd/ps/ps-sdw-dma.c | 375 ++++++++++++++---- 14 files changed, 1440 insertions(+), 351 deletions(-) create mode 100644 sound/soc/amd/acp/amd-acp70-acpi-match.c create mode 100644 sound/soc/amd/ps/ps-common.c

Rename macros and structure names, variable with ACP63 tag which are specific to ACP6.3 platform. Rename 'stream_index' and 'sdw_dma_data' variable names to avoid check patch warnings.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/acp63.h | 66 ++++++++++++++++---------------- sound/soc/amd/ps/pci-ps.c | 64 +++++++++++++++---------------- sound/soc/amd/ps/ps-sdw-dma.c | 72 +++++++++++++++++------------------ 3 files changed, 101 insertions(+), 101 deletions(-)
diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index e54eabaa4d3e..01910273624b 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -13,13 +13,13 @@ #define ACP63_REG_END 0x125C000
#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001 -#define ACP_PGFSM_CNTL_POWER_ON_MASK 1 -#define ACP_PGFSM_CNTL_POWER_OFF_MASK 0 -#define ACP_PGFSM_STATUS_MASK 3 -#define ACP_POWERED_ON 0 -#define ACP_POWER_ON_IN_PROGRESS 1 -#define ACP_POWERED_OFF 2 -#define ACP_POWER_OFF_IN_PROGRESS 3 +#define ACP63_PGFSM_CNTL_POWER_ON_MASK 1 +#define ACP63_PGFSM_CNTL_POWER_OFF_MASK 0 +#define ACP63_PGFSM_STATUS_MASK 3 +#define ACP63_POWERED_ON 0 +#define ACP63_POWER_ON_IN_PROGRESS 1 +#define ACP63_POWERED_OFF 2 +#define ACP63_POWER_OFF_IN_PROGRESS 3
#define ACP_ERROR_MASK 0x20000000 #define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF @@ -60,7 +60,7 @@ #define AMD_SDW_MAX_MANAGERS 2
/* time in ms for acp timeout */ -#define ACP_TIMEOUT 500 +#define ACP63_TIMEOUT 500
#define ACP_SDW0_STAT BIT(21) #define ACP_SDW1_STAT BIT(2) @@ -72,13 +72,13 @@ #define ACP_AUDIO0_RX_THRESHOLD 0x1b #define ACP_AUDIO1_RX_THRESHOLD 0x19 #define ACP_AUDIO2_RX_THRESHOLD 0x17 -#define ACP_P1_AUDIO1_TX_THRESHOLD BIT(6) -#define ACP_P1_AUDIO1_RX_THRESHOLD BIT(5) -#define ACP_SDW_DMA_IRQ_MASK 0x1F800000 -#define ACP_P1_SDW_DMA_IRQ_MASK 0x60 +#define ACP63_P1_AUDIO1_TX_THRESHOLD BIT(6) +#define ACP63_P1_AUDIO1_RX_THRESHOLD BIT(5) +#define ACP63_SDW_DMA_IRQ_MASK 0x1F800000 +#define ACP63_P1_SDW_DMA_IRQ_MASK 0x60 #define ACP63_SDW0_DMA_MAX_STREAMS 6 #define ACP63_SDW1_DMA_MAX_STREAMS 2 -#define ACP_P1_AUDIO_TX_THRESHOLD 6 +#define ACP63_P1_AUDIO_TX_THRESHOLD 6
/* * Below entries describes SDW0 instance DMA stream id and DMA irq bit mapping @@ -91,8 +91,8 @@ * 4 (SDW0_AUDIO1_RX) 25 * 5 (SDW0_AUDIO2_RX) 23 */ -#define SDW0_DMA_TX_IRQ_MASK(i) (ACP_AUDIO0_TX_THRESHOLD - (2 * (i))) -#define SDW0_DMA_RX_IRQ_MASK(i) (ACP_AUDIO0_RX_THRESHOLD - (2 * ((i) - 3))) +#define ACP63_SDW0_DMA_TX_IRQ_MASK(i) (ACP_AUDIO0_TX_THRESHOLD - (2 * (i))) +#define ACP63_SDW0_DMA_RX_IRQ_MASK(i) (ACP_AUDIO0_RX_THRESHOLD - (2 * ((i) - 3)))
/* * Below entries describes SDW1 instance DMA stream id and DMA irq bit mapping @@ -101,7 +101,7 @@ * 0 (SDW1_AUDIO1_TX) 6 * 1 (SDW1_AUDIO1_RX) 5 */ -#define SDW1_DMA_IRQ_MASK(i) (ACP_P1_AUDIO_TX_THRESHOLD - (i)) +#define ACP63_SDW1_DMA_IRQ_MASK(i) (ACP63_P1_AUDIO_TX_THRESHOLD - (i))
#define ACP_DELAY_US 5 #define ACP_SDW_RING_BUFF_ADDR_OFFSET (128 * 1024) @@ -148,18 +148,18 @@ enum acp_config { ACP_CONFIG_15, };
-enum amd_sdw0_channel { - ACP_SDW0_AUDIO0_TX = 0, - ACP_SDW0_AUDIO1_TX, - ACP_SDW0_AUDIO2_TX, - ACP_SDW0_AUDIO0_RX, - ACP_SDW0_AUDIO1_RX, - ACP_SDW0_AUDIO2_RX, +enum amd_acp63_sdw0_channel { + ACP63_SDW0_AUDIO0_TX = 0, + ACP63_SDW0_AUDIO1_TX, + ACP63_SDW0_AUDIO2_TX, + ACP63_SDW0_AUDIO0_RX, + ACP63_SDW0_AUDIO1_RX, + ACP63_SDW0_AUDIO2_RX, };
-enum amd_sdw1_channel { - ACP_SDW1_AUDIO1_TX, - ACP_SDW1_AUDIO1_RX, +enum amd_acp63_sdw1_channel { + ACP63_SDW1_AUDIO1_TX, + ACP63_SDW1_AUDIO1_RX, };
struct pdm_stream_instance { @@ -180,8 +180,8 @@ struct pdm_dev_data { struct sdw_dma_dev_data { void __iomem *acp_base; struct mutex *acp_lock; /* used to protect acp common register access */ - struct snd_pcm_substream *sdw0_dma_stream[ACP63_SDW0_DMA_MAX_STREAMS]; - struct snd_pcm_substream *sdw1_dma_stream[ACP63_SDW1_DMA_MAX_STREAMS]; + struct snd_pcm_substream *acp63_sdw0_dma_stream[ACP63_SDW0_DMA_MAX_STREAMS]; + struct snd_pcm_substream *acp63_sdw1_dma_stream[ACP63_SDW1_DMA_MAX_STREAMS]; };
struct acp_sdw_dma_stream { @@ -232,8 +232,10 @@ struct sdw_dma_ring_buf_reg { * @addr: pci ioremap address * @reg_range: ACP reigister range * @acp_rev: ACP PCI revision id - * @sdw0-dma_intr_stat: DMA interrupt status array for SoundWire manager-SW0 instance - * @sdw_dma_intr_stat: DMA interrupt status array for SoundWire manager-SW1 instance + * @acp63_sdw0-dma_intr_stat: DMA interrupt status array for ACP6.3 platform SoundWire + * manager-SW0 instance + * @acp63_sdw_dma_intr_stat: DMA interrupt status array for ACP6.3 platform SoundWire + * manager-SW1 instance */
struct acp63_dev_data { @@ -256,8 +258,8 @@ struct acp63_dev_data { u32 addr; u32 reg_range; u32 acp_rev; - u16 sdw0_dma_intr_stat[ACP63_SDW0_DMA_MAX_STREAMS]; - u16 sdw1_dma_intr_stat[ACP63_SDW1_DMA_MAX_STREAMS]; + u16 acp63_sdw0_dma_intr_stat[ACP63_SDW0_DMA_MAX_STREAMS]; + u16 acp63_sdw1_dma_intr_stat[ACP63_SDW1_DMA_MAX_STREAMS]; };
int snd_amd_acp_find_config(struct pci_dev *pci); diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 8b556950b855..f5beb7f14913 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -30,10 +30,10 @@ static int acp63_power_on(void __iomem *acp_base) if (!val) return val;
- if ((val & ACP_PGFSM_STATUS_MASK) != ACP_POWER_ON_IN_PROGRESS) - writel(ACP_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL); + if ((val & ACP63_PGFSM_STATUS_MASK) != ACP63_POWER_ON_IN_PROGRESS) + writel(ACP63_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL);
- return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP_TIMEOUT); + return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP63_TIMEOUT); }
static int acp63_reset(void __iomem *acp_base) @@ -45,13 +45,13 @@ static int acp63_reset(void __iomem *acp_base)
ret = readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK, - DELAY_US, ACP_TIMEOUT); + DELAY_US, ACP63_TIMEOUT); if (ret) return ret;
writel(0, acp_base + ACP_SOFT_RESET);
- return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP_TIMEOUT); + return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP63_TIMEOUT); }
static void acp63_enable_interrupts(void __iomem *acp_base) @@ -104,24 +104,24 @@ static int acp63_deinit(void __iomem *acp_base, struct device *dev)
static irqreturn_t acp63_irq_thread(int irq, void *context) { - struct sdw_dma_dev_data *sdw_dma_data; + struct sdw_dma_dev_data *sdw_data; struct acp63_dev_data *adata = context; - u32 stream_index; + u32 stream_id;
- sdw_dma_data = dev_get_drvdata(&adata->sdw_dma_dev->dev); + sdw_data = dev_get_drvdata(&adata->sdw_dma_dev->dev);
- for (stream_index = 0; stream_index < ACP63_SDW0_DMA_MAX_STREAMS; stream_index++) { - if (adata->sdw0_dma_intr_stat[stream_index]) { - if (sdw_dma_data->sdw0_dma_stream[stream_index]) - snd_pcm_period_elapsed(sdw_dma_data->sdw0_dma_stream[stream_index]); - adata->sdw0_dma_intr_stat[stream_index] = 0; + for (stream_id = 0; stream_id < ACP63_SDW0_DMA_MAX_STREAMS; stream_id++) { + if (adata->acp63_sdw0_dma_intr_stat[stream_id]) { + if (sdw_data->acp63_sdw0_dma_stream[stream_id]) + snd_pcm_period_elapsed(sdw_data->acp63_sdw0_dma_stream[stream_id]); + adata->acp63_sdw0_dma_intr_stat[stream_id] = 0; } } - for (stream_index = 0; stream_index < ACP63_SDW1_DMA_MAX_STREAMS; stream_index++) { - if (adata->sdw1_dma_intr_stat[stream_index]) { - if (sdw_dma_data->sdw1_dma_stream[stream_index]) - snd_pcm_period_elapsed(sdw_dma_data->sdw1_dma_stream[stream_index]); - adata->sdw1_dma_intr_stat[stream_index] = 0; + for (stream_id = 0; stream_id < ACP63_SDW1_DMA_MAX_STREAMS; stream_id++) { + if (adata->acp63_sdw1_dma_intr_stat[stream_id]) { + if (sdw_data->acp63_sdw1_dma_stream[stream_id]) + snd_pcm_period_elapsed(sdw_data->acp63_sdw1_dma_stream[stream_id]); + adata->acp63_sdw1_dma_intr_stat[stream_id] = 0; } } return IRQ_HANDLED; @@ -180,48 +180,48 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id) snd_pcm_period_elapsed(ps_pdm_data->capture_stream); irq_flag = 1; } - if (ext_intr_stat & ACP_SDW_DMA_IRQ_MASK) { + if (ext_intr_stat & ACP63_SDW_DMA_IRQ_MASK) { for (index = ACP_AUDIO2_RX_THRESHOLD; index <= ACP_AUDIO0_TX_THRESHOLD; index++) { if (ext_intr_stat & BIT(index)) { writel(BIT(index), adata->acp63_base + ACP_EXTERNAL_INTR_STAT); switch (index) { case ACP_AUDIO0_TX_THRESHOLD: - stream_id = ACP_SDW0_AUDIO0_TX; + stream_id = ACP63_SDW0_AUDIO0_TX; break; case ACP_AUDIO1_TX_THRESHOLD: - stream_id = ACP_SDW0_AUDIO1_TX; + stream_id = ACP63_SDW0_AUDIO1_TX; break; case ACP_AUDIO2_TX_THRESHOLD: - stream_id = ACP_SDW0_AUDIO2_TX; + stream_id = ACP63_SDW0_AUDIO2_TX; break; case ACP_AUDIO0_RX_THRESHOLD: - stream_id = ACP_SDW0_AUDIO0_RX; + stream_id = ACP63_SDW0_AUDIO0_RX; break; case ACP_AUDIO1_RX_THRESHOLD: - stream_id = ACP_SDW0_AUDIO1_RX; + stream_id = ACP63_SDW0_AUDIO1_RX; break; case ACP_AUDIO2_RX_THRESHOLD: - stream_id = ACP_SDW0_AUDIO2_RX; + stream_id = ACP63_SDW0_AUDIO2_RX; break; }
- adata->sdw0_dma_intr_stat[stream_id] = 1; + adata->acp63_sdw0_dma_intr_stat[stream_id] = 1; sdw_dma_irq_flag = 1; } } }
- if (ext_intr_stat1 & ACP_P1_AUDIO1_RX_THRESHOLD) { - writel(ACP_P1_AUDIO1_RX_THRESHOLD, + if (ext_intr_stat1 & ACP63_P1_AUDIO1_RX_THRESHOLD) { + writel(ACP63_P1_AUDIO1_RX_THRESHOLD, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); - adata->sdw1_dma_intr_stat[ACP_SDW1_AUDIO1_RX] = 1; + adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_RX] = 1; sdw_dma_irq_flag = 1; }
- if (ext_intr_stat1 & ACP_P1_AUDIO1_TX_THRESHOLD) { - writel(ACP_P1_AUDIO1_TX_THRESHOLD, + if (ext_intr_stat1 & ACP63_P1_AUDIO1_TX_THRESHOLD) { + writel(ACP63_P1_AUDIO1_TX_THRESHOLD, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); - adata->sdw1_dma_intr_stat[ACP_SDW1_AUDIO1_TX] = 1; + adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_TX] = 1; sdw_dma_irq_flag = 1; }
diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index b602cca92b8b..878683619a05 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -18,7 +18,7 @@
#define DRV_NAME "amd_ps_sdw_dma"
-static struct sdw_dma_ring_buf_reg sdw0_dma_ring_buf_reg[ACP63_SDW0_DMA_MAX_STREAMS] = { +static struct sdw_dma_ring_buf_reg acp63_sdw0_dma_reg[ACP63_SDW0_DMA_MAX_STREAMS] = { {ACP_AUDIO0_TX_DMA_SIZE, ACP_AUDIO0_TX_FIFOADDR, ACP_AUDIO0_TX_FIFOSIZE, ACP_AUDIO0_TX_RINGBUFSIZE, ACP_AUDIO0_TX_RINGBUFADDR, ACP_AUDIO0_TX_INTR_WATERMARK_SIZE, ACP_AUDIO0_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_TX_LINEARPOSITIONCNTR_HIGH}, @@ -44,7 +44,7 @@ static struct sdw_dma_ring_buf_reg sdw0_dma_ring_buf_reg[ACP63_SDW0_DMA_MAX_STRE * For TX/RX streams DMA registers programming for SDW1 instance, it uses ACP_P1_AUDIO1 register * set as per hardware register documentation */ -static struct sdw_dma_ring_buf_reg sdw1_dma_ring_buf_reg[ACP63_SDW1_DMA_MAX_STREAMS] = { +static struct sdw_dma_ring_buf_reg acp63_sdw1_dma_reg[ACP63_SDW1_DMA_MAX_STREAMS] = { {ACP_P1_AUDIO1_TX_DMA_SIZE, ACP_P1_AUDIO1_TX_FIFOADDR, ACP_P1_AUDIO1_TX_FIFOSIZE, ACP_P1_AUDIO1_TX_RINGBUFSIZE, ACP_P1_AUDIO1_TX_RINGBUFADDR, ACP_P1_AUDIO1_TX_INTR_WATERMARK_SIZE, @@ -55,7 +55,7 @@ static struct sdw_dma_ring_buf_reg sdw1_dma_ring_buf_reg[ACP63_SDW1_DMA_MAX_STRE ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH}, };
-static u32 sdw0_dma_enable_reg[ACP63_SDW0_DMA_MAX_STREAMS] = { +static u32 acp63_sdw0_dma_enable_reg[ACP63_SDW0_DMA_MAX_STREAMS] = { ACP_SW0_AUDIO0_TX_EN, ACP_SW0_AUDIO1_TX_EN, ACP_SW0_AUDIO2_TX_EN, @@ -70,7 +70,7 @@ static u32 sdw0_dma_enable_reg[ACP63_SDW0_DMA_MAX_STREAMS] = { * it uses ACP_SW1_AUDIO1_TX_EN and ACP_SW1_AUDIO1_RX_EN registers * as per hardware register documentation. */ -static u32 sdw1_dma_enable_reg[ACP63_SDW1_DMA_MAX_STREAMS] = { +static u32 acp63_sdw1_dma_enable_reg[ACP63_SDW1_DMA_MAX_STREAMS] = { ACP_SW1_AUDIO1_TX_EN, ACP_SW1_AUDIO1_RX_EN, }; @@ -117,8 +117,8 @@ static const struct snd_pcm_hardware acp63_sdw_hardware_capture = { static void acp63_enable_disable_sdw_dma_interrupts(void __iomem *acp_base, bool enable) { u32 ext_intr_cntl, ext_intr_cntl1; - u32 irq_mask = ACP_SDW_DMA_IRQ_MASK; - u32 irq_mask1 = ACP_P1_SDW_DMA_IRQ_MASK; + u32 irq_mask = ACP63_SDW_DMA_IRQ_MASK; + u32 irq_mask1 = ACP63_P1_SDW_DMA_IRQ_MASK;
if (enable) { ext_intr_cntl = readl(acp_base + ACP_EXTERNAL_INTR_CNTL); @@ -182,18 +182,18 @@ static int acp63_configure_sdw_ringbuffer(void __iomem *acp_base, u32 stream_id,
switch (manager_instance) { case ACP_SDW0: - reg_dma_size = sdw0_dma_ring_buf_reg[stream_id].reg_dma_size; - reg_fifo_addr = sdw0_dma_ring_buf_reg[stream_id].reg_fifo_addr; - reg_fifo_size = sdw0_dma_ring_buf_reg[stream_id].reg_fifo_size; - reg_ring_buf_size = sdw0_dma_ring_buf_reg[stream_id].reg_ring_buf_size; - reg_ring_buf_addr = sdw0_dma_ring_buf_reg[stream_id].reg_ring_buf_addr; + reg_dma_size = acp63_sdw0_dma_reg[stream_id].reg_dma_size; + reg_fifo_addr = acp63_sdw0_dma_reg[stream_id].reg_fifo_addr; + reg_fifo_size = acp63_sdw0_dma_reg[stream_id].reg_fifo_size; + reg_ring_buf_size = acp63_sdw0_dma_reg[stream_id].reg_ring_buf_size; + reg_ring_buf_addr = acp63_sdw0_dma_reg[stream_id].reg_ring_buf_addr; break; case ACP_SDW1: - reg_dma_size = sdw1_dma_ring_buf_reg[stream_id].reg_dma_size; - reg_fifo_addr = sdw1_dma_ring_buf_reg[stream_id].reg_fifo_addr; - reg_fifo_size = sdw1_dma_ring_buf_reg[stream_id].reg_fifo_size; - reg_ring_buf_size = sdw1_dma_ring_buf_reg[stream_id].reg_ring_buf_size; - reg_ring_buf_addr = sdw1_dma_ring_buf_reg[stream_id].reg_ring_buf_addr; + reg_dma_size = acp63_sdw1_dma_reg[stream_id].reg_dma_size; + reg_fifo_addr = acp63_sdw1_dma_reg[stream_id].reg_fifo_addr; + reg_fifo_size = acp63_sdw1_dma_reg[stream_id].reg_fifo_size; + reg_ring_buf_size = acp63_sdw1_dma_reg[stream_id].reg_ring_buf_size; + reg_ring_buf_addr = acp63_sdw1_dma_reg[stream_id].reg_ring_buf_addr; break; default: return -EINVAL; @@ -267,19 +267,19 @@ static int acp63_sdw_dma_hw_params(struct snd_soc_component *component, stream_id = stream->stream_id; switch (stream->instance) { case ACP_SDW0: - sdw_data->sdw0_dma_stream[stream_id] = substream; - water_mark_size_reg = sdw0_dma_ring_buf_reg[stream_id].water_mark_size_reg; + sdw_data->acp63_sdw0_dma_stream[stream_id] = substream; + water_mark_size_reg = acp63_sdw0_dma_reg[stream_id].water_mark_size_reg; acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - irq_mask = BIT(SDW0_DMA_TX_IRQ_MASK(stream_id)); + irq_mask = BIT(ACP63_SDW0_DMA_TX_IRQ_MASK(stream_id)); else - irq_mask = BIT(SDW0_DMA_RX_IRQ_MASK(stream_id)); + irq_mask = BIT(ACP63_SDW0_DMA_RX_IRQ_MASK(stream_id)); break; case ACP_SDW1: - sdw_data->sdw1_dma_stream[stream_id] = substream; + sdw_data->acp63_sdw1_dma_stream[stream_id] = substream; acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL1; - water_mark_size_reg = sdw1_dma_ring_buf_reg[stream_id].water_mark_size_reg; - irq_mask = BIT(SDW1_DMA_IRQ_MASK(stream_id)); + water_mark_size_reg = acp63_sdw1_dma_reg[stream_id].water_mark_size_reg; + irq_mask = BIT(ACP63_SDW1_DMA_IRQ_MASK(stream_id)); break; default: return -EINVAL; @@ -310,12 +310,12 @@ static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __io byte_count.bytescount = 0; switch (stream->instance) { case ACP_SDW0: - pos_low_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_low_reg; - pos_high_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_high_reg; + pos_low_reg = acp63_sdw0_dma_reg[stream->stream_id].pos_low_reg; + pos_high_reg = acp63_sdw0_dma_reg[stream->stream_id].pos_high_reg; break; case ACP_SDW1: - pos_low_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_low_reg; - pos_high_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_high_reg; + pos_low_reg = acp63_sdw1_dma_reg[stream->stream_id].pos_low_reg; + pos_high_reg = acp63_sdw1_dma_reg[stream->stream_id].pos_high_reg; break; default: goto POINTER_RETURN_BYTES; @@ -369,10 +369,10 @@ static int acp63_sdw_dma_close(struct snd_soc_component *component, return -EINVAL; switch (stream->instance) { case ACP_SDW0: - sdw_data->sdw0_dma_stream[stream->stream_id] = NULL; + sdw_data->acp63_sdw0_dma_stream[stream->stream_id] = NULL; break; case ACP_SDW1: - sdw_data->sdw1_dma_stream[stream->stream_id] = NULL; + sdw_data->acp63_sdw1_dma_stream[stream->stream_id] = NULL; break; default: return -EINVAL; @@ -395,10 +395,10 @@ static int acp63_sdw_dma_enable(struct snd_pcm_substream *substream, stream_id = stream->stream_id; switch (stream->instance) { case ACP_SDW0: - sdw_dma_en_reg = sdw0_dma_enable_reg[stream_id]; + sdw_dma_en_reg = acp63_sdw0_dma_enable_reg[stream_id]; break; case ACP_SDW1: - sdw_dma_en_reg = sdw1_dma_enable_reg[stream_id]; + sdw_dma_en_reg = acp63_sdw1_dma_enable_reg[stream_id]; break; default: return -EINVAL; @@ -512,13 +512,11 @@ static int acp_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data)
for (index = 0; index < stream_count; index++) { if (instance == ACP_SDW0) { - substream = sdw_data->sdw0_dma_stream[index]; - water_mark_size_reg = - sdw0_dma_ring_buf_reg[index].water_mark_size_reg; + substream = sdw_data->acp63_sdw0_dma_stream[index]; + water_mark_size_reg = acp63_sdw0_dma_reg[index].water_mark_size_reg; } else { - substream = sdw_data->sdw1_dma_stream[index]; - water_mark_size_reg = - sdw1_dma_ring_buf_reg[index].water_mark_size_reg; + substream = sdw_data->acp63_sdw1_dma_stream[index]; + water_mark_size_reg = acp63_sdw1_dma_reg[index].water_mark_size_reg; }
if (substream && substream->runtime) {

Use macro for ACP6.3 PCI revision id instead of hard coded value.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/acp63.h | 1 + sound/soc/amd/ps/pci-ps.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 01910273624b..8f3a597f658b 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -11,6 +11,7 @@ #define ACP_DEVICE_ID 0x15E2 #define ACP63_REG_START 0x1240000 #define ACP63_REG_END 0x125C000 +#define ACP63_PCI_REV 0x63
#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001 #define ACP63_PGFSM_CNTL_POWER_ON_MASK 1 diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index f5beb7f14913..9cc66a807ad9 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -562,7 +562,7 @@ static int snd_acp63_probe(struct pci_dev *pci,
/* Pink Sardine device check */ switch (pci->revision) { - case 0x63: + case ACP63_PCI_REV: break; default: dev_dbg(&pci->dev, "acp63 pci device not found\n");

Add ACP6.3 platform specific PCI driver hw_ops for acp init/de-init sequence.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/Makefile | 2 +- sound/soc/amd/ps/acp63.h | 32 ++++++++++ sound/soc/amd/ps/pci-ps.c | 118 +++++++++-------------------------- sound/soc/amd/ps/ps-common.c | 104 ++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 89 deletions(-) create mode 100644 sound/soc/amd/ps/ps-common.c
diff --git a/sound/soc/amd/ps/Makefile b/sound/soc/amd/ps/Makefile index b5efb1c5382c..778ee4726389 100644 --- a/sound/soc/amd/ps/Makefile +++ b/sound/soc/amd/ps/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only # Pink Sardine platform Support -snd-pci-ps-y := pci-ps.o +snd-pci-ps-y := pci-ps.o ps-common.o snd-ps-pdm-dma-y := ps-pdm-dma.o snd-soc-ps-mach-y := ps-mach.o snd-ps-sdw-dma-y := ps-sdw-dma.o diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 8f3a597f658b..ec22a7dad6ac 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -130,6 +130,8 @@ #define SDW_MAX_BUFFER (SDW_PLAYBACK_MAX_PERIOD_SIZE * SDW_PLAYBACK_MAX_NUM_PERIODS) #define SDW_MIN_BUFFER SDW_MAX_BUFFER
+#define ACP_HW_OPS(acp_data, cb) ((acp_data)->hw_ops->cb) + enum acp_config { ACP_CONFIG_0 = 0, ACP_CONFIG_1, @@ -213,10 +215,23 @@ struct sdw_dma_ring_buf_reg { u32 pos_high_reg; };
+struct acp63_dev_data; + +/** + * struct acp_hw_ops - ACP PCI driver platform specific ops + * @acp_init: ACP initialization + * @acp_deinit: ACP de-initialization + */ +struct acp_hw_ops { + int (*acp_init)(void __iomem *acp_base, struct device *dev); + int (*acp_deinit)(void __iomem *acp_base, struct device *dev); +}; + /** * struct acp63_dev_data - acp pci driver context * @acp63_base: acp mmio base * @res: resource + * @hw_ops: ACP pci driver platform-specific ops * @pdm_dev: ACP PDM controller platform device * @dmic_codec: platform device for DMIC Codec * sdw_dma_dev: platform device for SoundWire DMA controller @@ -242,6 +257,7 @@ struct sdw_dma_ring_buf_reg { struct acp63_dev_data { void __iomem *acp63_base; struct resource *res; + struct acp_hw_ops *hw_ops; struct platform_device *pdm_dev; struct platform_device *dmic_codec_dev; struct platform_device *sdw_dma_dev; @@ -263,4 +279,20 @@ struct acp63_dev_data { u16 acp63_sdw1_dma_intr_stat[ACP63_SDW1_DMA_MAX_STREAMS]; };
+void acp63_hw_init_ops(struct acp_hw_ops *hw_ops); + +static inline int acp_hw_init(struct acp63_dev_data *adata, struct device *dev) +{ + if (adata && adata->hw_ops && adata->hw_ops->acp_init) + return ACP_HW_OPS(adata, acp_init)(adata->acp63_base, dev); + return -EOPNOTSUPP; +} + +static inline int acp_hw_deinit(struct acp63_dev_data *adata, struct device *dev) +{ + if (adata && adata->hw_ops && adata->hw_ops->acp_deinit) + return ACP_HW_OPS(adata, acp_deinit)(adata->acp63_base, dev); + return -EOPNOTSUPP; +} + int snd_amd_acp_find_config(struct pci_dev *pci); diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 9cc66a807ad9..120bab1844bb 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -21,87 +21,6 @@
#include "acp63.h"
-static int acp63_power_on(void __iomem *acp_base) -{ - u32 val; - - val = readl(acp_base + ACP_PGFSM_STATUS); - - if (!val) - return val; - - if ((val & ACP63_PGFSM_STATUS_MASK) != ACP63_POWER_ON_IN_PROGRESS) - writel(ACP63_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL); - - return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP63_TIMEOUT); -} - -static int acp63_reset(void __iomem *acp_base) -{ - u32 val; - int ret; - - writel(1, acp_base + ACP_SOFT_RESET); - - ret = readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, - val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK, - DELAY_US, ACP63_TIMEOUT); - if (ret) - return ret; - - writel(0, acp_base + ACP_SOFT_RESET); - - return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP63_TIMEOUT); -} - -static void acp63_enable_interrupts(void __iomem *acp_base) -{ - writel(1, acp_base + ACP_EXTERNAL_INTR_ENB); - writel(ACP_ERROR_IRQ, acp_base + ACP_EXTERNAL_INTR_CNTL); -} - -static void acp63_disable_interrupts(void __iomem *acp_base) -{ - writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base + ACP_EXTERNAL_INTR_STAT); - writel(0, acp_base + ACP_EXTERNAL_INTR_CNTL); - writel(0, acp_base + ACP_EXTERNAL_INTR_ENB); -} - -static int acp63_init(void __iomem *acp_base, struct device *dev) -{ - int ret; - - ret = acp63_power_on(acp_base); - if (ret) { - dev_err(dev, "ACP power on failed\n"); - return ret; - } - writel(0x01, acp_base + ACP_CONTROL); - ret = acp63_reset(acp_base); - if (ret) { - dev_err(dev, "ACP reset failed\n"); - return ret; - } - acp63_enable_interrupts(acp_base); - writel(0, acp_base + ACP_ZSC_DSP_CTRL); - return 0; -} - -static int acp63_deinit(void __iomem *acp_base, struct device *dev) -{ - int ret; - - acp63_disable_interrupts(acp_base); - ret = acp63_reset(acp_base); - if (ret) { - dev_err(dev, "ACP reset failed\n"); - return ret; - } - writel(0, acp_base + ACP_CONTROL); - writel(1, acp_base + ACP_ZSC_DSP_CTRL); - return 0; -} - static irqreturn_t acp63_irq_thread(int irq, void *context) { struct sdw_dma_dev_data *sdw_data; @@ -540,11 +459,29 @@ static int create_acp63_platform_devs(struct pci_dev *pci, struct acp63_dev_data unregister_pdm_dev: platform_device_unregister(adata->pdm_dev); de_init: - if (acp63_deinit(adata->acp63_base, &pci->dev)) + if (acp_hw_deinit(adata, &pci->dev)) dev_err(&pci->dev, "ACP de-init failed\n"); return ret; }
+static int acp_hw_init_ops(struct acp63_dev_data *adata, struct pci_dev *pci) +{ + adata->hw_ops = devm_kzalloc(&pci->dev, sizeof(struct acp_hw_ops), + GFP_KERNEL); + if (!adata->hw_ops) + return -ENOMEM; + + switch (adata->acp_rev) { + case ACP63_PCI_REV: + acp63_hw_init_ops(adata->hw_ops); + break; + default: + dev_err(&pci->dev, "ACP device not found\n"); + return -ENODEV; + } + return 0; +} + static int snd_acp63_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { @@ -598,7 +535,12 @@ static int snd_acp63_probe(struct pci_dev *pci, pci_set_master(pci); pci_set_drvdata(pci, adata); mutex_init(&adata->acp_lock); - ret = acp63_init(adata->acp63_base, &pci->dev); + ret = acp_hw_init_ops(adata, pci); + if (ret) { + dev_err(&pci->dev, "ACP hw ops init failed\n"); + goto release_regions; + } + ret = acp_hw_init(adata, &pci->dev); if (ret) goto release_regions; ret = devm_request_threaded_irq(&pci->dev, pci->irq, acp63_irq_handler, @@ -632,7 +574,7 @@ static int snd_acp63_probe(struct pci_dev *pci, pm_runtime_allow(&pci->dev); return 0; de_init: - if (acp63_deinit(adata->acp63_base, &pci->dev)) + if (acp_hw_deinit(adata, &pci->dev)) dev_err(&pci->dev, "ACP de-init failed\n"); release_regions: pci_release_regions(pci); @@ -677,7 +619,7 @@ static int __maybe_unused snd_acp63_suspend(struct device *dev) return 0; } } - ret = acp63_deinit(adata->acp63_base, dev); + ret = acp_hw_deinit(adata, dev); if (ret) dev_err(dev, "ACP de-init failed\n");
@@ -694,7 +636,7 @@ static int __maybe_unused snd_acp63_runtime_resume(struct device *dev) writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); return 0; } - ret = acp63_init(adata->acp63_base, dev); + ret = acp_hw_init(adata, dev); if (ret) { dev_err(dev, "ACP init failed\n"); return ret; @@ -716,7 +658,7 @@ static int __maybe_unused snd_acp63_resume(struct device *dev) return 0; }
- ret = acp63_init(adata->acp63_base, dev); + ret = acp_hw_deinit(adata, dev); if (ret) dev_err(dev, "ACP init failed\n");
@@ -744,7 +686,7 @@ static void snd_acp63_remove(struct pci_dev *pci) } if (adata->mach_dev) platform_device_unregister(adata->mach_dev); - ret = acp63_deinit(adata->acp63_base, &pci->dev); + ret = acp_hw_deinit(adata, &pci->dev); if (ret) dev_err(&pci->dev, "ACP de-init failed\n"); pm_runtime_forbid(&pci->dev); diff --git a/sound/soc/amd/ps/ps-common.c b/sound/soc/amd/ps/ps-common.c new file mode 100644 index 000000000000..771249a76537 --- /dev/null +++ b/sound/soc/amd/ps/ps-common.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * AMD ACP PCI driver callback routines for ACP6.3, ACP7.0 & ACP7.1 + * platforms. + * + * Copyright 2025 Advanced Micro Devices, Inc. + * Authors: Vijendar Mukunda Vijendar.Mukunda@amd.com + */ + +#include <linux/bitops.h> +#include <linux/delay.h> +#include <linux/export.h> +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/platform_device.h> + +#include "acp63.h" + +static int acp63_power_on(void __iomem *acp_base) +{ + u32 val; + + val = readl(acp_base + ACP_PGFSM_STATUS); + + if (!val) + return val; + + if ((val & ACP63_PGFSM_STATUS_MASK) != ACP63_POWER_ON_IN_PROGRESS) + writel(ACP63_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL); + + return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP63_TIMEOUT); +} + +static int acp63_reset(void __iomem *acp_base) +{ + u32 val; + int ret; + + writel(1, acp_base + ACP_SOFT_RESET); + + ret = readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, + val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK, + DELAY_US, ACP63_TIMEOUT); + if (ret) + return ret; + + writel(0, acp_base + ACP_SOFT_RESET); + + return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP63_TIMEOUT); +} + +static void acp63_enable_interrupts(void __iomem *acp_base) +{ + writel(1, acp_base + ACP_EXTERNAL_INTR_ENB); + writel(ACP_ERROR_IRQ, acp_base + ACP_EXTERNAL_INTR_CNTL); +} + +static void acp63_disable_interrupts(void __iomem *acp_base) +{ + writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base + ACP_EXTERNAL_INTR_STAT); + writel(0, acp_base + ACP_EXTERNAL_INTR_CNTL); + writel(0, acp_base + ACP_EXTERNAL_INTR_ENB); +} + +static int acp63_init(void __iomem *acp_base, struct device *dev) +{ + int ret; + + ret = acp63_power_on(acp_base); + if (ret) { + dev_err(dev, "ACP power on failed\n"); + return ret; + } + writel(0x01, acp_base + ACP_CONTROL); + ret = acp63_reset(acp_base); + if (ret) { + dev_err(dev, "ACP reset failed\n"); + return ret; + } + acp63_enable_interrupts(acp_base); + writel(0, acp_base + ACP_ZSC_DSP_CTRL); + return 0; +} + +static int acp63_deinit(void __iomem *acp_base, struct device *dev) +{ + int ret; + + acp63_disable_interrupts(acp_base); + ret = acp63_reset(acp_base); + if (ret) { + dev_err(dev, "ACP reset failed\n"); + return ret; + } + writel(0, acp_base + ACP_CONTROL); + writel(1, acp_base + ACP_ZSC_DSP_CTRL); + return 0; +} + +void acp63_hw_init_ops(struct acp_hw_ops *hw_ops) +{ + hw_ops->acp_init = acp63_init; + hw_ops->acp_deinit = acp63_deinit; +}

Add acp pci driver pm ops related callback functions for ACP6.3 platform.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/acp63.h | 44 ++++++++++++++++++ sound/soc/amd/ps/pci-ps.c | 82 ++++------------------------------ sound/soc/amd/ps/ps-common.c | 86 ++++++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+), 74 deletions(-)
diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index ec22a7dad6ac..4e3f7eaac040 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -221,10 +221,18 @@ struct acp63_dev_data; * struct acp_hw_ops - ACP PCI driver platform specific ops * @acp_init: ACP initialization * @acp_deinit: ACP de-initialization + * acp_suspend: ACP system level suspend callback + * acp_resume: ACP system level resume callback + * acp_suspend_runtime: ACP runtime suspend callback + * acp_resume_runtime: ACP runtime resume callback */ struct acp_hw_ops { int (*acp_init)(void __iomem *acp_base, struct device *dev); int (*acp_deinit)(void __iomem *acp_base, struct device *dev); + int (*acp_suspend)(struct device *dev); + int (*acp_resume)(struct device *dev); + int (*acp_suspend_runtime)(struct device *dev); + int (*acp_resume_runtime)(struct device *dev); };
/** @@ -295,4 +303,40 @@ static inline int acp_hw_deinit(struct acp63_dev_data *adata, struct device *dev return -EOPNOTSUPP; }
+static inline int acp_hw_suspend(struct device *dev) +{ + struct acp63_dev_data *adata = dev_get_drvdata(dev); + + if (adata && adata->hw_ops && adata->hw_ops->acp_suspend) + return ACP_HW_OPS(adata, acp_suspend)(dev); + return -EOPNOTSUPP; +} + +static inline int acp_hw_resume(struct device *dev) +{ + struct acp63_dev_data *adata = dev_get_drvdata(dev); + + if (adata && adata->hw_ops && adata->hw_ops->acp_resume) + return ACP_HW_OPS(adata, acp_resume)(dev); + return -EOPNOTSUPP; +} + +static inline int acp_hw_suspend_runtime(struct device *dev) +{ + struct acp63_dev_data *adata = dev_get_drvdata(dev); + + if (adata && adata->hw_ops && adata->hw_ops->acp_suspend_runtime) + return ACP_HW_OPS(adata, acp_suspend_runtime)(dev); + return -EOPNOTSUPP; +} + +static inline int acp_hw_runtime_resume(struct device *dev) +{ + struct acp63_dev_data *adata = dev_get_drvdata(dev); + + if (adata && adata->hw_ops && adata->hw_ops->acp_resume_runtime) + return ACP_HW_OPS(adata, acp_resume_runtime)(dev); + return -EOPNOTSUPP; +} + int snd_amd_acp_find_config(struct pci_dev *pci); diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 120bab1844bb..a37fb6172958 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -584,90 +584,24 @@ static int snd_acp63_probe(struct pci_dev *pci, return ret; }
-static bool check_acp_sdw_enable_status(struct acp63_dev_data *adata) +static int __maybe_unused snd_acp_suspend(struct device *dev) { - u32 sdw0_en, sdw1_en; - - sdw0_en = readl(adata->acp63_base + ACP_SW0_EN); - sdw1_en = readl(adata->acp63_base + ACP_SW1_EN); - return (sdw0_en || sdw1_en); + return acp_hw_suspend(dev); }
-static void handle_acp63_sdw_pme_event(struct acp63_dev_data *adata) +static int __maybe_unused snd_acp_runtime_resume(struct device *dev) { - u32 val; - - val = readl(adata->acp63_base + ACP_SW0_WAKE_EN); - if (val && adata->sdw->pdev[0]) - pm_request_resume(&adata->sdw->pdev[0]->dev); - - val = readl(adata->acp63_base + ACP_SW1_WAKE_EN); - if (val && adata->sdw->pdev[1]) - pm_request_resume(&adata->sdw->pdev[1]->dev); + return acp_hw_runtime_resume(dev); }
-static int __maybe_unused snd_acp63_suspend(struct device *dev) +static int __maybe_unused snd_acp_resume(struct device *dev) { - struct acp63_dev_data *adata; - int ret; - - adata = dev_get_drvdata(dev); - if (adata->is_sdw_dev) { - adata->sdw_en_stat = check_acp_sdw_enable_status(adata); - if (adata->sdw_en_stat) { - writel(1, adata->acp63_base + ACP_ZSC_DSP_CTRL); - return 0; - } - } - ret = acp_hw_deinit(adata, dev); - if (ret) - dev_err(dev, "ACP de-init failed\n"); - - return ret; -} - -static int __maybe_unused snd_acp63_runtime_resume(struct device *dev) -{ - struct acp63_dev_data *adata; - int ret; - - adata = dev_get_drvdata(dev); - if (adata->sdw_en_stat) { - writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); - return 0; - } - ret = acp_hw_init(adata, dev); - if (ret) { - dev_err(dev, "ACP init failed\n"); - return ret; - } - - if (!adata->sdw_en_stat) - handle_acp63_sdw_pme_event(adata); - return 0; -} - -static int __maybe_unused snd_acp63_resume(struct device *dev) -{ - struct acp63_dev_data *adata; - int ret; - - adata = dev_get_drvdata(dev); - if (adata->sdw_en_stat) { - writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); - return 0; - } - - ret = acp_hw_deinit(adata, dev); - if (ret) - dev_err(dev, "ACP init failed\n"); - - return ret; + return acp_hw_resume(dev); }
static const struct dev_pm_ops acp63_pm_ops = { - SET_RUNTIME_PM_OPS(snd_acp63_suspend, snd_acp63_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(snd_acp63_suspend, snd_acp63_resume) + SET_RUNTIME_PM_OPS(snd_acp_suspend, snd_acp_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(snd_acp_suspend, snd_acp_resume) };
static void snd_acp63_remove(struct pci_dev *pci) diff --git a/sound/soc/amd/ps/ps-common.c b/sound/soc/amd/ps/ps-common.c index 771249a76537..7643f321be37 100644 --- a/sound/soc/amd/ps/ps-common.c +++ b/sound/soc/amd/ps/ps-common.c @@ -13,6 +13,7 @@ #include <linux/io.h> #include <linux/iopoll.h> #include <linux/platform_device.h> +#include <linux/pm_runtime.h>
#include "acp63.h"
@@ -97,8 +98,93 @@ static int acp63_deinit(void __iomem *acp_base, struct device *dev) return 0; }
+static bool check_acp_sdw_enable_status(struct acp63_dev_data *adata) +{ + u32 sdw0_en, sdw1_en; + + sdw0_en = readl(adata->acp63_base + ACP_SW0_EN); + sdw1_en = readl(adata->acp63_base + ACP_SW1_EN); + return (sdw0_en || sdw1_en); +} + +static void handle_acp63_sdw_pme_event(struct acp63_dev_data *adata) +{ + u32 val; + + val = readl(adata->acp63_base + ACP_SW0_WAKE_EN); + if (val && adata->sdw->pdev[0]) + pm_request_resume(&adata->sdw->pdev[0]->dev); + + val = readl(adata->acp63_base + ACP_SW1_WAKE_EN); + if (val && adata->sdw->pdev[1]) + pm_request_resume(&adata->sdw->pdev[1]->dev); +} + +static int __maybe_unused snd_acp63_suspend(struct device *dev) +{ + struct acp63_dev_data *adata; + int ret; + + adata = dev_get_drvdata(dev); + if (adata->is_sdw_dev) { + adata->sdw_en_stat = check_acp_sdw_enable_status(adata); + if (adata->sdw_en_stat) { + writel(1, adata->acp63_base + ACP_ZSC_DSP_CTRL); + return 0; + } + } + ret = acp_hw_deinit(adata, dev); + if (ret) + dev_err(dev, "ACP de-init failed\n"); + + return ret; +} + +static int __maybe_unused snd_acp63_runtime_resume(struct device *dev) +{ + struct acp63_dev_data *adata; + int ret; + + adata = dev_get_drvdata(dev); + if (adata->sdw_en_stat) { + writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); + return 0; + } + ret = acp_hw_init(adata, dev); + if (ret) { + dev_err(dev, "ACP init failed\n"); + return ret; + } + + if (!adata->sdw_en_stat) + handle_acp63_sdw_pme_event(adata); + return 0; +} + +static int __maybe_unused snd_acp63_resume(struct device *dev) +{ + struct acp63_dev_data *adata; + int ret; + + adata = dev_get_drvdata(dev); + if (adata->sdw_en_stat) { + writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); + return 0; + } + + ret = acp_hw_init(adata, dev); + if (ret) + dev_err(dev, "ACP init failed\n"); + + return ret; +} + void acp63_hw_init_ops(struct acp_hw_ops *hw_ops) { hw_ops->acp_init = acp63_init; hw_ops->acp_deinit = acp63_deinit; + hw_ops->acp_suspend = snd_acp63_suspend; + hw_ops->acp_resume = snd_acp63_resume; + hw_ops->acp_suspend_runtime = snd_acp63_suspend; + hw_ops->acp_resume_runtime = snd_acp63_runtime_resume; }

Add pci driver callback to read acp pin configuration for ACP6.3 platform.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/acp63.h | 8 ++++++++ sound/soc/amd/ps/pci-ps.c | 26 +------------------------- sound/soc/amd/ps/ps-common.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 25 deletions(-)
diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 4e3f7eaac040..a918a988e4d8 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -221,6 +221,7 @@ struct acp63_dev_data; * struct acp_hw_ops - ACP PCI driver platform specific ops * @acp_init: ACP initialization * @acp_deinit: ACP de-initialization + * @acp_get_config: function to read the acp pin configuration * acp_suspend: ACP system level suspend callback * acp_resume: ACP system level resume callback * acp_suspend_runtime: ACP runtime suspend callback @@ -229,6 +230,7 @@ struct acp63_dev_data; struct acp_hw_ops { int (*acp_init)(void __iomem *acp_base, struct device *dev); int (*acp_deinit)(void __iomem *acp_base, struct device *dev); + void (*acp_get_config)(struct pci_dev *pci, struct acp63_dev_data *acp_data); int (*acp_suspend)(struct device *dev); int (*acp_resume)(struct device *dev); int (*acp_suspend_runtime)(struct device *dev); @@ -303,6 +305,12 @@ static inline int acp_hw_deinit(struct acp63_dev_data *adata, struct device *dev return -EOPNOTSUPP; }
+static inline void acp_hw_get_config(struct pci_dev *pci, struct acp63_dev_data *adata) +{ + if (adata && adata->hw_ops && adata->hw_ops->acp_get_config) + ACP_HW_OPS(adata, acp_get_config)(pci, adata); +} + static inline int acp_hw_suspend(struct device *dev) { struct acp63_dev_data *adata = dev_get_drvdata(dev); diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index a37fb6172958..96399acf906c 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -299,7 +299,6 @@ static int get_acp63_device_config(struct pci_dev *pci, struct acp63_dev_data *a const union acpi_object *obj; acpi_handle handle; acpi_integer dmic_status; - u32 config; bool is_dmic_dev = false; bool is_sdw_dev = false; bool wov_en, dmic_en; @@ -309,30 +308,7 @@ static int get_acp63_device_config(struct pci_dev *pci, struct acp63_dev_data *a wov_en = true; dmic_en = false;
- config = readl(acp_data->acp63_base + ACP_PIN_CONFIG); - switch (config) { - case ACP_CONFIG_4: - case ACP_CONFIG_5: - case ACP_CONFIG_10: - case ACP_CONFIG_11: - acp_data->is_pdm_config = true; - break; - case ACP_CONFIG_2: - case ACP_CONFIG_3: - acp_data->is_sdw_config = true; - break; - case ACP_CONFIG_6: - case ACP_CONFIG_7: - case ACP_CONFIG_12: - case ACP_CONFIG_8: - case ACP_CONFIG_13: - case ACP_CONFIG_14: - acp_data->is_pdm_config = true; - acp_data->is_sdw_config = true; - break; - default: - break; - } + acp_hw_get_config(pci, acp_data);
if (acp_data->is_pdm_config) { pdm_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), ACP63_DMIC_ADDR, 0); diff --git a/sound/soc/amd/ps/ps-common.c b/sound/soc/amd/ps/ps-common.c index 7643f321be37..30e9e5fe034b 100644 --- a/sound/soc/amd/ps/ps-common.c +++ b/sound/soc/amd/ps/ps-common.c @@ -12,6 +12,7 @@ #include <linux/export.h> #include <linux/io.h> #include <linux/iopoll.h> +#include <linux/pci.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h>
@@ -98,6 +99,37 @@ static int acp63_deinit(void __iomem *acp_base, struct device *dev) return 0; }
+static void acp63_get_config(struct pci_dev *pci, struct acp63_dev_data *acp_data) +{ + u32 config; + + config = readl(acp_data->acp63_base + ACP_PIN_CONFIG); + dev_dbg(&pci->dev, "ACP config value: %d\n", config); + switch (config) { + case ACP_CONFIG_4: + case ACP_CONFIG_5: + case ACP_CONFIG_10: + case ACP_CONFIG_11: + acp_data->is_pdm_config = true; + break; + case ACP_CONFIG_2: + case ACP_CONFIG_3: + acp_data->is_sdw_config = true; + break; + case ACP_CONFIG_6: + case ACP_CONFIG_7: + case ACP_CONFIG_12: + case ACP_CONFIG_8: + case ACP_CONFIG_13: + case ACP_CONFIG_14: + acp_data->is_pdm_config = true; + acp_data->is_sdw_config = true; + break; + default: + break; + } +} + static bool check_acp_sdw_enable_status(struct acp63_dev_data *adata) { u32 sdw0_en, sdw1_en; @@ -183,6 +215,7 @@ void acp63_hw_init_ops(struct acp_hw_ops *hw_ops) { hw_ops->acp_init = acp63_init; hw_ops->acp_deinit = acp63_deinit; + hw_ops->acp_get_config = acp63_get_config; hw_ops->acp_suspend = snd_acp63_suspend; hw_ops->acp_resume = snd_acp63_resume; hw_ops->acp_suspend_runtime = snd_acp63_suspend;

Add acp pci driver Soundwire DMA irq thread callaback for ACP6.3 platform.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/acp63.h | 8 ++++++++ sound/soc/amd/ps/pci-ps.c | 19 +------------------ sound/soc/amd/ps/ps-common.c | 25 +++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 18 deletions(-)
diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index a918a988e4d8..9a20846d30ff 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -222,6 +222,7 @@ struct acp63_dev_data; * @acp_init: ACP initialization * @acp_deinit: ACP de-initialization * @acp_get_config: function to read the acp pin configuration + * @acp_sdw_dma_irq_thread: ACP SoundWire DMA interrupt thread * acp_suspend: ACP system level suspend callback * acp_resume: ACP system level resume callback * acp_suspend_runtime: ACP runtime suspend callback @@ -231,6 +232,7 @@ struct acp_hw_ops { int (*acp_init)(void __iomem *acp_base, struct device *dev); int (*acp_deinit)(void __iomem *acp_base, struct device *dev); void (*acp_get_config)(struct pci_dev *pci, struct acp63_dev_data *acp_data); + void (*acp_sdw_dma_irq_thread)(struct acp63_dev_data *acp_data); int (*acp_suspend)(struct device *dev); int (*acp_resume)(struct device *dev); int (*acp_suspend_runtime)(struct device *dev); @@ -311,6 +313,12 @@ static inline void acp_hw_get_config(struct pci_dev *pci, struct acp63_dev_data ACP_HW_OPS(adata, acp_get_config)(pci, adata); }
+static inline void acp_hw_sdw_dma_irq_thread(struct acp63_dev_data *adata) +{ + if (adata && adata->hw_ops && adata->hw_ops->acp_sdw_dma_irq_thread) + ACP_HW_OPS(adata, acp_sdw_dma_irq_thread)(adata); +} + static inline int acp_hw_suspend(struct device *dev) { struct acp63_dev_data *adata = dev_get_drvdata(dev); diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 96399acf906c..5d9c230043a6 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -23,26 +23,9 @@
static irqreturn_t acp63_irq_thread(int irq, void *context) { - struct sdw_dma_dev_data *sdw_data; struct acp63_dev_data *adata = context; - u32 stream_id;
- sdw_data = dev_get_drvdata(&adata->sdw_dma_dev->dev); - - for (stream_id = 0; stream_id < ACP63_SDW0_DMA_MAX_STREAMS; stream_id++) { - if (adata->acp63_sdw0_dma_intr_stat[stream_id]) { - if (sdw_data->acp63_sdw0_dma_stream[stream_id]) - snd_pcm_period_elapsed(sdw_data->acp63_sdw0_dma_stream[stream_id]); - adata->acp63_sdw0_dma_intr_stat[stream_id] = 0; - } - } - for (stream_id = 0; stream_id < ACP63_SDW1_DMA_MAX_STREAMS; stream_id++) { - if (adata->acp63_sdw1_dma_intr_stat[stream_id]) { - if (sdw_data->acp63_sdw1_dma_stream[stream_id]) - snd_pcm_period_elapsed(sdw_data->acp63_sdw1_dma_stream[stream_id]); - adata->acp63_sdw1_dma_intr_stat[stream_id] = 0; - } - } + acp_hw_sdw_dma_irq_thread(adata); return IRQ_HANDLED; }
diff --git a/sound/soc/amd/ps/ps-common.c b/sound/soc/amd/ps/ps-common.c index 30e9e5fe034b..9098974b3608 100644 --- a/sound/soc/amd/ps/ps-common.c +++ b/sound/soc/amd/ps/ps-common.c @@ -15,6 +15,7 @@ #include <linux/pci.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <sound/pcm_params.h>
#include "acp63.h"
@@ -211,11 +212,35 @@ static int __maybe_unused snd_acp63_resume(struct device *dev) return ret; }
+static void acp63_sdw_dma_irq_thread(struct acp63_dev_data *adata) +{ + struct sdw_dma_dev_data *sdw_data; + u32 stream_id; + + sdw_data = dev_get_drvdata(&adata->sdw_dma_dev->dev); + + for (stream_id = 0; stream_id < ACP63_SDW0_DMA_MAX_STREAMS; stream_id++) { + if (adata->acp63_sdw0_dma_intr_stat[stream_id]) { + if (sdw_data->acp63_sdw0_dma_stream[stream_id]) + snd_pcm_period_elapsed(sdw_data->acp63_sdw0_dma_stream[stream_id]); + adata->acp63_sdw0_dma_intr_stat[stream_id] = 0; + } + } + for (stream_id = 0; stream_id < ACP63_SDW1_DMA_MAX_STREAMS; stream_id++) { + if (adata->acp63_sdw1_dma_intr_stat[stream_id]) { + if (sdw_data->acp63_sdw1_dma_stream[stream_id]) + snd_pcm_period_elapsed(sdw_data->acp63_sdw1_dma_stream[stream_id]); + adata->acp63_sdw1_dma_intr_stat[stream_id] = 0; + } + } +} + void acp63_hw_init_ops(struct acp_hw_ops *hw_ops) { hw_ops->acp_init = acp63_init; hw_ops->acp_deinit = acp63_deinit; hw_ops->acp_get_config = acp63_get_config; + hw_ops->acp_sdw_dma_irq_thread = acp63_sdw_dma_irq_thread; hw_ops->acp_suspend = snd_acp63_suspend; hw_ops->acp_resume = snd_acp63_resume; hw_ops->acp_suspend_runtime = snd_acp63_suspend;

Move the Soundwire DMA interrupt handling to separate function.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/pci-ps.c | 96 ++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 46 deletions(-)
diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 5d9c230043a6..04b43b4128bc 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -21,6 +21,55 @@
#include "acp63.h"
+static short int check_and_handle_sdw_dma_irq(struct acp63_dev_data *adata, u32 ext_intr_stat, + u32 ext_intr_stat1) +{ + u32 stream_id = 0; + u16 sdw_dma_irq_flag = 0; + u16 index; + + if (ext_intr_stat & ACP63_SDW_DMA_IRQ_MASK) { + for (index = ACP_AUDIO2_RX_THRESHOLD; index <= ACP_AUDIO0_TX_THRESHOLD; index++) { + if (ext_intr_stat & BIT(index)) { + writel(BIT(index), adata->acp63_base + ACP_EXTERNAL_INTR_STAT); + switch (index) { + case ACP_AUDIO0_TX_THRESHOLD: + stream_id = ACP63_SDW0_AUDIO0_TX; + break; + case ACP_AUDIO1_TX_THRESHOLD: + stream_id = ACP63_SDW0_AUDIO1_TX; + break; + case ACP_AUDIO2_TX_THRESHOLD: + stream_id = ACP63_SDW0_AUDIO2_TX; + break; + case ACP_AUDIO0_RX_THRESHOLD: + stream_id = ACP63_SDW0_AUDIO0_RX; + break; + case ACP_AUDIO1_RX_THRESHOLD: + stream_id = ACP63_SDW0_AUDIO1_RX; + break; + case ACP_AUDIO2_RX_THRESHOLD: + stream_id = ACP63_SDW0_AUDIO2_RX; + break; + } + adata->acp63_sdw0_dma_intr_stat[stream_id] = 1; + sdw_dma_irq_flag = 1; + } + } + } + if (ext_intr_stat1 & ACP63_P1_AUDIO1_RX_THRESHOLD) { + writel(ACP63_P1_AUDIO1_RX_THRESHOLD, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_RX] = 1; + sdw_dma_irq_flag = 1; + } + if (ext_intr_stat1 & ACP63_P1_AUDIO1_TX_THRESHOLD) { + writel(ACP63_P1_AUDIO1_TX_THRESHOLD, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_TX] = 1; + sdw_dma_irq_flag = 1; + } + return sdw_dma_irq_flag; +} + static irqreturn_t acp63_irq_thread(int irq, void *context) { struct acp63_dev_data *adata = context; @@ -35,10 +84,8 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id) struct pdm_dev_data *ps_pdm_data; struct amd_sdw_manager *amd_manager; u32 ext_intr_stat, ext_intr_stat1; - u32 stream_id = 0; u16 irq_flag = 0; u16 sdw_dma_irq_flag = 0; - u16 index;
adata = dev_id; if (!adata) @@ -82,51 +129,8 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id) snd_pcm_period_elapsed(ps_pdm_data->capture_stream); irq_flag = 1; } - if (ext_intr_stat & ACP63_SDW_DMA_IRQ_MASK) { - for (index = ACP_AUDIO2_RX_THRESHOLD; index <= ACP_AUDIO0_TX_THRESHOLD; index++) { - if (ext_intr_stat & BIT(index)) { - writel(BIT(index), adata->acp63_base + ACP_EXTERNAL_INTR_STAT); - switch (index) { - case ACP_AUDIO0_TX_THRESHOLD: - stream_id = ACP63_SDW0_AUDIO0_TX; - break; - case ACP_AUDIO1_TX_THRESHOLD: - stream_id = ACP63_SDW0_AUDIO1_TX; - break; - case ACP_AUDIO2_TX_THRESHOLD: - stream_id = ACP63_SDW0_AUDIO2_TX; - break; - case ACP_AUDIO0_RX_THRESHOLD: - stream_id = ACP63_SDW0_AUDIO0_RX; - break; - case ACP_AUDIO1_RX_THRESHOLD: - stream_id = ACP63_SDW0_AUDIO1_RX; - break; - case ACP_AUDIO2_RX_THRESHOLD: - stream_id = ACP63_SDW0_AUDIO2_RX; - break; - } - - adata->acp63_sdw0_dma_intr_stat[stream_id] = 1; - sdw_dma_irq_flag = 1; - } - } - } - - if (ext_intr_stat1 & ACP63_P1_AUDIO1_RX_THRESHOLD) { - writel(ACP63_P1_AUDIO1_RX_THRESHOLD, - adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); - adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_RX] = 1; - sdw_dma_irq_flag = 1; - } - - if (ext_intr_stat1 & ACP63_P1_AUDIO1_TX_THRESHOLD) { - writel(ACP63_P1_AUDIO1_TX_THRESHOLD, - adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); - adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_TX] = 1; - sdw_dma_irq_flag = 1; - }
+ sdw_dma_irq_flag = check_and_handle_sdw_dma_irq(adata, ext_intr_stat, ext_intr_stat1); if (sdw_dma_irq_flag) return IRQ_WAKE_THREAD;

Store acp pci revision id in SoundWire dma driver private data structure. It will be used to distinguish platform specific code.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/acp63.h | 1 + sound/soc/amd/ps/ps-sdw-dma.c | 1 + 2 files changed, 2 insertions(+)
diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 9a20846d30ff..098597d92bf9 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -183,6 +183,7 @@ struct pdm_dev_data { struct sdw_dma_dev_data { void __iomem *acp_base; struct mutex *acp_lock; /* used to protect acp common register access */ + u32 acp_rev; struct snd_pcm_substream *acp63_sdw0_dma_stream[ACP63_SDW0_DMA_MAX_STREAMS]; struct snd_pcm_substream *acp63_sdw1_dma_stream[ACP63_SDW1_DMA_MAX_STREAMS]; }; diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 878683619a05..b3c716371d15 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -474,6 +474,7 @@ static int acp63_sdw_platform_probe(struct platform_device *pdev) return -ENOMEM;
sdw_data->acp_lock = &acp_data->acp_lock; + sdw_data->acp_rev = acp_data->acp_rev; dev_set_drvdata(&pdev->dev, sdw_data); status = devm_snd_soc_register_component(&pdev->dev, &acp63_sdw_component,

Refactor existing SoundWire dma driver code by adding acp_rev check for ACP6.3 platform.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/ps-sdw-dma.c | 146 +++++++++++++++++++++------------- 1 file changed, 89 insertions(+), 57 deletions(-)
diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index b3c716371d15..d10950e1cf73 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -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,20 +180,26 @@ static int acp63_configure_sdw_ringbuffer(void __iomem *acp_base, u32 stream_id, u32 sdw_ring_buf_size; u32 sdw_mem_window_offset;
- switch (manager_instance) { - case ACP_SDW0: - reg_dma_size = acp63_sdw0_dma_reg[stream_id].reg_dma_size; - reg_fifo_addr = acp63_sdw0_dma_reg[stream_id].reg_fifo_addr; - reg_fifo_size = acp63_sdw0_dma_reg[stream_id].reg_fifo_size; - reg_ring_buf_size = acp63_sdw0_dma_reg[stream_id].reg_ring_buf_size; - reg_ring_buf_addr = acp63_sdw0_dma_reg[stream_id].reg_ring_buf_addr; - break; - case ACP_SDW1: - reg_dma_size = acp63_sdw1_dma_reg[stream_id].reg_dma_size; - reg_fifo_addr = acp63_sdw1_dma_reg[stream_id].reg_fifo_addr; - reg_fifo_size = acp63_sdw1_dma_reg[stream_id].reg_fifo_size; - reg_ring_buf_size = acp63_sdw1_dma_reg[stream_id].reg_ring_buf_size; - reg_ring_buf_addr = acp63_sdw1_dma_reg[stream_id].reg_ring_buf_addr; + 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; + reg_fifo_addr = acp63_sdw0_dma_reg[stream_id].reg_fifo_addr; + reg_fifo_size = acp63_sdw0_dma_reg[stream_id].reg_fifo_size; + reg_ring_buf_size = acp63_sdw0_dma_reg[stream_id].reg_ring_buf_size; + reg_ring_buf_addr = acp63_sdw0_dma_reg[stream_id].reg_ring_buf_addr; + break; + case ACP_SDW1: + reg_dma_size = acp63_sdw1_dma_reg[stream_id].reg_dma_size; + reg_fifo_addr = acp63_sdw1_dma_reg[stream_id].reg_fifo_addr; + reg_fifo_size = acp63_sdw1_dma_reg[stream_id].reg_fifo_size; + reg_ring_buf_size = acp63_sdw1_dma_reg[stream_id].reg_ring_buf_size; + reg_ring_buf_addr = acp63_sdw1_dma_reg[stream_id].reg_ring_buf_addr; + break; + default: + return -EINVAL; + } break; default: return -EINVAL; @@ -265,21 +271,27 @@ static int acp63_sdw_dma_hw_params(struct snd_soc_component *component, if (!stream) return -EINVAL; stream_id = stream->stream_id; - switch (stream->instance) { - case ACP_SDW0: - sdw_data->acp63_sdw0_dma_stream[stream_id] = substream; - water_mark_size_reg = acp63_sdw0_dma_reg[stream_id].water_mark_size_reg; - acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - irq_mask = BIT(ACP63_SDW0_DMA_TX_IRQ_MASK(stream_id)); - else - irq_mask = BIT(ACP63_SDW0_DMA_RX_IRQ_MASK(stream_id)); - break; - case ACP_SDW1: - sdw_data->acp63_sdw1_dma_stream[stream_id] = substream; - acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL1; - water_mark_size_reg = acp63_sdw1_dma_reg[stream_id].water_mark_size_reg; - irq_mask = BIT(ACP63_SDW1_DMA_IRQ_MASK(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; + water_mark_size_reg = acp63_sdw0_dma_reg[stream_id].water_mark_size_reg; + acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + irq_mask = BIT(ACP63_SDW0_DMA_TX_IRQ_MASK(stream_id)); + else + irq_mask = BIT(ACP63_SDW0_DMA_RX_IRQ_MASK(stream_id)); + break; + case ACP_SDW1: + sdw_data->acp63_sdw1_dma_stream[stream_id] = substream; + acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL1; + water_mark_size_reg = acp63_sdw1_dma_reg[stream_id].water_mark_size_reg; + irq_mask = BIT(ACP63_SDW1_DMA_IRQ_MASK(stream_id)); + break; + default: + return -EINVAL; + } break; default: return -EINVAL; @@ -290,7 +302,7 @@ static int acp63_sdw_dma_hw_params(struct snd_soc_component *component, 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,20 +314,27 @@ 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 (stream->instance) { - case ACP_SDW0: - pos_low_reg = acp63_sdw0_dma_reg[stream->stream_id].pos_low_reg; - pos_high_reg = acp63_sdw0_dma_reg[stream->stream_id].pos_high_reg; - break; - case ACP_SDW1: - pos_low_reg = acp63_sdw1_dma_reg[stream->stream_id].pos_low_reg; - pos_high_reg = acp63_sdw1_dma_reg[stream->stream_id].pos_high_reg; + 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; + pos_high_reg = acp63_sdw0_dma_reg[stream->stream_id].pos_high_reg; + break; + case ACP_SDW1: + pos_low_reg = acp63_sdw1_dma_reg[stream->stream_id].pos_low_reg; + pos_high_reg = acp63_sdw1_dma_reg[stream->stream_id].pos_high_reg; + break; + default: + goto POINTER_RETURN_BYTES; + } break; default: goto POINTER_RETURN_BYTES; @@ -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,12 +386,18 @@ static int acp63_sdw_dma_close(struct snd_soc_component *component, stream = substream->runtime->private_data; if (!stream) return -EINVAL; - switch (stream->instance) { - case ACP_SDW0: - sdw_data->acp63_sdw0_dma_stream[stream->stream_id] = NULL; - break; - case ACP_SDW1: - sdw_data->acp63_sdw1_dma_stream[stream->stream_id] = NULL; + 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; + break; + case ACP_SDW1: + sdw_data->acp63_sdw1_dma_stream[stream->stream_id] = NULL; + break; + default: + return -EINVAL; + } break; default: return -EINVAL; @@ -382,7 +407,7 @@ static int acp63_sdw_dma_close(struct snd_soc_component *component, }
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,12 +418,18 @@ static int acp63_sdw_dma_enable(struct snd_pcm_substream *substream,
stream = substream->runtime->private_data; stream_id = stream->stream_id; - switch (stream->instance) { - case ACP_SDW0: - sdw_dma_en_reg = acp63_sdw0_dma_enable_reg[stream_id]; - break; - case ACP_SDW1: - sdw_dma_en_reg = acp63_sdw1_dma_enable_reg[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]; + break; + case ACP_SDW1: + sdw_dma_en_reg = acp63_sdw1_dma_enable_reg[stream_id]; + break; + default: + return -EINVAL; + } break; default: return -EINVAL; @@ -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);

Refactor SoundWire dma interrupts enable/disable sequence by passing interrupt mask values as an arguments. This will allow to use same function for enabling/disabling SoundWire dma interrupts for different platforms.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/ps-sdw-dma.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index d10950e1cf73..674203a20338 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -114,11 +114,10 @@ static const struct snd_pcm_hardware acp63_sdw_hardware_capture = { .periods_max = SDW_CAPTURE_MAX_NUM_PERIODS, };
-static void acp63_enable_disable_sdw_dma_interrupts(void __iomem *acp_base, bool enable) +static void acp63_enable_disable_sdw_dma_interrupts(void __iomem *acp_base, u32 irq_mask, + u32 irq_mask1, bool enable) { u32 ext_intr_cntl, ext_intr_cntl1; - u32 irq_mask = ACP63_SDW_DMA_IRQ_MASK; - u32 irq_mask1 = ACP63_P1_SDW_DMA_IRQ_MASK;
if (enable) { ext_intr_cntl = readl(acp_base + ACP_EXTERNAL_INTR_CNTL); @@ -533,9 +532,11 @@ static int acp_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data) struct snd_pcm_substream *substream; struct snd_pcm_runtime *runtime; u32 period_bytes, buf_size, water_mark_size_reg; - u32 stream_count; + u32 stream_count, irq_mask, irq_mask1; int index, instance, ret;
+ irq_mask = ACP63_SDW_DMA_IRQ_MASK; + irq_mask1 = ACP63_P1_SDW_DMA_IRQ_MASK; for (instance = 0; instance < AMD_SDW_MAX_MANAGERS; instance++) { if (instance == ACP_SDW0) stream_count = ACP63_SDW0_DMA_MAX_STREAMS; @@ -566,7 +567,7 @@ static int acp_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data) } } } - acp63_enable_disable_sdw_dma_interrupts(sdw_data->acp_base, true); + acp63_enable_disable_sdw_dma_interrupts(sdw_data->acp_base, irq_mask, irq_mask1, true); return 0; }

Rename acp_restore_sdw_dma_config() as acp63_restore_sdw_dma_config() which is specific to ACP6.3 platform.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/ps-sdw-dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 674203a20338..7cd153a4edc9 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -526,7 +526,7 @@ static void acp63_sdw_platform_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); }
-static int acp_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data) +static int acp63_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data) { struct acp_sdw_dma_stream *stream; struct snd_pcm_substream *substream; @@ -576,7 +576,7 @@ static int __maybe_unused acp63_sdw_pcm_resume(struct device *dev) struct sdw_dma_dev_data *sdw_data;
sdw_data = dev_get_drvdata(dev); - return acp_restore_sdw_dma_config(sdw_data); + return acp63_restore_sdw_dma_config(sdw_data); }
static const struct dev_pm_ops acp63_pm_ops = {

Add below ACP pci driver hw_ops for ACP7.0 & ACP7.1 variants. - acp_init() - acp_deinit() - acp_get_config()
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/acp63.h | 14 ++++ sound/soc/amd/ps/pci-ps.c | 10 ++- sound/soc/amd/ps/ps-common.c | 138 +++++++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+), 2 deletions(-)
diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 098597d92bf9..f65f242211e9 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -12,6 +12,8 @@ #define ACP63_REG_START 0x1240000 #define ACP63_REG_END 0x125C000 #define ACP63_PCI_REV 0x63 +#define ACP70_PCI_REV 0x70 +#define ACP71_PCI_REV 0x71
#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001 #define ACP63_PGFSM_CNTL_POWER_ON_MASK 1 @@ -132,6 +134,12 @@
#define ACP_HW_OPS(acp_data, cb) ((acp_data)->hw_ops->cb)
+#define ACP70_PGFSM_CNTL_POWER_ON_MASK 0x1F +#define ACP70_PGFSM_CNTL_POWER_OFF_MASK 0 +#define ACP70_PGFSM_STATUS_MASK 0xFF +#define ACP70_TIMEOUT 2000 +#define ACP70_SDW_HOST_WAKE_MASK 0x0C00000 + enum acp_config { ACP_CONFIG_0 = 0, ACP_CONFIG_1, @@ -149,6 +157,11 @@ enum acp_config { ACP_CONFIG_13, ACP_CONFIG_14, ACP_CONFIG_15, + ACP_CONFIG_16, + ACP_CONFIG_17, + ACP_CONFIG_18, + ACP_CONFIG_19, + ACP_CONFIG_20, };
enum amd_acp63_sdw0_channel { @@ -293,6 +306,7 @@ struct acp63_dev_data { };
void acp63_hw_init_ops(struct acp_hw_ops *hw_ops); +void acp70_hw_init_ops(struct acp_hw_ops *hw_ops);
static inline int acp_hw_init(struct acp63_dev_data *adata, struct device *dev) { diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 04b43b4128bc..8f73d2ce2197 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -438,6 +438,10 @@ static int acp_hw_init_ops(struct acp63_dev_data *adata, struct pci_dev *pci) case ACP63_PCI_REV: acp63_hw_init_ops(adata->hw_ops); break; + case ACP70_PCI_REV: + case ACP71_PCI_REV: + acp70_hw_init_ops(adata->hw_ops); + break; default: dev_err(&pci->dev, "ACP device not found\n"); return -ENODEV; @@ -460,12 +464,14 @@ static int snd_acp63_probe(struct pci_dev *pci, if (flag) return -ENODEV;
- /* Pink Sardine device check */ + /* ACP PCI revision id check for ACP6.3, ACP7.0 & ACP7.1 platforms */ switch (pci->revision) { case ACP63_PCI_REV: + case ACP70_PCI_REV: + case ACP71_PCI_REV: break; default: - dev_dbg(&pci->dev, "acp63 pci device not found\n"); + dev_dbg(&pci->dev, "acp63/acp70/acp71 pci device not found\n"); return -ENODEV; } if (pci_enable_device(pci)) { diff --git a/sound/soc/amd/ps/ps-common.c b/sound/soc/amd/ps/ps-common.c index 9098974b3608..a15284bde48d 100644 --- a/sound/soc/amd/ps/ps-common.c +++ b/sound/soc/amd/ps/ps-common.c @@ -246,3 +246,141 @@ void acp63_hw_init_ops(struct acp_hw_ops *hw_ops) hw_ops->acp_suspend_runtime = snd_acp63_suspend; hw_ops->acp_resume_runtime = snd_acp63_runtime_resume; } + +static int acp70_power_on(void __iomem *acp_base) +{ + u32 val = 0; + + val = readl(acp_base + ACP_PGFSM_STATUS); + + if (!val) + return 0; + if (val & ACP70_PGFSM_STATUS_MASK) + writel(ACP70_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL); + + return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP70_TIMEOUT); +} + +static int acp70_reset(void __iomem *acp_base) +{ + u32 val; + int ret; + + writel(1, acp_base + ACP_SOFT_RESET); + + ret = readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, + val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK, + DELAY_US, ACP70_TIMEOUT); + if (ret) + return ret; + + writel(0, acp_base + ACP_SOFT_RESET); + + return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP70_TIMEOUT); +} + +static void acp70_enable_sdw_host_wake_interrupts(void __iomem *acp_base) +{ + u32 ext_intr_cntl1; + + ext_intr_cntl1 = readl(acp_base + ACP_EXTERNAL_INTR_CNTL1); + ext_intr_cntl1 |= ACP70_SDW_HOST_WAKE_MASK; + writel(ext_intr_cntl1, acp_base + ACP_EXTERNAL_INTR_CNTL1); +} + +static void acp70_enable_interrupts(void __iomem *acp_base) +{ + u32 sdw0_wake_en, sdw1_wake_en; + + writel(1, acp_base + ACP_EXTERNAL_INTR_ENB); + writel(ACP_ERROR_IRQ, acp_base + ACP_EXTERNAL_INTR_CNTL); + sdw0_wake_en = readl(acp_base + ACP_SW0_WAKE_EN); + sdw1_wake_en = readl(acp_base + ACP_SW1_WAKE_EN); + if (sdw0_wake_en || sdw1_wake_en) + acp70_enable_sdw_host_wake_interrupts(acp_base); +} + +static void acp70_disable_interrupts(void __iomem *acp_base) +{ + writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base + ACP_EXTERNAL_INTR_STAT); + writel(0, acp_base + ACP_EXTERNAL_INTR_CNTL); + writel(0, acp_base + ACP_EXTERNAL_INTR_ENB); +} + +static int acp70_init(void __iomem *acp_base, struct device *dev) +{ + int ret; + + ret = acp70_power_on(acp_base); + if (ret) { + dev_err(dev, "ACP power on failed\n"); + return ret; + } + writel(0x01, acp_base + ACP_CONTROL); + ret = acp70_reset(acp_base); + if (ret) { + dev_err(dev, "ACP reset failed\n"); + return ret; + } + writel(0, acp_base + ACP_ZSC_DSP_CTRL); + acp70_enable_interrupts(acp_base); + writel(0x1, acp_base + ACP_PME_EN); + return 0; +} + +static int acp70_deinit(void __iomem *acp_base, struct device *dev) +{ + int ret; + + acp70_disable_interrupts(acp_base); + ret = acp70_reset(acp_base); + if (ret) { + dev_err(dev, "ACP reset failed\n"); + return ret; + } + writel(0x01, acp_base + ACP_ZSC_DSP_CTRL); + return 0; +} + +static void acp70_get_config(struct pci_dev *pci, struct acp63_dev_data *acp_data) +{ + u32 config; + + config = readl(acp_data->acp63_base + ACP_PIN_CONFIG); + dev_dbg(&pci->dev, "ACP config value: %d\n", config); + switch (config) { + case ACP_CONFIG_4: + case ACP_CONFIG_5: + case ACP_CONFIG_10: + case ACP_CONFIG_11: + case ACP_CONFIG_20: + acp_data->is_pdm_config = true; + break; + case ACP_CONFIG_2: + case ACP_CONFIG_3: + case ACP_CONFIG_16: + acp_data->is_sdw_config = true; + break; + case ACP_CONFIG_6: + case ACP_CONFIG_7: + case ACP_CONFIG_12: + case ACP_CONFIG_8: + case ACP_CONFIG_13: + case ACP_CONFIG_14: + case ACP_CONFIG_17: + case ACP_CONFIG_18: + case ACP_CONFIG_19: + acp_data->is_pdm_config = true; + acp_data->is_sdw_config = true; + break; + default: + break; + } +} + +void acp70_hw_init_ops(struct acp_hw_ops *hw_ops) +{ + hw_ops->acp_init = acp70_init; + hw_ops->acp_deinit = acp70_deinit; + hw_ops->acp_get_config = acp70_get_config; +}

Add ACP7.0 & ACP7.1 platform specific PM ops related hw_ops.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/ps-common.c | 65 ++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+)
diff --git a/sound/soc/amd/ps/ps-common.c b/sound/soc/amd/ps/ps-common.c index a15284bde48d..6639dac0a415 100644 --- a/sound/soc/amd/ps/ps-common.c +++ b/sound/soc/amd/ps/ps-common.c @@ -378,9 +378,74 @@ static void acp70_get_config(struct pci_dev *pci, struct acp63_dev_data *acp_dat } }
+static int __maybe_unused snd_acp70_suspend(struct device *dev) +{ + struct acp63_dev_data *adata; + int ret; + + adata = dev_get_drvdata(dev); + if (adata->is_sdw_dev) { + adata->sdw_en_stat = check_acp_sdw_enable_status(adata); + if (adata->sdw_en_stat) { + writel(1, adata->acp63_base + ACP_ZSC_DSP_CTRL); + return 0; + } + } + ret = acp_hw_deinit(adata, dev); + if (ret) + dev_err(dev, "ACP de-init failed\n"); + + return ret; +} + +static int __maybe_unused snd_acp70_runtime_resume(struct device *dev) +{ + struct acp63_dev_data *adata; + int ret; + + adata = dev_get_drvdata(dev); + + if (adata->sdw_en_stat) { + writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); + writel(1, adata->acp63_base + ACP_PME_EN); + return 0; + } + + ret = acp_hw_init(adata, dev); + if (ret) { + dev_err(dev, "ACP init failed\n"); + return ret; + } + return 0; +} + +static int __maybe_unused snd_acp70_resume(struct device *dev) +{ + struct acp63_dev_data *adata; + int ret; + + adata = dev_get_drvdata(dev); + + if (adata->sdw_en_stat) { + writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); + writel(1, adata->acp63_base + ACP_PME_EN); + return 0; + } + + ret = acp_hw_init(adata, dev); + if (ret) + dev_err(dev, "ACP init failed\n"); + + return ret; +} + void acp70_hw_init_ops(struct acp_hw_ops *hw_ops) { hw_ops->acp_init = acp70_init; hw_ops->acp_deinit = acp70_deinit; hw_ops->acp_get_config = acp70_get_config; + hw_ops->acp_suspend = snd_acp70_suspend; + hw_ops->acp_resume = snd_acp70_resume; + hw_ops->acp_suspend_runtime = snd_acp70_suspend; + hw_ops->acp_resume_runtime = snd_acp70_runtime_resume; }

Add SoundWire dma driver changes specific to ACP7.0 & ACP7.1 platforms.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/acp63.h | 52 ++++++++++++ sound/soc/amd/ps/ps-sdw-dma.c | 154 ++++++++++++++++++++++++++++++++++ 2 files changed, 206 insertions(+)
diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index f65f242211e9..4d197bb8271a 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -140,6 +140,47 @@ #define ACP70_TIMEOUT 2000 #define ACP70_SDW_HOST_WAKE_MASK 0x0C00000
+#define ACP70_SDW0_DMA_MAX_STREAMS 6 +#define ACP70_SDW1_DMA_MAX_STREAMS ACP70_SDW0_DMA_MAX_STREAMS + +#define ACP70_P1_AUDIO0_TX_THRESHOLD 0x8 +#define ACP70_P1_AUDIO1_TX_THRESHOLD 0x6 +#define ACP70_P1_AUDIO2_TX_THRESHOLD 0x4 +#define ACP70_P1_AUDIO0_RX_THRESHOLD 0x7 +#define ACP70_P1_AUDIO1_RX_THRESHOLD 0x5 +#define ACP70_P1_AUDIO2_RX_THRESHOLD 0x3 + +#define ACP70_SDW0_DMA_TX_IRQ_MASK(i) (ACP_AUDIO0_TX_THRESHOLD - (2 * (i))) +#define ACP70_SDW0_DMA_RX_IRQ_MASK(i) (ACP_AUDIO0_RX_THRESHOLD - (2 * ((i) - 3))) + +/* + * Below entries describes SDW1 instance DMA stream id and DMA irq bit mapping + * in ACP_EXTENAL_INTR_CNTL1 register for ACP70/ACP71 platforms + * Stream id IRQ Bit + * 0 (SDW1_AUDIO0_TX) 8 + * 1 (SDW1_AUDIO1_TX) 6 + * 2 (SDW1_AUDIO2_TX) 4 + * 3 (SDW1_AUDIO0_RX) 7 + * 4 (SDW1_AUDIO1_RX) 5 + * 5 (SDW1_AUDIO2_RX) 3 + */ +#define ACP70_SDW1_DMA_TX_IRQ_MASK(i) (ACP70_P1_AUDIO0_TX_THRESHOLD - (2 * (i))) +#define ACP70_SDW1_DMA_RX_IRQ_MASK(i) (ACP70_P1_AUDIO0_RX_THRESHOLD - (2 * ((i) - 3))) + +#define ACP70_SW0_AUDIO0_TX_EN ACP_SW0_AUDIO0_TX_EN +#define ACP70_SW0_AUDIO1_TX_EN ACP_SW0_AUDIO1_TX_EN +#define ACP70_SW0_AUDIO2_TX_EN ACP_SW0_AUDIO2_TX_EN +#define ACP70_SW0_AUDIO0_RX_EN ACP_SW0_AUDIO0_RX_EN +#define ACP70_SW0_AUDIO1_RX_EN ACP_SW0_AUDIO1_RX_EN +#define ACP70_SW0_AUDIO2_RX_EN ACP_SW0_AUDIO2_RX_EN + +#define ACP70_SW1_AUDIO0_TX_EN 0x0003C10 +#define ACP70_SW1_AUDIO1_TX_EN 0x0003C50 +#define ACP70_SW1_AUDIO2_TX_EN 0x0003C6C +#define ACP70_SW1_AUDIO0_RX_EN 0x0003C88 +#define ACP70_SW1_AUDIO1_RX_EN 0x0003D28 +#define ACP70_SW1_AUDIO2_RX_EN 0x0003D44 + enum acp_config { ACP_CONFIG_0 = 0, ACP_CONFIG_1, @@ -178,6 +219,15 @@ enum amd_acp63_sdw1_channel { ACP63_SDW1_AUDIO1_RX, };
+enum amd_acp70_sdw_channel { + ACP70_SDW_AUDIO0_TX = 0, + ACP70_SDW_AUDIO1_TX, + ACP70_SDW_AUDIO2_TX, + ACP70_SDW_AUDIO0_RX, + ACP70_SDW_AUDIO1_RX, + ACP70_SDW_AUDIO2_RX, +}; + struct pdm_stream_instance { u16 num_pages; u16 channels; @@ -199,6 +249,8 @@ struct sdw_dma_dev_data { u32 acp_rev; struct snd_pcm_substream *acp63_sdw0_dma_stream[ACP63_SDW0_DMA_MAX_STREAMS]; struct snd_pcm_substream *acp63_sdw1_dma_stream[ACP63_SDW1_DMA_MAX_STREAMS]; + struct snd_pcm_substream *acp70_sdw0_dma_stream[ACP70_SDW0_DMA_MAX_STREAMS]; + struct snd_pcm_substream *acp70_sdw1_dma_stream[ACP70_SDW1_DMA_MAX_STREAMS]; };
struct acp_sdw_dma_stream { diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 7cd153a4edc9..2966244eb25e 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -75,6 +75,72 @@ static u32 acp63_sdw1_dma_enable_reg[ACP63_SDW1_DMA_MAX_STREAMS] = { ACP_SW1_AUDIO1_RX_EN, };
+static struct sdw_dma_ring_buf_reg acp70_sdw0_dma_reg[ACP70_SDW0_DMA_MAX_STREAMS] = { + {ACP_AUDIO0_TX_DMA_SIZE, ACP_AUDIO0_TX_FIFOADDR, ACP_AUDIO0_TX_FIFOSIZE, + ACP_AUDIO0_TX_RINGBUFSIZE, ACP_AUDIO0_TX_RINGBUFADDR, ACP_AUDIO0_TX_INTR_WATERMARK_SIZE, + ACP_AUDIO0_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_TX_LINEARPOSITIONCNTR_HIGH}, + {ACP_AUDIO1_TX_DMA_SIZE, ACP_AUDIO1_TX_FIFOADDR, ACP_AUDIO1_TX_FIFOSIZE, + ACP_AUDIO1_TX_RINGBUFSIZE, ACP_AUDIO1_TX_RINGBUFADDR, ACP_AUDIO1_TX_INTR_WATERMARK_SIZE, + ACP_AUDIO1_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO1_TX_LINEARPOSITIONCNTR_HIGH}, + {ACP_AUDIO2_TX_DMA_SIZE, ACP_AUDIO2_TX_FIFOADDR, ACP_AUDIO2_TX_FIFOSIZE, + ACP_AUDIO2_TX_RINGBUFSIZE, ACP_AUDIO2_TX_RINGBUFADDR, ACP_AUDIO2_TX_INTR_WATERMARK_SIZE, + ACP_AUDIO2_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO2_TX_LINEARPOSITIONCNTR_HIGH}, + {ACP_AUDIO0_RX_DMA_SIZE, ACP_AUDIO0_RX_FIFOADDR, ACP_AUDIO0_RX_FIFOSIZE, + ACP_AUDIO0_RX_RINGBUFSIZE, ACP_AUDIO0_RX_RINGBUFADDR, ACP_AUDIO0_RX_INTR_WATERMARK_SIZE, + ACP_AUDIO0_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_RX_LINEARPOSITIONCNTR_HIGH}, + {ACP_AUDIO1_RX_DMA_SIZE, ACP_AUDIO1_RX_FIFOADDR, ACP_AUDIO1_RX_FIFOSIZE, + ACP_AUDIO1_RX_RINGBUFSIZE, ACP_AUDIO1_RX_RINGBUFADDR, ACP_AUDIO1_RX_INTR_WATERMARK_SIZE, + ACP_AUDIO1_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH}, + {ACP_AUDIO2_RX_DMA_SIZE, ACP_AUDIO2_RX_FIFOADDR, ACP_AUDIO2_RX_FIFOSIZE, + ACP_AUDIO2_RX_RINGBUFSIZE, ACP_AUDIO2_RX_RINGBUFADDR, ACP_AUDIO2_RX_INTR_WATERMARK_SIZE, + ACP_AUDIO2_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO2_RX_LINEARPOSITIONCNTR_HIGH} +}; + +static struct sdw_dma_ring_buf_reg acp70_sdw1_dma_reg[ACP70_SDW1_DMA_MAX_STREAMS] = { + {ACP_P1_AUDIO0_TX_DMA_SIZE, ACP_P1_AUDIO0_TX_FIFOADDR, ACP_P1_AUDIO0_TX_FIFOSIZE, + ACP_P1_AUDIO0_TX_RINGBUFSIZE, ACP_P1_AUDIO0_TX_RINGBUFADDR, + ACP_P1_AUDIO0_TX_INTR_WATERMARK_SIZE, + ACP_P1_AUDIO0_TX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO0_TX_LINEARPOSITIONCNTR_HIGH}, + {ACP_P1_AUDIO1_TX_DMA_SIZE, ACP_P1_AUDIO1_TX_FIFOADDR, ACP_P1_AUDIO1_TX_FIFOSIZE, + ACP_P1_AUDIO1_TX_RINGBUFSIZE, ACP_P1_AUDIO1_TX_RINGBUFADDR, + ACP_P1_AUDIO1_TX_INTR_WATERMARK_SIZE, + ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR_HIGH}, + {ACP_P1_AUDIO2_TX_DMA_SIZE, ACP_P1_AUDIO2_TX_FIFOADDR, ACP_P1_AUDIO2_TX_FIFOSIZE, + ACP_P1_AUDIO2_TX_RINGBUFSIZE, ACP_P1_AUDIO2_TX_RINGBUFADDR, + ACP_P1_AUDIO2_TX_INTR_WATERMARK_SIZE, + ACP_P1_AUDIO2_TX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO2_TX_LINEARPOSITIONCNTR_HIGH}, + {ACP_P1_AUDIO0_RX_DMA_SIZE, ACP_P1_AUDIO0_RX_FIFOADDR, ACP_P1_AUDIO0_RX_FIFOSIZE, + ACP_P1_AUDIO0_RX_RINGBUFSIZE, ACP_P1_AUDIO0_RX_RINGBUFADDR, + ACP_P1_AUDIO0_RX_INTR_WATERMARK_SIZE, + ACP_P1_AUDIO0_RX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO0_RX_LINEARPOSITIONCNTR_HIGH}, + {ACP_P1_AUDIO1_RX_DMA_SIZE, ACP_P1_AUDIO1_RX_FIFOADDR, ACP_P1_AUDIO1_RX_FIFOSIZE, + ACP_P1_AUDIO1_RX_RINGBUFSIZE, ACP_P1_AUDIO1_RX_RINGBUFADDR, + ACP_P1_AUDIO1_RX_INTR_WATERMARK_SIZE, + ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH}, + {ACP_P1_AUDIO2_RX_DMA_SIZE, ACP_P1_AUDIO2_RX_FIFOADDR, ACP_P1_AUDIO2_RX_FIFOSIZE, + ACP_P1_AUDIO2_RX_RINGBUFSIZE, ACP_P1_AUDIO2_RX_RINGBUFADDR, + ACP_P1_AUDIO2_RX_INTR_WATERMARK_SIZE, + ACP_P1_AUDIO2_RX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO2_RX_LINEARPOSITIONCNTR_HIGH} +}; + +static u32 acp70_sdw0_dma_enable_reg[ACP70_SDW0_DMA_MAX_STREAMS] = { + ACP70_SW0_AUDIO0_TX_EN, + ACP70_SW0_AUDIO1_TX_EN, + ACP70_SW0_AUDIO2_TX_EN, + ACP70_SW0_AUDIO0_RX_EN, + ACP70_SW0_AUDIO1_RX_EN, + ACP70_SW0_AUDIO2_RX_EN, +}; + +static u32 acp70_sdw1_dma_enable_reg[ACP70_SDW1_DMA_MAX_STREAMS] = { + ACP70_SW1_AUDIO0_TX_EN, + ACP70_SW1_AUDIO1_TX_EN, + ACP70_SW1_AUDIO2_TX_EN, + ACP70_SW1_AUDIO0_RX_EN, + ACP70_SW1_AUDIO1_RX_EN, + ACP70_SW1_AUDIO2_RX_EN, +}; + static const struct snd_pcm_hardware acp63_sdw_hardware_playback = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -200,6 +266,27 @@ static int acp63_configure_sdw_ringbuffer(void __iomem *acp_base, u32 stream_id, return -EINVAL; } break; + case ACP70_PCI_REV: + case ACP71_PCI_REV: + switch (manager_instance) { + case ACP_SDW0: + reg_dma_size = acp70_sdw0_dma_reg[stream_id].reg_dma_size; + reg_fifo_addr = acp70_sdw0_dma_reg[stream_id].reg_fifo_addr; + reg_fifo_size = acp70_sdw0_dma_reg[stream_id].reg_fifo_size; + reg_ring_buf_size = acp70_sdw0_dma_reg[stream_id].reg_ring_buf_size; + reg_ring_buf_addr = acp70_sdw0_dma_reg[stream_id].reg_ring_buf_addr; + break; + case ACP_SDW1: + reg_dma_size = acp70_sdw1_dma_reg[stream_id].reg_dma_size; + reg_fifo_addr = acp70_sdw1_dma_reg[stream_id].reg_fifo_addr; + reg_fifo_size = acp70_sdw1_dma_reg[stream_id].reg_fifo_size; + reg_ring_buf_size = acp70_sdw1_dma_reg[stream_id].reg_ring_buf_size; + reg_ring_buf_addr = acp70_sdw1_dma_reg[stream_id].reg_ring_buf_addr; + break; + default: + return -EINVAL; + } + break; default: return -EINVAL; } @@ -292,6 +379,32 @@ static int acp63_sdw_dma_hw_params(struct snd_soc_component *component, return -EINVAL; } break; + case ACP70_PCI_REV: + case ACP71_PCI_REV: + switch (stream->instance) { + case ACP_SDW0: + sdw_data->acp70_sdw0_dma_stream[stream_id] = substream; + water_mark_size_reg = acp70_sdw0_dma_reg[stream_id].water_mark_size_reg; + acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + irq_mask = BIT(ACP70_SDW0_DMA_TX_IRQ_MASK(stream_id)); + else + irq_mask = BIT(ACP70_SDW0_DMA_RX_IRQ_MASK(stream_id)); + break; + case ACP_SDW1: + sdw_data->acp70_sdw1_dma_stream[stream_id] = substream; + acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL1; + water_mark_size_reg = acp70_sdw1_dma_reg[stream_id].water_mark_size_reg; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + irq_mask = BIT(ACP70_SDW1_DMA_TX_IRQ_MASK(stream_id)); + else + irq_mask = BIT(ACP70_SDW1_DMA_RX_IRQ_MASK(stream_id)); + + break; + default: + return -EINVAL; + } + break; default: return -EINVAL; } @@ -335,6 +448,21 @@ static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __io goto POINTER_RETURN_BYTES; } break; + case ACP70_PCI_REV: + case ACP71_PCI_REV: + switch (stream->instance) { + case ACP_SDW0: + pos_low_reg = acp70_sdw0_dma_reg[stream->stream_id].pos_low_reg; + pos_high_reg = acp70_sdw0_dma_reg[stream->stream_id].pos_high_reg; + break; + case ACP_SDW1: + pos_low_reg = acp70_sdw1_dma_reg[stream->stream_id].pos_low_reg; + pos_high_reg = acp70_sdw1_dma_reg[stream->stream_id].pos_high_reg; + break; + default: + goto POINTER_RETURN_BYTES; + } + break; default: goto POINTER_RETURN_BYTES; } @@ -398,6 +526,19 @@ static int acp63_sdw_dma_close(struct snd_soc_component *component, return -EINVAL; } break; + case ACP70_PCI_REV: + case ACP71_PCI_REV: + switch (stream->instance) { + case ACP_SDW0: + sdw_data->acp70_sdw0_dma_stream[stream->stream_id] = NULL; + break; + case ACP_SDW1: + sdw_data->acp70_sdw1_dma_stream[stream->stream_id] = NULL; + break; + default: + return -EINVAL; + } + break; default: return -EINVAL; } @@ -430,6 +571,19 @@ static int acp63_sdw_dma_enable(struct snd_pcm_substream *substream, return -EINVAL; } break; + case ACP70_PCI_REV: + case ACP71_PCI_REV: + switch (stream->instance) { + case ACP_SDW0: + sdw_dma_en_reg = acp70_sdw0_dma_enable_reg[stream_id]; + break; + case ACP_SDW1: + sdw_dma_en_reg = acp70_sdw1_dma_enable_reg[stream_id]; + break; + default: + return -EINVAL; + } + break; default: return -EINVAL; }

Implement function to restore the dma configuration during system level resume for ACP7.0 & ACP7.1 platforms. Add a conditional check to invoke restore dma configuration function based on acp pci revision id.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/acp63.h | 2 ++ sound/soc/amd/ps/ps-sdw-dma.c | 46 ++++++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 4d197bb8271a..0aef3a852ff1 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -142,6 +142,8 @@
#define ACP70_SDW0_DMA_MAX_STREAMS 6 #define ACP70_SDW1_DMA_MAX_STREAMS ACP70_SDW0_DMA_MAX_STREAMS +#define ACP70_SDW_DMA_IRQ_MASK 0x1F800000 +#define ACP70_P1_SDW_DMA_IRQ_MASK 0x1F8
#define ACP70_P1_AUDIO0_TX_THRESHOLD 0x8 #define ACP70_P1_AUDIO1_TX_THRESHOLD 0x6 diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 2966244eb25e..557d312a23b2 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -725,12 +725,56 @@ static int acp63_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data) return 0; }
+static int acp70_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data) +{ + struct acp_sdw_dma_stream *stream; + struct snd_pcm_substream *substream; + struct snd_pcm_runtime *runtime; + u32 period_bytes, buf_size, water_mark_size_reg; + u32 stream_count, irq_mask, irq_mask1; + int index, instance, ret; + + irq_mask = ACP70_SDW_DMA_IRQ_MASK; + irq_mask1 = ACP70_P1_SDW_DMA_IRQ_MASK; + stream_count = ACP70_SDW0_DMA_MAX_STREAMS; + for (instance = 0; instance < AMD_SDW_MAX_MANAGERS; instance++) { + for (index = 0; index < stream_count; index++) { + if (instance == ACP_SDW0) { + substream = sdw_data->acp70_sdw0_dma_stream[index]; + water_mark_size_reg = acp70_sdw0_dma_reg[index].water_mark_size_reg; + } else { + substream = sdw_data->acp70_sdw1_dma_stream[index]; + water_mark_size_reg = acp70_sdw1_dma_reg[index].water_mark_size_reg; + } + + if (substream && substream->runtime) { + runtime = substream->runtime; + stream = runtime->private_data; + period_bytes = frames_to_bytes(runtime, runtime->period_size); + 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, + sdw_data->acp_rev); + if (ret) + return ret; + writel(period_bytes, sdw_data->acp_base + water_mark_size_reg); + } + } + } + acp63_enable_disable_sdw_dma_interrupts(sdw_data->acp_base, irq_mask, irq_mask1, true); + return 0; +} + static int __maybe_unused acp63_sdw_pcm_resume(struct device *dev) { struct sdw_dma_dev_data *sdw_data;
sdw_data = dev_get_drvdata(dev); - return acp63_restore_sdw_dma_config(sdw_data); + if (sdw_data->acp_rev == ACP63_PCI_REV) + return acp63_restore_sdw_dma_config(sdw_data); + else + return acp70_restore_sdw_dma_config(sdw_data); }
static const struct dev_pm_ops acp63_pm_ops = {

Add Soundwie dma interrupts handling for ACP7.0 & ACP7.1 platforms. Add acp pci revision id conditional checks for handling platform specific implementation.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/acp63.h | 6 ++++ sound/soc/amd/ps/pci-ps.c | 61 ++++++++++++++++++++++++++++++------ sound/soc/amd/ps/ps-common.c | 24 ++++++++++++++ 3 files changed, 81 insertions(+), 10 deletions(-)
diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 0aef3a852ff1..48dac2a044c2 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -332,6 +332,10 @@ struct acp_hw_ops { * manager-SW0 instance * @acp63_sdw_dma_intr_stat: DMA interrupt status array for ACP6.3 platform SoundWire * manager-SW1 instance + * @acp70_sdw0-dma_intr_stat: DMA interrupt status array for ACP7.0 platform SoundWire + * manager-SW0 instance + * @acp70_sdw_dma_intr_stat: DMA interrupt status array for ACP7.0 platform SoundWire + * manager-SW1 instance */
struct acp63_dev_data { @@ -357,6 +361,8 @@ struct acp63_dev_data { u32 acp_rev; u16 acp63_sdw0_dma_intr_stat[ACP63_SDW0_DMA_MAX_STREAMS]; u16 acp63_sdw1_dma_intr_stat[ACP63_SDW1_DMA_MAX_STREAMS]; + u16 acp70_sdw0_dma_intr_stat[ACP70_SDW0_DMA_MAX_STREAMS]; + u16 acp70_sdw1_dma_intr_stat[ACP70_SDW1_DMA_MAX_STREAMS]; };
void acp63_hw_init_ops(struct acp_hw_ops *hw_ops); diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 8f73d2ce2197..a9e140ca1296 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -52,20 +52,61 @@ static short int check_and_handle_sdw_dma_irq(struct acp63_dev_data *adata, u32 stream_id = ACP63_SDW0_AUDIO2_RX; break; } - adata->acp63_sdw0_dma_intr_stat[stream_id] = 1; + if (adata->acp_rev >= ACP70_PCI_REV) + adata->acp70_sdw0_dma_intr_stat[stream_id] = 1; + else + adata->acp63_sdw0_dma_intr_stat[stream_id] = 1; + sdw_dma_irq_flag = 1; } } } - if (ext_intr_stat1 & ACP63_P1_AUDIO1_RX_THRESHOLD) { - writel(ACP63_P1_AUDIO1_RX_THRESHOLD, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); - adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_RX] = 1; - sdw_dma_irq_flag = 1; - } - if (ext_intr_stat1 & ACP63_P1_AUDIO1_TX_THRESHOLD) { - writel(ACP63_P1_AUDIO1_TX_THRESHOLD, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); - adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_TX] = 1; - sdw_dma_irq_flag = 1; + if (adata->acp_rev == ACP63_PCI_REV) { + if (ext_intr_stat1 & ACP63_P1_AUDIO1_RX_THRESHOLD) { + writel(ACP63_P1_AUDIO1_RX_THRESHOLD, + adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_RX] = 1; + sdw_dma_irq_flag = 1; + } + if (ext_intr_stat1 & ACP63_P1_AUDIO1_TX_THRESHOLD) { + writel(ACP63_P1_AUDIO1_TX_THRESHOLD, + adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_TX] = 1; + sdw_dma_irq_flag = 1; + } + } else { + if (ext_intr_stat1 & ACP70_P1_SDW_DMA_IRQ_MASK) { + for (index = ACP70_P1_AUDIO2_RX_THRESHOLD; + index <= ACP70_P1_AUDIO0_TX_THRESHOLD; index++) { + if (ext_intr_stat1 & BIT(index)) { + writel(BIT(index), + adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + switch (index) { + case ACP70_P1_AUDIO0_TX_THRESHOLD: + stream_id = ACP70_SDW_AUDIO0_TX; + break; + case ACP70_P1_AUDIO1_TX_THRESHOLD: + stream_id = ACP70_SDW_AUDIO1_TX; + break; + case ACP70_P1_AUDIO2_TX_THRESHOLD: + stream_id = ACP70_SDW_AUDIO2_TX; + break; + case ACP70_P1_AUDIO0_RX_THRESHOLD: + stream_id = ACP70_SDW_AUDIO0_RX; + break; + case ACP70_P1_AUDIO1_RX_THRESHOLD: + stream_id = ACP70_SDW_AUDIO1_RX; + break; + case ACP70_P1_AUDIO2_RX_THRESHOLD: + stream_id = ACP70_SDW_AUDIO2_RX; + break; + } + + adata->acp70_sdw1_dma_intr_stat[stream_id] = 1; + sdw_dma_irq_flag = 1; + } + } + } } return sdw_dma_irq_flag; } diff --git a/sound/soc/amd/ps/ps-common.c b/sound/soc/amd/ps/ps-common.c index 6639dac0a415..1c89fb5fe1da 100644 --- a/sound/soc/amd/ps/ps-common.c +++ b/sound/soc/amd/ps/ps-common.c @@ -378,6 +378,29 @@ static void acp70_get_config(struct pci_dev *pci, struct acp63_dev_data *acp_dat } }
+static void acp70_sdw_dma_irq_thread(struct acp63_dev_data *adata) +{ + struct sdw_dma_dev_data *sdw_data; + u32 stream_id; + + sdw_data = dev_get_drvdata(&adata->sdw_dma_dev->dev); + + for (stream_id = 0; stream_id < ACP70_SDW0_DMA_MAX_STREAMS; stream_id++) { + if (adata->acp70_sdw0_dma_intr_stat[stream_id]) { + if (sdw_data->acp70_sdw0_dma_stream[stream_id]) + snd_pcm_period_elapsed(sdw_data->acp70_sdw0_dma_stream[stream_id]); + adata->acp70_sdw0_dma_intr_stat[stream_id] = 0; + } + } + for (stream_id = 0; stream_id < ACP70_SDW1_DMA_MAX_STREAMS; stream_id++) { + if (adata->acp70_sdw1_dma_intr_stat[stream_id]) { + if (sdw_data->acp70_sdw1_dma_stream[stream_id]) + snd_pcm_period_elapsed(sdw_data->acp70_sdw1_dma_stream[stream_id]); + adata->acp70_sdw1_dma_intr_stat[stream_id] = 0; + } + } +} + static int __maybe_unused snd_acp70_suspend(struct device *dev) { struct acp63_dev_data *adata; @@ -444,6 +467,7 @@ void acp70_hw_init_ops(struct acp_hw_ops *hw_ops) hw_ops->acp_init = acp70_init; hw_ops->acp_deinit = acp70_deinit; hw_ops->acp_get_config = acp70_get_config; + hw_ops->acp_sdw_dma_irq_thread = acp70_sdw_dma_irq_thread; hw_ops->acp_suspend = snd_acp70_suspend; hw_ops->acp_resume = snd_acp70_resume; hw_ops->acp_suspend_runtime = snd_acp70_suspend;

On Fri, Feb 07, 2025 at 11:58:10AM +0530, Vijendar Mukunda wrote:
- if (adata->acp_rev == ACP63_PCI_REV) {
- } else {
Unless I find something major in the rest of the series I'll apply this but it's much better to write these as case statements, that way if you get additional types to handle it's easier to extend the code sensibly. Please update this incrementally.

On 07/02/25 19:02, Mark Brown wrote:
On Fri, Feb 07, 2025 at 11:58:10AM +0530, Vijendar Mukunda wrote:
- if (adata->acp_rev == ACP63_PCI_REV) {
- } else {
Unless I find something major in the rest of the series I'll apply this but it's much better to write these as case statements, that way if you get additional types to handle it's easier to extend the code sensibly. Please update this incrementally.
Will push it as an incremental patch.

Add SoundWire wake interrupt handling for ACP7.0 & ACP7.1 platforms.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/acp63.h | 8 +++++ sound/soc/amd/ps/pci-ps.c | 62 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+)
diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 48dac2a044c2..9940151b0675 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -139,6 +139,10 @@ #define ACP70_PGFSM_STATUS_MASK 0xFF #define ACP70_TIMEOUT 2000 #define ACP70_SDW_HOST_WAKE_MASK 0x0C00000 +#define ACP70_SDW0_HOST_WAKE_STAT BIT(24) +#define ACP70_SDW1_HOST_WAKE_STAT BIT(25) +#define ACP70_SDW0_PME_STAT BIT(26) +#define ACP70_SDW1_PME_STAT BIT(27)
#define ACP70_SDW0_DMA_MAX_STREAMS 6 #define ACP70_SDW1_DMA_MAX_STREAMS ACP70_SDW0_DMA_MAX_STREAMS @@ -325,6 +329,8 @@ struct acp_hw_ops { * @is_pdm_config: flat set to true when PDM configuration is selected from BIOS * @is_sdw_config: flag set to true when SDW configuration is selected from BIOS * @sdw_en_stat: flag set to true when any one of the SoundWire manager instance is enabled + * @acp70_sdw0_wake_event: flag set to true when wake irq asserted for SW0 instance + * @acp70_sdw1_wake_event: flag set to true when wake irq asserted for SW1 instance * @addr: pci ioremap address * @reg_range: ACP reigister range * @acp_rev: ACP PCI revision id @@ -356,6 +362,8 @@ struct acp63_dev_data { bool is_pdm_config; bool is_sdw_config; bool sdw_en_stat; + bool acp70_sdw0_wake_event; + bool acp70_sdw1_wake_event; u32 addr; u32 reg_range; u32 acp_rev; diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index a9e140ca1296..6a725cf36345 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -21,6 +21,65 @@
#include "acp63.h"
+static void handle_acp70_sdw_wake_event(struct acp63_dev_data *adata) +{ + struct amd_sdw_manager *amd_manager; + + if (adata->acp70_sdw0_wake_event) { + amd_manager = dev_get_drvdata(&adata->sdw->pdev[0]->dev); + if (amd_manager) + pm_request_resume(amd_manager->dev); + adata->acp70_sdw0_wake_event = 0; + } + + if (adata->acp70_sdw1_wake_event) { + amd_manager = dev_get_drvdata(&adata->sdw->pdev[1]->dev); + if (amd_manager) + pm_request_resume(amd_manager->dev); + adata->acp70_sdw1_wake_event = 0; + } +} + +static short int check_and_handle_acp70_sdw_wake_irq(struct acp63_dev_data *adata) +{ + u32 ext_intr_stat1; + int irq_flag = 0; + bool sdw_wake_irq = false; + + ext_intr_stat1 = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + if (ext_intr_stat1 & ACP70_SDW0_HOST_WAKE_STAT) { + writel(ACP70_SDW0_HOST_WAKE_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + adata->acp70_sdw0_wake_event = true; + sdw_wake_irq = true; + } + + if (ext_intr_stat1 & ACP70_SDW1_HOST_WAKE_STAT) { + writel(ACP70_SDW1_HOST_WAKE_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + adata->acp70_sdw1_wake_event = true; + sdw_wake_irq = true; + } + + if (ext_intr_stat1 & ACP70_SDW0_PME_STAT) { + writel(0, adata->acp63_base + ACP_SW0_WAKE_EN); + writel(ACP70_SDW0_PME_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + adata->acp70_sdw0_wake_event = true; + sdw_wake_irq = true; + } + + if (ext_intr_stat1 & ACP70_SDW1_PME_STAT) { + writel(0, adata->acp63_base + ACP_SW1_WAKE_EN); + writel(ACP70_SDW1_PME_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + adata->acp70_sdw1_wake_event = true; + sdw_wake_irq = true; + } + + if (sdw_wake_irq) { + handle_acp70_sdw_wake_event(adata); + irq_flag = 1; + } + return irq_flag; +} + static short int check_and_handle_sdw_dma_irq(struct acp63_dev_data *adata, u32 ext_intr_stat, u32 ext_intr_stat1) { @@ -163,6 +222,9 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id) irq_flag = 1; }
+ if (adata->acp_rev >= ACP70_PCI_REV) + irq_flag = check_and_handle_acp70_sdw_wake_irq(adata); + if (ext_intr_stat & BIT(PDM_DMA_STAT)) { ps_pdm_data = dev_get_drvdata(&adata->pdm_dev->dev); writel(BIT(PDM_DMA_STAT), adata->acp63_base + ACP_EXTERNAL_INTR_STAT);

Update module description for Pink Sardine platform acp pci driver, SoundWire dma driver and PDM driver modules.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/pci-ps.c | 2 +- sound/soc/amd/ps/ps-pdm-dma.c | 2 +- sound/soc/amd/ps/ps-sdw-dma.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 6a725cf36345..3a6034e074f5 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -723,7 +723,7 @@ module_pci_driver(ps_acp63_driver);
MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); MODULE_AUTHOR("Syed.SabaKareem@amd.com"); -MODULE_DESCRIPTION("AMD ACP Pink Sardine PCI driver"); +MODULE_DESCRIPTION("AMD common ACP PCI driver for ACP6.3, ACP7.0 & ACP7.1 platforms"); MODULE_IMPORT_NS("SOUNDWIRE_AMD_INIT"); MODULE_IMPORT_NS("SND_AMD_SOUNDWIRE_ACPI"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/amd/ps/ps-pdm-dma.c b/sound/soc/amd/ps/ps-pdm-dma.c index 318fc260f293..e726186fe8c6 100644 --- a/sound/soc/amd/ps/ps-pdm-dma.c +++ b/sound/soc/amd/ps/ps-pdm-dma.c @@ -458,6 +458,6 @@ static struct platform_driver acp63_pdm_dma_driver = { module_platform_driver(acp63_pdm_dma_driver);
MODULE_AUTHOR("Syed.SabaKareem@amd.com"); -MODULE_DESCRIPTION("AMD PINK SARDINE PDM Driver"); +MODULE_DESCRIPTION("AMD common PDM Driver for ACP6.3, ACP7,0 & ACP7.1 platforms"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:" DRV_NAME); diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 557d312a23b2..2461c6421ae9 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -793,6 +793,6 @@ static struct platform_driver acp63_sdw_dma_driver = { module_platform_driver(acp63_sdw_dma_driver);
MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); -MODULE_DESCRIPTION("AMD ACP6.3 PS SDW DMA Driver"); +MODULE_DESCRIPTION("AMD common SDW DMA Driver for ACP6.3, ACP7.0 & ACP7.1 platforms"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRV_NAME);

Update files description for acp pci driver, SoundWire DMA driver, PDM driver and acp header file as new support is added for ACP7.0 & ACP7.1 platforms.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/acp63.h | 4 ++-- sound/soc/amd/ps/pci-ps.c | 4 ++-- sound/soc/amd/ps/ps-pdm-dma.c | 4 ++-- sound/soc/amd/ps/ps-sdw-dma.c | 5 +++-- 4 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 9940151b0675..85feae45c44c 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -1,8 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* - * AMD ALSA SoC PDM Driver + * AMD Common ACP header file for ACP6.3, ACP7.0 & ACP7.1 platforms * - * Copyright (C) 2022, 2023 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (C) 2022, 2023, 2025 Advanced Micro Devices, Inc. All rights reserved. */
#include <linux/soundwire/sdw_amd.h> diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 3a6034e074f5..2cbfeb07d5c4 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * AMD Pink Sardine ACP PCI Driver + * AMD common ACP PCI driver for ACP6.3, ACP7.0 & ACP7.1 platforms. * - * Copyright 2022 Advanced Micro Devices, Inc. + * Copyright 2022, 2025 Advanced Micro Devices, Inc. */
#include <linux/pci.h> diff --git a/sound/soc/amd/ps/ps-pdm-dma.c b/sound/soc/amd/ps/ps-pdm-dma.c index e726186fe8c6..7cdeb34e8f73 100644 --- a/sound/soc/amd/ps/ps-pdm-dma.c +++ b/sound/soc/amd/ps/ps-pdm-dma.c @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * AMD ALSA SoC Pink Sardine PDM Driver + * AMD ALSA SoC common PDM Driver for ACP6.3, ACP7.0 & ACP7.1 platforms. * - * Copyright 2022 Advanced Micro Devices, Inc. + * Copyright 2022, 2025 Advanced Micro Devices, Inc. */
#include <linux/platform_device.h> diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 2461c6421ae9..21b336109c99 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * AMD ALSA SoC Pink Sardine SoundWire DMA Driver + * AMD ALSA SoC common SoundWire DMA Driver for ACP6.3, ACP7.0 and ACP7.1 + * platforms. * - * Copyright 2023 Advanced Micro Devices, Inc. + * Copyright 2023, 2025 Advanced Micro Devices, Inc. */
#include <linux/err.h>

Update Pink Sardine platform Kconfig option description.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/Kconfig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig index 803521178279..c7daae392d74 100644 --- a/sound/soc/amd/Kconfig +++ b/sound/soc/amd/Kconfig @@ -161,15 +161,15 @@ config SND_SOC_AMD_SOUNDWIRE If unsure select "N".
config SND_SOC_AMD_PS - tristate "AMD Audio Coprocessor-v6.3 Pink Sardine support" + tristate "AMD Audio Coprocessor-v6.3/v7.0/v7.1 support" select SND_SOC_AMD_SOUNDWIRE_LINK_BASELINE select SND_SOC_ACPI_AMD_MATCH depends on X86 && PCI && ACPI help - This option enables Audio Coprocessor i.e ACP v6.3 support on - AMD Pink sardine platform. By enabling this flag build will be - triggered for ACP PCI driver, ACP PDM DMA driver, ACP SoundWire - DMA driver. + This option enables Audio Coprocessor i.e ACP6.3/ACP7.0/ACP7.1 + variants support. By enabling this flag build will be triggered + for ACP PCI driver, ACP PDM DMA driver, ACP SoundWire DMA + driver. Say m if you have such a device. If unsure select "N".

Add SoundWire generic machine driver changes for legacy stack(No DSP) for ACP7.0 and ACP7.1 platforms.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/acp/acp-sdw-legacy-mach.c | 11 ++++++++ sound/soc/amd/acp/acp-sdw-mach-common.c | 34 +++++++++++++++++++++++++ sound/soc/amd/acp/soc_amd_sdw_common.h | 11 ++++++++ 3 files changed, 56 insertions(+)
diff --git a/sound/soc/amd/acp/acp-sdw-legacy-mach.c b/sound/soc/amd/acp/acp-sdw-legacy-mach.c index 9280cd30d19c..00aeea70f04e 100644 --- a/sound/soc/amd/acp/acp-sdw-legacy-mach.c +++ b/sound/soc/amd/acp/acp-sdw-legacy-mach.c @@ -122,6 +122,13 @@ static int create_sdw_dailink(struct snd_soc_card *card, if (ret) return ret; break; + case ACP70_PCI_REV: + case ACP71_PCI_REV: + ret = get_acp70_cpu_pin_id(ffs(soc_end->link_mask - 1), + *be_id, &cpu_pin_id, dev); + if (ret) + return ret; + break; default: return -EINVAL; } @@ -221,6 +228,8 @@ static int create_sdw_dailinks(struct snd_soc_card *card,
switch (amd_ctx->acp_rev) { case ACP63_PCI_REV: + case ACP70_PCI_REV: + case ACP71_PCI_REV: sdw_platform_component->name = "amd_ps_sdw_dma.0"; break; default: @@ -266,6 +275,8 @@ static int create_dmic_dailinks(struct snd_soc_card *card,
switch (amd_ctx->acp_rev) { case ACP63_PCI_REV: + case ACP70_PCI_REV: + case ACP71_PCI_REV: pdm_cpu->name = "acp_ps_pdm_dma.0"; pdm_platform->name = "acp_ps_pdm_dma.0"; break; diff --git a/sound/soc/amd/acp/acp-sdw-mach-common.c b/sound/soc/amd/acp/acp-sdw-mach-common.c index 6f5c39ed1a18..e5f394dc2f4c 100644 --- a/sound/soc/amd/acp/acp-sdw-mach-common.c +++ b/sound/soc/amd/acp/acp-sdw-mach-common.c @@ -59,6 +59,40 @@ int get_acp63_cpu_pin_id(u32 sdw_link_id, int be_id, int *cpu_pin_id, struct dev } EXPORT_SYMBOL_NS_GPL(get_acp63_cpu_pin_id, "SND_SOC_AMD_SDW_MACH");
+int get_acp70_cpu_pin_id(u32 sdw_link_id, int be_id, int *cpu_pin_id, struct device *dev) +{ + switch (sdw_link_id) { + case AMD_SDW0: + case AMD_SDW1: + switch (be_id) { + case SOC_SDW_JACK_OUT_DAI_ID: + *cpu_pin_id = ACP70_SW_AUDIO0_TX; + break; + case SOC_SDW_JACK_IN_DAI_ID: + *cpu_pin_id = ACP70_SW_AUDIO0_RX; + break; + case SOC_SDW_AMP_OUT_DAI_ID: + *cpu_pin_id = ACP70_SW_AUDIO1_TX; + break; + case SOC_SDW_AMP_IN_DAI_ID: + *cpu_pin_id = ACP70_SW_AUDIO1_RX; + break; + case SOC_SDW_DMIC_DAI_ID: + *cpu_pin_id = ACP70_SW_AUDIO2_RX; + break; + default: + dev_err(dev, "Invalid be id:%d\n", be_id); + return -EINVAL; + } + break; + default: + return -EINVAL; + } + dev_dbg(dev, "sdw_link_id:%d, be_id:%d, cpu_pin_id:%d\n", sdw_link_id, be_id, *cpu_pin_id); + return 0; +} +EXPORT_SYMBOL_NS_GPL(get_acp70_cpu_pin_id, "SND_SOC_AMD_SDW_MACH"); + MODULE_DESCRIPTION("AMD SoundWire Common Machine driver"); MODULE_AUTHOR("Vijendar Mukunda Vijendar.Mukunda@amd.com"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/amd/acp/soc_amd_sdw_common.h b/sound/soc/amd/acp/soc_amd_sdw_common.h index b7bae107c13e..9bedccfe25a9 100644 --- a/sound/soc/amd/acp/soc_amd_sdw_common.h +++ b/sound/soc/amd/acp/soc_amd_sdw_common.h @@ -19,6 +19,8 @@
#define AMD_SDW_MAX_GROUPS 9 #define ACP63_PCI_REV 0x63 +#define ACP70_PCI_REV 0x70 +#define ACP71_PCI_REV 0x71 #define SOC_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0)) #define ASOC_SDW_FOUR_SPK BIT(4) #define ASOC_SDW_ACP_DMIC BIT(5) @@ -38,11 +40,20 @@
#define ACP_DMIC_BE_ID 4
+#define ACP70_SW_AUDIO0_TX 0 +#define ACP70_SW_AUDIO1_TX 1 +#define ACP70_SW_AUDIO2_TX 2 + +#define ACP70_SW_AUDIO0_RX 3 +#define ACP70_SW_AUDIO1_RX 4 +#define ACP70_SW_AUDIO2_RX 5 + struct amd_mc_ctx { unsigned int acp_rev; unsigned int max_sdw_links; };
int get_acp63_cpu_pin_id(u32 sdw_link_id, int be_id, int *cpu_pin_id, struct device *dev); +int get_acp70_cpu_pin_id(u32 sdw_link_id, int be_id, int *cpu_pin_id, struct device *dev);
#endif

Add support for corresponding codecs on ACP7.0 platform hardware configuration.
SDW0: RT711 Jack SDW0: RT1316 Left Speaker SDW0: RT1316 Right Speaker SDW1: RT714 DMIC
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/acp/Makefile | 2 +- sound/soc/amd/acp/amd-acp70-acpi-match.c | 88 ++++++++++++++++++++++++ sound/soc/amd/mach-config.h | 1 + sound/soc/amd/ps/pci-ps.c | 6 +- 4 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 sound/soc/amd/acp/amd-acp70-acpi-match.c
diff --git a/sound/soc/amd/acp/Makefile b/sound/soc/amd/acp/Makefile index bb2702036338..7c75892e678b 100644 --- a/sound/soc/amd/acp/Makefile +++ b/sound/soc/amd/acp/Makefile @@ -22,7 +22,7 @@ snd-acp70-y := acp70.o snd-acp-mach-y := acp-mach-common.o snd-acp-legacy-mach-y := acp-legacy-mach.o acp3x-es83xx/acp3x-es83xx.o snd-acp-sof-mach-y := acp-sof-mach.o -snd-soc-acpi-amd-match-y := amd-acp63-acpi-match.o +snd-soc-acpi-amd-match-y := amd-acp63-acpi-match.o amd-acp70-acpi-match.o snd-acp-sdw-mach-y := acp-sdw-mach-common.o snd-acp-sdw-sof-mach-y += acp-sdw-sof-mach.o snd-acp-sdw-legacy-mach-y += acp-sdw-legacy-mach.o diff --git a/sound/soc/amd/acp/amd-acp70-acpi-match.c b/sound/soc/amd/acp/amd-acp70-acpi-match.c new file mode 100644 index 000000000000..fa59b462f227 --- /dev/null +++ b/sound/soc/amd/acp/amd-acp70-acpi-match.c @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * amd-acp70-acpi-match.c - tables and support for ACP 7.0 & ACP7.1 + * ACPI enumeration. + * + * Copyright 2025 Advanced Micro Devices, Inc. + */ + +#include <sound/soc-acpi.h> +#include "../mach-config.h" + +static const struct snd_soc_acpi_endpoint single_endpoint = { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0 +}; + +static const struct snd_soc_acpi_endpoint spk_l_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 0, + .group_id = 1 +}; + +static const struct snd_soc_acpi_endpoint spk_r_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 1, + .group_id = 1 +}; + +static const struct snd_soc_acpi_adr_device rt711_rt1316_group_adr[] = { + { + .adr = 0x000030025D071101ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt711" + }, + { + .adr = 0x000030025D131601ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "rt1316-1" + }, + { + .adr = 0x000032025D131601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1316-2" + }, +}; + +static const struct snd_soc_acpi_adr_device rt714_adr[] = { + { + .adr = 0x130025d071401ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt714" + } +}; + +static const struct snd_soc_acpi_link_adr acp70_4_in_1_sdca[] = { + { .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_rt1316_group_adr), + .adr_d = rt711_rt1316_group_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt714_adr), + .adr_d = rt714_adr, + }, + {} +}; + +struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sdw_machines[] = { + { + .link_mask = BIT(0) | BIT(1), + .links = acp70_4_in_1_sdca, + .drv_name = "amd_sdw", + }, + {}, +}; +EXPORT_SYMBOL(snd_soc_acpi_amd_acp70_sdw_machines); + +MODULE_DESCRIPTION("AMD ACP7.0 & ACP7.1 tables and support for ACPI enumeration"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); diff --git a/sound/soc/amd/mach-config.h b/sound/soc/amd/mach-config.h index a86c76f781f9..fdf016a64bbf 100644 --- a/sound/soc/amd/mach-config.h +++ b/sound/soc/amd/mach-config.h @@ -26,6 +26,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sof_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sdw_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sof_sdw_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sof_machines[]; +extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sdw_machines[];
struct config_entry { u32 flags; diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 2cbfeb07d5c4..220dca8cba85 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -632,7 +632,11 @@ static int snd_acp63_probe(struct pci_dev *pci, dev_err(&pci->dev, "ACP platform devices creation failed\n"); goto de_init; } - adata->machines = snd_soc_acpi_amd_acp63_sdw_machines; + if (adata->acp_rev >= ACP70_PCI_REV) + adata->machines = snd_soc_acpi_amd_acp70_sdw_machines; + else + adata->machines = snd_soc_acpi_amd_acp63_sdw_machines; + ret = acp63_machine_register(&pci->dev); if (ret) { dev_err(&pci->dev, "ACP machine register failed\n");

Patch adds driver data and match table for rt722 multi-function codec on acp7.0 and acp7.1 platforms at sdw link0 for legacy(NO DSP) stack.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/acp/amd-acp70-acpi-match.c | 44 ++++++++++++++++++++++++ 1 file changed, 44 insertions(+)
diff --git a/sound/soc/amd/acp/amd-acp70-acpi-match.c b/sound/soc/amd/acp/amd-acp70-acpi-match.c index fa59b462f227..fe166015dc29 100644 --- a/sound/soc/amd/acp/amd-acp70-acpi-match.c +++ b/sound/soc/amd/acp/amd-acp70-acpi-match.c @@ -73,7 +73,51 @@ static const struct snd_soc_acpi_link_adr acp70_4_in_1_sdca[] = { {} };
+static const struct snd_soc_acpi_endpoint rt722_endpoints[] = { + { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + +static const struct snd_soc_acpi_adr_device rt722_0_single_adr[] = { + { + .adr = 0x000030025d072201ull, + .num_endpoints = ARRAY_SIZE(rt722_endpoints), + .endpoints = rt722_endpoints, + .name_prefix = "rt722" + } +}; + +static const struct snd_soc_acpi_link_adr acp70_rt722_only[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt722_0_single_adr), + .adr_d = rt722_0_single_adr, + }, + {} +}; + struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sdw_machines[] = { + { + .link_mask = BIT(0), + .links = acp70_rt722_only, + .drv_name = "amd_sdw", + }, { .link_mask = BIT(0) | BIT(1), .links = acp70_4_in_1_sdca,

This patch adds below machine configuration for the ACP7.0 & ACP7.1 platforms.
Link 0: RT722 codec with three endpoints: Headset, Speaker, and DMIC. Link 1: RT1320 amplifier.
Note: The Speaker endpoint on the RT722 codec is not used.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/acp/Kconfig | 1 + sound/soc/amd/acp/amd-acp70-acpi-match.c | 28 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+)
diff --git a/sound/soc/amd/acp/Kconfig b/sound/soc/amd/acp/Kconfig index 03f3fcbba5af..53793ec7c7b4 100644 --- a/sound/soc/amd/acp/Kconfig +++ b/sound/soc/amd/acp/Kconfig @@ -156,6 +156,7 @@ config SND_SOC_AMD_LEGACY_SDW_MACH select SND_SOC_RT712_SDCA_SDW select SND_SOC_RT712_SDCA_DMIC_SDW select SND_SOC_RT1316_SDW + select SND_SOC_RT1320_SDW select SND_SOC_RT715_SDW select SND_SOC_RT715_SDCA_SDW select SND_SOC_RT722_SDCA_SDW diff --git a/sound/soc/amd/acp/amd-acp70-acpi-match.c b/sound/soc/amd/acp/amd-acp70-acpi-match.c index fe166015dc29..e87ccfeee5bd 100644 --- a/sound/soc/amd/acp/amd-acp70-acpi-match.c +++ b/sound/soc/amd/acp/amd-acp70-acpi-match.c @@ -103,6 +103,15 @@ static const struct snd_soc_acpi_adr_device rt722_0_single_adr[] = { } };
+static const struct snd_soc_acpi_adr_device rt1320_1_single_adr[] = { + { + .adr = 0x000130025D132001ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt1320-1" + } +}; + static const struct snd_soc_acpi_link_adr acp70_rt722_only[] = { { .mask = BIT(0), @@ -112,7 +121,26 @@ static const struct snd_soc_acpi_link_adr acp70_rt722_only[] = { {} };
+static const struct snd_soc_acpi_link_adr acp70_rt722_l0_rt1320_l1[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt722_0_single_adr), + .adr_d = rt722_0_single_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1320_1_single_adr), + .adr_d = rt1320_1_single_adr, + }, + {} +}; + struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sdw_machines[] = { + { + .link_mask = BIT(0) | BIT(1), + .links = acp70_rt722_l0_rt1320_l1, + .drv_name = "amd_sdw", + }, { .link_mask = BIT(0), .links = acp70_rt722_only,

This patch adds a quirk to include the codec amplifier function for Dell SKU's listed in quirk table.
Note: In these SKU's, the RT722 codec amplifier is excluded, and an external amplifier is used instead.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/acp/acp-sdw-legacy-mach.c | 34 +++++++++++++++++++++++++ sound/soc/amd/acp/soc_amd_sdw_common.h | 1 + 2 files changed, 35 insertions(+)
diff --git a/sound/soc/amd/acp/acp-sdw-legacy-mach.c b/sound/soc/amd/acp/acp-sdw-legacy-mach.c index 00aeea70f04e..2020c5cfb3d5 100644 --- a/sound/soc/amd/acp/acp-sdw-legacy-mach.c +++ b/sound/soc/amd/acp/acp-sdw-legacy-mach.c @@ -28,6 +28,8 @@ static void log_quirks(struct device *dev) SOC_JACK_JDSRC(soc_sdw_quirk)); if (soc_sdw_quirk & ASOC_SDW_ACP_DMIC) dev_dbg(dev, "quirk SOC_SDW_ACP_DMIC enabled\n"); + if (soc_sdw_quirk & ASOC_SDW_CODEC_SPKR) + dev_dbg(dev, "quirk ASOC_SDW_CODEC_SPKR enabled\n"); }
static int soc_sdw_quirk_cb(const struct dmi_system_id *id) @@ -45,6 +47,38 @@ static const struct dmi_system_id soc_sdw_quirk_table[] = { }, .driver_data = (void *)RT711_JD2, }, + { + .callback = soc_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0D80"), + }, + .driver_data = (void *)(ASOC_SDW_CODEC_SPKR), + }, + { + .callback = soc_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0D81"), + }, + .driver_data = (void *)(ASOC_SDW_CODEC_SPKR), + }, + { + .callback = soc_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0D82"), + }, + .driver_data = (void *)(ASOC_SDW_CODEC_SPKR), + }, + { + .callback = soc_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0D83"), + }, + .driver_data = (void *)(ASOC_SDW_CODEC_SPKR), + }, {} };
diff --git a/sound/soc/amd/acp/soc_amd_sdw_common.h b/sound/soc/amd/acp/soc_amd_sdw_common.h index 9bedccfe25a9..1f24e0e06487 100644 --- a/sound/soc/amd/acp/soc_amd_sdw_common.h +++ b/sound/soc/amd/acp/soc_amd_sdw_common.h @@ -24,6 +24,7 @@ #define SOC_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0)) #define ASOC_SDW_FOUR_SPK BIT(4) #define ASOC_SDW_ACP_DMIC BIT(5) +#define ASOC_SDW_CODEC_SPKR BIT(15)
#define AMD_SDW0 0 #define AMD_SDW1 1

On Fri, 07 Feb 2025 11:57:54 +0530, Vijendar Mukunda wrote:
This patch series includes the below changes
- Refactor existing ACP6.3 platform ACP PCI driver, SoundWire DMA driver code.
- Add Audio IO support for ACP7.0 and ACP7.1 platforms for
SoundWire IO and ACP PDM controller combination.
- Add SoundWire generic machine driver changes for legacy stack
(No DSP enabled) for ACP7.0 & ACP7.1 platforms.
- Add SoundWire machines for ACP7.0 & ACP7.1 platforms.
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[01/25] ASoC: amd: ps: rename structure names, variable and other macros commit: e2ceac2f323625632f12dd5333092976298a0cde [02/25] ASoC: amd: ps: use macro for ACP6.3 pci revision id commit: 4b36a47e2d989b98953dbfb1e97da0f0169f5086 [03/25] ASoC: amd: ps: add acp pci driver hw_ops for acp6.3 platform commit: db746fff89a14419379226ce0df8b94f472cf38c [04/25] ASoC: amd: ps: add callback functions for acp pci driver pm ops commit: 491628388005a26c02d6827e649284357daec213 [05/25] ASoC: amd: ps: add callback to read acp pin configuration commit: 6547577e94ae3d9f8ff30d3267fe7ec394e3b20d [06/25] ASoC: amd: ps: add soundwire dma irq thread callback commit: 0a27b2d7a224326fab543ca586d501fe1857b655 [07/25] ASoC: amd: ps: refactor soundwire dma interrupt handling commit: 4516be370ced14c4fb454fd6cc016e47bffe109e [08/25] ASoC: amd: ps: store acp revision id in SoundWire dma driver private data commit: fcb754602724fa2a1d0db72f13ddc3ef0306f911 [09/25] ASoC: amd: ps: refactor soundwire dma driver code commit: 0fa0843db17ccd427fc7a23d313aafa88fc89e04 [10/25] ASoC: amd: ps: refactor soundwire dma interrupts enable/disable sequence commit: 43d6140cedad9f031b47dfde6f85856e007b3f04 [11/25] ASoC: amd: ps: rename acp_restore_sdw_dma_config() function commit: 605aab3b3ca83f58681841b2dd16d4a7baefde6c [12/25] ASoC: amd: ps: add pci driver hw_ops for ACP7.0 & ACP7.1 variants commit: 7c0ea26c57b0bb72d503fe27d6533f5addc5e3a3 [13/25] ASoC: amd: ps: add pm ops related hw_ops for ACP7.0 & ACP7.1 platforms commit: fde277dbcf53be685d0b9976d636366c80a74da8 [14/25] ASoC: amd: ps: add ACP7.0 & ACP7.1 specific soundwire dma driver changes commit: c878d5c1a525b88807d9d79888fe8340bcbf1aa3 [15/25] ASoC: amd: ps: implement function to restore dma config for ACP7.0 platform commit: 1c35755f46423150e19ff57448786b4bb48fdb46 [16/25] ASoC: amd: ps: add soundwire dma interrupts handling for ACP7.0 platform commit: 0b6914a0121b4c9fc8f575b60a5dd43b74612908 [17/25] ASoC: amd: ps: add soundwire wake interrupt handling commit: 3898b189079c85735f57759b0d407518c01c745e [18/25] ASoC: amd: ps: update module description commit: 0eb8f83c055cb3461734710d1b1ce2dd4f01806e [19/25] ASoC: amd: ps: update file description and copyright year commit: f1e91acacf86fb2cd7478af490326cb9aa63e8ae [20/25] ASoC: amd: update Pink Sardine platform Kconfig description commit: 552f66c40134542f15d4302837e7d581a0b8e217 [21/25] ASoC: amd: acp: add machine driver changes for ACP7.0 and ACP7.1 platforms commit: 638ad2bdb2f994c8bd99cc40e0c4796a8617ccf3 [22/25] ASoC: amd: acp: add RT711, RT714 & RT1316 support for ACP7.0 platform commit: 187150671d83324f1ca56f7ab5e00f16a3b9f2a9 [23/25] ASoC: amd: acp: amd-acp70-acpi-match: Add rt722 support commit: d0252b0b945ec67fd09fc764dcadf445fb7757ee [24/25] ASoC: amd: acp: amd-acp70-acpi-match: Add RT1320 & RT722 combination soundwire machine commit: 31e3100d5e1fe69f944f84867be0cbfa5fd380c8 [25/25] ASoC: amd: amd_sdw: Add quirks for Dell SKU's commit: 4bb5b6f13fd83b32c8a93fbd399e7558415d1ce0
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (3)
-
Mark Brown
-
Mukunda,Vijendar
-
Vijendar Mukunda