Commit 275b583d authored by Cezary Rojewski's avatar Cezary Rojewski Committed by Mark Brown

ASoC: Intel: avs: ICL-based platforms support

Define handlers specific to cAVS 2.0 platforms, that is ICL, JSL and all
other variants based on this very version of AudioDSP architecture. Most
operations are inherited from their predecessors with the major
difference being firmware-logging functionality - IPC request as well as
debug memory windows layout have changed.
Reviewed-by: default avatarAmadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Signed-off-by: default avatarCezary Rojewski <cezary.rojewski@intel.com>
Link: https://msgid.link/r/20240220115035.770402-8-cezary.rojewski@intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 8a6502ad
......@@ -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 cnl.o
snd-soc-avs-objs += skl.o apl.o cnl.o icl.o
snd-soc-avs-objs += trace.o
# tell define_trace.h where to find the trace header
......
......@@ -67,6 +67,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;
extern const struct avs_dsp_ops avs_icl_dsp_ops;
#define AVS_PLATATTR_CLDMA BIT_ULL(0)
#define AVS_PLATATTR_IMR BIT_ULL(1)
......@@ -269,11 +270,16 @@ 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_icl_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_icl_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);
bool avs_icl_d0ix_toggle(struct avs_dev *adev, struct avs_ipc_msg *tx, bool wake);
int avs_apl_set_d0ix(struct avs_dev *adev, bool enable);
int avs_icl_set_d0ix(struct avs_dev *adev, bool enable);
/* Firmware resources management */
......
......@@ -808,6 +808,26 @@ static const struct avs_spec cnl_desc = {
.hipc = &cnl_hipc_spec,
};
static const struct avs_spec icl_desc = {
.name = "icl",
.min_fw_version = { 10, 23, 0, 5040 },
.dsp_ops = &avs_icl_dsp_ops,
.core_init_mask = 1,
.attributes = AVS_PLATATTR_IMR,
.sram = &apl_sram_spec,
.hipc = &cnl_hipc_spec,
};
static const struct avs_spec jsl_desc = {
.name = "jsl",
.min_fw_version = { 10, 26, 0, 5872 },
.dsp_ops = &avs_icl_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) },
......@@ -822,6 +842,10 @@ static const struct pci_device_id avs_ids[] = {
{ 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) },
{ PCI_DEVICE_DATA(INTEL, HDA_ICL_LP, &icl_desc) },
{ PCI_DEVICE_DATA(INTEL, HDA_ICL_N, &icl_desc) },
{ PCI_DEVICE_DATA(INTEL, HDA_ICL_H, &icl_desc) },
{ PCI_DEVICE_DATA(INTEL, HDA_JSL_N, &jsl_desc) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, avs_ids);
......
// 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 <linux/slab.h>
#include "avs.h"
#include "messages.h"
#ifdef CONFIG_DEBUG_FS
int avs_icl_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_icl_log_state_info *info;
u32 size, num_libs = adev->fw_cfg.max_libs_count;
int i, ret;
if (fls_long(resource_mask) > num_libs)
return -EINVAL;
size = struct_size(info, logs_priorities_mask, num_libs);
info = kzalloc(size, GFP_KERNEL);
if (!info)
return -ENOMEM;
info->aging_timer_period = aging_period;
info->fifo_full_timer_period = fifo_full_period;
info->enable = enable;
if (enable)
for_each_set_bit(i, &resource_mask, num_libs)
info->logs_priorities_mask[i] = *priorities++;
ret = avs_ipc_set_enable_logs(adev, (u8 *)info, size);
kfree(info);
if (ret)
return AVS_IPC_RET(ret);
return 0;
}
#endif
union avs_icl_memwnd2_slot_type {
u32 val;
struct {
u32 resource_id:8;
u32 type:24;
};
} __packed;
struct avs_icl_memwnd2_desc {
u32 resource_id;
union avs_icl_memwnd2_slot_type slot_id;
u32 vma;
} __packed;
#define AVS_ICL_MEMWND2_SLOTS_COUNT 15
struct avs_icl_memwnd2 {
union {
struct avs_icl_memwnd2_desc slot_desc[AVS_ICL_MEMWND2_SLOTS_COUNT];
u8 rsvd[PAGE_SIZE];
};
u8 slot_array[AVS_ICL_MEMWND2_SLOTS_COUNT][PAGE_SIZE];
} __packed;
#define AVS_ICL_SLOT_UNUSED \
((union avs_icl_memwnd2_slot_type) { 0x00000000U })
#define AVS_ICL_SLOT_CRITICAL_LOG \
((union avs_icl_memwnd2_slot_type) { 0x54524300U })
#define AVS_ICL_SLOT_DEBUG_LOG \
((union avs_icl_memwnd2_slot_type) { 0x474f4c00U })
#define AVS_ICL_SLOT_GDB_STUB \
((union avs_icl_memwnd2_slot_type) { 0x42444700U })
#define AVS_ICL_SLOT_BROKEN \
((union avs_icl_memwnd2_slot_type) { 0x44414544U })
static int avs_icl_slot_offset(struct avs_dev *adev, union avs_icl_memwnd2_slot_type slot_type)
{
struct avs_icl_memwnd2_desc desc[AVS_ICL_MEMWND2_SLOTS_COUNT];
int i;
memcpy_fromio(&desc, avs_sram_addr(adev, AVS_DEBUG_WINDOW), sizeof(desc));
for (i = 0; i < AVS_ICL_MEMWND2_SLOTS_COUNT; i++)
if (desc[i].slot_id.val == slot_type.val)
return offsetof(struct avs_icl_memwnd2, slot_array) +
avs_skl_log_buffer_offset(adev, i);
return -ENXIO;
}
int avs_icl_log_buffer_offset(struct avs_dev *adev, u32 core)
{
union avs_icl_memwnd2_slot_type slot_type = AVS_ICL_SLOT_DEBUG_LOG;
int ret;
slot_type.resource_id = core;
ret = avs_icl_slot_offset(adev, slot_type);
if (ret < 0)
dev_dbg(adev->dev, "No slot offset found for: %x\n",
slot_type.val);
return ret;
}
bool avs_icl_d0ix_toggle(struct avs_dev *adev, struct avs_ipc_msg *tx, bool wake)
{
/* Payload-less IPCs do not take part in d0ix toggling. */
return tx->size;
}
int avs_icl_set_d0ix(struct avs_dev *adev, bool enable)
{
int ret;
ret = avs_ipc_set_d0ix(adev, enable, false);
return AVS_IPC_RET(ret);
}
const struct avs_dsp_ops avs_icl_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_icl_log_buffer_offset,
.log_buffer_status = avs_apl_log_buffer_status,
.coredump = avs_apl_coredump,
.d0ix_toggle = avs_icl_d0ix_toggle,
.set_d0ix = avs_icl_set_d0ix,
AVS_SET_ENABLE_LOGS_OP(icl)
};
......@@ -381,6 +381,7 @@ int avs_ipc_set_d0ix(struct avs_dev *adev, bool enable_pg, bool streaming)
msg.ext.set_d0ix.wake = enable_pg;
msg.ext.set_d0ix.streaming = streaming;
msg.ext.set_d0ix.prevent_pg = !enable_pg;
request.header = msg.val;
......
......@@ -145,8 +145,12 @@ union avs_module_msg {
u32 src_queue:3;
} bind_unbind;
struct {
/* pre-IceLake */
u32 wake:1;
u32 streaming:1;
/* IceLake and onwards */
u32 prevent_pg:1;
u32 prevent_local_cg:1;
} set_d0ix;
} ext;
};
......@@ -376,6 +380,30 @@ struct avs_apl_log_state_info {
struct avs_skl_log_state logs_core[];
} __packed;
enum avs_icl_log_priority {
AVS_ICL_LOG_CRITICAL = 0,
AVS_ICL_LOG_HIGH,
AVS_ICL_LOG_MEDIUM,
AVS_ICL_LOG_LOW,
AVS_ICL_LOG_VERBOSE,
};
enum avs_icl_log_source {
AVS_ICL_LOG_INFRA = 0,
AVS_ICL_LOG_HAL,
AVS_ICL_LOG_MODULE,
AVS_ICL_LOG_AUDIO,
AVS_ICL_LOG_SENSING,
AVS_ICL_LOG_ULP_INFRA,
};
struct avs_icl_log_state_info {
u32 aging_timer_period;
u32 fifo_full_timer_period;
u32 enable;
u32 logs_priorities_mask[];
} __packed;
int avs_ipc_set_enable_logs(struct avs_dev *adev, u8 *log_info, size_t size);
struct avs_fw_version {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment