Skip to content

Commit da5edbd

Browse files
piotrkmxkv2019i
authored andcommitted
ace_v1x: host system time set and get
Base firmware functionality for setting and getting host system time. Signed-off-by: Piotr Kmiecik <piotrx.kmiecik@intel.com>
1 parent 0b69384 commit da5edbd

2 files changed

Lines changed: 124 additions & 2 deletions

File tree

src/audio/base_fw.c

Lines changed: 109 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,20 @@
99
#include <ipc4/logging.h>
1010
#include <sof_versions.h>
1111

12+
#if CONFIG_ACE_V1X_ART_COUNTER || CONFIG_ACE_V1X_RTC_COUNTER
13+
#include <zephyr/device.h>
14+
#include <zephyr/drivers/counter.h>
15+
#endif
16+
1217
LOG_MODULE_REGISTER(basefw, CONFIG_SOF_LOG_LEVEL);
1318

1419
/* 0e398c32-5ade-ba4b-93b1-c50432280ee4 */
1520
DECLARE_SOF_RT_UUID("basefw", basefw_comp_uuid, 0xe398c32, 0x5ade, 0xba4b,
1621
0x93, 0xb1, 0xc5, 0x04, 0x32, 0x28, 0x0e, 0xe4);
1722
DECLARE_TR_CTX(basefw_comp_tr, SOF_UUID(basefw_comp_uuid), LOG_LEVEL_INFO);
1823

24+
static struct ipc4_system_time_info global_system_time_info;
25+
1926
static inline void set_tuple(struct ipc4_tuple *tuple, uint32_t type, uint32_t length, void *data)
2027
{
2128
tuple->type = type;
@@ -228,13 +235,103 @@ static int basefw_mem_state_info(uint32_t *data_offset, char *data)
228235
return 0;
229236
}
230237

