ASoC: SOF: amd: Make ACP core code generic for newer SOC transition
Newer AMD SOC differs slightly in terms of few registers offset and configuration. Add offsets into chip_info struct to make core ACP code more generic and resusable on newer SOC. Signed-off-by: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com> Signed-off-by: V sujith kumar Reddy <Vsujithkumar.Reddy@amd.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20220913144319.1055302-2-Vsujithkumar.Reddy@amd.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
9f27530a73
commit
4da6b033f5
@ -4,7 +4,7 @@
|
||||
#
|
||||
# Copyright(c) 2021 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
snd-sof-amd-acp-objs := acp.o acp-loader.o acp-ipc.o acp-pcm.o acp-stream.o acp-trace.o
|
||||
snd-sof-amd-acp-objs := acp.o acp-loader.o acp-ipc.o acp-pcm.o acp-stream.o acp-trace.o acp-common.o
|
||||
snd-sof-amd-renoir-objs := pci-rn.o renoir.o
|
||||
|
||||
obj-$(CONFIG_SND_SOC_SOF_AMD_COMMON) += snd-sof-amd-acp.o
|
||||
|
110
sound/soc/sof/amd/acp-common.c
Normal file
110
sound/soc/sof/amd/acp-common.c
Normal file
@ -0,0 +1,110 @@
|
||||
// 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) 2022 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
|
||||
// V sujith kumar Reddy <Vsujithkumar.Reddy@amd.com>
|
||||
|
||||
/* ACP-specific Common code */
|
||||
|
||||
#include "../sof-priv.h"
|
||||
#include "../sof-audio.h"
|
||||
#include "../ops.h"
|
||||
#include "../sof-audio.h"
|
||||
#include "acp.h"
|
||||
#include "acp-dsp-offset.h"
|
||||
|
||||
int acp_dai_probe(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component);
|
||||
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
|
||||
unsigned int val;
|
||||
|
||||
val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->i2s_pin_config_offset);
|
||||
if (val != desc->i2s_mode) {
|
||||
dev_err(sdev->dev, "I2S Mode is not supported (I2S_PIN_CONFIG: %#x)\n", val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_NS(acp_dai_probe, SND_SOC_SOF_AMD_COMMON);
|
||||
|
||||
struct snd_soc_acpi_mach *amd_sof_machine_select(struct snd_sof_dev *sdev)
|
||||
{
|
||||
struct snd_sof_pdata *sof_pdata = sdev->pdata;
|
||||
const struct sof_dev_desc *desc = sof_pdata->desc;
|
||||
struct snd_soc_acpi_mach *mach;
|
||||
|
||||
mach = snd_soc_acpi_find_machine(desc->machines);
|
||||
if (!mach) {
|
||||
dev_warn(sdev->dev, "No matching ASoC machine driver found\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sof_pdata->tplg_filename = mach->sof_tplg_filename;
|
||||
sof_pdata->fw_filename = mach->fw_filename;
|
||||
|
||||
return mach;
|
||||
}
|
||||
|
||||
/* AMD Common DSP ops */
|
||||
struct snd_sof_dsp_ops sof_acp_common_ops = {
|
||||
/* probe and remove */
|
||||
.probe = amd_sof_acp_probe,
|
||||
.remove = amd_sof_acp_remove,
|
||||
|
||||
/* Register IO */
|
||||
.write = sof_io_write,
|
||||
.read = sof_io_read,
|
||||
|
||||
/* Block IO */
|
||||
.block_read = acp_dsp_block_read,
|
||||
.block_write = acp_dsp_block_write,
|
||||
|
||||
/*Firmware loading */
|
||||
.load_firmware = snd_sof_load_firmware_memcpy,
|
||||
.pre_fw_run = acp_dsp_pre_fw_run,
|
||||
.get_bar_index = acp_get_bar_index,
|
||||
|
||||
/* DSP core boot */
|
||||
.run = acp_sof_dsp_run,
|
||||
|
||||
/*IPC */
|
||||
.send_msg = acp_sof_ipc_send_msg,
|
||||
.ipc_msg_data = acp_sof_ipc_msg_data,
|
||||
.get_mailbox_offset = acp_sof_ipc_get_mailbox_offset,
|
||||
.irq_thread = acp_sof_ipc_irq_thread,
|
||||
|
||||
/* stream callbacks */
|
||||
.pcm_open = acp_pcm_open,
|
||||
.pcm_close = acp_pcm_close,
|
||||
.pcm_hw_params = acp_pcm_hw_params,
|
||||
|
||||
.hw_info = SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_PAUSE |
|
||||
SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
|
||||
|
||||
/* Machine driver callbacks */
|
||||
.machine_select = amd_sof_machine_select,
|
||||
.machine_register = sof_machine_register,
|
||||
.machine_unregister = sof_machine_unregister,
|
||||
|
||||
/* Trace Logger */
|
||||
.trace_init = acp_sof_trace_init,
|
||||
.trace_release = acp_sof_trace_release,
|
||||
|
||||
/* PM */
|
||||
.suspend = amd_sof_acp_suspend,
|
||||
.resume = amd_sof_acp_resume,
|
||||
};
|
||||
EXPORT_SYMBOL_NS(sof_acp_common_ops, SND_SOC_SOF_AMD_COMMON);
|
||||
|
||||
MODULE_IMPORT_NS(SND_SOC_SOF_AMD_COMMON);
|
||||
MODULE_DESCRIPTION("ACP SOF COMMON Driver");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
@ -48,22 +48,23 @@
|
||||
#define ACP_SOFT_RESET 0x1000
|
||||
#define ACP_CONTROL 0x1004
|
||||
|
||||
#define ACP_I2S_PIN_CONFIG 0x1400
|
||||
#define ACP3X_I2S_PIN_CONFIG 0x1400
|
||||
|
||||
/* Registers from ACP_PGFSM block */
|
||||
#define ACP_PGFSM_CONTROL 0x141C
|
||||
#define ACP_PGFSM_STATUS 0x1420
|
||||
#define ACP_CLKMUX_SEL 0x1424
|
||||
/* Registers offsets from ACP_PGFSM block */
|
||||
#define ACP3X_PGFSM_BASE 0x141C
|
||||
#define PGFSM_CONTROL_OFFSET 0x0
|
||||
#define PGFSM_STATUS_OFFSET 0x4
|
||||
#define ACP3X_CLKMUX_SEL 0x1424
|
||||
|
||||
/* Registers from ACP_INTR block */
|
||||
#define ACP_EXTERNAL_INTR_ENB 0x1800
|
||||
#define ACP_EXTERNAL_INTR_CNTL 0x1804
|
||||
#define ACP_EXTERNAL_INTR_STAT 0x1808
|
||||
#define ACP_DSP_SW_INTR_CNTL 0x1814
|
||||
#define ACP_DSP_SW_INTR_STAT 0x1818
|
||||
#define ACP_SW_INTR_TRIG 0x181C
|
||||
#define ACP3X_EXT_INTR_STAT 0x1808
|
||||
|
||||
#define ACP3X_DSP_SW_INTR_BASE 0x1814
|
||||
#define DSP_SW_INTR_CNTL_OFFSET 0x0
|
||||
#define DSP_SW_INTR_STAT_OFFSET 0x4
|
||||
#define DSP_SW_INTR_TRIG_OFFSET 0x8
|
||||
#define ACP_ERROR_STATUS 0x18C4
|
||||
#define ACP_AXI2DAGB_SEM_0 0x1880
|
||||
#define ACP3X_AXI2DAGB_SEM_0 0x1880
|
||||
|
||||
/* Registers from ACP_SHA block */
|
||||
#define ACP_SHA_DSP_FW_QUALIFIER 0x1C70
|
||||
|
@ -30,11 +30,14 @@ EXPORT_SYMBOL_NS(acp_mailbox_read, SND_SOC_SOF_AMD_COMMON);
|
||||
static void acpbus_trigger_host_to_dsp_swintr(struct acp_dev_data *adata)
|
||||
{
|
||||
struct snd_sof_dev *sdev = adata->dev;
|
||||
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
|
||||
u32 swintr_trigger;
|
||||
|
||||
swintr_trigger = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SW_INTR_TRIG);
|
||||
swintr_trigger = snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->dsp_intr_base +
|
||||
DSP_SW_INTR_TRIG_OFFSET);
|
||||
swintr_trigger |= 0x01;
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SW_INTR_TRIG, swintr_trigger);
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->dsp_intr_base + DSP_SW_INTR_TRIG_OFFSET,
|
||||
swintr_trigger);
|
||||
}
|
||||
|
||||
static void acp_ipc_host_msg_set(struct snd_sof_dev *sdev)
|
||||
@ -61,10 +64,11 @@ static void acp_dsp_ipc_dsp_done(struct snd_sof_dev *sdev)
|
||||
int acp_sof_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
|
||||
{
|
||||
struct acp_dev_data *adata = sdev->pdata->hw_pdata;
|
||||
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
|
||||
unsigned int offset = offsetof(struct scratch_ipc_conf, sof_in_box);
|
||||
unsigned int count = ACP_HW_SEM_RETRY_COUNT;
|
||||
|
||||
while (snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_AXI2DAGB_SEM_0)) {
|
||||
while (snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->hw_semaphore_offset)) {
|
||||
/* Wait until acquired HW Semaphore Lock or timeout*/
|
||||
count--;
|
||||
if (!count) {
|
||||
@ -80,7 +84,7 @@ int acp_sof_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
|
||||
acpbus_trigger_host_to_dsp_swintr(adata);
|
||||
|
||||
/* Unlock or Release HW Semaphore */
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_AXI2DAGB_SEM_0, 0x0);
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->hw_semaphore_offset, 0x0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -186,7 +190,9 @@ EXPORT_SYMBOL_NS(acp_sof_ipc_msg_data, SND_SOC_SOF_AMD_COMMON);
|
||||
|
||||
int acp_sof_ipc_get_mailbox_offset(struct snd_sof_dev *sdev)
|
||||
{
|
||||
return ACP_SCRATCH_MEMORY_ADDRESS;
|
||||
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
|
||||
|
||||
return desc->sram_pte_offset;
|
||||
}
|
||||
EXPORT_SYMBOL_NS(acp_sof_ipc_get_mailbox_offset, SND_SOC_SOF_AMD_COMMON);
|
||||
|
||||
|
@ -30,9 +30,10 @@
|
||||
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)
|
||||
{
|
||||
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
|
||||
switch (blk_type) {
|
||||
case SOF_FW_BLK_TYPE_SRAM:
|
||||
offset = offset - ACP_SCRATCH_MEMORY_ADDRESS;
|
||||
offset = offset - desc->sram_pte_offset;
|
||||
memcpy_from_scratch(sdev, offset, dest, size);
|
||||
break;
|
||||
default:
|
||||
@ -49,6 +50,7 @@ int acp_dsp_block_write(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_t
|
||||
{
|
||||
struct snd_sof_pdata *plat_data = sdev->pdata;
|
||||
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;
|
||||
void *dest;
|
||||
u32 dma_size, page_count;
|
||||
@ -84,7 +86,7 @@ int acp_dsp_block_write(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_t
|
||||
adata->fw_data_bin_size = size + offset;
|
||||
break;
|
||||
case SOF_FW_BLK_TYPE_SRAM:
|
||||
offset = offset - ACP_SCRATCH_MEMORY_ADDRESS;
|
||||
offset = offset - desc->sram_pte_offset;
|
||||
memcpy_to_scratch(sdev, offset, src, size);
|
||||
return 0;
|
||||
default:
|
||||
@ -105,14 +107,13 @@ EXPORT_SYMBOL_NS(acp_get_bar_index, SND_SOC_SOF_AMD_COMMON);
|
||||
|
||||
static void configure_pte_for_fw_loading(int type, int num_pages, struct acp_dev_data *adata)
|
||||
{
|
||||
struct snd_sof_dev *sdev;
|
||||
struct snd_sof_dev *sdev = adata->dev;
|
||||
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
|
||||
unsigned int low, high;
|
||||
dma_addr_t addr;
|
||||
u16 page_idx;
|
||||
u32 offset;
|
||||
|
||||
sdev = adata->dev;
|
||||
|
||||
switch (type) {
|
||||
case FW_BIN:
|
||||
offset = FW_BIN_PTE_OFFSET;
|
||||
@ -129,7 +130,7 @@ static void configure_pte_for_fw_loading(int type, int num_pages, struct acp_dev
|
||||
|
||||
/* Group Enable */
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACPAXI2AXI_ATU_BASE_ADDR_GRP_1,
|
||||
ACP_SRAM_PTE_OFFSET | BIT(31));
|
||||
desc->sram_pte_offset | BIT(31));
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1,
|
||||
PAGE_SIZE_4K_ENABLE);
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
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);
|
||||
unsigned int pte_reg, pte_size, phy_addr_offset, index;
|
||||
int stream_tag = stream->stream_tag;
|
||||
u32 low, high, offset, reg_val;
|
||||
@ -96,7 +97,7 @@ int acp_dsp_stream_config(struct snd_sof_dev *sdev, struct acp_dsp_stream *strea
|
||||
phy_addr_offset, stream->reg_offset);
|
||||
|
||||
/* Group Enable */
|
||||
reg_val = ACP_SRAM_PTE_OFFSET + offset;
|
||||
reg_val = desc->sram_pte_offset + offset;
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, pte_reg, reg_val | BIT(31));
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, pte_size, PAGE_SIZE_4K_ENABLE);
|
||||
|
||||
|
@ -39,9 +39,10 @@ static int smn_read(struct pci_dev *dev, u32 smn_addr, u32 *data)
|
||||
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);
|
||||
unsigned int addr;
|
||||
|
||||
addr = ACP_SRAM_PTE_OFFSET + offsetof(struct scratch_reg_conf, dma_desc);
|
||||
addr = desc->sram_pte_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);
|
||||
@ -300,8 +301,9 @@ void memcpy_to_scratch(struct snd_sof_dev *sdev, u32 offset, unsigned int *src,
|
||||
static int acp_memory_init(struct snd_sof_dev *sdev)
|
||||
{
|
||||
struct acp_dev_data *adata = sdev->pdata->hw_pdata;
|
||||
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
|
||||
|
||||
snd_sof_dsp_update_bits(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_CNTL,
|
||||
snd_sof_dsp_update_bits(sdev, ACP_DSP_BAR, desc->dsp_intr_base + DSP_SW_INTR_CNTL_OFFSET,
|
||||
ACP_DSP_INTR_EN_MASK, ACP_DSP_INTR_EN_MASK);
|
||||
init_dma_descriptor(adata);
|
||||
|
||||
@ -311,18 +313,20 @@ static int acp_memory_init(struct snd_sof_dev *sdev)
|
||||
static irqreturn_t acp_irq_thread(int irq, void *context)
|
||||
{
|
||||
struct snd_sof_dev *sdev = context;
|
||||
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
|
||||
unsigned int base = desc->dsp_intr_base;
|
||||
unsigned int val, count = ACP_HW_SEM_RETRY_COUNT;
|
||||
|
||||
val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_EXTERNAL_INTR_STAT);
|
||||
val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->ext_intr_stat);
|
||||
if (val & ACP_SHA_STAT) {
|
||||
/* Clear SHA interrupt raised by PSP */
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_EXTERNAL_INTR_STAT, val);
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_stat, val);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_STAT);
|
||||
val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET);
|
||||
if (val & ACP_DSP_TO_HOST_IRQ) {
|
||||
while (snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_AXI2DAGB_SEM_0)) {
|
||||
while (snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->hw_semaphore_offset)) {
|
||||
/* Wait until acquired HW Semaphore lock or timeout */
|
||||
count--;
|
||||
if (!count) {
|
||||
@ -333,10 +337,10 @@ static irqreturn_t acp_irq_thread(int irq, void *context)
|
||||
|
||||
sof_ops(sdev)->irq_thread(irq, sdev);
|
||||
val |= ACP_DSP_TO_HOST_IRQ;
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_STAT, val);
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET, val);
|
||||
|
||||
/* Unlock or Release HW Semaphore */
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_AXI2DAGB_SEM_0, 0x0);
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->hw_semaphore_offset, 0x0);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@ -347,9 +351,11 @@ static irqreturn_t acp_irq_thread(int irq, void *context)
|
||||
static irqreturn_t acp_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct snd_sof_dev *sdev = dev_id;
|
||||
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
|
||||
unsigned int base = desc->dsp_intr_base;
|
||||
unsigned int val;
|
||||
|
||||
val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_STAT);
|
||||
val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET);
|
||||
if (val)
|
||||
return IRQ_WAKE_THREAD;
|
||||
|
||||
@ -358,20 +364,22 @@ 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);
|
||||
unsigned int base = desc->pgfsm_base;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_PGFSM_STATUS);
|
||||
val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, base + PGFSM_STATUS_OFFSET);
|
||||
|
||||
if (val == ACP_POWERED_ON)
|
||||
return 0;
|
||||
|
||||
if (val & ACP_PGFSM_STATUS_MASK)
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_PGFSM_CONTROL,
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + PGFSM_CONTROL_OFFSET,
|
||||
ACP_PGFSM_CNTL_POWER_ON_MASK);
|
||||
|
||||
ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_PGFSM_STATUS, val, !val,
|
||||
ACP_REG_POLL_INTERVAL, ACP_REG_POLL_TIMEOUT_US);
|
||||
ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, base + PGFSM_STATUS_OFFSET, val,
|
||||
!val, ACP_REG_POLL_INTERVAL, ACP_REG_POLL_TIMEOUT_US);
|
||||
if (ret < 0)
|
||||
dev_err(sdev->dev, "timeout in ACP_PGFSM_STATUS read\n");
|
||||
|
||||
@ -437,6 +445,7 @@ EXPORT_SYMBOL_NS(amd_sof_acp_suspend, SND_SOC_SOF_AMD_COMMON);
|
||||
|
||||
int amd_sof_acp_resume(struct snd_sof_dev *sdev)
|
||||
{
|
||||
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
|
||||
int ret;
|
||||
|
||||
ret = acp_init(sdev);
|
||||
@ -445,7 +454,7 @@ int amd_sof_acp_resume(struct snd_sof_dev *sdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_CLKMUX_SEL, 0x03);
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->acp_clkmux_sel, 0x03);
|
||||
|
||||
ret = acp_memory_init(sdev);
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
#define ACP_SOFT_RESET_DONE_MASK 0x00010001
|
||||
|
||||
#define ACP_DSP_INTR_EN_MASK 0x00000001
|
||||
#define ACP_SRAM_PTE_OFFSET 0x02050000
|
||||
#define ACP3X_SRAM_PTE_OFFSET 0x02050000
|
||||
#define PAGE_SIZE_4K_ENABLE 0x2
|
||||
#define ACP_PAGE_SIZE 0x1000
|
||||
#define ACP_DMA_CH_RUN 0x02
|
||||
@ -45,7 +45,7 @@
|
||||
#define ACPBUS_REG_BASE_OFFSET ACP_DMA_CNTL_0
|
||||
|
||||
#define ACP_DEFAULT_DRAM_LENGTH 0x00080000
|
||||
#define ACP_SCRATCH_MEMORY_ADDRESS 0x02050000
|
||||
#define ACP3X_SCRATCH_MEMORY_ADDRESS 0x02050000
|
||||
#define ACP_SYSTEM_MEMORY_WINDOW 0x4000000
|
||||
#define ACP_IRAM_BASE_ADDRESS 0x000000
|
||||
#define ACP_DATA_RAM_BASE_ADDRESS 0x01000000
|
||||
@ -139,6 +139,19 @@ struct acp_dsp_stream {
|
||||
unsigned int reg_offset;
|
||||
};
|
||||
|
||||
struct sof_amd_acp_desc {
|
||||
unsigned int rev;
|
||||
unsigned int host_bridge_id;
|
||||
unsigned int i2s_mode;
|
||||
u32 pgfsm_base;
|
||||
u32 ext_intr_stat;
|
||||
u32 dsp_intr_base;
|
||||
u32 sram_pte_offset;
|
||||
u32 i2s_pin_config_offset;
|
||||
u32 hw_semaphore_offset;
|
||||
u32 acp_clkmux_sel;
|
||||
};
|
||||
|
||||
/* Common device data struct for ACP devices */
|
||||
struct acp_dev_data {
|
||||
struct snd_sof_dev *dev;
|
||||
@ -206,8 +219,13 @@ int acp_pcm_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_substream *substr
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_sof_platform_stream_params *platform_params);
|
||||
|
||||
extern struct snd_sof_dsp_ops sof_renoir_ops;
|
||||
extern struct snd_sof_dsp_ops sof_acp_common_ops;
|
||||
|
||||
extern struct snd_sof_dsp_ops sof_renoir_ops;
|
||||
int sof_renoir_ops_init(struct snd_sof_dev *sdev);
|
||||
|
||||
int acp_dai_probe(struct snd_soc_dai *dai);
|
||||
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);
|
||||
|
||||
@ -220,10 +238,6 @@ int acp_sof_trace_release(struct snd_sof_dev *sdev);
|
||||
int amd_sof_acp_suspend(struct snd_sof_dev *sdev, u32 target_state);
|
||||
int amd_sof_acp_resume(struct snd_sof_dev *sdev);
|
||||
|
||||
struct sof_amd_acp_desc {
|
||||
unsigned int host_bridge_id;
|
||||
};
|
||||
|
||||
static inline const struct sof_amd_acp_desc *get_chip_info(struct snd_sof_pdata *pdata)
|
||||
{
|
||||
const struct sof_dev_desc *desc = pdata->desc;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "../sof-pci-dev.h"
|
||||
#include "../../amd/mach-config.h"
|
||||
#include "acp.h"
|
||||
#include "acp-dsp-offset.h"
|
||||
|
||||
#define ACP3x_REG_START 0x1240000
|
||||
#define ACP3x_REG_END 0x125C000
|
||||
@ -44,7 +45,16 @@ static const struct resource renoir_res[] = {
|
||||
};
|
||||
|
||||
static const struct sof_amd_acp_desc renoir_chip_info = {
|
||||
.rev = 3,
|
||||
.host_bridge_id = HOST_BRIDGE_CZN,
|
||||
.i2s_mode = 0x04,
|
||||
.pgfsm_base = ACP3X_PGFSM_BASE,
|
||||
.ext_intr_stat = ACP3X_EXT_INTR_STAT,
|
||||
.dsp_intr_base = ACP3X_DSP_SW_INTR_BASE,
|
||||
.sram_pte_offset = ACP3X_SRAM_PTE_OFFSET,
|
||||
.i2s_pin_config_offset = ACP3X_I2S_PIN_CONFIG,
|
||||
.hw_semaphore_offset = ACP3X_AXI2DAGB_SEM_0,
|
||||
.acp_clkmux_sel = ACP3X_CLKMUX_SEL,
|
||||
};
|
||||
|
||||
static const struct sof_dev_desc renoir_desc = {
|
||||
@ -68,6 +78,7 @@ static const struct sof_dev_desc renoir_desc = {
|
||||
},
|
||||
.nocodec_tplg_filename = "sof-acp.tplg",
|
||||
.ops = &sof_renoir_ops,
|
||||
.ops_init = sof_renoir_ops_init,
|
||||
};
|
||||
|
||||
static int acp_pci_rn_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
|
||||
|
@ -23,22 +23,6 @@
|
||||
#define I2S_SP_INSTANCE 1
|
||||
#define PDM_DMIC_INSTANCE 2
|
||||
|
||||
#define I2S_MODE 0x04
|
||||
|
||||
static int renoir_dai_probe(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component);
|
||||
unsigned int val;
|
||||
|
||||
val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_I2S_PIN_CONFIG);
|
||||
if (val != I2S_MODE) {
|
||||
dev_err(sdev->dev, "I2S Mode is not supported (I2S_PIN_CONFIG: %#x)\n", val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_dai_driver renoir_sof_dai[] = {
|
||||
[I2S_BT_INSTANCE] = {
|
||||
.id = I2S_BT_INSTANCE,
|
||||
@ -62,7 +46,7 @@ static struct snd_soc_dai_driver renoir_sof_dai[] = {
|
||||
.rate_min = 8000,
|
||||
.rate_max = 48000,
|
||||
},
|
||||
.probe = &renoir_dai_probe,
|
||||
.probe = &acp_dai_probe,
|
||||
},
|
||||
|
||||
[I2S_SP_INSTANCE] = {
|
||||
@ -87,7 +71,7 @@ static struct snd_soc_dai_driver renoir_sof_dai[] = {
|
||||
.rate_min = 8000,
|
||||
.rate_max = 48000,
|
||||
},
|
||||
.probe = &renoir_dai_probe,
|
||||
.probe = &acp_dai_probe,
|
||||
},
|
||||
|
||||
[PDM_DMIC_INSTANCE] = {
|
||||
@ -104,82 +88,21 @@ static struct snd_soc_dai_driver renoir_sof_dai[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct snd_soc_acpi_mach *amd_sof_machine_select(struct snd_sof_dev *sdev)
|
||||
/* Renoir ops */
|
||||
struct snd_sof_dsp_ops sof_renoir_ops;
|
||||
EXPORT_SYMBOL_NS(sof_renoir_ops, SND_SOC_SOF_AMD_COMMON);
|
||||
|
||||
int sof_renoir_ops_init(struct snd_sof_dev *sdev)
|
||||
{
|
||||
struct snd_sof_pdata *sof_pdata = sdev->pdata;
|
||||
const struct sof_dev_desc *desc = sof_pdata->desc;
|
||||
struct snd_soc_acpi_mach *mach;
|
||||
/* common defaults */
|
||||
memcpy(&sof_renoir_ops, &sof_acp_common_ops, sizeof(struct snd_sof_dsp_ops));
|
||||
|
||||
mach = snd_soc_acpi_find_machine(desc->machines);
|
||||
if (!mach) {
|
||||
dev_warn(sdev->dev, "No matching ASoC machine driver found\n");
|
||||
return NULL;
|
||||
}
|
||||
sof_renoir_ops.drv = renoir_sof_dai;
|
||||
sof_renoir_ops.num_drv = ARRAY_SIZE(renoir_sof_dai);
|
||||
|
||||
sof_pdata->tplg_filename = mach->sof_tplg_filename;
|
||||
sof_pdata->fw_filename = mach->fw_filename;
|
||||
|
||||
return mach;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* AMD Renoir DSP ops */
|
||||
struct snd_sof_dsp_ops sof_renoir_ops = {
|
||||
/* probe and remove */
|
||||
.probe = amd_sof_acp_probe,
|
||||
.remove = amd_sof_acp_remove,
|
||||
|
||||
/* Register IO */
|
||||
.write = sof_io_write,
|
||||
.read = sof_io_read,
|
||||
|
||||
/* Block IO */
|
||||
.block_read = acp_dsp_block_read,
|
||||
.block_write = acp_dsp_block_write,
|
||||
|
||||
/*Firmware loading */
|
||||
.load_firmware = snd_sof_load_firmware_memcpy,
|
||||
.pre_fw_run = acp_dsp_pre_fw_run,
|
||||
.get_bar_index = acp_get_bar_index,
|
||||
|
||||
/* DSP core boot */
|
||||
.run = acp_sof_dsp_run,
|
||||
|
||||
/*IPC */
|
||||
.send_msg = acp_sof_ipc_send_msg,
|
||||
.ipc_msg_data = acp_sof_ipc_msg_data,
|
||||
.get_mailbox_offset = acp_sof_ipc_get_mailbox_offset,
|
||||
.irq_thread = acp_sof_ipc_irq_thread,
|
||||
|
||||
/* DAI drivers */
|
||||
.drv = renoir_sof_dai,
|
||||
.num_drv = ARRAY_SIZE(renoir_sof_dai),
|
||||
|
||||
/* stream callbacks */
|
||||
.pcm_open = acp_pcm_open,
|
||||
.pcm_close = acp_pcm_close,
|
||||
.pcm_hw_params = acp_pcm_hw_params,
|
||||
|
||||
.hw_info = SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_PAUSE |
|
||||
SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
|
||||
|
||||
/* Machine driver callbacks */
|
||||
.machine_select = amd_sof_machine_select,
|
||||
.machine_register = sof_machine_register,
|
||||
.machine_unregister = sof_machine_unregister,
|
||||
|
||||
/* Trace Logger */
|
||||
.trace_init = acp_sof_trace_init,
|
||||
.trace_release = acp_sof_trace_release,
|
||||
|
||||
/* PM */
|
||||
.suspend = amd_sof_acp_suspend,
|
||||
.resume = amd_sof_acp_resume,
|
||||
};
|
||||
EXPORT_SYMBOL(sof_renoir_ops);
|
||||
|
||||
MODULE_IMPORT_NS(SND_SOC_SOF_AMD_COMMON);
|
||||
MODULE_DESCRIPTION("RENOIR SOF Driver");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
Loading…
Reference in New Issue
Block a user