]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
ASoC: Intel: avs: SKL-based platforms support
authorCezary Rojewski <cezary.rojewski@intel.com>
Mon, 16 May 2022 10:11:15 +0000 (12:11 +0200)
committerMark Brown <broonie@kernel.org>
Tue, 17 May 2022 10:58:07 +0000 (11:58 +0100)
Define handlers specific to cAVS 1.5 platforms, that is SKL, KBL, AML
and all other variants based on this very version of AudioDSP
architecture. Most are specific to SKL-alike platforms with only
skl_log_buffer_offset() being exposed and used later by younger
equivalents.

Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://lore.kernel.org/r/20220516101116.190192-15-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/avs/Makefile
sound/soc/intel/avs/avs.h
sound/soc/intel/avs/core.c
sound/soc/intel/avs/messages.h
sound/soc/intel/avs/registers.h
sound/soc/intel/avs/skl.c [new file with mode: 0644]

index 592d4dc02c56f0d4a9eb9045a99d5375bc061894..7d09385bc9707b2df7d012259d9ee85af6f47ed1 100644 (file)
@@ -3,6 +3,7 @@
 snd-soc-avs-objs := dsp.o ipc.o messages.o utils.o core.o loader.o \
                    topology.o path.o pcm.o board_selection.o
 snd-soc-avs-objs += cldma.o
+snd-soc-avs-objs += skl.o
 
 snd-soc-avs-objs += trace.o
 # tell define_trace.h where to find the trace header
