ASoC: SOF: amd: Make ACP core code generic for newer SOC transition
authorAjit Kumar Pandey <AjitKumar.Pandey@amd.com>
Tue, 13 Sep 2022 14:43:15 +0000 (20:13 +0530)
committerMark Brown <broonie@kernel.org>
Tue, 20 Sep 2022 18:38:01 +0000 (19:38 +0100)
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>
sound/soc/sof/amd/Makefile
sound/soc/sof/amd/acp-common.c [new file with mode: 0644]
sound/soc/sof/amd/acp-dsp-offset.h
sound/soc/sof/amd/acp-ipc.c
sound/soc/sof/amd/acp-loader.c
sound/soc/sof/amd/acp-stream.c
sound/soc/sof/amd/acp.c
sound/soc/sof/amd/acp.h
sound/soc/sof/amd/pci-rn.c
sound/soc/sof/amd/renoir.c

index 7b9f1a0..efea92f 100644 (file)
@@ -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
diff --git a/sound/soc/sof/amd/acp-common.c b/sound/soc/sof/amd/acp-common.c
new file mode 100644 (file)
index 0000000..12bdd97
--- /dev/null
@@ -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");
index 56cefd4..47151a8 100644 (file)
 #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
index e1842f0..e093924 100644 (file)
@@ -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);
 
index 7ca51e0..f372f93 100644 (file)
 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);
 
index b3ca4a9..f71b4e6 100644 (file)
@@ -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);
 
index c40d290..47eaabc 100644 (file)
@@ -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);
 
index 4c42b8f..bc024be 100644 (file)
@@ -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_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;
index 3a7fed2..fca40b2 100644 (file)
@@ -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)
index 9261c8b..6ea8727 100644 (file)
 #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)
-{
-       struct snd_sof_pdata *sof_pdata = sdev->pdata;
-       const struct sof_dev_desc *desc = sof_pdata->desc;
-       struct snd_soc_acpi_mach *mach;
+/* Renoir ops */
+struct snd_sof_dsp_ops sof_renoir_ops;
+EXPORT_SYMBOL_NS(sof_renoir_ops, SND_SOC_SOF_AMD_COMMON);
 
-       mach = snd_soc_acpi_find_machine(desc->machines);
-       if (!mach) {
-               dev_warn(sdev->dev, "No matching ASoC machine driver found\n");
-               return NULL;
-       }
+int sof_renoir_ops_init(struct snd_sof_dev *sdev)
+{
+       /* common defaults */
+       memcpy(&sof_renoir_ops, &sof_acp_common_ops, sizeof(struct snd_sof_dsp_ops));
 
-       sof_pdata->tplg_filename = mach->sof_tplg_filename;
-       sof_pdata->fw_filename = mach->fw_filename;
+       sof_renoir_ops.drv = renoir_sof_dai;
+       sof_renoir_ops.num_drv = ARRAY_SIZE(renoir_sof_dai);
 
-       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");