From 72873d1d2bfeeae506742862c2c8dc1a7451a9cc Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Thu, 18 Apr 2024 16:37:21 +0300 Subject: [PATCH] audio: base_fw: move IPC4_EXTENDED_SYSTEM_TIME to platform code Move implementation of IPC4_EXTENDED_SYSTEM_TIME from generic to platform specific code. The implementation depends on specific ART counter that is not available on all platforms, so it is better to handle this in platform specific code. Signed-off-by: Kai Vehmanen --- src/audio/base_fw.c | 77 ++----------------- src/include/ipc4/base_fw.h | 2 + src/platform/intel/ace/lib/base_fw_platform.c | 76 +++++++++++++++++- 3 files changed, 82 insertions(+), 73 deletions(-) diff --git a/src/audio/base_fw.c b/src/audio/base_fw.c index 7c760b171854..62d2d07f6d58 100644 --- a/src/audio/base_fw.c +++ b/src/audio/base_fw.c @@ -27,10 +27,6 @@ #include "adsp_debug_window.h" #endif -#if CONFIG_ACE_V1X_ART_COUNTER || CONFIG_ACE_V1X_RTC_COUNTER -#include -#include -#endif #include LOG_MODULE_REGISTER(basefw, CONFIG_SOF_LOG_LEVEL); @@ -158,6 +154,11 @@ static int basefw_hw_config(uint32_t *data_offset, char *data) return 0; } +struct ipc4_system_time_info *basefw_get_system_time_info(void) +{ + return &global_system_time_info; +} + static log_timestamp_t basefw_get_timestamp(void) { return sof_cycle_get_64() + global_cycle_delta; @@ -212,63 +213,6 @@ static uint32_t basefw_get_system_time(uint32_t *data_offset, char *data) return IPC4_SUCCESS; } -static uint32_t basefw_get_ext_system_time(uint32_t *data_offset, char *data) -{ -#if CONFIG_ACE_V1X_ART_COUNTER && CONFIG_ACE_V1X_RTC_COUNTER - struct ipc4_ext_system_time *ext_system_time = (struct ipc4_ext_system_time *)(data); - struct ipc4_ext_system_time ext_system_time_data = {0}; - - uint64_t host_time = ((uint64_t)global_system_time_info.host_time.val_u << 32) - | (uint64_t)global_system_time_info.host_time.val_l; - uint64_t dsp_time = ((uint64_t)global_system_time_info.dsp_time.val_u << 32) - | (uint64_t)global_system_time_info.dsp_time.val_l; - - if (host_time == 0 || dsp_time == 0) - return IPC4_INVALID_RESOURCE_STATE; - - uint64_t art = 0; - uint64_t wallclk = 0; - uint64_t rtc = 0; - - const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(ace_art_counter)); - - if (!dev) { - LOG_DBG("board: ART counter device binding failed"); - return IPC4_MOD_NOT_INITIALIZED; - } - - counter_get_value_64(dev, &art); - - wallclk = sof_cycle_get_64(); - ext_system_time_data.art_l = (uint32_t)art; - ext_system_time_data.art_u = (uint32_t)(art >> 32); - uint64_t delta = (wallclk - dsp_time) / (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000000); - - uint64_t new_host_time = (host_time + delta); - - ext_system_time_data.utc_l = (uint32_t)new_host_time; - ext_system_time_data.utc_u = (uint32_t)(new_host_time >> 32); - - dev = DEVICE_DT_GET(DT_NODELABEL(ace_rtc_counter)); - - if (!dev) { - LOG_DBG("board: RTC counter device binding failed"); - return IPC4_MOD_NOT_INITIALIZED; - } - - counter_get_value_64(dev, &rtc); - ext_system_time_data.rtc_l = (uint32_t)rtc; - ext_system_time_data.rtc_u = (uint32_t)(rtc >> 32); - - memcpy_s(ext_system_time, sizeof(ext_system_time), &ext_system_time_data, - sizeof(ext_system_time)); - *data_offset = sizeof(struct ipc4_ext_system_time); - - return IPC4_SUCCESS; -#endif - return IPC4_UNAVAILABLE; -} - static int basefw_register_kcps(bool first_block, bool last_block, uint32_t data_offset_or_size, @@ -410,8 +354,6 @@ static int basefw_get_large_config(struct comp_dev *dev, extended_param_id.full = param_id; - uint32_t ret = -EINVAL; - switch (extended_param_id.part.parameter_type) { case IPC4_PERF_MEASUREMENTS_STATE: case IPC4_GLOBAL_PERF_DATA: @@ -428,15 +370,6 @@ static int basefw_get_large_config(struct comp_dev *dev, return basefw_hw_config(data_offset, data); case IPC4_SYSTEM_TIME: return basefw_get_system_time(data_offset, data); - case IPC4_EXTENDED_SYSTEM_TIME: - ret = basefw_get_ext_system_time(data_offset, data); - if (ret == IPC4_UNAVAILABLE) { - tr_warn(&basefw_comp_tr, "returning success for get host EXTENDED_SYSTEM_TIME without handling it"); - return 0; - } else { - return ret; - } - break; case IPC4_POWER_STATE_INFO_GET: return basefw_power_state_info_get(data_offset, data); case IPC4_SCHEDULERS_INFO_GET: diff --git a/src/include/ipc4/base_fw.h b/src/include/ipc4/base_fw.h index 1d1648d73cd0..72a08bb8cdcb 100644 --- a/src/include/ipc4/base_fw.h +++ b/src/include/ipc4/base_fw.h @@ -701,4 +701,6 @@ struct schedulers_info { struct scheduler_props scheduler_info[]; } __packed __aligned(4); +struct ipc4_system_time_info *basefw_get_system_time_info(void); + #endif /* __SOF_IPC4_BASE_FW_H__ */ diff --git a/src/platform/intel/ace/lib/base_fw_platform.c b/src/platform/intel/ace/lib/base_fw_platform.c index 6962f072eb52..1a6fa38fce8c 100644 --- a/src/platform/intel/ace/lib/base_fw_platform.c +++ b/src/platform/intel/ace/lib/base_fw_platform.c @@ -14,6 +14,11 @@ #include #endif +#if CONFIG_ACE_V1X_ART_COUNTER || CONFIG_ACE_V1X_RTC_COUNTER +#include +#include +#endif + #include LOG_MODULE_REGISTER(basefw_platform, CONFIG_SOF_LOG_LEVEL); @@ -129,6 +134,63 @@ static int basefw_mem_state_info(uint32_t *data_offset, char *data) return 0; } +static uint32_t basefw_get_ext_system_time(uint32_t *data_offset, char *data) +{ +#if CONFIG_ACE_V1X_ART_COUNTER && CONFIG_ACE_V1X_RTC_COUNTER + struct ipc4_ext_system_time *ext_system_time = (struct ipc4_ext_system_time *)(data); + struct ipc4_ext_system_time ext_system_time_data = {0}; + struct ipc4_system_time_info *time_info = basefw_get_system_time_info(); + uint64_t host_time = ((uint64_t)time_info->host_time.val_u << 32) + | (uint64_t)time_info->host_time.val_l; + uint64_t dsp_time = ((uint64_t)time_info->dsp_time.val_u << 32) + | (uint64_t)time_info->dsp_time.val_l; + + if (host_time == 0 || dsp_time == 0) + return IPC4_INVALID_RESOURCE_STATE; + + uint64_t art = 0; + uint64_t wallclk = 0; + uint64_t rtc = 0; + + const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(ace_art_counter)); + + if (!dev) { + LOG_DBG("board: ART counter device binding failed"); + return IPC4_MOD_NOT_INITIALIZED; + } + + counter_get_value_64(dev, &art); + + wallclk = sof_cycle_get_64(); + ext_system_time_data.art_l = (uint32_t)art; + ext_system_time_data.art_u = (uint32_t)(art >> 32); + uint64_t delta = (wallclk - dsp_time) / (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000000); + + uint64_t new_host_time = (host_time + delta); + + ext_system_time_data.utc_l = (uint32_t)new_host_time; + ext_system_time_data.utc_u = (uint32_t)(new_host_time >> 32); + + dev = DEVICE_DT_GET(DT_NODELABEL(ace_rtc_counter)); + + if (!dev) { + LOG_DBG("board: RTC counter device binding failed"); + return IPC4_MOD_NOT_INITIALIZED; + } + + counter_get_value_64(dev, &rtc); + ext_system_time_data.rtc_l = (uint32_t)rtc; + ext_system_time_data.rtc_u = (uint32_t)(rtc >> 32); + + memcpy_s(ext_system_time, sizeof(ext_system_time), &ext_system_time_data, + sizeof(ext_system_time)); + *data_offset = sizeof(struct ipc4_ext_system_time); + + return IPC4_SUCCESS; +#endif + return IPC4_UNAVAILABLE; +} + int platform_basefw_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, @@ -141,14 +203,26 @@ int platform_basefw_get_large_config(struct comp_dev *dev, extended_param_id.full = param_id; + uint32_t ret = -EINVAL; + switch (extended_param_id.part.parameter_type) { case IPC4_MEMORY_STATE_INFO_GET: return basefw_mem_state_info(data_offset, data); + case IPC4_EXTENDED_SYSTEM_TIME: + ret = basefw_get_ext_system_time(data_offset, data); + if (ret == IPC4_UNAVAILABLE) { + tr_warn(&basefw_comp_tr, + "returning success for get host EXTENDED_SYSTEM_TIME without handling it"); + return 0; + } else { + return ret; + } + break; default: break; } - return -EINVAL; + return ret; } static int fw_config_set_force_l1_exit(const struct sof_tlv *tlv)