238+
static uint32_t basefw_set_system_time(uint32_t param_id,
239+
bool first_block,
240+
bool last_block,
241+
uint32_t data_offset,
242+
char *data)
243+
{
244+
/* TODO: configurate time to logging subsystem */
245+
if (!(first_block && last_block))
246+
return IPC4_INVALID_REQUEST;
247+
248+
global_system_time_info.host_time.val_l = ((struct ipc4_system_time *)data)->val_l;
249+
global_system_time_info.host_time.val_u = ((struct ipc4_system_time *)data)->val_u;
250+
251+
uint64_t current_dsp_time = sof_cycle_get_64();
252+
253+
global_system_time_info.dsp_time.val_l = (uint32_t)(current_dsp_time);
254+
global_system_time_info.dsp_time.val_u = (uint32_t)(current_dsp_time >> 32);
255+
256+
return IPC4_SUCCESS;
257+
}
258+
259+
static uint32_t basefw_get_system_time(uint32_t *data_offset, char *data)
260+
{
261+
struct ipc4_system_time *system_time = (struct ipc4_system_time *)data;
262+
263+
system_time->val_l = global_system_time_info.host_time.val_l;
264+
system_time->val_u = global_system_time_info.host_time.val_u;
265+
*data_offset = sizeof(struct ipc4_system_time);
266+
return IPC4_SUCCESS;
267+
}
268+
269+
static uint32_t basefw_get_ext_system_time(uint32_t *data_offset, char *data)
270+
{
271+
#if CONFIG_ACE_V1X_ART_COUNTER && CONFIG_ACE_V1X_RTC_COUNTER
272+
struct ipc4_ext_system_time *ext_system_time = (struct ipc4_ext_system_time *)(data);
273+
struct ipc4_ext_system_time ext_system_time_data = {0};
274+
275+
uint64_t host_time = ((uint64_t)global_system_time_info.host_time.val_u << 32)
276+
| (uint64_t)global_system_time_info.host_time.val_l;
277+
uint64_t dsp_time = ((uint64_t)global_system_time_info.dsp_time.val_u << 32)
278+
| (uint64_t)global_system_time_info.dsp_time.val_l;
279+
280+
if (host_time == 0 || dsp_time == 0)
281+
return IPC4_INVALID_RESOURCE_STATE;
282+
283+
uint64_t art = 0;
284+
uint64_t wallclk = 0;
285+
uint64_t rtc = 0;
286+
287+
const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(ace_art_counter));
288+
289+
if (!dev) {
290+
LOG_DBG("board: ART counter device binding failed");
291+
return IPC4_MOD_NOT_INITIALIZED;
292+
}
293+
294+
counter_get_value_64(dev, &art);
295+
296+
wallclk = sof_cycle_get_64();
297+
ext_system_time_data.art_l = (uint32_t)art;
298+
ext_system_time_data.art_u = (uint32_t)(art >> 32);
299+
uint64_t delta = (wallclk - dsp_time) / (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000000);
300+
301+
uint64_t new_host_time = (host_time + delta);
302+
303+
ext_system_time_data.utc_l = (uint32_t)new_host_time;
304+
ext_system_time_data.utc_u = (uint32_t)(new_host_time >> 32);
305+
306+
dev = DEVICE_DT_GET(DT_NODELABEL(ace_rtc_counter));
307+
308+
if (!dev) {
309+
LOG_DBG("board: RTC counter device binding failed");
310+
return IPC4_MOD_NOT_INITIALIZED;
311+
}
312+
313+
counter_get_value_64(dev, &rtc);
314+
ext_system_time_data.rtc_l = (uint32_t)rtc;
315+
ext_system_time_data.rtc_u = (uint32_t)(rtc >> 32);
316+
317+
memcpy_s(ext_system_time, sizeof(ext_system_time), &ext_system_time_data,
318+
sizeof(ext_system_time));
319+
*data_offset = sizeof(struct ipc4_ext_system_time);
320+
321+
return IPC4_SUCCESS;
322+
#endif
323+
return IPC4_UNAVAILABLE;
324+
}
325+
231326
static int basefw_get_large_config(struct comp_dev *dev,
232327
uint32_t param_id,
233328
bool first_block,
234329
bool last_block,
235330
uint32_t *data_offset,
236331
char *data)
237332
{
333+
uint32_t ret = -EINVAL;
334+
238335
switch (param_id) {
239336
case IPC4_PERF_MEASUREMENTS_STATE:
240337
case IPC4_GLOBAL_PERF_DATA:
@@ -251,6 +348,16 @@ static int basefw_get_large_config(struct comp_dev *dev,
251348
return basefw_hw_config(data_offset, data);
252349
case IPC4_MEMORY_STATE_INFO_GET:
253350
return basefw_mem_state_info(data_offset, data);
351+
case IPC4_SYSTEM_TIME:
352+
return basefw_get_system_time(data_offset, data);
353+
case IPC4_EXTENDED_SYSTEM_TIME:
354+
ret = basefw_get_ext_system_time(data_offset, data);
355+
if (ret == IPC4_UNAVAILABLE) {
356+
tr_warn(&basefw_comp_tr, "returning success for get host EXTENDED_SYSTEM_TIME without handling it");
357+
return 0;
358+
} else {
359+
return ret;
360+
}
254361
/* TODO: add more support */
255362
case IPC4_DSP_RESOURCE_STATE:
256363
case IPC4_NOTIFICATION_MASK:
@@ -283,8 +390,8 @@ static int basefw_set_large_config(struct comp_dev *dev,
283390
tr_warn(&basefw_comp_tr, "returning success for Set FW_CONFIG without handling it");
284391
return 0;
285392
case IPC4_SYSTEM_TIME:
286-
tr_warn(&basefw_comp_tr, "returning success for Set SYSTEM_TIME without handling it");
287-
return 0;
393+
return basefw_set_system_time(param_id, first_block,
394+
last_block, data_offset, data);
288395
case IPC4_ENABLE_LOGS:
289396
return ipc4_logging_enable_logs(first_block, last_block, data_offset, data);
290397
default:

src/include/ipc4/base_fw.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,21 @@ struct ipc4_system_time_info {
558558
struct ipc4_system_time dsp_time;
559559
} __attribute__((packed, aligned(4)));
560560

561+
struct ipc4_ext_system_time {
562+
/* Lower DWORD of current system time value. */
563+
uint32_t utc_l;
564+
/* Upper DWORD of current system time value. */
565+
uint32_t utc_u;
566+
/* Lower DWORD of current RTC value. */
567+
uint32_t rtc_l;
568+
/* Upper DWORD of current RTC value. */
569+
uint32_t rtc_u;
570+
/* Lower DWORD of current ART value. */
571+
uint32_t art_l;
572+
/* Upper DWORD of current ART value. */
573+
uint32_t art_u;
574+
};
575+
561576
enum ipc4_pipeline_attributes {
562577
/* Determines whether on pipeline will be allocated module(s) with ULP capability */
563578
IPC4_ULTRA_LOW_POWER = 0,

0 commit comments

Comments
 (0)