Skip to content

Commit

Permalink
audio: base_fw: move IPC4_EXTENDED_SYSTEM_TIME to platform code
Browse files Browse the repository at this point in the history
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 <kai.vehmanen@linux.intel.com>
  • Loading branch information
kv2019i committed Apr 18, 2024
1 parent 29eda8e commit 72873d1
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 73 deletions.
77 changes: 5 additions & 72 deletions src/audio/base_fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@
#include "adsp_debug_window.h"
#endif

#if CONFIG_ACE_V1X_ART_COUNTER || CONFIG_ACE_V1X_RTC_COUNTER
#include <zephyr/device.h>
#include <zephyr/drivers/counter.h>
#endif
#include <zephyr/logging/log_ctrl.h>

LOG_MODULE_REGISTER(basefw, CONFIG_SOF_LOG_LEVEL);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down
2 changes: 2 additions & 0 deletions src/include/ipc4/base_fw.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__ */
76 changes: 75 additions & 1 deletion src/platform/intel/ace/lib/base_fw_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
#include <intel_adsp_hda.h>
#endif

#if CONFIG_ACE_V1X_ART_COUNTER || CONFIG_ACE_V1X_RTC_COUNTER
#include <zephyr/device.h>
#include <zephyr/drivers/counter.h>
#endif

#include <ipc4/base_fw.h>

LOG_MODULE_REGISTER(basefw_platform, CONFIG_SOF_LOG_LEVEL);
Expand Down Expand Up @@ -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,
Expand All @@ -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)
Expand Down

0 comments on commit 72873d1

Please sign in to comment.