index 7e175ee4cd03ddc1ac24e42a44508156697b2af1..237e4422dcaddb501c4ab52e62b6451a4e73ab2a 100644 (file)
@@ -56,6 +56,8 @@ struct avs_dsp_ops {
 #define avs_dsp_op(adev, op, ...) \
        ((adev)->spec->dsp_ops->op(adev, ## __VA_ARGS__))
 
+extern const struct avs_dsp_ops skl_dsp_ops;
+
 #define AVS_PLATATTR_CLDMA             BIT_ULL(0)
 #define AVS_PLATATTR_IMR               BIT_ULL(1)
 
@@ -249,6 +251,8 @@ void avs_ipc_block(struct avs_ipc *ipc);
 int avs_dsp_disable_d0ix(struct avs_dev *adev);
 int avs_dsp_enable_d0ix(struct avs_dev *adev);
 
+int skl_log_buffer_offset(struct avs_dev *adev, u32 core);
+
 /* Firmware resources management */
 
 int avs_get_module_entry(struct avs_dev *adev, const guid_t *uuid, struct avs_module_entry *entry);
index 43ce6453e5ccf13d7b40ab7bd54a050d105a2098..7e78a9a9d16658e099eb00c66a77ad28b46dad71 100644 (file)
@@ -634,7 +634,25 @@ static const struct dev_pm_ops avs_dev_pm = {
        SET_RUNTIME_PM_OPS(avs_runtime_suspend, avs_runtime_resume, NULL)
 };
 
+static const struct avs_spec skl_desc = {
+       .name = "skl",
+       .min_fw_version = {
+               .major = 9,
+               .minor = 21,
+               .hotfix = 0,
+               .build = 4732,
+       },
+       .dsp_ops = &skl_dsp_ops,
+       .core_init_mask = 1,
+       .attributes = AVS_PLATATTR_CLDMA,
+       .sram_base_offset = SKL_ADSP_SRAM_BASE_OFFSET,
+       .sram_window_size = SKL_ADSP_SRAM_WINDOW_SIZE,
+       .rom_status = SKL_ADSP_SRAM_BASE_OFFSET,
+};
+
 static const struct pci_device_id avs_ids[] = {
+       { PCI_VDEVICE(INTEL, 0x9d70), (unsigned long)&skl_desc }, /* SKL */
+       { PCI_VDEVICE(INTEL, 0x9d71), (unsigned long)&skl_desc }, /* KBL */
        { 0 }
 };
 MODULE_DEVICE_TABLE(pci, avs_ids);
index 257482e160bc113d05ad97b84ebc7b7b0c20e1cc..981ec024b1527250cd87ae2c3c418c292a077286 100644 (file)
@@ -347,6 +347,24 @@ enum avs_log_enable {
        AVS_LOG_ENABLE = 1
 };
 
+enum avs_skl_log_priority {
+       AVS_SKL_LOG_CRITICAL = 1,
+       AVS_SKL_LOG_HIGH,
+       AVS_SKL_LOG_MEDIUM,
+       AVS_SKL_LOG_LOW,
+       AVS_SKL_LOG_VERBOSE,
+};
+
+struct skl_log_state {
+       u32 enable;
+       u32 min_priority;
+} __packed;
+
+struct skl_log_state_info {
+       u32 core_mask;
+       struct skl_log_state logs_core[];
+} __packed;
+
 int avs_ipc_set_enable_logs(struct avs_dev *adev, u8 *log_info, size_t size);
 
 struct avs_fw_version {
index b2100dc630e44e96701aefb9bbb74890f9b825c8..68f06aa4e10fb357b9dcb63afc7d8b935c752a38 100644 (file)
 #define SKL_ADSP_HIPCIE_DONE           BIT(30)
 #define SKL_ADSP_HIPCT_BUSY            BIT(31)
 
+/* Intel HD Audio SRAM windows base addresses */
+#define SKL_ADSP_SRAM_BASE_OFFSET      0x8000
+#define SKL_ADSP_SRAM_WINDOW_SIZE      0x2000
+
 /* Constants used when accessing SRAM, space shared with firmware */
 #define AVS_FW_REG_BASE(adev)          ((adev)->spec->sram_base_offset)
 #define AVS_FW_REG_STATUS(adev)                (AVS_FW_REG_BASE(adev) + 0x0)
diff --git a/sound/soc/intel/avs/skl.c b/sound/soc/intel/avs/skl.c
new file mode 100644 (file)
index 0000000..bda5ec7
--- /dev/null
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+//
+// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
+//          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+//
+
+#include <linux/devcoredump.h>
+#include <linux/slab.h>
+#include <sound/hdaudio_ext.h>
+#include "avs.h"
+#include "messages.h"
+
+static int skl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period,
+                          u32 fifo_full_period, unsigned long resource_mask, u32 *priorities)
+{
+       struct skl_log_state_info *info;
+       u32 size, num_cores = adev->hw_cfg.dsp_cores;
+       int ret, i;
+
+       if (fls_long(resource_mask) > num_cores)
+               return -EINVAL;
+       size = struct_size(info, logs_core, num_cores);
+       info = kzalloc(size, GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       info->core_mask = resource_mask;
+       if (enable)
+               for_each_set_bit(i, &resource_mask, GENMASK(num_cores, 0)) {
+                       info->logs_core[i].enable = enable;
+                       info->logs_core[i].min_priority = *priorities++;
+               }
+       else
+               for_each_set_bit(i, &resource_mask, GENMASK(num_cores, 0))
+                       info->logs_core[i].enable = enable;
+
+       ret = avs_ipc_set_enable_logs(adev, (u8 *)info, size);
+       kfree(info);
+       if (ret)
+               return AVS_IPC_RET(ret);
+
+       return 0;
+}
+
+int skl_log_buffer_offset(struct avs_dev *adev, u32 core)
+{
+       return core * avs_log_buffer_size(adev);
+}
+
+/* fw DbgLogWp registers */
+#define FW_REGS_DBG_LOG_WP(core) (0x30 + 0x4 * core)
+
+static int
+skl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg)
+{
+       unsigned long flags;
+       void __iomem *buf;
+       u16 size, write, offset;
+
+       spin_lock_irqsave(&adev->dbg.trace_lock, flags);
+       if (!kfifo_initialized(&adev->dbg.trace_fifo)) {
+               spin_unlock_irqrestore(&adev->dbg.trace_lock, flags);
+               return 0;
+       }
+
+       size = avs_log_buffer_size(adev) / 2;
+       write = readl(avs_sram_addr(adev, AVS_FW_REGS_WINDOW) + FW_REGS_DBG_LOG_WP(msg->log.core));
+       /* determine buffer half */
+       offset = (write < size) ? size : 0;
+
+       /* Address is guaranteed to exist in SRAM2. */
+       buf = avs_log_buffer_addr(adev, msg->log.core) + offset;
+       __kfifo_fromio_locked(&adev->dbg.trace_fifo, buf, size, &adev->dbg.fifo_lock);
+       wake_up(&adev->dbg.trace_waitq);
+       spin_unlock_irqrestore(&adev->dbg.trace_lock, flags);
+
+       return 0;
+}
+
+static int skl_coredump(struct avs_dev *adev, union avs_notify_msg *msg)
+{
+       u8 *dump;
+
+       dump = vzalloc(AVS_FW_REGS_SIZE);
+       if (!dump)
+               return -ENOMEM;
+
+       memcpy_fromio(dump, avs_sram_addr(adev, AVS_FW_REGS_WINDOW), AVS_FW_REGS_SIZE);
+       dev_coredumpv(adev->dev, dump, AVS_FW_REGS_SIZE, GFP_KERNEL);
+
+       return 0;
+}
+
+static bool
+skl_d0ix_toggle(struct avs_dev *adev, struct avs_ipc_msg *tx, bool wake)
+{
+       /* unsupported on cAVS 1.5 hw */
+       return false;
+}
+
+static int skl_set_d0ix(struct avs_dev *adev, bool enable)
+{
+       /* unsupported on cAVS 1.5 hw */
+       return 0;
+}
+
+const struct avs_dsp_ops skl_dsp_ops = {
+       .power = avs_dsp_core_power,
+       .reset = avs_dsp_core_reset,
+       .stall = avs_dsp_core_stall,
+       .irq_handler = avs_dsp_irq_handler,
+       .irq_thread = avs_dsp_irq_thread,
+       .int_control = avs_dsp_interrupt_control,
+       .load_basefw = avs_cldma_load_basefw,
+       .load_lib = avs_cldma_load_library,
+       .transfer_mods = avs_cldma_transfer_modules,
+       .enable_logs = skl_enable_logs,
+       .log_buffer_offset = skl_log_buffer_offset,
+       .log_buffer_status = skl_log_buffer_status,
+       .coredump = skl_coredump,
+       .d0ix_toggle = skl_d0ix_toggle,
+       .set_d0ix = skl_set_d0ix,
+};