diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/soc/amd/common/block/acp/Kconfig | 6 | ||||
-rw-r--r-- | src/soc/amd/common/block/acp/Makefile.inc | 3 | ||||
-rw-r--r-- | src/soc/amd/common/block/acp/acp.c | 2 | ||||
-rw-r--r-- | src/soc/amd/common/block/acp/acp_gen2.c | 42 | ||||
-rw-r--r-- | src/soc/amd/common/block/include/amdblocks/acp.h | 17 |
5 files changed, 70 insertions, 0 deletions
diff --git a/src/soc/amd/common/block/acp/Kconfig b/src/soc/amd/common/block/acp/Kconfig index 7747c9359e..df17f71057 100644 --- a/src/soc/amd/common/block/acp/Kconfig +++ b/src/soc/amd/common/block/acp/Kconfig @@ -3,3 +3,9 @@ config SOC_AMD_COMMON_BLOCK_ACP_GEN1 help Select this option to perform Audio Co-Processor(ACP) configuration. Used by the ACP in AMD family 17h, 19h, and earlier (picasso, cezanne) + +config SOC_AMD_COMMON_BLOCK_ACP_GEN2 + bool + help + Select this option to perform Audio Co-Processor(ACP) configuration. + Used by the ACP in AMD sabrina (family 17h) and possibly newer CPUs. diff --git a/src/soc/amd/common/block/acp/Makefile.inc b/src/soc/amd/common/block/acp/Makefile.inc index 311fb75662..c1fa6ec408 100644 --- a/src/soc/amd/common/block/acp/Makefile.inc +++ b/src/soc/amd/common/block/acp/Makefile.inc @@ -1,2 +1,5 @@ ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_ACP_GEN1) += acp.c ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_ACP_GEN1) += acp_gen1.c + +ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_ACP_GEN2) += acp.c +ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_ACP_GEN2) += acp_gen2.c diff --git a/src/soc/amd/common/block/acp/acp.c b/src/soc/amd/common/block/acp/acp.c index 057d50ad96..b9dfce29ce 100644 --- a/src/soc/amd/common/block/acp/acp.c +++ b/src/soc/amd/common/block/acp/acp.c @@ -12,6 +12,8 @@ #include <commonlib/helpers.h> #include "acp_def.h" +_Static_assert(!(CONFIG(SOC_AMD_COMMON_BLOCK_ACP_GEN1) && CONFIG(SOC_AMD_COMMON_BLOCK_ACP_GEN2)), + "Cannot select both ACP_GEN1 and ACP_GEN2 - check your config"); static const char *acp_acpi_name(const struct device *dev) { diff --git a/src/soc/amd/common/block/acp/acp_gen2.c b/src/soc/amd/common/block/acp/acp_gen2.c new file mode 100644 index 0000000000..50de4b0bd9 --- /dev/null +++ b/src/soc/amd/common/block/acp/acp_gen2.c @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <amdblocks/acp.h> +#include <amdblocks/chip.h> +#include <device/device.h> +#include <device/mmio.h> +#include <console/console.h> +#include "acp_def.h" + +/* ACP registers and associated fields */ +#define ACP_PME_EN 0x41400 +#define PME_EN_MASK (1 << 0) +#define ACP_I2S_PIN_CONFIG 0x41440 /* HDA, Soundwire, I2S */ +#define PIN_CONFIG_MASK (0xf << 0) +#define ACP_I2S_WAKE_EN 0x4145C +#define WAKE_EN_MASK (1 << 0) + +static void acp_update32(uintptr_t bar, uint32_t reg, uint32_t clear, uint32_t set) +{ + clrsetbits32((void *)(bar + reg), clear, set); +} + +void acp_init(struct device *dev) +{ + const struct soc_amd_common_config *cfg = soc_get_common_config(); + struct resource *res; + uintptr_t bar; + + res = dev->resource_list; + if (!res || !res->base) { + printk(BIOS_ERR, "Error, unable to configure pin in %s\n", __func__); + return; + } + + /* Set the proper I2S_PIN_CONFIG state */ + bar = (uintptr_t)res->base; + acp_update32(bar, ACP_I2S_PIN_CONFIG, PIN_CONFIG_MASK, cfg->acp_config.acp_pin_cfg); + + /* Enable ACP_PME_EN and ACP_I2S_WAKE_EN for I2S_WAKE event */ + acp_update32(bar, ACP_I2S_WAKE_EN, WAKE_EN_MASK, !!cfg->acp_config.acp_i2s_wake_enable); + acp_update32(bar, ACP_PME_EN, PME_EN_MASK, !!cfg->acp_config.acp_pme_enable); +} diff --git a/src/soc/amd/common/block/include/amdblocks/acp.h b/src/soc/amd/common/block/include/amdblocks/acp.h index 13254e4c0a..04112ca272 100644 --- a/src/soc/amd/common/block/include/amdblocks/acp.h +++ b/src/soc/amd/common/block/include/amdblocks/acp.h @@ -7,12 +7,29 @@ struct acp_config { enum { +#if CONFIG(SOC_AMD_COMMON_BLOCK_ACP_GEN2) + ACP_PINS_HDA_3SDI = 1, /* HDA 3xSDI */ + ACP_PINS_HDA_1SDI_1SW = 2, /* HDA 1xSDI, SW w/Data0 */ + ACP_PINS_4SW_1SW = 3, /* SW w/Data0-3, SW w/Data0 */ + ACP_PINS_HDA_3SDI_PDM2 = 4, /* HDA 3xSDI, PDM 2CH */ + ACP_PINS_HDA_1SDI_PDM6 = 5, /* HDA 1xSDI, PDM 6CH */ + ACP_PINS_HDA_1SDI_1SW_PDM2 = 6, /* HDA 1xSDI, SW w/Data0, PDM 2CH */ + ACP_PINS_4SW_PDM6 = 7, /* SW w/Data0-3, PDM 6CH */ + ACP_PINS_4SW_1SW_PDM2 = 8, /* SW w/Data0-3, SW w/Data0, PDM 2CH */ + ACP_PINS_I2S = 9, /* 3xI2S, Refclk, Intr */ + ACP_PINS_HDA_3SDI_PDM6_I2S = 10,/* HDA 3xSDI, PDM 6CH, I2S */ + ACP_PINS_HDA_3SDI_PDM8 = 11, /* HDA 3xSDI, PDM 8CH */ + ACP_PINS_HDA_1SDI_1SW_PDM6_I2S = 12,/* HDA 1xSDI, SW w/Data0, PDM 6CH, I2S */ + ACP_PINS_4SW_1SW_PDM6_I2S = 13, /* SW w/Data0-3, SW w/Data0, PDM 6CH, I2S */ + ACP_PINS_4SW_1SW_PDM8 = 14, /* SW w/Data0-3, SW w/Data0, PDM 8CH */ +#else I2S_PINS_MAX_HDA = 0, /* HDA w/reset 3xSDI, SW w/Data0 */ I2S_PINS_MAX_MHDA = 1, /* HDA no reset 3xSDI, SW w/Data0-1 */ I2S_PINS_MIN_HDA = 2, /* HDA w/reset 1xSDI, SW w/Data0-2 */ I2S_PINS_MIN_MHDA = 3, /* HDA no reset 1xSDI, SW w/Data0-3 */ I2S_PINS_I2S_TDM = 4, I2S_PINS_UNCONF = 7, /* All pads will be input mode */ +#endif } acp_pin_cfg; /* Enable ACP I2S wake feature (0 = disable, 1 = enable) */ |