aboutsummaryrefslogtreecommitdiff
path: root/sound/soc/sof
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sof')
-rw-r--r--sound/soc/sof/amd/Kconfig11
-rw-r--r--sound/soc/sof/amd/Makefile4
-rw-r--r--sound/soc/sof/amd/acp-common.c3
-rw-r--r--sound/soc/sof/amd/acp-dsp-offset.h24
-rw-r--r--sound/soc/sof/amd/acp-loader.c2
-rw-r--r--sound/soc/sof/amd/acp.c88
-rw-r--r--sound/soc/sof/amd/acp.h11
-rw-r--r--sound/soc/sof/amd/acp70.c142
-rw-r--r--sound/soc/sof/amd/pci-acp63.c2
-rw-r--r--sound/soc/sof/amd/pci-acp70.c112
-rw-r--r--sound/soc/sof/amd/pci-rmb.c1
-rw-r--r--sound/soc/sof/amd/pci-rn.c1
-rw-r--r--sound/soc/sof/amd/pci-vangogh.c1
-rw-r--r--sound/soc/sof/imx/imx8.c2
-rw-r--r--sound/soc/sof/imx/imx8m.c2
-rw-r--r--sound/soc/sof/imx/imx8ulp.c2
-rw-r--r--sound/soc/sof/intel/Kconfig17
-rw-r--r--sound/soc/sof/intel/Makefile2
-rw-r--r--sound/soc/sof/intel/bdw.c2
-rw-r--r--sound/soc/sof/intel/byt.c2
-rw-r--r--sound/soc/sof/intel/hda-dsp.c1
-rw-r--r--sound/soc/sof/intel/hda-stream.c4
-rw-r--r--sound/soc/sof/intel/hda.c282
-rw-r--r--sound/soc/sof/intel/hda.h1
-rw-r--r--sound/soc/sof/intel/lnl.c27
-rw-r--r--sound/soc/sof/intel/mtl.c16
-rw-r--r--sound/soc/sof/intel/mtl.h2
-rw-r--r--sound/soc/sof/intel/pci-ptl.c77
-rw-r--r--sound/soc/sof/intel/shim.h1
-rw-r--r--sound/soc/sof/mediatek/mt8186/mt8186.c2
-rw-r--r--sound/soc/sof/mediatek/mt8195/mt8195.c2
-rw-r--r--sound/soc/sof/pcm.c2
-rw-r--r--sound/soc/sof/sof-audio.h8
-rw-r--r--sound/soc/sof/sof-priv.h16
-rw-r--r--sound/soc/sof/topology.c8
35 files changed, 659 insertions, 221 deletions
diff --git a/sound/soc/sof/amd/Kconfig b/sound/soc/sof/amd/Kconfig
index 2729c6eb3feb..f4cafe801017 100644
--- a/sound/soc/sof/amd/Kconfig
+++ b/sound/soc/sof/amd/Kconfig
@@ -23,6 +23,7 @@ config SND_SOC_SOF_AMD_COMMON
select SND_AMD_ACP_CONFIG
select SND_SOC_SOF_XTENSA
select SND_SOC_SOF_ACP_PROBES
+ select SND_SOC_ACPI_AMD_MATCH
select SND_SOC_ACPI if ACPI
help
This option is not user-selectable but automatically handled by
@@ -87,4 +88,14 @@ config SND_SOC_SOF_AMD_ACP63
AMD ACP6.3 version based platforms.
Say Y if you want to enable SOF on ACP6.3 based platform.
If unsure select "N".
+
+config SND_SOC_SOF_AMD_ACP70
+ tristate "SOF support for ACP7.0 platform"
+ depends on SND_SOC_SOF_PCI
+ select SND_SOC_SOF_AMD_COMMON
+ help
+ Select this option for SOF support on
+ AMD ACP7.0 version based platforms.
+ Say Y if you want to enable SOF on ACP7.0 based platform.
+
endif
diff --git a/sound/soc/sof/amd/Makefile b/sound/soc/sof/amd/Makefile
index 63fe0d55fd0e..6ae39fd5a836 100644
--- a/sound/soc/sof/amd/Makefile
+++ b/sound/soc/sof/amd/Makefile
@@ -2,7 +2,7 @@
# This file is provided under a dual BSD/GPLv2 license. When using or
# redistributing this file, you may do so under either license.
#
-# Copyright(c) 2021, 2023 Advanced Micro Devices, Inc. All rights reserved.
+# Copyright(c) 2021, 2023, 2024 Advanced Micro Devices, Inc. All rights reserved.
snd-sof-amd-acp-y := acp.o acp-loader.o acp-ipc.o acp-pcm.o acp-stream.o acp-trace.o acp-common.o
snd-sof-amd-acp-$(CONFIG_SND_SOC_SOF_ACP_PROBES) += acp-probes.o
@@ -10,9 +10,11 @@ snd-sof-amd-renoir-y := pci-rn.o renoir.o
snd-sof-amd-rembrandt-y := pci-rmb.o rembrandt.o
snd-sof-amd-vangogh-y := pci-vangogh.o vangogh.o
snd-sof-amd-acp63-y := pci-acp63.o acp63.o
+snd-sof-amd-acp70-y := pci-acp70.o acp70.o
obj-$(CONFIG_SND_SOC_SOF_AMD_COMMON) += snd-sof-amd-acp.o
obj-$(CONFIG_SND_SOC_SOF_AMD_RENOIR) += snd-sof-amd-renoir.o
obj-$(CONFIG_SND_SOC_SOF_AMD_REMBRANDT) += snd-sof-amd-rembrandt.o
obj-$(CONFIG_SND_SOC_SOF_AMD_VANGOGH) += snd-sof-amd-vangogh.o
obj-$(CONFIG_SND_SOC_SOF_AMD_ACP63) += snd-sof-amd-acp63.o
+obj-$(CONFIG_SND_SOC_SOF_AMD_ACP70) += snd-sof-amd-acp70.o
diff --git a/sound/soc/sof/amd/acp-common.c b/sound/soc/sof/amd/acp-common.c
index 81bb93e98358..dbcaac84cb73 100644
--- a/sound/soc/sof/amd/acp-common.c
+++ b/sound/soc/sof/amd/acp-common.c
@@ -153,6 +153,7 @@ static struct snd_soc_acpi_mach *amd_sof_sdw_machine_select(struct snd_sof_dev *
break;
}
if (mach && mach->link_mask) {
+ mach->mach_params.subsystem_rev = acp_data->pci_rev;
mach->mach_params.links = mach->links;
mach->mach_params.link_mask = mach->link_mask;
mach->mach_params.platform = dev_name(sdev->dev);
@@ -173,6 +174,7 @@ static struct snd_soc_acpi_mach *amd_sof_sdw_machine_select(struct snd_sof_dev *
struct snd_soc_acpi_mach *amd_sof_machine_select(struct snd_sof_dev *sdev)
{
struct snd_sof_pdata *sof_pdata = sdev->pdata;
+ struct acp_dev_data *acp_data = sdev->pdata->hw_pdata;
const struct sof_dev_desc *desc = sof_pdata->desc;
struct snd_soc_acpi_mach *mach = NULL;
@@ -186,6 +188,7 @@ struct snd_soc_acpi_mach *amd_sof_machine_select(struct snd_sof_dev *sdev)
}
}
+ mach->mach_params.subsystem_rev = acp_data->pci_rev;
sof_pdata->tplg_filename = mach->sof_tplg_filename;
sof_pdata->fw_filename = mach->fw_filename;
diff --git a/sound/soc/sof/amd/acp-dsp-offset.h b/sound/soc/sof/amd/acp-dsp-offset.h
index 072b703f9b3f..ecdcae07ace7 100644
--- a/sound/soc/sof/amd/acp-dsp-offset.h
+++ b/sound/soc/sof/amd/acp-dsp-offset.h
@@ -3,7 +3,7 @@
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
- * Copyright(c) 2021, 2023 Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright(c) 2021, 2023, 2024 Advanced Micro Devices, Inc. All rights reserved.
*
* Author: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
*/
@@ -23,6 +23,17 @@
#define ACP_DMA_CH_STS 0xE8
#define ACP_DMA_CH_GROUP 0xEC
#define ACP_DMA_CH_RST_STS 0xF0
+#define ACP70_DMA_CNTL_0 0x00
+#define ACP70_DMA_DSCR_STRT_IDX_0 0x28
+#define ACP70_DMA_DSCR_CNT_0 0x50
+#define ACP70_DMA_PRIO_0 0x78
+#define ACP70_DMA_CUR_DSCR_0 0xA0
+#define ACP70_DMA_ERR_STS_0 0xF0
+#define ACP70_DMA_DESC_BASE_ADDR 0x118
+#define ACP70_DMA_DESC_MAX_NUM_DSCR 0x11C
+#define ACP70_DMA_CH_STS 0x120
+#define ACP70_DMA_CH_GROUP 0x124
+#define ACP70_DMA_CH_RST_STS 0x128
/* Registers from ACP_DSP_0 block */
#define ACP_DSP0_RUNSTALL 0x414
@@ -56,11 +67,13 @@
#define ACP3X_PGFSM_BASE 0x141C
#define ACP5X_PGFSM_BASE 0x1424
#define ACP6X_PGFSM_BASE 0x1024
+#define ACP70_PGFSM_BASE ACP6X_PGFSM_BASE
#define PGFSM_CONTROL_OFFSET 0x0
#define PGFSM_STATUS_OFFSET 0x4
#define ACP3X_CLKMUX_SEL 0x1424
#define ACP5X_CLKMUX_SEL 0x142C
#define ACP6X_CLKMUX_SEL 0x102C
+#define ACP70_CLKMUX_SEL ACP6X_CLKMUX_SEL
/* Registers from ACP_INTR block */
#define ACP3X_EXT_INTR_STAT 0x1808
@@ -69,22 +82,30 @@
#define ACP6X_EXTERNAL_INTR_CNTL 0x1A04
#define ACP6X_EXT_INTR_STAT 0x1A0C
#define ACP6X_EXT_INTR_STAT1 0x1A10
+#define ACP70_EXTERNAL_INTR_ENB ACP6X_EXTERNAL_INTR_ENB
+#define ACP70_EXTERNAL_INTR_CNTL ACP6X_EXTERNAL_INTR_CNTL
+#define ACP70_EXT_INTR_STAT ACP6X_EXT_INTR_STAT
+#define ACP70_EXT_INTR_STAT1 ACP6X_EXT_INTR_STAT1
#define ACP3X_DSP_SW_INTR_BASE 0x1814
#define ACP5X_DSP_SW_INTR_BASE 0x1814
#define ACP6X_DSP_SW_INTR_BASE 0x1808
+#define ACP70_DSP_SW_INTR_BASE ACP6X_DSP_SW_INTR_BASE
#define DSP_SW_INTR_CNTL_OFFSET 0x0
#define DSP_SW_INTR_STAT_OFFSET 0x4
#define DSP_SW_INTR_TRIG_OFFSET 0x8
#define ACP3X_ERROR_STATUS 0x18C4
#define ACP6X_ERROR_STATUS 0x1A4C
+#define ACP70_ERROR_STATUS ACP6X_ERROR_STATUS
#define ACP3X_AXI2DAGB_SEM_0 0x1880
#define ACP5X_AXI2DAGB_SEM_0 0x1884
#define ACP6X_AXI2DAGB_SEM_0 0x1874
+#define ACP70_AXI2DAGB_SEM_0 ACP6X_AXI2DAGB_SEM_0
/* ACP common registers to report errors related to I2S & SoundWire interfaces */
#define ACP3X_SW_I2S_ERROR_REASON 0x18C8
#define ACP6X_SW0_I2S_ERROR_REASON 0x18B4
+#define ACP7X_SW0_I2S_ERROR_REASON ACP6X_SW0_I2S_ERROR_REASON
#define ACP_SW1_I2S_ERROR_REASON 0x1A50
/* Registers from ACP_SHA block */
@@ -101,6 +122,7 @@
#define ACP_SCRATCH_REG_0 0x10000
#define ACP6X_DSP_FUSION_RUNSTALL 0x0644
+#define ACP70_DSP_FUSION_RUNSTALL ACP6X_DSP_FUSION_RUNSTALL
/* Cache window registers */
#define ACP_DSP0_CACHE_OFFSET0 0x0420
diff --git a/sound/soc/sof/amd/acp-loader.c b/sound/soc/sof/amd/acp-loader.c
index 2d5e58846499..19f10dd77e4b 100644
--- a/sound/soc/sof/amd/acp-loader.c
+++ b/sound/soc/sof/amd/acp-loader.c
@@ -219,7 +219,7 @@ int acp_dsp_pre_fw_run(struct snd_sof_dev *sdev)
dev_err(sdev->dev, "acp dma transfer status: %d\n", ret);
}
- if (desc->rev > 3) {
+ if (adata->pci_rev > ACP_RN_PCI_ID) {
/* Cache Window enable */
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DSP0_CACHE_OFFSET0, desc->sram_pte_offset);
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DSP0_CACHE_SIZE0, SRAM1_SIZE | BIT(31));
diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c
index 85b58c8ccd0d..d579c3849392 100644
--- a/sound/soc/sof/amd/acp.c
+++ b/sound/soc/sof/amd/acp.c
@@ -64,13 +64,24 @@ static void init_dma_descriptor(struct acp_dev_data *adata)
{
struct snd_sof_dev *sdev = adata->dev;
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
+ struct acp_dev_data *acp_data = sdev->pdata->hw_pdata;
unsigned int addr;
+ unsigned int acp_dma_desc_base_addr, acp_dma_desc_max_num_dscr;
addr = desc->sram_pte_offset + sdev->debug_box.offset +
offsetof(struct scratch_reg_conf, dma_desc);
- snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_DESC_BASE_ADDR, addr);
- snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_DESC_MAX_NUM_DSCR, ACP_MAX_DESC_CNT);
+ switch (acp_data->pci_rev) {
+ case ACP70_PCI_ID:
+ acp_dma_desc_base_addr = ACP70_DMA_DESC_BASE_ADDR;
+ acp_dma_desc_max_num_dscr = ACP70_DMA_DESC_MAX_NUM_DSCR;
+ break;
+ default:
+ acp_dma_desc_base_addr = ACP_DMA_DESC_BASE_ADDR;
+ acp_dma_desc_max_num_dscr = ACP_DMA_DESC_MAX_NUM_DSCR;
+ }
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, acp_dma_desc_base_addr, addr);
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, acp_dma_desc_max_num_dscr, ACP_MAX_DESC_CNT);
}
static void configure_dma_descriptor(struct acp_dev_data *adata, unsigned short idx,
@@ -92,29 +103,51 @@ static int config_dma_channel(struct acp_dev_data *adata, unsigned int ch,
unsigned int idx, unsigned int dscr_count)
{
struct snd_sof_dev *sdev = adata->dev;
+ struct acp_dev_data *acp_data = sdev->pdata->hw_pdata;
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
unsigned int val, status;
+ unsigned int acp_dma_cntl_0, acp_dma_ch_rst_sts, acp_dma_dscr_err_sts_0;
+ unsigned int acp_dma_dscr_cnt_0, acp_dma_prio_0, acp_dma_dscr_strt_idx_0;
int ret;
- snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_CNTL_0 + ch * sizeof(u32),
+ switch (acp_data->pci_rev) {
+ case ACP70_PCI_ID:
+ acp_dma_cntl_0 = ACP70_DMA_CNTL_0;
+ acp_dma_ch_rst_sts = ACP70_DMA_CH_RST_STS;
+ acp_dma_dscr_err_sts_0 = ACP70_DMA_ERR_STS_0;
+ acp_dma_dscr_cnt_0 = ACP70_DMA_DSCR_CNT_0;
+ acp_dma_prio_0 = ACP70_DMA_PRIO_0;
+ acp_dma_dscr_strt_idx_0 = ACP70_DMA_DSCR_STRT_IDX_0;
+ break;
+ default:
+ acp_dma_cntl_0 = ACP_DMA_CNTL_0;
+ acp_dma_ch_rst_sts = ACP_DMA_CH_RST_STS;
+ acp_dma_dscr_err_sts_0 = ACP_DMA_ERR_STS_0;
+ acp_dma_dscr_cnt_0 = ACP_DMA_DSCR_CNT_0;
+ acp_dma_prio_0 = ACP_DMA_PRIO_0;
+ acp_dma_dscr_strt_idx_0 = ACP_DMA_DSCR_STRT_IDX_0;
+ }
+
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, acp_dma_cntl_0 + ch * sizeof(u32),
ACP_DMA_CH_RST | ACP_DMA_CH_GRACEFUL_RST_EN);
- ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_DMA_CH_RST_STS, val,
+ ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, acp_dma_ch_rst_sts, val,
val & (1 << ch), ACP_REG_POLL_INTERVAL,
ACP_REG_POLL_TIMEOUT_US);
if (ret < 0) {
status = snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->acp_error_stat);
- val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DMA_ERR_STS_0 + ch * sizeof(u32));
+ val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, acp_dma_dscr_err_sts_0 +
+ ch * sizeof(u32));
dev_err(sdev->dev, "ACP_DMA_ERR_STS :0x%x ACP_ERROR_STATUS :0x%x\n", val, status);
return ret;
}
- snd_sof_dsp_write(sdev, ACP_DSP_BAR, (ACP_DMA_CNTL_0 + ch * sizeof(u32)), 0);
- snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_DSCR_CNT_0 + ch * sizeof(u32), dscr_count);
- snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_DSCR_STRT_IDX_0 + ch * sizeof(u32), idx);
- snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_PRIO_0 + ch * sizeof(u32), 0);
- snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_CNTL_0 + ch * sizeof(u32), ACP_DMA_CH_RUN);
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, (acp_dma_cntl_0 + ch * sizeof(u32)), 0);
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, acp_dma_dscr_cnt_0 + ch * sizeof(u32), dscr_count);
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, acp_dma_dscr_strt_idx_0 + ch * sizeof(u32), idx);
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, acp_dma_prio_0 + ch * sizeof(u32), 0);
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, acp_dma_cntl_0 + ch * sizeof(u32), ACP_DMA_CH_RUN);
return ret;
}
@@ -236,7 +269,6 @@ int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr,
unsigned int image_length)
{
struct snd_sof_dev *sdev = adata->dev;
- const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
unsigned int tx_count, fw_qualifier, val;
int ret;
@@ -265,8 +297,9 @@ int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr,
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_DESTINATION_ADDR, dest_addr);
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_MSG_LENGTH, image_length);
- /* psp_send_cmd only required for vangogh platform (rev - 5) */
- if (desc->rev == 5 && !(adata->quirks && adata->quirks->skip_iram_dram_size_mod)) {
+ /* psp_send_cmd only required for vangogh platform */
+ if (adata->pci_rev == ACP_VANGOGH_PCI_ID &&
+ !(adata->quirks && adata->quirks->skip_iram_dram_size_mod)) {
/* Modify IRAM and DRAM size */
ret = psp_send_cmd(adata, MBOX_ACP_IRAM_DRAM_FENCE_COMMAND | IRAM_DRAM_FENCE_2);
if (ret)
@@ -285,8 +318,8 @@ int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr,
return ret;
}
- /* psp_send_cmd only required for renoir platform (rev - 3) */
- if (desc->rev == 3) {
+ /* psp_send_cmd only required for renoir platform*/
+ if (adata->pci_rev == ACP_RN_PCI_ID) {
ret = psp_send_cmd(adata, MBOX_ACP_SHA_DMA_COMMAND);
if (ret)
return ret;
@@ -405,7 +438,7 @@ static irqreturn_t acp_irq_handler(int irq, void *dev_id)
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_stat, ACP_ERROR_IRQ_MASK);
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->acp_sw0_i2s_err_reason, 0);
/* ACP_SW1_I2S_ERROR_REASON is newly added register from rmb platform onwards */
- if (desc->rev >= 6)
+ if (adata->pci_rev >= ACP_RMB_PCI_ID)
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SW1_I2S_ERROR_REASON, 0);
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->acp_error_stat, 0);
irq_flag = 1;
@@ -431,6 +464,7 @@ static irqreturn_t acp_irq_handler(int irq, void *dev_id)
static int acp_power_on(struct snd_sof_dev *sdev)
{
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
+ struct acp_dev_data *adata = sdev->pdata->hw_pdata;
unsigned int base = desc->pgfsm_base;
unsigned int val;
unsigned int acp_pgfsm_status_mask, acp_pgfsm_cntl_mask;
@@ -441,16 +475,21 @@ static int acp_power_on(struct snd_sof_dev *sdev)
if (val == ACP_POWERED_ON)
return 0;
- switch (desc->rev) {
- case 3:
- case 5:
+ switch (adata->pci_rev) {
+ case ACP_RN_PCI_ID:
+ case ACP_VANGOGH_PCI_ID:
acp_pgfsm_status_mask = ACP3X_PGFSM_STATUS_MASK;
acp_pgfsm_cntl_mask = ACP3X_PGFSM_CNTL_POWER_ON_MASK;
break;
- case 6:
+ case ACP_RMB_PCI_ID:
+ case ACP63_PCI_ID:
acp_pgfsm_status_mask = ACP6X_PGFSM_STATUS_MASK;
acp_pgfsm_cntl_mask = ACP6X_PGFSM_CNTL_POWER_ON_MASK;
break;
+ case ACP70_PCI_ID:
+ acp_pgfsm_status_mask = ACP70_PGFSM_STATUS_MASK;
+ acp_pgfsm_cntl_mask = ACP70_PGFSM_CNTL_POWER_ON_MASK;
+ break;
default:
return -EINVAL;
}
@@ -559,8 +598,11 @@ static bool check_acp_sdw_enable_status(struct snd_sof_dev *sdev)
int amd_sof_acp_suspend(struct snd_sof_dev *sdev, u32 target_state)
{
+ struct acp_dev_data *acp_data;
int ret;
+ bool enable = false;
+ acp_data = sdev->pdata->hw_pdata;
/* When acp_reset() function is invoked, it will apply ACP SOFT reset and
* DSP reset. ACP Soft reset sequence will cause all ACP IP registers will
* be reset to default values which will break the ClockStop Mode functionality.
@@ -575,8 +617,9 @@ int amd_sof_acp_suspend(struct snd_sof_dev *sdev, u32 target_state)
dev_err(sdev->dev, "ACP Reset failed\n");
return ret;
}
-
- snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_CONTROL, 0x00);
+ if (acp_data->pci_rev == ACP70_PCI_ID)
+ enable = true;
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_CONTROL, enable);
return 0;
}
@@ -713,6 +756,7 @@ int amd_sof_acp_probe(struct snd_sof_dev *sdev)
pci_set_master(pci);
adata->addr = addr;
adata->reg_range = chip->reg_end_addr - chip->reg_start_addr;
+ adata->pci_rev = pci->revision;
mutex_init(&adata->acp_lock);
sdev->pdata->hw_pdata = adata;
adata->smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, chip->host_bridge_id, NULL);
diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h
index 61b28df8c908..800594440f73 100644
--- a/sound/soc/sof/amd/acp.h
+++ b/sound/soc/sof/amd/acp.h
@@ -29,6 +29,8 @@
#define ACP3X_PGFSM_STATUS_MASK 0x03
#define ACP6X_PGFSM_CNTL_POWER_ON_MASK 0x07
#define ACP6X_PGFSM_STATUS_MASK 0x0F
+#define ACP70_PGFSM_CNTL_POWER_ON_MASK 0x1F
+#define ACP70_PGFSM_STATUS_MASK 0xFF
#define ACP_POWERED_ON 0x00
#define ACP_ASSERT_RESET 0x01
@@ -42,6 +44,7 @@
#define ACP3X_SRAM_PTE_OFFSET 0x02050000
#define ACP5X_SRAM_PTE_OFFSET 0x02050000
#define ACP6X_SRAM_PTE_OFFSET 0x03800000
+#define ACP70_SRAM_PTE_OFFSET ACP6X_SRAM_PTE_OFFSET
#define PAGE_SIZE_4K_ENABLE 0x2
#define ACP_PAGE_SIZE 0x1000
#define ACP_DMA_CH_RUN 0x02
@@ -63,17 +66,20 @@
#define ACP_DRAM_BASE_ADDRESS 0x01000000
#define ACP_DRAM_PAGE_COUNT 128
#define ACP_SRAM_BASE_ADDRESS 0x3806000
+#define ACP7X_SRAM_BASE_ADDRESS 0x380C000
#define ACP_DSP_TO_HOST_IRQ 0x04
#define ACP_RN_PCI_ID 0x01
#define ACP_VANGOGH_PCI_ID 0x50
#define ACP_RMB_PCI_ID 0x6F
#define ACP63_PCI_ID 0x63
+#define ACP70_PCI_ID 0x70
#define HOST_BRIDGE_CZN 0x1630
#define HOST_BRIDGE_VGH 0x1645
#define HOST_BRIDGE_RMB 0x14B5
#define HOST_BRIDGE_ACP63 0x14E8
+#define HOST_BRIDGE_ACP70 0x1507
#define ACP_SHA_STAT 0x8000
#define ACP_PSP_TIMEOUT_US 1000000
#define ACP_EXT_INTR_ERROR_STAT 0x20000000
@@ -190,7 +196,6 @@ struct acp_dsp_stream {
};
struct sof_amd_acp_desc {
- unsigned int rev;
const char *name;
unsigned int host_bridge_id;
u32 pgfsm_base;
@@ -256,6 +261,7 @@ struct acp_dev_data {
bool is_dram_in_use;
bool is_sram_in_use;
bool sdw_en_stat;
+ unsigned int pci_rev;
};
void memcpy_to_scratch(struct snd_sof_dev *sdev, u32 offset, unsigned int *src, size_t bytes);
@@ -326,6 +332,9 @@ int sof_rembrandt_ops_init(struct snd_sof_dev *sdev);
extern struct snd_sof_dsp_ops sof_acp63_ops;
int sof_acp63_ops_init(struct snd_sof_dev *sdev);
+extern struct snd_sof_dsp_ops sof_acp70_ops;
+int sof_acp70_ops_init(struct snd_sof_dev *sdev);
+
struct snd_soc_acpi_mach *amd_sof_machine_select(struct snd_sof_dev *sdev);
/* Machine configuration */
int snd_amd_acp_find_config(struct pci_dev *pci);
diff --git a/sound/soc/sof/amd/acp70.c b/sound/soc/sof/amd/acp70.c
new file mode 100644
index 000000000000..7d1842f42c90
--- /dev/null
+++ b/sound/soc/sof/amd/acp70.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2024 Advanced Micro Devices, Inc.
+//
+// Authors: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+/*
+ * Hardware interface for Audio DSP on ACP7.0 version based platform
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+
+#include "../ops.h"
+#include "../sof-audio.h"
+#include "acp.h"
+#include "acp-dsp-offset.h"
+
+#define I2S_HS_INSTANCE 0
+#define I2S_BT_INSTANCE 1
+#define I2S_SP_INSTANCE 2
+#define PDM_DMIC_INSTANCE 3
+#define I2S_HS_VIRTUAL_INSTANCE 4
+
+static struct snd_soc_dai_driver acp70_sof_dai[] = {
+ [I2S_HS_INSTANCE] = {
+ .id = I2S_HS_INSTANCE,
+ .name = "acp-sof-hs",
+ .playback = {
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ },
+ .capture = {
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ /* Supporting only stereo for I2S HS controller capture */
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ },
+
+ [I2S_BT_INSTANCE] = {
+ .id = I2S_BT_INSTANCE,
+ .name = "acp-sof-bt",
+ .playback = {
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ },
+ .capture = {
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ /* Supporting only stereo for I2S BT controller capture */
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ },
+
+ [I2S_SP_INSTANCE] = {
+ .id = I2S_SP_INSTANCE,
+ .name = "acp-sof-sp",
+ .playback = {
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ },
+ .capture = {
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ /* Supporting only stereo for I2S SP controller capture */
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ },
+
+ [PDM_DMIC_INSTANCE] = {
+ .id = PDM_DMIC_INSTANCE,
+ .name = "acp-sof-dmic",
+ .capture = {
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 4,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ },
+
+ [I2S_HS_VIRTUAL_INSTANCE] = {
+ .id = I2S_HS_VIRTUAL_INSTANCE,
+ .name = "acp-sof-hs-virtual",
+ .playback = {
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ },
+ },
+};
+
+/* Phoenix ops */
+struct snd_sof_dsp_ops sof_acp70_ops;
+EXPORT_SYMBOL_NS(sof_acp70_ops, SND_SOC_SOF_AMD_COMMON);
+
+int sof_acp70_ops_init(struct snd_sof_dev *sdev)
+{
+ /* common defaults */
+ memcpy(&sof_acp70_ops, &sof_acp_common_ops, sizeof(struct snd_sof_dsp_ops));
+
+ sof_acp70_ops.drv = acp70_sof_dai;
+ sof_acp70_ops.num_drv = ARRAY_SIZE(acp70_sof_dai);
+
+ return 0;
+}
diff --git a/sound/soc/sof/amd/pci-acp63.c b/sound/soc/sof/amd/pci-acp63.c
index 986f5928caed..b54ed61b79ed 100644
--- a/sound/soc/sof/amd/pci-acp63.c
+++ b/sound/soc/sof/amd/pci-acp63.c
@@ -28,7 +28,6 @@
#define ACP6x_REG_END 0x125C000
static const struct sof_amd_acp_desc acp63_chip_info = {
- .rev = 6,
.host_bridge_id = HOST_BRIDGE_ACP63,
.pgfsm_base = ACP6X_PGFSM_BASE,
.ext_intr_enb = ACP6X_EXTERNAL_INTR_ENB,
@@ -50,6 +49,7 @@ static const struct sof_amd_acp_desc acp63_chip_info = {
static const struct sof_dev_desc acp63_desc = {
.machines = snd_soc_acpi_amd_acp63_sof_machines,
+ .alt_machines = snd_soc_acpi_amd_acp63_sof_sdw_machines,
.resindex_lpe_base = 0,
.resindex_pcicfg_base = -1,
.resindex_imr_base = -1,
diff --git a/sound/soc/sof/amd/pci-acp70.c b/sound/soc/sof/amd/pci-acp70.c
new file mode 100644
index 000000000000..a5d8b6a95a22
--- /dev/null
+++ b/sound/soc/sof/amd/pci-acp70.c
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2024 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Authors: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+/*.
+ * PCI interface for ACP7.0 device
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <sound/sof.h>
+#include <sound/soc-acpi.h>
+
+#include "../ops.h"
+#include "../sof-pci-dev.h"
+#include "../../amd/mach-config.h"
+#include "acp.h"
+#include "acp-dsp-offset.h"
+
+#define ACP70_FUTURE_REG_ACLK_0 0x1854
+#define ACP70_REG_START 0x1240000
+#define ACP70_REG_END 0x125C000
+
+static const struct sof_amd_acp_desc acp70_chip_info = {
+ .host_bridge_id = HOST_BRIDGE_ACP70,
+ .pgfsm_base = ACP70_PGFSM_BASE,
+ .ext_intr_enb = ACP70_EXTERNAL_INTR_ENB,
+ .ext_intr_cntl = ACP70_EXTERNAL_INTR_CNTL,
+ .ext_intr_stat = ACP70_EXT_INTR_STAT,
+ .ext_intr_stat1 = ACP70_EXT_INTR_STAT1,
+ .dsp_intr_base = ACP70_DSP_SW_INTR_BASE,
+ .acp_sw0_i2s_err_reason = ACP7X_SW0_I2S_ERROR_REASON,
+ .sram_pte_offset = ACP70_SRAM_PTE_OFFSET,
+ .hw_semaphore_offset = ACP70_AXI2DAGB_SEM_0,
+ .fusion_dsp_offset = ACP70_DSP_FUSION_RUNSTALL,
+ .probe_reg_offset = ACP70_FUTURE_REG_ACLK_0,
+ .reg_start_addr = ACP70_REG_START,
+ .reg_end_addr = ACP70_REG_END,
+};
+
+static const struct sof_dev_desc acp70_desc = {
+ .machines = snd_soc_acpi_amd_acp70_sof_machines,
+ .resindex_lpe_base = 0,
+ .resindex_pcicfg_base = -1,
+ .resindex_imr_base = -1,
+ .irqindex_host_ipc = -1,
+ .chip_info = &acp70_chip_info,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+ .ipc_default = SOF_IPC_TYPE_3,
+ .default_fw_path = {
+ [SOF_IPC_TYPE_3] = "amd/sof",
+ },
+ .default_tplg_path = {
+ [SOF_IPC_TYPE_3] = "amd/sof-tplg",
+ },
+ .default_fw_filename = {
+ [SOF_IPC_TYPE_3] = "sof-acp_7_0.ri",
+ },
+ .nocodec_tplg_filename = "sof-acp.tplg",
+ .ops = &sof_acp70_ops,
+ .ops_init = sof_acp70_ops_init,
+};
+
+static int acp70_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+{
+ unsigned int flag;
+
+ if (pci->revision != ACP70_PCI_ID)
+ return -ENODEV;
+
+ flag = snd_amd_acp_find_config(pci);
+ if (flag != FLAG_AMD_SOF && flag != FLAG_AMD_SOF_ONLY_DMIC)
+ return -ENODEV;
+
+ return sof_pci_probe(pci, pci_id);
+};
+
+static void acp70_pci_remove(struct pci_dev *pci)
+{
+ sof_pci_remove(pci);
+}
+
+/* PCI IDs */
+static const struct pci_device_id acp70_pci_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_PCI_DEV_ID),
+ .driver_data = (unsigned long)&acp70_desc},
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, acp70_pci_ids);
+
+/* pci_driver definition */
+static struct pci_driver snd_sof_pci_amd_acp70_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = acp70_pci_ids,
+ .probe = acp70_pci_probe,
+ .remove = acp70_pci_remove,
+ .driver = {
+ .pm = &sof_pci_pm,
+ },
+};
+module_pci_driver(snd_sof_pci_amd_acp70_driver);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("ACP70 SOF Driver");
+MODULE_IMPORT_NS(SND_SOC_SOF_AMD_COMMON);
+MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV);
diff --git a/sound/soc/sof/amd/pci-rmb.c b/sound/soc/sof/amd/pci-rmb.c
index a366f904e6f3..c45256bf4fda 100644
--- a/sound/soc/sof/amd/pci-rmb.c
+++ b/sound/soc/sof/amd/pci-rmb.c
@@ -28,7 +28,6 @@
#define ACP6X_FUTURE_REG_ACLK_0 0x1854
static const struct sof_amd_acp_desc rembrandt_chip_info = {
- .rev = 6,
.host_bridge_id = HOST_BRIDGE_RMB,
.pgfsm_base = ACP6X_PGFSM_BASE,
.ext_intr_stat = ACP6X_EXT_INTR_STAT,
diff --git a/sound/soc/sof/amd/pci-rn.c b/sound/soc/sof/amd/pci-rn.c
index 2b7c53470ce8..386a0f1e7ee0 100644
--- a/sound/soc/sof/amd/pci-rn.c
+++ b/sound/soc/sof/amd/pci-rn.c
@@ -28,7 +28,6 @@
#define ACP3X_FUTURE_REG_ACLK_0 0x1860
static const struct sof_amd_acp_desc renoir_chip_info = {
- .rev = 3,
.host_bridge_id = HOST_BRIDGE_CZN,
.pgfsm_base = ACP3X_PGFSM_BASE,
.ext_intr_stat = ACP3X_EXT_INTR_STAT,
diff --git a/sound/soc/sof/amd/pci-vangogh.c b/sound/soc/sof/amd/pci-vangogh.c
index eba580840100..cb845f81795e 100644
--- a/sound/soc/sof/amd/pci-vangogh.c
+++ b/sound/soc/sof/amd/pci-vangogh.c
@@ -26,7 +26,6 @@
#define ACP5X_FUTURE_REG_ACLK_0 0x1864
static const struct sof_amd_acp_desc vangogh_chip_info = {
- .rev = 5,
.name = "vangogh",
.host_bridge_id = HOST_BRIDGE_VGH,
.pgfsm_base = ACP5X_PGFSM_BASE,
diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c
index 9f24e3c283dd..f09ee0dea2cc 100644
--- a/sound/soc/sof/imx/imx8.c
+++ b/sound/soc/sof/imx/imx8.c
@@ -658,7 +658,7 @@ MODULE_DEVICE_TABLE(of, sof_of_imx8_ids);
/* DT driver definition */
static struct platform_driver snd_sof_of_imx8_driver = {
.probe = sof_of_probe,
- .remove_new = sof_of_remove,
+ .remove = sof_of_remove,
.driver = {
.name = "sof-audio-of-imx8",
.pm = &sof_of_pm,
diff --git a/sound/soc/sof/imx/imx8m.c b/sound/soc/sof/imx/imx8m.c
index cdd1e79ef9f6..01d3ad3314f3 100644
--- a/sound/soc/sof/imx/imx8m.c
+++ b/sound/soc/sof/imx/imx8m.c
@@ -505,7 +505,7 @@ MODULE_DEVICE_TABLE(of, sof_of_imx8m_ids);
/* DT driver definition */
static struct platform_driver snd_sof_of_imx8m_driver = {
.probe = sof_of_probe,
- .remove_new = sof_of_remove,
+ .remove = sof_of_remove,
.driver = {
.name = "sof-audio-of-imx8m",
.pm = &sof_of_pm,
diff --git a/sound/soc/sof/imx/imx8ulp.c b/sound/soc/sof/imx/imx8ulp.c
index 2585b1beef23..e5eee1c9f6da 100644
--- a/sound/soc/sof/imx/imx8ulp.c
+++ b/sound/soc/sof/imx/imx8ulp.c
@@ -507,7 +507,7 @@ MODULE_DEVICE_TABLE(of, sof_of_imx8ulp_ids);
/* DT driver definition */
static struct platform_driver snd_sof_of_imx8ulp_driver = {
.probe = sof_of_probe,
- .remove_new = sof_of_remove,
+ .remove = sof_of_remove,
.driver = {
.name = "sof-audio-of-imx8ulp",
.pm = &sof_of_pm,
diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig
index 3396bd46b778..2c43558d96b9 100644
--- a/sound/soc/sof/intel/Kconfig
+++ b/sound/soc/sof/intel/Kconfig
@@ -281,6 +281,23 @@ config SND_SOC_SOF_LUNARLAKE
Say Y if you have such a device.
If unsure select "N".
+config SND_SOC_SOF_INTEL_PTL
+ tristate
+ select SND_SOC_SOF_HDA_COMMON
+ select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
+ select SND_SOC_SOF_IPC4
+ select SND_SOC_SOF_INTEL_LNL
+
+config SND_SOC_SOF_PANTHERLAKE
+ tristate "SOF support for Pantherlake"
+ default SND_SOC_SOF_PCI
+ select SND_SOC_SOF_INTEL_PTL
+ help
+ This adds support for Sound Open Firmware for Intel(R) platforms
+ using the Pantherlake processors.
+ Say Y if you have such a device.
+ If unsure select "N".
+
config SND_SOC_SOF_HDA_COMMON
tristate
diff --git a/sound/soc/sof/intel/Makefile b/sound/soc/sof/intel/Makefile
index b56fa5530b8b..f40daa616803 100644
--- a/sound/soc/sof/intel/Makefile
+++ b/sound/soc/sof/intel/Makefile
@@ -34,6 +34,7 @@ snd-sof-pci-intel-icl-y := pci-icl.o icl.o
snd-sof-pci-intel-tgl-y := pci-tgl.o tgl.o
snd-sof-pci-intel-mtl-y := pci-mtl.o mtl.o
snd-sof-pci-intel-lnl-y := pci-lnl.o lnl.o
+snd-sof-pci-intel-ptl-y := pci-ptl.o
obj-$(CONFIG_SND_SOC_SOF_MERRIFIELD) += snd-sof-pci-intel-tng.o
obj-$(CONFIG_SND_SOC_SOF_INTEL_SKL) += snd-sof-pci-intel-skl.o
@@ -43,3 +44,4 @@ obj-$(CONFIG_SND_SOC_SOF_INTEL_ICL) += snd-sof-pci-intel-icl.o
obj-$(CONFIG_SND_SOC_SOF_INTEL_TGL) += snd-sof-pci-intel-tgl.o
obj-$(CONFIG_SND_SOC_SOF_INTEL_MTL) += snd-sof-pci-intel-mtl.o
obj-$(CONFIG_SND_SOC_SOF_INTEL_LNL) += snd-sof-pci-intel-lnl.o
+obj-$(CONFIG_SND_SOC_SOF_INTEL_PTL) += snd-sof-pci-intel-ptl.o
diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c
index 7f18080e4e19..322ff118f0f6 100644
--- a/sound/soc/sof/intel/bdw.c
+++ b/sound/soc/sof/intel/bdw.c
@@ -684,7 +684,7 @@ static int sof_broadwell_probe(struct platform_device *pdev)
/* acpi_driver definition */
static struct platform_driver snd_sof_acpi_intel_bdw_driver = {
.probe = sof_broadwell_probe,
- .remove_new = sof_acpi_remove,
+ .remove = sof_acpi_remove,
.driver = {
.name = "sof-audio-acpi-intel-bdw",
.pm = &sof_acpi_pm,
diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c
index 7a57e162fb1c..f531710cf94e 100644
--- a/sound/soc/sof/intel/byt.c
+++ b/sound/soc/sof/intel/byt.c
@@ -465,7 +465,7 @@ static int sof_baytrail_probe(struct platform_device *pdev)
/* acpi_driver definition */
static struct platform_driver snd_sof_acpi_intel_byt_driver = {
.probe = sof_baytrail_probe,
- .remove_new = sof_acpi_remove,
+ .remove = sof_acpi_remove,
.driver = {
.name = "sof-audio-acpi-intel-byt",
.pm = &sof_acpi_pm,
diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c
index 1315f5bc3e31..4c88522d4048 100644
--- a/sound/soc/sof/intel/hda-dsp.c
+++ b/sound/soc/sof/intel/hda-dsp.c
@@ -69,6 +69,7 @@ static void hda_get_interfaces(struct snd_sof_dev *sdev, u32 *interface_mask)
interface_mask[SOF_DAI_HOST_ACCESS] = BIT(SOF_DAI_INTEL_HDA);
break;
case SOF_INTEL_ACE_2_0:
+ case SOF_INTEL_ACE_3_0:
interface_mask[SOF_DAI_DSP_ACCESS] =
BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC) |
BIT(SOF_DAI_INTEL_HDA) | BIT(SOF_DAI_INTEL_ALH);
diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c
index 8213debde497..3ac63ce67ab1 100644
--- a/sound/soc/sof/intel/hda-stream.c
+++ b/sound/soc/sof/intel/hda-stream.c
@@ -216,9 +216,7 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags)
/* stream found ? */
if (!hext_stream) {
- dev_err(sdev->dev, "error: no free %s streams\n",
- direction == SNDRV_PCM_STREAM_PLAYBACK ?
- "playback" : "capture");
+ dev_err(sdev->dev, "error: no free %s streams\n", snd_pcm_direction_name(direction));
return hext_stream;
}
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index 5a40b8fbbbd3..70fc08c8fc99 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -444,6 +444,10 @@ static int mclk_id_override = -1;
module_param_named(mclk_id, mclk_id_override, int, 0444);
MODULE_PARM_DESC(mclk_id, "SOF SSP mclk_id");
+static int bt_link_mask_override;
+module_param_named(bt_link_mask, bt_link_mask_override, int, 0444);
+MODULE_PARM_DESC(bt_link_mask, "SOF BT offload link mask");
+
static int hda_init(struct snd_sof_dev *sdev)
{
struct hda_bus *hbus;
@@ -511,6 +515,8 @@ static int check_dmic_num(struct snd_sof_dev *sdev)
if (nhlt)
dmic_num = intel_nhlt_get_dmic_geo(sdev->dev, nhlt);
+ dev_info(sdev->dev, "DMICs detected in NHLT tables: %d\n", dmic_num);
+
/* allow for module parameter override */
if (dmic_num_override != -1) {
dev_dbg(sdev->dev,
@@ -527,7 +533,7 @@ static int check_dmic_num(struct snd_sof_dev *sdev)
return dmic_num;
}
-static int check_nhlt_ssp_mask(struct snd_sof_dev *sdev)
+static int check_nhlt_ssp_mask(struct snd_sof_dev *sdev, u8 device_type)
{
struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
struct nhlt_acpi_table *nhlt;
@@ -538,9 +544,11 @@ static int check_nhlt_ssp_mask(struct snd_sof_dev *sdev)
return ssp_mask;
if (intel_nhlt_has_endpoint_type(nhlt, NHLT_LINK_SSP)) {
- ssp_mask = intel_nhlt_ssp_endpoint_mask(nhlt, NHLT_DEVICE_I2S);
+ ssp_mask = intel_nhlt_ssp_endpoint_mask(nhlt, device_type);
if (ssp_mask)
- dev_info(sdev->dev, "NHLT_DEVICE_I2S detected, ssp_mask %#x\n", ssp_mask);
+ dev_info(sdev->dev, "NHLT device %s(%d) detected, ssp_mask %#x\n",
+ device_type == NHLT_DEVICE_BT ? "BT" : "I2S",
+ device_type, ssp_mask);
}
return ssp_mask;
@@ -558,82 +566,6 @@ static int check_nhlt_ssp_mclk_mask(struct snd_sof_dev *sdev, int ssp_num)
return intel_nhlt_ssp_mclk_mask(nhlt, ssp_num);
}
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) || IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
-
-static const char *fixup_tplg_name(struct snd_sof_dev *sdev,
- const char *sof_tplg_filename,
- const char *idisp_str,
- const char *dmic_str)
-{
- const char *tplg_filename = NULL;
- char *filename, *tmp;
- const char *split_ext;
-
- filename = kstrdup(sof_tplg_filename, GFP_KERNEL);
- if (!filename)
- return NULL;
-
- /* this assumes a .tplg extension */
- tmp = filename;
- split_ext = strsep(&tmp, ".");
- if (split_ext)
- tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
- "%s%s%s.tplg",
- split_ext, idisp_str, dmic_str);
- kfree(filename);
-
- return tplg_filename;
-}
-
-static int dmic_detect_topology_fixup(struct snd_sof_dev *sdev,
- const char **tplg_filename,
- const char *idisp_str,
- int *dmic_found,
- bool tplg_fixup)
-{
- const char *dmic_str;
- int dmic_num;
-
- /* first check for DMICs (using NHLT or module parameter) */
- dmic_num = check_dmic_num(sdev);
-
- switch (dmic_num) {
- case 1:
- dmic_str = "-1ch";
- break;
- case 2:
- dmic_str = "-2ch";
- break;
- case 3:
- dmic_str = "-3ch";
- break;
- case 4:
- dmic_str = "-4ch";
- break;
- default:
- dmic_num = 0;
- dmic_str = "";
- break;
- }
-
- if (tplg_fixup) {
- const char *default_tplg_filename = *tplg_filename;
- const char *fixed_tplg_filename;
-
- fixed_tplg_filename = fixup_tplg_name(sdev, default_tplg_filename,
- idisp_str, dmic_str);
- if (!fixed_tplg_filename)
- return -ENOMEM;
- *tplg_filename = fixed_tplg_filename;
- }
-
- dev_info(sdev->dev, "DMICs detected in NHLT tables: %d\n", dmic_num);
- *dmic_found = dmic_num;
-
- return 0;
-}
-#endif
-
static int hda_init_caps(struct snd_sof_dev *sdev)
{
u32 interface_mask = hda_get_interface_mask(sdev);
@@ -1045,10 +977,7 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev,
struct snd_soc_acpi_mach *hda_mach;
struct snd_sof_pdata *pdata = sdev->pdata;
const char *tplg_filename;
- const char *idisp_str;
- int dmic_num = 0;
int codec_num = 0;
- int ret;
int i;
/* codec detection */
@@ -1071,33 +1000,30 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev,
* - one external HDAudio codec
*/
if (!*mach && codec_num <= 2) {
- bool tplg_fixup;
+ bool tplg_fixup = false;
hda_mach = snd_soc_acpi_intel_hda_machines;
dev_info(bus->dev, "using HDA machine driver %s now\n",
hda_mach->drv_name);
- if (codec_num == 1 && HDA_IDISP_CODEC(bus->codec_mask))
- idisp_str = "-idisp";
- else
- idisp_str = "";
-
- /* topology: use the info from hda_machines */
- if (pdata->tplg_filename) {
- tplg_fixup = false;
- tplg_filename = pdata->tplg_filename;
- } else {
+ /*
+ * topology: use the info from hda_machines since tplg file name
+ * is not overwritten
+ */
+ if (!pdata->tplg_filename)
tplg_fixup = true;
- tplg_filename = hda_mach->sof_tplg_filename;
- }
- ret = dmic_detect_topology_fixup(sdev, &tplg_filename, idisp_str, &dmic_num,
- tplg_fixup);
- if (ret < 0)
- return;
- hda_mach->mach_params.dmic_num = dmic_num;
- pdata->tplg_filename = tplg_filename;
+ if (tplg_fixup &&
+ codec_num == 1 && HDA_IDISP_CODEC(bus->codec_mask)) {
+ tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
+ "%s-idisp",
+ hda_mach->sof_tplg_filename);
+ if (!tplg_filename)
+ return;
+
+ hda_mach->sof_tplg_filename = tplg_filename;
+ }
if (codec_num == 2 ||
(codec_num == 1 && !HDA_IDISP_CODEC(bus->codec_mask))) {
@@ -1125,7 +1051,6 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev,
if (*mach) {
mach_params = &(*mach)->mach_params;
mach_params->codec_mask = bus->codec_mask;
- mach_params->common_hdmi_codec_drv = true;
}
}
#else
@@ -1205,45 +1130,10 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev
break;
}
if (mach && mach->link_mask) {
- int dmic_num = 0;
- bool tplg_fixup;
- const char *tplg_filename;
-
mach->mach_params.links = mach->links;
mach->mach_params.link_mask = mach->link_mask;
mach->mach_params.platform = dev_name(sdev->dev);
- if (pdata->tplg_filename) {
- tplg_fixup = false;
- } else {
- tplg_fixup = true;
- tplg_filename = mach->sof_tplg_filename;
- }
-
- /*
- * DMICs use up to 4 pins and are typically pin-muxed with SoundWire
- * link 2 and 3, or link 1 and 2, thus we only try to enable dmics
- * if all conditions are true:
- * a) 2 or fewer links are used by SoundWire
- * b) the NHLT table reports the presence of microphones
- */
- if (hweight_long(mach->link_mask) <= 2) {
- int ret;
-
- ret = dmic_detect_topology_fixup(sdev, &tplg_filename, "",
- &dmic_num, tplg_fixup);
- if (ret < 0)
- return NULL;
- }
- if (tplg_fixup)
- pdata->tplg_filename = tplg_filename;
- mach->mach_params.dmic_num = dmic_num;
-
- dev_dbg(sdev->dev,
- "SoundWire machine driver %s topology %s\n",
- mach->drv_name,
- pdata->tplg_filename);
-
return mach;
}
@@ -1300,6 +1190,19 @@ static int check_tplg_quirk_mask(struct snd_soc_acpi_mach *mach)
return 0;
}
+static char *remove_file_ext(const char *tplg_filename)
+{
+ char *filename, *tmp;
+
+ filename = kstrdup(tplg_filename, GFP_KERNEL);
+ if (!filename)
+ return NULL;
+
+ /* remove file extension if exist */
+ tmp = filename;
+ return strsep(&tmp, ".");
+}
+
struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
{
u32 interface_mask = hda_get_interface_mask(sdev);
@@ -1311,21 +1214,75 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
const char *tplg_filename;
const char *tplg_suffix;
bool amp_name_valid;
+ bool i2s_mach_found = false;
+ bool sdw_mach_found = false;
/* Try I2S or DMIC if it is supported */
- if (interface_mask & (BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC)))
+ if (interface_mask & (BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC))) {
mach = snd_soc_acpi_find_machine(desc->machines);
+ if (mach)
+ i2s_mach_found = true;
+ }
+
+ /*
+ * If I2S fails and no external HDaudio codec is detected,
+ * try SoundWire if it is supported
+ */
+ if (!mach && !HDA_EXT_CODEC(bus->codec_mask) &&
+ (interface_mask & BIT(SOF_DAI_INTEL_ALH))) {
+ mach = hda_sdw_machine_select(sdev);
+ if (mach)
+ sdw_mach_found = true;
+ }
+
+ /*
+ * Choose HDA generic machine driver if mach is NULL.
+ * Otherwise, set certain mach params.
+ */
+ hda_generic_machine_select(sdev, &mach);
+ if (!mach) {
+ dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n");
+ return NULL;
+ }
+
+ /* report BT offload link mask to machine driver */
+ mach->mach_params.bt_link_mask = check_nhlt_ssp_mask(sdev, NHLT_DEVICE_BT);
+
+ dev_info(sdev->dev, "BT link detected in NHLT tables: %#x\n",
+ mach->mach_params.bt_link_mask);
+
+ /* allow for module parameter override */
+ if (bt_link_mask_override) {
+ dev_dbg(sdev->dev, "overriding BT link detected in NHLT tables %#x by kernel param %#x\n",
+ mach->mach_params.bt_link_mask, bt_link_mask_override);
+ mach->mach_params.bt_link_mask = bt_link_mask_override;
+ }
+
+ if (hweight_long(mach->mach_params.bt_link_mask) > 1) {
+ dev_warn(sdev->dev, "invalid BT link mask %#x found, reset the mask\n",
+ mach->mach_params.bt_link_mask);
+ mach->mach_params.bt_link_mask = 0;
+ }
+ /*
+ * Fixup tplg file name by appending dmic num, ssp num, codec/amplifier
+ * name string if quirk flag is set.
+ */
if (mach) {
- bool add_extension = false;
bool tplg_fixup = false;
+ bool dmic_fixup = false;
/*
* If tplg file name is overridden, use it instead of
* the one set in mach table
*/
if (!sof_pdata->tplg_filename) {
- sof_pdata->tplg_filename = mach->sof_tplg_filename;
+ /* remove file extension if it exists */
+ tplg_filename = remove_file_ext(mach->sof_tplg_filename);
+ if (!tplg_filename)
+ return NULL;
+
+ sof_pdata->tplg_filename = tplg_filename;
tplg_fixup = true;
}
@@ -1343,20 +1300,36 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
/* report to machine driver if any DMICs are found */
mach->mach_params.dmic_num = check_dmic_num(sdev);
+ if (sdw_mach_found) {
+ /*
+ * DMICs use up to 4 pins and are typically pin-muxed with SoundWire
+ * link 2 and 3, or link 1 and 2, thus we only try to enable dmics
+ * if all conditions are true:
+ * a) 2 or fewer links are used by SoundWire
+ * b) the NHLT table reports the presence of microphones
+ */
+ if (hweight_long(mach->link_mask) <= 2)
+ dmic_fixup = true;
+ else
+ mach->mach_params.dmic_num = 0;
+ } else {
+ if (mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER)
+ dmic_fixup = true;
+ }
+
if (tplg_fixup &&
- mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER &&
+ dmic_fixup &&
mach->mach_params.dmic_num) {
tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
"%s%s%d%s",
sof_pdata->tplg_filename,
- "-dmic",
+ i2s_mach_found ? "-dmic" : "-",
mach->mach_params.dmic_num,
"ch");
if (!tplg_filename)
return NULL;
sof_pdata->tplg_filename = tplg_filename;
- add_extension = true;
}
if (mach->link_mask) {
@@ -1365,7 +1338,7 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
}
/* report SSP link mask to machine driver */
- mach->mach_params.i2s_link_mask = check_nhlt_ssp_mask(sdev);
+ mach->mach_params.i2s_link_mask = check_nhlt_ssp_mask(sdev, NHLT_DEVICE_I2S);
if (tplg_fixup &&
mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER &&
@@ -1396,7 +1369,6 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
return NULL;
sof_pdata->tplg_filename = tplg_filename;
- add_extension = true;
mclk_mask = check_nhlt_ssp_mclk_mask(sdev, ssp_num);
@@ -1435,7 +1407,6 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
return NULL;
sof_pdata->tplg_filename = tplg_filename;
- add_extension = true;
}
@@ -1457,10 +1428,9 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
return NULL;
sof_pdata->tplg_filename = tplg_filename;
- add_extension = true;
}
- if (tplg_fixup && add_extension) {
+ if (tplg_fixup) {
tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
"%s%s",
sof_pdata->tplg_filename,
@@ -1479,22 +1449,6 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
}
}
- /*
- * If I2S fails and no external HDaudio codec is detected,
- * try SoundWire if it is supported
- */
- if (!mach && !HDA_EXT_CODEC(bus->codec_mask) &&
- (interface_mask & BIT(SOF_DAI_INTEL_ALH)))
- mach = hda_sdw_machine_select(sdev);
-
- /*
- * Choose HDA generic machine driver if mach is NULL.
- * Otherwise, set certain mach params.
- */
- hda_generic_machine_select(sdev, &mach);
- if (!mach)
- dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n");
-
return mach;
}
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 3c9e1d59e1ab..b74a472435b5 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -920,6 +920,7 @@ extern const struct sof_intel_dsp_desc adls_chip_info;
extern const struct sof_intel_dsp_desc mtl_chip_info;
extern const struct sof_intel_dsp_desc arl_s_chip_info;
extern const struct sof_intel_dsp_desc lnl_chip_info;
+extern const struct sof_intel_dsp_desc ptl_chip_info;
/* Probes support */
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES)
diff --git a/sound/soc/sof/intel/lnl.c b/sound/soc/sof/intel/lnl.c
index 4b5665f82170..3d5a1f8b17e5 100644
--- a/sound/soc/sof/intel/lnl.c
+++ b/sound/soc/sof/intel/lnl.c
@@ -22,6 +22,7 @@
/* LunarLake ops */
struct snd_sof_dsp_ops sof_lnl_ops;
+EXPORT_SYMBOL_NS(sof_lnl_ops, SND_SOC_SOF_INTEL_LNL);
static const struct snd_sof_debugfs_map lnl_dsp_debugfs[] = {
{"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS},
@@ -181,6 +182,7 @@ int sof_lnl_ops_init(struct snd_sof_dev *sdev)
return 0;
};
+EXPORT_SYMBOL_NS(sof_lnl_ops_init, SND_SOC_SOF_INTEL_LNL);
/* Check if an SDW IRQ occurred */
static bool lnl_dsp_check_sdw_irq(struct snd_sof_dev *sdev)
@@ -245,3 +247,28 @@ const struct sof_intel_dsp_desc lnl_chip_info = {
.disable_interrupts = lnl_dsp_disable_interrupts,
.hw_ip_version = SOF_INTEL_ACE_2_0,
};
+
+const struct sof_intel_dsp_desc ptl_chip_info = {
+ .cores_num = 5,
+ .init_core_mask = BIT(0),
+ .host_managed_cores_mask = BIT(0),
+ .ipc_req = MTL_DSP_REG_HFIPCXIDR,
+ .ipc_req_mask = MTL_DSP_REG_HFIPCXIDR_BUSY,
+ .ipc_ack = MTL_DSP_REG_HFIPCXIDA,
+ .ipc_ack_mask = MTL_DSP_REG_HFIPCXIDA_DONE,
+ .ipc_ctl = MTL_DSP_REG_HFIPCXCTL,
+ .rom_status_reg = LNL_DSP_REG_HFDSC,
+ .rom_init_timeout = 300,
+ .ssp_count = MTL_SSP_COUNT,
+ .d0i3_offset = MTL_HDA_VS_D0I3C,
+ .read_sdw_lcount = hda_sdw_check_lcount_ext,
+ .enable_sdw_irq = lnl_enable_sdw_irq,
+ .check_sdw_irq = lnl_dsp_check_sdw_irq,
+ .check_sdw_wakeen_irq = lnl_sdw_check_wakeen_irq,
+ .check_ipc_irq = mtl_dsp_check_ipc_irq,
+ .cl_init = mtl_dsp_cl_init,
+ .power_down_dsp = mtl_power_down_dsp,
+ .disable_interrupts = lnl_dsp_disable_interrupts,
+ .hw_ip_version = SOF_INTEL_ACE_3_0,
+};
+EXPORT_SYMBOL_NS(ptl_chip_info, SND_SOC_SOF_INTEL_LNL);
diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c
index 1bf274509ee6..2b9d22ccf345 100644
--- a/sound/soc/sof/intel/mtl.c
+++ b/sound/soc/sof/intel/mtl.c
@@ -245,6 +245,18 @@ int mtl_dsp_pre_fw_run(struct snd_sof_dev *sdev)
u32 cpa;
u32 pgs;
int ret;
+ u32 dsppwrctl;
+ u32 dsppwrsts;
+ const struct sof_intel_dsp_desc *chip;
+
+ chip = get_chip_info(sdev->pdata);
+ if (chip->hw_ip_version > SOF_INTEL_ACE_2_0) {
+ dsppwrctl = PTL_HFPWRCTL2;
+ dsppwrsts = PTL_HFPWRSTS2;
+ } else {
+ dsppwrctl = MTL_HFPWRCTL;
+ dsppwrsts = MTL_HFPWRSTS;
+ }
/* Set the DSP subsystem power on */
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFDSSCS,
@@ -264,14 +276,14 @@ int mtl_dsp_pre_fw_run(struct snd_sof_dev *sdev)
}
/* Power up gated-DSP-0 domain in order to access the DSP shim register block. */
- snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFPWRCTL,
+ snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, dsppwrctl,
MTL_HFPWRCTL_WPDSPHPXPG, MTL_HFPWRCTL_WPDSPHPXPG);
usleep_range(1000, 1010);
/* poll with timeout to check if operation successful */
pgs = MTL_HFPWRSTS_DSPHPXPGS_MASK;
- ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_HFPWRSTS, dsphfpwrsts,
+ ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, dsppwrsts, dsphfpwrsts,
(dsphfpwrsts & pgs) == pgs,
HDA_DSP_REG_POLL_INTERVAL_US,
HDA_DSP_RESET_TIMEOUT_US);
diff --git a/sound/soc/sof/intel/mtl.h b/sound/soc/sof/intel/mtl.h
index 7acaa7e724f4..9ab4b21c960e 100644
--- a/sound/soc/sof/intel/mtl.h
+++ b/sound/soc/sof/intel/mtl.h
@@ -12,9 +12,11 @@
#define MTL_HFDSSCS_CPA_MASK BIT(24)
#define MTL_HFSNDWIE 0x114C
#define MTL_HFPWRCTL 0x1D18
+#define PTL_HFPWRCTL2 0x1D20
#define MTL_HfPWRCTL_WPIOXPG(x) BIT((x) + 8)
#define MTL_HFPWRCTL_WPDSPHPXPG BIT(0)
#define MTL_HFPWRSTS 0x1D1C
+#define PTL_HFPWRSTS2 0x1D24
#define MTL_HFPWRSTS_DSPHPXPGS_MASK BIT(0)
#define MTL_HFINTIPPTR 0x1108
#define MTL_IRQ_INTEN_L_HOST_IPC_MASK BIT(0)
diff --git a/sound/soc/sof/intel/pci-ptl.c b/sound/soc/sof/intel/pci-ptl.c
new file mode 100644
index 000000000000..69195b5e7b1a
--- /dev/null
+++ b/sound/soc/sof/intel/pci-ptl.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2024 Intel Corporation.
+//
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-match.h>
+#include <sound/sof.h>
+#include "../ops.h"
+#include "../sof-pci-dev.h"
+
+/* platform specific devices */
+#include "hda.h"
+#include "mtl.h"
+
+static const struct sof_dev_desc ptl_desc = {
+ .use_acpi_target_states = true,
+ .machines = snd_soc_acpi_intel_ptl_machines,
+ .alt_machines = snd_soc_acpi_intel_ptl_sdw_machines,
+ .resindex_lpe_base = 0,
+ .resindex_pcicfg_base = -1,
+ .resindex_imr_base = -1,
+ .irqindex_host_ipc = -1,
+ .chip_info = &ptl_chip_info,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_4,
+ .dspless_mode_supported = true,
+ .default_fw_path = {
+ [SOF_IPC_TYPE_4] = "intel/sof-ipc4/ptl",
+ },
+ .default_lib_path = {
+ [SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/ptl",
+ },
+ .default_tplg_path = {
+ [SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg",
+ },
+ .default_fw_filename = {
+ [SOF_IPC_TYPE_4] = "sof-ptl.ri",
+ },
+ .nocodec_tplg_filename = "sof-ptl-nocodec.tplg",
+ .ops = &sof_lnl_ops,
+ .ops_init = sof_lnl_ops_init,
+};
+
+/* PCI IDs */
+static const struct pci_device_id sof_pci_ids[] = {
+ { PCI_DEVICE_DATA(INTEL, HDA_PTL, &ptl_desc) }, /* PTL */
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, sof_pci_ids);
+
+/* pci_driver definition */
+static struct pci_driver snd_sof_pci_intel_ptl_driver = {
+ .name = "sof-audio-pci-intel-ptl",
+ .id_table = sof_pci_ids,
+ .probe = hda_pci_intel_probe,
+ .remove = sof_pci_remove,
+ .shutdown = sof_pci_shutdown,
+ .driver = {
+ .pm = &sof_pci_pm,
+ },
+};
+module_pci_driver(snd_sof_pci_intel_ptl_driver);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("SOF support for PantherLake platforms");
+MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_GENERIC);
+MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_COMMON);
+MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_LNL);
+MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_MTL);
+MODULE_IMPORT_NS(SND_SOC_SOF_HDA_MLINK);
+MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV);
diff --git a/sound/soc/sof/intel/shim.h b/sound/soc/sof/intel/shim.h
index 9328d2bbfd03..8709b750a11e 100644
--- a/sound/soc/sof/intel/shim.h
+++ b/sound/soc/sof/intel/shim.h
@@ -22,6 +22,7 @@ enum sof_intel_hw_ip_version {
SOF_INTEL_CAVS_2_5, /* TigerLake, AlderLake */
SOF_INTEL_ACE_1_0, /* MeteorLake */
SOF_INTEL_ACE_2_0, /* LunarLake */
+ SOF_INTEL_ACE_3_0, /* PantherLake */
};
/*
diff --git a/sound/soc/sof/mediatek/mt8186/mt8186.c b/sound/soc/sof/mediatek/mt8186/mt8186.c
index 74522400207e..9466f7d2e535 100644
--- a/sound/soc/sof/mediatek/mt8186/mt8186.c
+++ b/sound/soc/sof/mediatek/mt8186/mt8186.c
@@ -656,7 +656,7 @@ MODULE_DEVICE_TABLE(of, sof_of_mt8186_ids);
/* DT driver definition */
static struct platform_driver snd_sof_of_mt8186_driver = {
.probe = sof_of_probe,
- .remove_new = sof_of_remove,
+ .remove = sof_of_remove,
.shutdown = sof_of_shutdown,
.driver = {
.name = "sof-audio-of-mt8186",
diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c
index 82d221f53a46..5b4423ed8023 100644
--- a/sound/soc/sof/mediatek/mt8195/mt8195.c
+++ b/sound/soc/sof/mediatek/mt8195/mt8195.c
@@ -612,7 +612,7 @@ MODULE_DEVICE_TABLE(of, sof_of_mt8195_ids);
/* DT driver definition */
static struct platform_driver snd_sof_of_mt8195_driver = {
.probe = sof_of_probe,
- .remove_new = sof_of_remove,
+ .remove = sof_of_remove,
.shutdown = sof_of_shutdown,
.driver = {
.name = "sof-audio-of-mt8195",
diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index baad4c1445aa..35a7462d8b69 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -100,7 +100,7 @@ sof_pcm_setup_connected_widgets(struct snd_sof_dev *sdev, struct snd_soc_pcm_run
dpcm_end_walk_at_be);
if (ret < 0) {
dev_err(sdev->dev, "error: dai %s has no valid %s path\n", dai->name,
- dir == SNDRV_PCM_STREAM_PLAYBACK ? "playback" : "capture");
+ snd_pcm_direction_name(dir));
return ret;
}
diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h
index 49be02234fc3..01b819dd8498 100644
--- a/sound/soc/sof/sof-audio.h
+++ b/sound/soc/sof/sof-audio.h
@@ -314,12 +314,12 @@ struct sof_token_info {
/**
* struct snd_sof_pcm_stream_pipeline_list - List of pipelines associated with a PCM stream
- * @count: number of pipeline widgets in the @pipe_widgets array
* @pipelines: array of pipelines
+ * @count: number of pipeline widgets in the @pipe_widgets array
*/
struct snd_sof_pcm_stream_pipeline_list {
- u32 count;
struct snd_sof_pipeline **pipelines;
+ u32 count;
};
/* PCM stream, mapped to FW component */
@@ -347,12 +347,14 @@ struct snd_sof_pcm_stream {
/* ALSA SOF PCM device */
struct snd_sof_pcm {
struct snd_soc_component *scomp;
- struct snd_soc_tplg_pcm pcm;
struct snd_sof_pcm_stream stream[2];
struct list_head list; /* list in sdev pcm list */
struct snd_pcm_hw_params params[2];
bool prepared[2]; /* PCM_PARAMS set successfully */
bool pending_stop[2]; /* only used if (!pcm_ops->platform_stop_during_hw_free) */
+
+ /* Must be last - ends in a flex-array member. */
+ struct snd_soc_tplg_pcm pcm;
};
struct snd_sof_led_control {
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index 4d6a1517f9b3..843be3b6415d 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -132,16 +132,17 @@ struct snd_sof_pdata;
/**
* struct snd_sof_platform_stream_params - platform dependent stream parameters
- * @stream_tag: Stream tag to use
- * @use_phy_addr: Use the provided @phy_addr for configuration
* @phy_addr: Platform dependent address to be used, if @use_phy_addr
* is true
+ * @stream_tag: Stream tag to use
+ * @use_phy_addr: Use the provided @phy_addr for configuration
* @no_ipc_position: Disable position update IPC from firmware
+ * @cont_update_posn: Continuous position update.
*/
struct snd_sof_platform_stream_params {
+ u32 phy_addr;
u16 stream_tag;
bool use_phy_address;
- u32 phy_addr;
bool no_ipc_position;
bool cont_update_posn;
};
@@ -411,8 +412,8 @@ struct snd_sof_debugfs_map {
/* mailbox descriptor, used for host <-> DSP IPC */
struct snd_sof_mailbox {
- u32 offset;
size_t size;
+ u32 offset;
};
/* IPC message descriptor for host <-> DSP IO */
@@ -424,11 +425,12 @@ struct snd_sof_ipc_msg {
size_t reply_size;
int reply_error;
- /* notification, firmware initiated messages */
- void *rx_data;
+ bool ipc_complete;
wait_queue_head_t waitq;
- bool ipc_complete;
+
+ /* notification, firmware initiated messages */
+ void *rx_data;
};
/**
diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
index 496162df5270..b3fca5fd87d6 100644
--- a/sound/soc/sof/topology.c
+++ b/sound/soc/sof/topology.c
@@ -1349,7 +1349,7 @@ static int sof_parse_pin_binding(struct snd_sof_widget *swidget,
/* copy pin binding array to swidget only if it is defined in topology */
if (pin_binding[0]) {
- pb = kmemdup(pin_binding, num_pins * sizeof(char *), GFP_KERNEL);
+ pb = kmemdup_array(pin_binding, num_pins, sizeof(char *), GFP_KERNEL);
if (!pb) {
ret = -ENOMEM;
goto err;
@@ -1889,9 +1889,9 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_
return -ENOMEM;
slink->num_hw_configs = le32_to_cpu(cfg->num_hw_configs);
- slink->hw_configs = kmemdup(cfg->hw_config,
- sizeof(*slink->hw_configs) * slink->num_hw_configs,
- GFP_KERNEL);
+ slink->hw_configs = kmemdup_array(cfg->hw_config,
+ slink->num_hw_configs, sizeof(*slink->hw_configs),
+ GFP_KERNEL);
if (!slink->hw_configs) {
kfree(slink);
return -ENOMEM;