ASoC: Intel: avs: CNL-based platforms support
authorCezary Rojewski <cezary.rojewski@intel.com>
Tue, 20 Feb 2024 11:50:31 +0000 (12:50 +0100)
committerMark Brown <broonie@kernel.org>
Tue, 20 Feb 2024 13:19:56 +0000 (13:19 +0000)
Define handlers specific to cAVS 1.8 platforms, that is CNL, CFL, CML
and all other variants based on this very version of AudioDSP
architecture. Most operations are inherited from their predecessors.

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

index 460ee6599daf035baf03013be668a35c4e7cb5b4..a8d4b0ef2603f03275a3c3b46cb6e2f8e9fb8c57 100644 (file)
@@ -3,7 +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 control.o
 snd-soc-avs-objs += cldma.o
-snd-soc-avs-objs += skl.o apl.o
+snd-soc-avs-objs += skl.o apl.o cnl.o
 
 snd-soc-avs-objs += trace.o
 # tell define_trace.h where to find the trace header
index 6382543a9cdbc0af390ae6df912ad650ca4d8f47..c21ecaef9ebaa7d3a3093881777575d4e0ebe7fb 100644 (file)
@@ -13,9 +13,9 @@
 #include "path.h"
 #include "topology.h"
 
-static int __maybe_unused
-avs_apl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period,
-                   u32 fifo_full_period, unsigned long resource_mask, u32 *priorities)
+#ifdef CONFIG_DEBUG_FS
+int avs_apl_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 avs_apl_log_state_info *info;
        u32 size, num_cores = adev->hw_cfg.dsp_cores;
@@ -47,8 +47,9 @@ avs_apl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_
 
        return 0;
 }
+#endif
 
