Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions sound/soc/amd/acp-config.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,17 +421,32 @@ struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sof_machines[] = {
};
EXPORT_SYMBOL(snd_soc_acpi_amd_acp70_sof_machines);

struct snd_soc_acpi_mach snd_soc_acpi_amd_acp7x_sof_machines[] = {
struct snd_soc_acpi_mach snd_soc_acpi_amd_acp7f_sof_machines[] = {
{
.id = "AMDI1010",
.drv_name = "acp7x-dsp",
.drv_name = "acp7f-dsp",
.pdata = &acp_quirk_data,
.fw_filename = "sof-acp7x.ri",
.sof_tplg_filename = "sof-acp7x.tplg",
.fw_filename = "sof-acp7f.ri",
.sof_tplg_filename = "sof-acp7f.tplg",
},
{},
};
EXPORT_SYMBOL(snd_soc_acpi_amd_acp7x_sof_machines);
EXPORT_SYMBOL(snd_soc_acpi_amd_acp7f_sof_machines);

MODULE_DESCRIPTION("AMD ACP Machine Configuration Module");
MODULE_LICENSE("Dual BSD/GPL");

struct snd_soc_acpi_mach snd_soc_acpi_amd_acp7b_sof_machines[] = {
{
.id = "AMDI1010",
.drv_name = "acp7b-dsp",
.pdata = &acp_quirk_data,
.fw_filename = "sof-acp7b.ri",
.sof_tplg_filename = "sof-acp7b.tplg",
},
{},
};
EXPORT_SYMBOL(snd_soc_acpi_amd_acp7b_sof_machines);

MODULE_DESCRIPTION("AMD ACP Machine Configuration Module");
MODULE_LICENSE("Dual BSD/GPL");
25 changes: 25 additions & 0 deletions sound/soc/amd/acp/acp-mach-common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0-only
* Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved
*/
/*
* acp-mach-common.h - Structures shared across all AMD ACP machine drivers
* (I2S, SoundWire, and SOF paths).
*/

#ifndef __ACP_MACH_COMMON_H
#define __ACP_MACH_COMMON_H

/**
* struct amd_pdm_pdata - PDM controller platform data passed via mach->pdata
* @pdm_sel: active PDM controller (ACP7X_PDM_DMIC0 or ACP7X_PDM_DMIC1),
* non-zero when a PDM controller was identified via ACPI _DSD for
* ACP7.B/7.F platforms.
*
* Passed via mach->pdata by machine select logic to both I2S and SoundWire
* machine drivers so each can configure the correct DMIC DAI link.
*/
struct amd_pdm_pdata {
unsigned int pdm_sel;
};

#endif /* __ACP_MACH_COMMON_H */
14 changes: 2 additions & 12 deletions sound/soc/amd/acp/soc_amd_sdw_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,8 @@
#define ACP71_PCI_REV 0x71
#define ACP72_PCI_REV 0x72

/**
* struct amd_pdm_pdata - platform data passed via mach->pdata to machine driver
* @pdm_sel: active PDM controller (ACP7X_PDM_DMIC0 or ACP7X_PDM_DMIC1),
* non-zero when a PDM controller was identified via ACPI _DSD
*
* Carries the PDM controller selection for ACP7.B/7.F platforms, derived
* from the acp-audio-ep-port ACPI _DSD property and passed via mach->pdata
* to the machine driver.
*/
struct amd_pdm_pdata {
unsigned int pdm_sel;
};
/* amd_pdm_pdata is defined in acp-mach-common.h */
#include "acp-mach-common.h"

#define SOC_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0))
#define ASOC_SDW_FOUR_SPK BIT(4)
Expand Down
3 changes: 2 additions & 1 deletion sound/soc/amd/mach-config.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ 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[];
extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sof_sdw_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp7x_sof_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp7b_sof_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp7f_sof_machines[];

struct config_entry {
u32 flags;
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/sof/amd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#
# 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-y := acp.o acp-loader.o acp_asp_mailbox.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
snd-sof-amd-renoir-y := pci-rn.o renoir.o
snd-sof-amd-rembrandt-y := pci-rmb.o rembrandt.o
Expand Down
17 changes: 17 additions & 0 deletions sound/soc/sof/amd/acp-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ static struct snd_soc_acpi_mach *amd_sof_sdw_machine_select(struct snd_sof_dev *
struct snd_soc_acpi_mach *mach;
const struct snd_soc_acpi_link_adr *link;
struct acp_dev_data *acp_data = sdev->pdata->hw_pdata;
struct amd_pdm_pdata *pdm_pdata;
int ret, i;

if (acp_data->info.count) {
Expand All @@ -155,9 +156,25 @@ static struct snd_soc_acpi_mach *amd_sof_sdw_machine_select(struct snd_sof_dev *
}
if (mach && mach->link_mask) {
mach->mach_params.subsystem_rev = acp_data->pci_rev;
mach->mach_params.subsystem_vendor = acp_data->subsystem_vendor;
mach->mach_params.subsystem_device = acp_data->subsystem_device;
mach->mach_params.subsystem_id_set = true;
mach->mach_params.links = mach->links;
mach->mach_params.link_mask = mach->link_mask;
mach->mach_params.platform = dev_name(sdev->dev);

if (acp_data->pdm_sel) {
pdm_pdata = devm_kzalloc(sdev->dev,
sizeof(*pdm_pdata),
GFP_KERNEL);
if (!pdm_pdata)
return NULL;
pdm_pdata->pdm_sel = acp_data->pdm_sel;
mach->pdata = pdm_pdata;
}

dev_dbg(sdev->dev, "SSID %x%04x\n", mach->mach_params.subsystem_vendor,
mach->mach_params.subsystem_device);
return mach;
}
}
Expand Down
58 changes: 58 additions & 0 deletions sound/soc/sof/amd/acp-dsp-offset.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,30 @@

/* Registers from ACP_DSP_0 block */
#define ACP_DSP0_RUNSTALL 0x414
/*
* ATU group registers for groups 9–16.
* ACPAXI2AXI_ATU_CTRL (0xC40) sits between GRP_8 and GRP_9,
* so groups 9–16 are offset by 4 bytes relative to a simple stride.
*/
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_9 0xC44
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_9 0xC48
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_10 0xC4C
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_10 0xC50
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_11 0xC54
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_11 0xC58
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_12 0xC5C
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_12 0xC60
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_13 0xC64
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_13 0xC68
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_14 0xC6C
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_14 0xC70
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_15 0xC74
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_15 0xC78
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_16 0xC7C
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_16 0xC80

/* ATU page size value for 2 MB pages — used for carveout groups */
#define PAGE_SIZE_2M_ENABLE 0x0

/* Registers from ACP_AXI2AXIATU block */
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1 0xC00
Expand Down Expand Up @@ -132,6 +156,40 @@
#define ACP_SHA_DMA_INCLUDE_HDR 0x1CCC
#define ACP_SHA_PSP_ACK 0x1C74

/* ACP7.B/7.F MALL/Carveout configuration registers (ACP MMIO offsets) */
#define ACP7X_MALL_ADDR_VALID 0x114C
#define ACP7X_MALL_BASE_ADDR_LOW 0x1150
#define ACP7X_MALL_BASE_ADDR_HIGH 0x1154
#define ACP7X_MALL_SIZE 0x1158
#define ACP7X_MALL_VALID 0x115C

/* ASP MPASP mailbox SMN addresses for ACP7.B/7.F carveout firmware load */
#define MPASP_C2PMSG_173_REG 0x03810BB4
#define MPASP_C2PMSG_174_REG 0x03810BB8
#define MPASP_C2PMSG_175_REG 0x03810BBC
#define MPASP_C2PMSG_73_REG 0x03810A24

/* ASP mailbox command IDs */
#define ASP_MBOX_CMD_VALIDATE_IMAGE 0x0001
#define ASP_MBOX_CMD_CALC_HMAC 0x0002
#define ASP_MBOX_CMD_VALIDATE_HMAC 0x0003
#define ASP_MBOX_CMD_GET_CARVEOUT_ADDR 0x0004

/* MPASP_C2PMSG_173 control register bit definitions */
#define ASP_MBOX_READY_BIT BIT(31)
#define ASP_MBOX_CMD_ID_MASK 0xFFFF

/* ASP mailbox timeout: 5 seconds per ASP firmware load specification */
#define ASP_MBOX_TIMEOUT_US 5000000
/* Short timeout for the initial GET_CARVEOUT_ADDR probe: fail fast when
* ASP does not support carveout rather than blocking probe for 5 seconds.
*/
#define ASP_MBOX_PROBE_TIMEOUT_US 50000
#define ASP_MBOX_POLL_INTERVAL_US 1000

/* ASP mailbox payload cookie "ACPB" */
#define ASP_MBOX_COOKIE 0x41435042

#define ACP_SCRATCH_REG_0 0x10000
#define ACP6X_DSP_FUSION_RUNSTALL 0x0644
#define ACP70_DSP_FUSION_RUNSTALL ACP6X_DSP_FUSION_RUNSTALL
Expand Down
71 changes: 69 additions & 2 deletions sound/soc/sof/amd/acp-loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
#define FW_BIN_PTE_OFFSET 0x00
#define FW_DATA_BIN_PTE_OFFSET 0x08

#define ACP_DSP_RUN 0x00

int acp_dsp_block_read(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type,
u32 offset, void *dest, size_t size)
{
Expand Down Expand Up @@ -168,12 +166,76 @@ int acp_dsp_pre_fw_run(struct snd_sof_dev *sdev)
struct pci_dev *pci = to_pci_dev(sdev->dev);
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
struct acp_dev_data *adata;
u64 carveout_offset;
unsigned int src_addr, size_fw, dest_addr;
u32 page_count, dma_size;
u32 acp_logical_addr;
int ret;

adata = sdev->pdata->hw_pdata;

if (adata->asp_carveout_base) {
size_fw = adata->fw_code_raw_size;
page_count = PAGE_ALIGN(size_fw) >> PAGE_SHIFT;
adata->fw_bin_page_count = page_count;

if (adata->fw_code_carveout_addr < adata->asp_carveout_base ||
adata->fw_code_carveout_addr - adata->asp_carveout_base +
size_fw > adata->asp_carveout_size) {
dev_err(sdev->dev,
"carveout addr 0x%llx out of window [0x%llx+0x%x]\n",
adata->fw_code_carveout_addr,
adata->asp_carveout_base,
adata->asp_carveout_size);
return -EINVAL;
}
carveout_offset = adata->fw_code_carveout_addr - adata->asp_carveout_base;
acp_logical_addr = ACP_SYSTEM_MEMORY_WINDOW +
(adata->asp_carveout_group_start * 8 * SZ_1M) +
(u32)carveout_offset;

ret = configure_and_run_sha_dma(adata, NULL,
acp_logical_addr,
ACP_IRAM_BASE_ADDRESS, size_fw);
if (ret < 0) {
dev_err(sdev->dev, "SHA DMA from carveout failed: %d\n", ret);
return ret;
}

if (adata->is_sram_in_use) {
configure_pte_for_fw_loading(FW_SRAM_DATA_BIN,
ACP_SRAM_PAGE_COUNT, adata);
src_addr = ACP_SYSTEM_MEMORY_WINDOW + ACP_DEFAULT_SRAM_LENGTH +
(page_count * ACP_PAGE_SIZE);
dest_addr = ACP7X_SRAM_BASE_ADDRESS;
ret = configure_and_run_dma(adata, src_addr, dest_addr,
adata->fw_sram_data_bin_size);
if (ret < 0) {
dev_err(sdev->dev, "SRAM DMA failed: %d\n", ret);
dma_free_coherent(&pci->dev, ACP_DEFAULT_SRAM_LENGTH,
adata->sram_data_buf, adata->sram_dma_addr);
adata->sram_data_buf = NULL;
return ret;
}
ret = acp_dma_status(adata, 0);
if (ret < 0)
dev_err(sdev->dev, "SRAM DMA status error: %d\n", ret);
}

/* Enable cache window */
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));

if (adata->is_sram_in_use) {
dma_free_coherent(&pci->dev, ACP_DEFAULT_SRAM_LENGTH,
adata->sram_data_buf, adata->sram_dma_addr);
adata->sram_data_buf = NULL;
}
return ret;
}

if (adata->pci_rev >= ACP7B_PCI_ID) {
if (adata->acp_sof_signed_firmware_image) {
if (adata->fw_bin_size <= ACP_IMAGE_HEADER_SIZE) {
Expand All @@ -195,6 +257,11 @@ int acp_dsp_pre_fw_run(struct snd_sof_dev *sdev)
size_fw = adata->fw_bin_size;
}
} else if (adata->quirks && adata->quirks->signed_fw_image) {
if (adata->fw_bin_size <= ACP_FIRMWARE_SIGNATURE) {
dev_err(sdev->dev, "Invalid signed firmware size %u\n",
adata->fw_bin_size);
return -EINVAL;
}
size_fw = adata->fw_bin_size - ACP_FIRMWARE_SIGNATURE;
} else {
size_fw = adata->fw_bin_size;
Expand Down
9 changes: 0 additions & 9 deletions sound/soc/sof/amd/acp-stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,6 @@
#include "acp-dsp-offset.h"
#include "acp.h"

#define PTE_GRP1_OFFSET 0x00000000
#define PTE_GRP2_OFFSET 0x00800000
#define PTE_GRP3_OFFSET 0x01000000
#define PTE_GRP4_OFFSET 0x01800000
#define PTE_GRP5_OFFSET 0x02000000
#define PTE_GRP6_OFFSET 0x02800000
#define PTE_GRP7_OFFSET 0x03000000
#define PTE_GRP8_OFFSET 0x03800000

int acp_dsp_stream_config(struct snd_sof_dev *sdev, struct acp_dsp_stream *stream)
{
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
Expand Down
Loading
Loading