From e584701a0170aff5dd9ca291bc91566f114a4d18 Mon Sep 17 00:00:00 2001 From: Krzysztof Frydryk Date: Mon, 28 Nov 2022 08:55:01 +0100 Subject: [PATCH] ipc4: basefw: Handle kcps related IPCs Handle register_kcps, resource_allocation_request for kcps, power_state_info_get. Signed-off-by: Krzysztof Frydryk --- src/audio/base_fw.c | 76 +++++++++++++++++++++++++++++++++++++- src/include/ipc4/base_fw.h | 5 +++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/src/audio/base_fw.c b/src/audio/base_fw.c index 10e85f5bc..be7f6a03d 100644 --- a/src/audio/base_fw.c +++ b/src/audio/base_fw.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #if CONFIG_ACE_V1X_ART_COUNTER || CONFIG_ACE_V1X_RTC_COUNTER #include @@ -323,6 +325,71 @@ static uint32_t basefw_get_ext_system_time(uint32_t *data_offset, char *data) return IPC4_UNAVAILABLE; } +static int basefw_register_kcps(bool first_block, + bool last_block, + uint32_t data_offset_or_size, + const char *data) +{ + if (!(first_block && last_block)) + return -EINVAL; + + /* value of kcps to request on core 0. Can be negative */ + if (core_kcps_adjust(0, *(int32_t *)data)) + return -EINVAL; + + return 0; +} + +static int basefw_kcps_allocation_request(struct ipc4_resource_kcps *request) +{ + if (core_kcps_adjust(request->core_id, request->kcps)) + return -EINVAL; + + return 0; +} + +static int basefw_resource_allocation_request(bool first_block, + bool last_block, + uint32_t data_offset_or_size, + const char *data) +{ + struct ipc4_resource_request *request; + + if (!(first_block && last_block)) + return -EINVAL; + + request = (struct ipc4_resource_request *)data; + + switch (request->ra_type) { + case IPC4_RAT_DSP_KCPS: + return basefw_kcps_allocation_request(&request->ra_data.kcps); + case IPC4_RAT_MEMORY: + return -EINVAL; + default: + return -EINVAL; + } +} + +static int basefw_power_state_info_get(uint32_t *data_offset, char *data) +{ + struct ipc4_tuple *tuple = (struct ipc4_tuple *)data; + uint32_t core_kcps[CONFIG_CORE_COUNT] = {0}; + int core_id; + + set_tuple_uint32(tuple, IPC4_ACTIVE_CORES_MASK, cpu_enabled_cores()); + tuple = next_tuple(tuple); + + for (core_id = 0; core_id < CONFIG_CORE_COUNT; core_id++) { + if (cpu_is_core_enabled(core_id)) + core_kcps[core_id] = core_kcps_get(core_id); + } + + set_tuple(tuple, IPC4_CORE_KCPS, sizeof(core_kcps), core_kcps); + tuple = next_tuple(tuple); + *data_offset = (int)((char *)tuple - data); + return 0; +} + static int basefw_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, @@ -358,6 +425,9 @@ static int basefw_get_large_config(struct comp_dev *dev, } else { return ret; } + break; + case IPC4_POWER_STATE_INFO_GET: + return basefw_power_state_info_get(data_offset, data); /* TODO: add more support */ case IPC4_DSP_RESOURCE_STATE: case IPC4_NOTIFICATION_MASK: @@ -366,7 +436,6 @@ static int basefw_get_large_config(struct comp_dev *dev, case IPC4_PIPELINE_PROPS_GET: case IPC4_SCHEDULERS_INFO_GET: case IPC4_GATEWAYS_INFO_GET: - case IPC4_POWER_STATE_INFO_GET: case IPC4_LIBRARIES_INFO_GET: case IPC4_PERF_MEASUREMENTS_STATE: case IPC4_GLOBAL_PERF_DATA: @@ -394,6 +463,11 @@ static int basefw_set_large_config(struct comp_dev *dev, last_block, data_offset, data); case IPC4_ENABLE_LOGS: return ipc4_logging_enable_logs(first_block, last_block, data_offset, data); + case IPC4_REGISTER_KCPS: + return basefw_register_kcps(first_block, last_block, data_offset, data); + case IPC4_RESOURCE_ALLOCATION_REQUEST: + return basefw_resource_allocation_request(first_block, last_block, data_offset, + data); default: break; } diff --git a/src/include/ipc4/base_fw.h b/src/include/ipc4/base_fw.h index 2e9d91d55..2f9c7bc86 100644 --- a/src/include/ipc4/base_fw.h +++ b/src/include/ipc4/base_fw.h @@ -667,3 +667,8 @@ struct ipc4_log_state_info { */ uint32_t logs_mask[IPC4_MAX_LIBS_COUNT]; } __attribute__((packed, aligned(4))); + +enum ipc4_power_state_type { + IPC4_ACTIVE_CORES_MASK = 0, + IPC4_CORE_KCPS = 1, +};