-static int avs_apl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg)
+int avs_apl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg)
 {
        struct avs_apl_log_buffer_layout layout;
        void __iomem *addr, *buf;
@@ -102,7 +103,7 @@ static int avs_apl_wait_log_entry(struct avs_dev *adev, u32 core,
 /* reads log header and tests its type */
 #define avs_apl_is_entry_stackdump(addr) ((readl(addr) >> 30) & 0x1)
 
-static int avs_apl_coredump(struct avs_dev *adev, union avs_notify_msg *msg)
+int avs_apl_coredump(struct avs_dev *adev, union avs_notify_msg *msg)
 {
        struct avs_apl_log_buffer_layout layout;
        void __iomem *addr, *buf;
@@ -202,7 +203,7 @@ static bool avs_apl_lp_streaming(struct avs_dev *adev)
        return true;
 }
 
-static bool avs_apl_d0ix_toggle(struct avs_dev *adev, struct avs_ipc_msg *tx, bool wake)
+bool avs_apl_d0ix_toggle(struct avs_dev *adev, struct avs_ipc_msg *tx, bool wake)
 {
        /* wake in all cases */
        if (wake)
@@ -219,7 +220,7 @@ static bool avs_apl_d0ix_toggle(struct avs_dev *adev, struct avs_ipc_msg *tx, bo
        return avs_apl_lp_streaming(adev);
 }
 
-static int avs_apl_set_d0ix(struct avs_dev *adev, bool enable)
+int avs_apl_set_d0ix(struct avs_dev *adev, bool enable)
 {
        bool streaming = false;
        int ret;
index 3d823880f965c8332e71f1712002849a27b6e4a3..b53cf35fa556a5ff396e6c371d2ad860994fef2d 100644 (file)
@@ -66,6 +66,7 @@ struct avs_dsp_ops {
 
 extern const struct avs_dsp_ops avs_skl_dsp_ops;
 extern const struct avs_dsp_ops avs_apl_dsp_ops;
+extern const struct avs_dsp_ops avs_cnl_dsp_ops;
 
 #define AVS_PLATATTR_CLDMA             BIT_ULL(0)
 #define AVS_PLATATTR_IMR               BIT_ULL(1)
@@ -265,7 +266,14 @@ int avs_dsp_disable_d0ix(struct avs_dev *adev);
 int avs_dsp_enable_d0ix(struct avs_dev *adev);
 
 irqreturn_t avs_skl_irq_thread(struct avs_dev *adev);
+irqreturn_t avs_cnl_irq_thread(struct avs_dev *adev);
+int avs_apl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period,
+                       u32 fifo_full_period, unsigned long resource_mask, u32 *priorities);
 int avs_skl_log_buffer_offset(struct avs_dev *adev, u32 core);
+int avs_apl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg);
+int avs_apl_coredump(struct avs_dev *adev, union avs_notify_msg *msg);
+bool avs_apl_d0ix_toggle(struct avs_dev *adev, struct avs_ipc_msg *tx, bool wake);
+int avs_apl_set_d0ix(struct avs_dev *adev, bool enable);
 
 /* Firmware resources management */
 
diff --git a/sound/soc/intel/avs/cnl.c b/sound/soc/intel/avs/cnl.c
new file mode 100644 (file)
index 0000000..5423c29
--- /dev/null
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright(c) 2021-2024 Intel Corporation. All rights reserved.
+//
+// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
+//          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+//
+
+#include <sound/hdaudio_ext.h>
+#include "avs.h"
+#include "messages.h"
+
+irqreturn_t avs_cnl_irq_thread(struct avs_dev *adev)
+{
+       union avs_reply_msg msg;
+       u32 hipctdr, hipctdd, hipctda;
+
+       hipctdr = snd_hdac_adsp_readl(adev, CNL_ADSP_REG_HIPCTDR);
+       hipctdd = snd_hdac_adsp_readl(adev, CNL_ADSP_REG_HIPCTDD);
+
+       /* Ensure DSP sent new response to process. */
+       if (!(hipctdr & CNL_ADSP_HIPCTDR_BUSY))
+               return IRQ_NONE;
+
+       msg.primary = hipctdr;
+       msg.ext.val = hipctdd;
+       avs_dsp_process_response(adev, msg.val);
+
+       /* Tell DSP we accepted its message. */
+       snd_hdac_adsp_updatel(adev, CNL_ADSP_REG_HIPCTDR,
+                             CNL_ADSP_HIPCTDR_BUSY, CNL_ADSP_HIPCTDR_BUSY);
+       /* Ack this response. */
+       snd_hdac_adsp_updatel(adev, CNL_ADSP_REG_HIPCTDA,
+                             CNL_ADSP_HIPCTDA_DONE, CNL_ADSP_HIPCTDA_DONE);
+       /* HW might have been clock gated, give some time for change to propagate. */
+       snd_hdac_adsp_readl_poll(adev, CNL_ADSP_REG_HIPCTDA, hipctda,
+                                !(hipctda & CNL_ADSP_HIPCTDA_DONE), 10, 1000);
+       /* Unmask busy interrupt. */
+       snd_hdac_adsp_updatel(adev, CNL_ADSP_REG_HIPCCTL,
+                             AVS_ADSP_HIPCCTL_BUSY, AVS_ADSP_HIPCCTL_BUSY);
+
+       return IRQ_HANDLED;
+}
+
+const struct avs_dsp_ops avs_cnl_dsp_ops = {
+       .power = avs_dsp_core_power,
+       .reset = avs_dsp_core_reset,
+       .stall = avs_dsp_core_stall,
+       .irq_handler = avs_irq_handler,
+       .irq_thread = avs_cnl_irq_thread,
+       .int_control = avs_dsp_interrupt_control,
+       .load_basefw = avs_hda_load_basefw,
+       .load_lib = avs_hda_load_library,
+       .transfer_mods = avs_hda_transfer_modules,
+       .log_buffer_offset = avs_skl_log_buffer_offset,
+       .log_buffer_status = avs_apl_log_buffer_status,
+       .coredump = avs_apl_coredump,
+       .d0ix_toggle = avs_apl_d0ix_toggle,
+       .set_d0ix = avs_apl_set_d0ix,
+       AVS_SET_ENABLE_LOGS_OP(apl)
+};
index b8645a9760f527f066c77cf01f51187de9b826fa..2054c2034fe2a1486709f261891e62b3c95ae8f7 100644 (file)
@@ -767,6 +767,17 @@ static const struct avs_hipc_spec skl_hipc_spec = {
        .ctl_offset = SKL_ADSP_REG_HIPCCTL,
 };
 
+static const struct avs_hipc_spec cnl_hipc_spec = {
+       .req_offset = CNL_ADSP_REG_HIPCIDR,
+       .req_ext_offset = CNL_ADSP_REG_HIPCIDD,
+       .req_busy_mask = CNL_ADSP_HIPCIDR_BUSY,
+       .ack_offset = CNL_ADSP_REG_HIPCIDA,
+       .ack_done_mask = CNL_ADSP_HIPCIDA_DONE,
+       .rsp_offset = CNL_ADSP_REG_HIPCTDR,
+       .rsp_busy_mask = CNL_ADSP_HIPCTDR_BUSY,
+       .ctl_offset = CNL_ADSP_REG_HIPCCTL,
+};
+
 static const struct avs_spec skl_desc = {
        .name = "skl",
        .min_fw_version = { 9, 21, 0, 4732 },
@@ -787,6 +798,16 @@ static const struct avs_spec apl_desc = {
        .hipc = &skl_hipc_spec,
 };
 
+static const struct avs_spec cnl_desc = {
+       .name = "cnl",
+       .min_fw_version = { 10, 23, 0, 5314 },
+       .dsp_ops = &avs_cnl_dsp_ops,
+       .core_init_mask = 1,
+       .attributes = AVS_PLATATTR_IMR,
+       .sram = &apl_sram_spec,
+       .hipc = &cnl_hipc_spec,
+};
+
 static const struct pci_device_id avs_ids[] = {
        { PCI_DEVICE_DATA(INTEL, HDA_SKL_LP, &skl_desc) },
        { PCI_DEVICE_DATA(INTEL, HDA_SKL, &skl_desc) },
@@ -796,6 +817,11 @@ static const struct pci_device_id avs_ids[] = {
        { PCI_DEVICE_DATA(INTEL, HDA_CML_S, &skl_desc) },
        { PCI_DEVICE_DATA(INTEL, HDA_APL, &apl_desc) },
        { PCI_DEVICE_DATA(INTEL, HDA_GML, &apl_desc) },
+       { PCI_DEVICE_DATA(INTEL, HDA_CNL_LP,    &cnl_desc) },
+       { PCI_DEVICE_DATA(INTEL, HDA_CNL_H,     &cnl_desc) },
+       { PCI_DEVICE_DATA(INTEL, HDA_CML_LP,    &cnl_desc) },
+       { PCI_DEVICE_DATA(INTEL, HDA_CML_H,     &cnl_desc) },
+       { PCI_DEVICE_DATA(INTEL, HDA_RKL_S,     &cnl_desc) },
        { 0 }
 };
 MODULE_DEVICE_TABLE(pci, avs_ids);
index 8468acd15c3d05f32ec64ce354e8fe9634e33f4c..6126adca500ceffbcef66de72713731872805d3f 100644 (file)
 #define SKL_ADSP_HIPCIE_DONE           BIT(30)
 #define SKL_ADSP_HIPCT_BUSY            BIT(31)
 
+/* CNL Intel HD Audio Inter-Processor Communication Registers */
+#define CNL_ADSP_IPC_BASE               0xC0
+#define CNL_ADSP_REG_HIPCTDR            (CNL_ADSP_IPC_BASE + 0x00)
+#define CNL_ADSP_REG_HIPCTDA            (CNL_ADSP_IPC_BASE + 0x04)
+#define CNL_ADSP_REG_HIPCTDD            (CNL_ADSP_IPC_BASE + 0x08)
+#define CNL_ADSP_REG_HIPCIDR            (CNL_ADSP_IPC_BASE + 0x10)
+#define CNL_ADSP_REG_HIPCIDA            (CNL_ADSP_IPC_BASE + 0x14)
+#define CNL_ADSP_REG_HIPCIDD            (CNL_ADSP_IPC_BASE + 0x18)
+#define CNL_ADSP_REG_HIPCCTL            (CNL_ADSP_IPC_BASE + 0x28)
+
+#define CNL_ADSP_HIPCTDR_BUSY          BIT(31)
+#define CNL_ADSP_HIPCTDA_DONE          BIT(31)
+#define CNL_ADSP_HIPCIDR_BUSY          BIT(31)
+#define CNL_ADSP_HIPCIDA_DONE          BIT(31)
+
 /* Intel HD Audio SRAM windows base addresses */
 #define SKL_ADSP_SRAM_BASE_OFFSET      0x8000
 #define SKL_ADSP_SRAM_WINDOW_SIZE      0x2000