Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: SOF: amd: add support for acp7.0 based platform

Add SOF support for ACP7.0 version based platform.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://patch.msgid.link/20240823053739.465187-3-Vijendar.Mukunda@amd.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Vijendar Mukunda and committed by
Mark Brown
490be7ba e17de785

+352 -14
+10
sound/soc/sof/amd/Kconfig
··· 88 88 AMD ACP6.3 version based platforms. 89 89 Say Y if you want to enable SOF on ACP6.3 based platform. 90 90 If unsure select "N". 91 + 92 + config SND_SOC_SOF_AMD_ACP70 93 + tristate "SOF support for ACP7.0 platform" 94 + depends on SND_SOC_SOF_PCI 95 + select SND_SOC_SOF_AMD_COMMON 96 + help 97 + Select this option for SOF support on 98 + AMD ACP7.0 version based platforms. 99 + Say Y if you want to enable SOF on ACP7.0 based platform. 100 + 91 101 endif
+3 -1
sound/soc/sof/amd/Makefile
··· 2 2 # This file is provided under a dual BSD/GPLv2 license. When using or 3 3 # redistributing this file, you may do so under either license. 4 4 # 5 - # Copyright(c) 2021, 2023 Advanced Micro Devices, Inc. All rights reserved. 5 + # Copyright(c) 2021, 2023, 2024 Advanced Micro Devices, Inc. All rights reserved. 6 6 7 7 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 8 8 snd-sof-amd-acp-$(CONFIG_SND_SOC_SOF_ACP_PROBES) += acp-probes.o ··· 10 10 snd-sof-amd-rembrandt-y := pci-rmb.o rembrandt.o 11 11 snd-sof-amd-vangogh-y := pci-vangogh.o vangogh.o 12 12 snd-sof-amd-acp63-y := pci-acp63.o acp63.o 13 + snd-sof-amd-acp70-y := pci-acp70.o acp70.o 13 14 14 15 obj-$(CONFIG_SND_SOC_SOF_AMD_COMMON) += snd-sof-amd-acp.o 15 16 obj-$(CONFIG_SND_SOC_SOF_AMD_RENOIR) += snd-sof-amd-renoir.o 16 17 obj-$(CONFIG_SND_SOC_SOF_AMD_REMBRANDT) += snd-sof-amd-rembrandt.o 17 18 obj-$(CONFIG_SND_SOC_SOF_AMD_VANGOGH) += snd-sof-amd-vangogh.o 18 19 obj-$(CONFIG_SND_SOC_SOF_AMD_ACP63) += snd-sof-amd-acp63.o 20 + obj-$(CONFIG_SND_SOC_SOF_AMD_ACP70) += snd-sof-amd-acp70.o
+23 -1
sound/soc/sof/amd/acp-dsp-offset.h
··· 3 3 * This file is provided under a dual BSD/GPLv2 license. When using or 4 4 * redistributing this file, you may do so under either license. 5 5 * 6 - * Copyright(c) 2021, 2023 Advanced Micro Devices, Inc. All rights reserved. 6 + * Copyright(c) 2021, 2023, 2024 Advanced Micro Devices, Inc. All rights reserved. 7 7 * 8 8 * Author: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com> 9 9 */ ··· 23 23 #define ACP_DMA_CH_STS 0xE8 24 24 #define ACP_DMA_CH_GROUP 0xEC 25 25 #define ACP_DMA_CH_RST_STS 0xF0 26 + #define ACP70_DMA_CNTL_0 0x00 27 + #define ACP70_DMA_DSCR_STRT_IDX_0 0x28 28 + #define ACP70_DMA_DSCR_CNT_0 0x50 29 + #define ACP70_DMA_PRIO_0 0x78 30 + #define ACP70_DMA_CUR_DSCR_0 0xA0 31 + #define ACP70_DMA_ERR_STS_0 0xF0 32 + #define ACP70_DMA_DESC_BASE_ADDR 0x118 33 + #define ACP70_DMA_DESC_MAX_NUM_DSCR 0x11C 34 + #define ACP70_DMA_CH_STS 0x120 35 + #define ACP70_DMA_CH_GROUP 0x124 36 + #define ACP70_DMA_CH_RST_STS 0x128 26 37 27 38 /* Registers from ACP_DSP_0 block */ 28 39 #define ACP_DSP0_RUNSTALL 0x414 ··· 67 56 #define ACP3X_PGFSM_BASE 0x141C 68 57 #define ACP5X_PGFSM_BASE 0x1424 69 58 #define ACP6X_PGFSM_BASE 0x1024 59 + #define ACP70_PGFSM_BASE ACP6X_PGFSM_BASE 70 60 #define PGFSM_CONTROL_OFFSET 0x0 71 61 #define PGFSM_STATUS_OFFSET 0x4 72 62 #define ACP3X_CLKMUX_SEL 0x1424 73 63 #define ACP5X_CLKMUX_SEL 0x142C 74 64 #define ACP6X_CLKMUX_SEL 0x102C 65 + #define ACP70_CLKMUX_SEL ACP6X_CLKMUX_SEL 75 66 76 67 /* Registers from ACP_INTR block */ 77 68 #define ACP3X_EXT_INTR_STAT 0x1808 ··· 82 69 #define ACP6X_EXTERNAL_INTR_CNTL 0x1A04 83 70 #define ACP6X_EXT_INTR_STAT 0x1A0C 84 71 #define ACP6X_EXT_INTR_STAT1 0x1A10 72 + #define ACP70_EXTERNAL_INTR_ENB ACP6X_EXTERNAL_INTR_ENB 73 + #define ACP70_EXTERNAL_INTR_CNTL ACP6X_EXTERNAL_INTR_CNTL 74 + #define ACP70_EXT_INTR_STAT ACP6X_EXT_INTR_STAT 75 + #define ACP70_EXT_INTR_STAT1 ACP6X_EXT_INTR_STAT1 85 76 86 77 #define ACP3X_DSP_SW_INTR_BASE 0x1814 87 78 #define ACP5X_DSP_SW_INTR_BASE 0x1814 88 79 #define ACP6X_DSP_SW_INTR_BASE 0x1808 80 + #define ACP70_DSP_SW_INTR_BASE ACP6X_DSP_SW_INTR_BASE 89 81 #define DSP_SW_INTR_CNTL_OFFSET 0x0 90 82 #define DSP_SW_INTR_STAT_OFFSET 0x4 91 83 #define DSP_SW_INTR_TRIG_OFFSET 0x8 92 84 #define ACP3X_ERROR_STATUS 0x18C4 93 85 #define ACP6X_ERROR_STATUS 0x1A4C 86 + #define ACP70_ERROR_STATUS ACP6X_ERROR_STATUS 94 87 #define ACP3X_AXI2DAGB_SEM_0 0x1880 95 88 #define ACP5X_AXI2DAGB_SEM_0 0x1884 96 89 #define ACP6X_AXI2DAGB_SEM_0 0x1874 90 + #define ACP70_AXI2DAGB_SEM_0 ACP6X_AXI2DAGB_SEM_0 97 91 98 92 /* ACP common registers to report errors related to I2S & SoundWire interfaces */ 99 93 #define ACP3X_SW_I2S_ERROR_REASON 0x18C8 100 94 #define ACP6X_SW0_I2S_ERROR_REASON 0x18B4 95 + #define ACP7X_SW0_I2S_ERROR_REASON ACP6X_SW0_I2S_ERROR_REASON 101 96 #define ACP_SW1_I2S_ERROR_REASON 0x1A50 102 97 103 98 /* Registers from ACP_SHA block */ ··· 122 101 123 102 #define ACP_SCRATCH_REG_0 0x10000 124 103 #define ACP6X_DSP_FUSION_RUNSTALL 0x0644 104 + #define ACP70_DSP_FUSION_RUNSTALL ACP6X_DSP_FUSION_RUNSTALL 125 105 126 106 /* Cache window registers */ 127 107 #define ACP_DSP0_CACHE_OFFSET0 0x0420
+53 -12
sound/soc/sof/amd/acp.c
··· 64 64 { 65 65 struct snd_sof_dev *sdev = adata->dev; 66 66 const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata); 67 + struct acp_dev_data *acp_data = sdev->pdata->hw_pdata; 67 68 unsigned int addr; 69 + unsigned int acp_dma_desc_base_addr, acp_dma_desc_max_num_dscr; 68 70 69 71 addr = desc->sram_pte_offset + sdev->debug_box.offset + 70 72 offsetof(struct scratch_reg_conf, dma_desc); 71 73 72 - snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_DESC_BASE_ADDR, addr); 73 - snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_DESC_MAX_NUM_DSCR, ACP_MAX_DESC_CNT); 74 + switch (acp_data->pci_rev) { 75 + case ACP70_PCI_ID: 76 + acp_dma_desc_base_addr = ACP70_DMA_DESC_BASE_ADDR; 77 + acp_dma_desc_max_num_dscr = ACP70_DMA_DESC_MAX_NUM_DSCR; 78 + break; 79 + default: 80 + acp_dma_desc_base_addr = ACP_DMA_DESC_BASE_ADDR; 81 + acp_dma_desc_max_num_dscr = ACP_DMA_DESC_MAX_NUM_DSCR; 82 + } 83 + snd_sof_dsp_write(sdev, ACP_DSP_BAR, acp_dma_desc_base_addr, addr); 84 + snd_sof_dsp_write(sdev, ACP_DSP_BAR, acp_dma_desc_max_num_dscr, ACP_MAX_DESC_CNT); 74 85 } 75 86 76 87 static void configure_dma_descriptor(struct acp_dev_data *adata, unsigned short idx, ··· 103 92 unsigned int idx, unsigned int dscr_count) 104 93 { 105 94 struct snd_sof_dev *sdev = adata->dev; 95 + struct acp_dev_data *acp_data = sdev->pdata->hw_pdata; 106 96 const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata); 107 97 unsigned int val, status; 98 + unsigned int acp_dma_cntl_0, acp_dma_ch_rst_sts, acp_dma_dscr_err_sts_0; 99 + unsigned int acp_dma_dscr_cnt_0, acp_dma_prio_0, acp_dma_dscr_strt_idx_0; 108 100 int ret; 109 101 110 - snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_CNTL_0 + ch * sizeof(u32), 102 + switch (acp_data->pci_rev) { 103 + case ACP70_PCI_ID: 104 + acp_dma_cntl_0 = ACP70_DMA_CNTL_0; 105 + acp_dma_ch_rst_sts = ACP70_DMA_CH_RST_STS; 106 + acp_dma_dscr_err_sts_0 = ACP70_DMA_ERR_STS_0; 107 + acp_dma_dscr_cnt_0 = ACP70_DMA_DSCR_CNT_0; 108 + acp_dma_prio_0 = ACP70_DMA_PRIO_0; 109 + acp_dma_dscr_strt_idx_0 = ACP70_DMA_DSCR_STRT_IDX_0; 110 + break; 111 + default: 112 + acp_dma_cntl_0 = ACP_DMA_CNTL_0; 113 + acp_dma_ch_rst_sts = ACP_DMA_CH_RST_STS; 114 + acp_dma_dscr_err_sts_0 = ACP_DMA_ERR_STS_0; 115 + acp_dma_dscr_cnt_0 = ACP_DMA_DSCR_CNT_0; 116 + acp_dma_prio_0 = ACP_DMA_PRIO_0; 117 + acp_dma_dscr_strt_idx_0 = ACP_DMA_DSCR_STRT_IDX_0; 118 + } 119 + 120 + snd_sof_dsp_write(sdev, ACP_DSP_BAR, acp_dma_cntl_0 + ch * sizeof(u32), 111 121 ACP_DMA_CH_RST | ACP_DMA_CH_GRACEFUL_RST_EN); 112 122 113 - ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_DMA_CH_RST_STS, val, 123 + ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, acp_dma_ch_rst_sts, val, 114 124 val & (1 << ch), ACP_REG_POLL_INTERVAL, 115 125 ACP_REG_POLL_TIMEOUT_US); 116 126 if (ret < 0) { 117 127 status = snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->acp_error_stat); 118 - val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DMA_ERR_STS_0 + ch * sizeof(u32)); 128 + val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, acp_dma_dscr_err_sts_0 + 129 + ch * sizeof(u32)); 119 130 120 131 dev_err(sdev->dev, "ACP_DMA_ERR_STS :0x%x ACP_ERROR_STATUS :0x%x\n", val, status); 121 132 return ret; 122 133 } 123 134 124 - snd_sof_dsp_write(sdev, ACP_DSP_BAR, (ACP_DMA_CNTL_0 + ch * sizeof(u32)), 0); 125 - snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_DSCR_CNT_0 + ch * sizeof(u32), dscr_count); 126 - snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_DSCR_STRT_IDX_0 + ch * sizeof(u32), idx); 127 - snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_PRIO_0 + ch * sizeof(u32), 0); 128 - snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_CNTL_0 + ch * sizeof(u32), ACP_DMA_CH_RUN); 135 + snd_sof_dsp_write(sdev, ACP_DSP_BAR, (acp_dma_cntl_0 + ch * sizeof(u32)), 0); 136 + snd_sof_dsp_write(sdev, ACP_DSP_BAR, acp_dma_dscr_cnt_0 + ch * sizeof(u32), dscr_count); 137 + snd_sof_dsp_write(sdev, ACP_DSP_BAR, acp_dma_dscr_strt_idx_0 + ch * sizeof(u32), idx); 138 + snd_sof_dsp_write(sdev, ACP_DSP_BAR, acp_dma_prio_0 + ch * sizeof(u32), 0); 139 + snd_sof_dsp_write(sdev, ACP_DSP_BAR, acp_dma_cntl_0 + ch * sizeof(u32), ACP_DMA_CH_RUN); 129 140 130 141 return ret; 131 142 } ··· 486 453 acp_pgfsm_status_mask = ACP6X_PGFSM_STATUS_MASK; 487 454 acp_pgfsm_cntl_mask = ACP6X_PGFSM_CNTL_POWER_ON_MASK; 488 455 break; 456 + case ACP70_PCI_ID: 457 + acp_pgfsm_status_mask = ACP70_PGFSM_STATUS_MASK; 458 + acp_pgfsm_cntl_mask = ACP70_PGFSM_CNTL_POWER_ON_MASK; 459 + break; 489 460 default: 490 461 return -EINVAL; 491 462 } ··· 598 561 599 562 int amd_sof_acp_suspend(struct snd_sof_dev *sdev, u32 target_state) 600 563 { 564 + struct acp_dev_data *acp_data; 601 565 int ret; 566 + bool enable = false; 602 567 568 + acp_data = sdev->pdata->hw_pdata; 603 569 /* When acp_reset() function is invoked, it will apply ACP SOFT reset and 604 570 * DSP reset. ACP Soft reset sequence will cause all ACP IP registers will 605 571 * be reset to default values which will break the ClockStop Mode functionality. ··· 617 577 dev_err(sdev->dev, "ACP Reset failed\n"); 618 578 return ret; 619 579 } 620 - 621 - snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_CONTROL, 0x00); 580 + if (acp_data->pci_rev == ACP70_PCI_ID) 581 + enable = true; 582 + snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_CONTROL, enable); 622 583 623 584 return 0; 624 585 }
+9
sound/soc/sof/amd/acp.h
··· 29 29 #define ACP3X_PGFSM_STATUS_MASK 0x03 30 30 #define ACP6X_PGFSM_CNTL_POWER_ON_MASK 0x07 31 31 #define ACP6X_PGFSM_STATUS_MASK 0x0F 32 + #define ACP70_PGFSM_CNTL_POWER_ON_MASK 0x1F 33 + #define ACP70_PGFSM_STATUS_MASK 0xFF 32 34 33 35 #define ACP_POWERED_ON 0x00 34 36 #define ACP_ASSERT_RESET 0x01 ··· 44 42 #define ACP3X_SRAM_PTE_OFFSET 0x02050000 45 43 #define ACP5X_SRAM_PTE_OFFSET 0x02050000 46 44 #define ACP6X_SRAM_PTE_OFFSET 0x03800000 45 + #define ACP70_SRAM_PTE_OFFSET ACP6X_SRAM_PTE_OFFSET 47 46 #define PAGE_SIZE_4K_ENABLE 0x2 48 47 #define ACP_PAGE_SIZE 0x1000 49 48 #define ACP_DMA_CH_RUN 0x02 ··· 66 63 #define ACP_DRAM_BASE_ADDRESS 0x01000000 67 64 #define ACP_DRAM_PAGE_COUNT 128 68 65 #define ACP_SRAM_BASE_ADDRESS 0x3806000 66 + #define ACP7X_SRAM_BASE_ADDRESS 0x380C000 69 67 #define ACP_DSP_TO_HOST_IRQ 0x04 70 68 71 69 #define ACP_RN_PCI_ID 0x01 72 70 #define ACP_VANGOGH_PCI_ID 0x50 73 71 #define ACP_RMB_PCI_ID 0x6F 74 72 #define ACP63_PCI_ID 0x63 73 + #define ACP70_PCI_ID 0x70 75 74 76 75 #define HOST_BRIDGE_CZN 0x1630 77 76 #define HOST_BRIDGE_VGH 0x1645 78 77 #define HOST_BRIDGE_RMB 0x14B5 79 78 #define HOST_BRIDGE_ACP63 0x14E8 79 + #define HOST_BRIDGE_ACP70 0x1507 80 80 #define ACP_SHA_STAT 0x8000 81 81 #define ACP_PSP_TIMEOUT_US 1000000 82 82 #define ACP_EXT_INTR_ERROR_STAT 0x20000000 ··· 331 325 int sof_rembrandt_ops_init(struct snd_sof_dev *sdev); 332 326 extern struct snd_sof_dsp_ops sof_acp63_ops; 333 327 int sof_acp63_ops_init(struct snd_sof_dev *sdev); 328 + 329 + extern struct snd_sof_dsp_ops sof_acp70_ops; 330 + int sof_acp70_ops_init(struct snd_sof_dev *sdev); 334 331 335 332 struct snd_soc_acpi_mach *amd_sof_machine_select(struct snd_sof_dev *sdev); 336 333 /* Machine configuration */
+142
sound/soc/sof/amd/acp70.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2 + // 3 + // This file is provided under a dual BSD/GPLv2 license. When using or 4 + // redistributing this file, you may do so under either license. 5 + // 6 + // Copyright(c) 2024 Advanced Micro Devices, Inc. 7 + // 8 + // Authors: Vijendar Mukunda <Vijendar.Mukunda@amd.com> 9 + 10 + /* 11 + * Hardware interface for Audio DSP on ACP7.0 version based platform 12 + */ 13 + 14 + #include <linux/platform_device.h> 15 + #include <linux/module.h> 16 + 17 + #include "../ops.h" 18 + #include "../sof-audio.h" 19 + #include "acp.h" 20 + #include "acp-dsp-offset.h" 21 + 22 + #define I2S_HS_INSTANCE 0 23 + #define I2S_BT_INSTANCE 1 24 + #define I2S_SP_INSTANCE 2 25 + #define PDM_DMIC_INSTANCE 3 26 + #define I2S_HS_VIRTUAL_INSTANCE 4 27 + 28 + static struct snd_soc_dai_driver acp70_sof_dai[] = { 29 + [I2S_HS_INSTANCE] = { 30 + .id = I2S_HS_INSTANCE, 31 + .name = "acp-sof-hs", 32 + .playback = { 33 + .rates = SNDRV_PCM_RATE_8000_96000, 34 + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 35 + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 36 + .channels_min = 2, 37 + .channels_max = 8, 38 + .rate_min = 8000, 39 + .rate_max = 96000, 40 + }, 41 + .capture = { 42 + .rates = SNDRV_PCM_RATE_8000_48000, 43 + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 44 + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 45 + /* Supporting only stereo for I2S HS controller capture */ 46 + .channels_min = 2, 47 + .channels_max = 2, 48 + .rate_min = 8000, 49 + .rate_max = 48000, 50 + }, 51 + }, 52 + 53 + [I2S_BT_INSTANCE] = { 54 + .id = I2S_BT_INSTANCE, 55 + .name = "acp-sof-bt", 56 + .playback = { 57 + .rates = SNDRV_PCM_RATE_8000_96000, 58 + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 59 + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 60 + .channels_min = 2, 61 + .channels_max = 8, 62 + .rate_min = 8000, 63 + .rate_max = 96000, 64 + }, 65 + .capture = { 66 + .rates = SNDRV_PCM_RATE_8000_48000, 67 + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 68 + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 69 + /* Supporting only stereo for I2S BT controller capture */ 70 + .channels_min = 2, 71 + .channels_max = 2, 72 + .rate_min = 8000, 73 + .rate_max = 48000, 74 + }, 75 + }, 76 + 77 + [I2S_SP_INSTANCE] = { 78 + .id = I2S_SP_INSTANCE, 79 + .name = "acp-sof-sp", 80 + .playback = { 81 + .rates = SNDRV_PCM_RATE_8000_96000, 82 + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 83 + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 84 + .channels_min = 2, 85 + .channels_max = 8, 86 + .rate_min = 8000, 87 + .rate_max = 96000, 88 + }, 89 + .capture = { 90 + .rates = SNDRV_PCM_RATE_8000_48000, 91 + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 92 + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 93 + /* Supporting only stereo for I2S SP controller capture */ 94 + .channels_min = 2, 95 + .channels_max = 2, 96 + .rate_min = 8000, 97 + .rate_max = 48000, 98 + }, 99 + }, 100 + 101 + [PDM_DMIC_INSTANCE] = { 102 + .id = PDM_DMIC_INSTANCE, 103 + .name = "acp-sof-dmic", 104 + .capture = { 105 + .rates = SNDRV_PCM_RATE_8000_48000, 106 + .formats = SNDRV_PCM_FMTBIT_S32_LE, 107 + .channels_min = 2, 108 + .channels_max = 4, 109 + .rate_min = 8000, 110 + .rate_max = 48000, 111 + }, 112 + }, 113 + 114 + [I2S_HS_VIRTUAL_INSTANCE] = { 115 + .id = I2S_HS_VIRTUAL_INSTANCE, 116 + .name = "acp-sof-hs-virtual", 117 + .playback = { 118 + .rates = SNDRV_PCM_RATE_8000_96000, 119 + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 120 + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, 121 + .channels_min = 2, 122 + .channels_max = 8, 123 + .rate_min = 8000, 124 + .rate_max = 96000, 125 + }, 126 + }, 127 + }; 128 + 129 + /* Phoenix ops */ 130 + struct snd_sof_dsp_ops sof_acp70_ops; 131 + EXPORT_SYMBOL_NS(sof_acp70_ops, SND_SOC_SOF_AMD_COMMON); 132 + 133 + int sof_acp70_ops_init(struct snd_sof_dev *sdev) 134 + { 135 + /* common defaults */ 136 + memcpy(&sof_acp70_ops, &sof_acp_common_ops, sizeof(struct snd_sof_dsp_ops)); 137 + 138 + sof_acp70_ops.drv = acp70_sof_dai; 139 + sof_acp70_ops.num_drv = ARRAY_SIZE(acp70_sof_dai); 140 + 141 + return 0; 142 + }
+112
sound/soc/sof/amd/pci-acp70.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2 + // 3 + // This file is provided under a dual BSD/GPLv2 license. When using or 4 + // redistributing this file, you may do so under either license. 5 + // 6 + // Copyright(c) 2024 Advanced Micro Devices, Inc. All rights reserved. 7 + // 8 + // Authors: Vijendar Mukunda <Vijendar.Mukunda@amd.com> 9 + 10 + /*. 11 + * PCI interface for ACP7.0 device 12 + */ 13 + 14 + #include <linux/module.h> 15 + #include <linux/pci.h> 16 + #include <linux/platform_device.h> 17 + #include <sound/sof.h> 18 + #include <sound/soc-acpi.h> 19 + 20 + #include "../ops.h" 21 + #include "../sof-pci-dev.h" 22 + #include "../../amd/mach-config.h" 23 + #include "acp.h" 24 + #include "acp-dsp-offset.h" 25 + 26 + #define ACP70_FUTURE_REG_ACLK_0 0x1854 27 + #define ACP70_REG_START 0x1240000 28 + #define ACP70_REG_END 0x125C000 29 + 30 + static const struct sof_amd_acp_desc acp70_chip_info = { 31 + .host_bridge_id = HOST_BRIDGE_ACP70, 32 + .pgfsm_base = ACP70_PGFSM_BASE, 33 + .ext_intr_enb = ACP70_EXTERNAL_INTR_ENB, 34 + .ext_intr_cntl = ACP70_EXTERNAL_INTR_CNTL, 35 + .ext_intr_stat = ACP70_EXT_INTR_STAT, 36 + .ext_intr_stat1 = ACP70_EXT_INTR_STAT1, 37 + .dsp_intr_base = ACP70_DSP_SW_INTR_BASE, 38 + .acp_sw0_i2s_err_reason = ACP7X_SW0_I2S_ERROR_REASON, 39 + .sram_pte_offset = ACP70_SRAM_PTE_OFFSET, 40 + .hw_semaphore_offset = ACP70_AXI2DAGB_SEM_0, 41 + .fusion_dsp_offset = ACP70_DSP_FUSION_RUNSTALL, 42 + .probe_reg_offset = ACP70_FUTURE_REG_ACLK_0, 43 + .reg_start_addr = ACP70_REG_START, 44 + .reg_end_addr = ACP70_REG_END, 45 + }; 46 + 47 + static const struct sof_dev_desc acp70_desc = { 48 + .machines = snd_soc_acpi_amd_acp70_sof_machines, 49 + .resindex_lpe_base = 0, 50 + .resindex_pcicfg_base = -1, 51 + .resindex_imr_base = -1, 52 + .irqindex_host_ipc = -1, 53 + .chip_info = &acp70_chip_info, 54 + .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), 55 + .ipc_default = SOF_IPC_TYPE_3, 56 + .default_fw_path = { 57 + [SOF_IPC_TYPE_3] = "amd/sof", 58 + }, 59 + .default_tplg_path = { 60 + [SOF_IPC_TYPE_3] = "amd/sof-tplg", 61 + }, 62 + .default_fw_filename = { 63 + [SOF_IPC_TYPE_3] = "sof-acp_7_0.ri", 64 + }, 65 + .nocodec_tplg_filename = "sof-acp.tplg", 66 + .ops = &sof_acp70_ops, 67 + .ops_init = sof_acp70_ops_init, 68 + }; 69 + 70 + static int acp70_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) 71 + { 72 + unsigned int flag; 73 + 74 + if (pci->revision != ACP70_PCI_ID) 75 + return -ENODEV; 76 + 77 + flag = snd_amd_acp_find_config(pci); 78 + if (flag != FLAG_AMD_SOF && flag != FLAG_AMD_SOF_ONLY_DMIC) 79 + return -ENODEV; 80 + 81 + return sof_pci_probe(pci, pci_id); 82 + }; 83 + 84 + static void acp70_pci_remove(struct pci_dev *pci) 85 + { 86 + sof_pci_remove(pci); 87 + } 88 + 89 + /* PCI IDs */ 90 + static const struct pci_device_id acp70_pci_ids[] = { 91 + { PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_PCI_DEV_ID), 92 + .driver_data = (unsigned long)&acp70_desc}, 93 + { 0, } 94 + }; 95 + MODULE_DEVICE_TABLE(pci, acp70_pci_ids); 96 + 97 + /* pci_driver definition */ 98 + static struct pci_driver snd_sof_pci_amd_acp70_driver = { 99 + .name = KBUILD_MODNAME, 100 + .id_table = acp70_pci_ids, 101 + .probe = acp70_pci_probe, 102 + .remove = acp70_pci_remove, 103 + .driver = { 104 + .pm = &sof_pci_pm, 105 + }, 106 + }; 107 + module_pci_driver(snd_sof_pci_amd_acp70_driver); 108 + 109 + MODULE_LICENSE("Dual BSD/GPL"); 110 + MODULE_DESCRIPTION("ACP70 SOF Driver"); 111 + MODULE_IMPORT_NS(SND_SOC_SOF_AMD_COMMON); 112 + MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV);