timer_domain: refine the timer_domain_set() logic

Do timer_domain refining as below:

Use unified LL_TIMER_SET_OVERHEAD_TICKS=1000 which denote the max
overhead that the timer_domain_set() will take, and remove the
definition from each platforms.

Don't add any overhead if no needed(e.g. if the start > current +
overhead). This will help to schedule the task ASAP, and make the
catching up (of the previous delay) possible.

Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
This commit is contained in:
Keyon Jie 2021-02-04 10:44:12 +08:00 committed by Liam Girdwood
parent 1f7a2805de
commit 5104f5e02d
7 changed files with 21 additions and 25 deletions

View File

@ -165,8 +165,7 @@ static inline bool domain_is_pending(struct ll_schedule_domain *domain,
return ret;
}
struct ll_schedule_domain *timer_domain_init(struct timer *timer, int clk,
uint64_t timeout);
struct ll_schedule_domain *timer_domain_init(struct timer *timer, int clk);
struct ll_schedule_domain *dma_multi_chan_domain_init(struct dma *dma_array,
uint32_t num_dma, int clk,

View File

@ -219,8 +219,7 @@ int platform_init(struct sof *sof)
/* init low latency timer domain and scheduler */
sof->platform_timer_domain =
timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK,
CONFIG_SYSTICK_PERIOD);
timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK);
scheduler_init_ll(sof->platform_timer_domain);
/* init the system agent */

View File

@ -192,8 +192,7 @@ int platform_init(struct sof *sof)
/* init low latency timer domain and scheduler */
sof->platform_timer_domain =
timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK,
CONFIG_SYSTICK_PERIOD);
timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK);
scheduler_init_ll(sof->platform_timer_domain);
/* init the system agent */

View File

@ -158,8 +158,7 @@ int platform_init(struct sof *sof)
/* init low latency domains and schedulers */
sof->platform_timer_domain =
timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK,
CONFIG_SYSTICK_PERIOD);
timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK);
scheduler_init_ll(sof->platform_timer_domain);
platform_timer_start(sof->platform_timer);

View File

@ -157,8 +157,7 @@ int platform_init(struct sof *sof)
/* init low latency domains and schedulers */
sof->platform_timer_domain =
timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK,
CONFIG_SYSTICK_PERIOD);
timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK);
scheduler_init_ll(sof->platform_timer_domain);
platform_timer_start(sof->platform_timer);

View File

@ -386,8 +386,7 @@ int platform_init(struct sof *sof)
/* init low latency timer domain and scheduler */
sof->platform_timer_domain =
timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK,
CONFIG_SYSTICK_PERIOD);
timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK);
scheduler_init_ll(sof->platform_timer_domain);
/* init the system agent */

View File

@ -8,6 +8,7 @@
#include <sof/lib/alloc.h>
#include <sof/lib/cpu.h>
#include <sof/lib/memory.h>
#include <sof/math/numbers.h>
#include <sof/platform.h>
#include <sof/schedule/ll_schedule.h>
#include <sof/schedule/ll_schedule_domain.h>
@ -53,6 +54,8 @@ K_THREAD_STACK_DEFINE(ll_workq_stack3, ZEPHYR_LL_WORKQ_SIZE);
#endif
#endif
#define LL_TIMER_SET_OVERHEAD_TICKS 1000 /* overhead/delay to set the tick, in ticks */
struct timer_domain {
#ifdef __ZEPHYR__
struct k_work_q ll_workq[CONFIG_CORE_COUNT];
@ -60,7 +63,7 @@ struct timer_domain {
#endif
struct timer *timer;
void *arg[CONFIG_CORE_COUNT];
uint64_t timeout; /* in microseconds */
uint64_t timeout; /* in ticks */
};
#ifdef __ZEPHYR__
@ -228,11 +231,13 @@ static void timer_domain_disable(struct ll_schedule_domain *domain, int core)
static void timer_domain_set(struct ll_schedule_domain *domain, uint64_t start)
{
struct timer_domain *timer_domain = ll_sch_domain_get_pdata(domain);
uint64_t ticks_tout = domain->ticks_per_ms * timer_domain->timeout /
1000;
uint64_t ticks_tout = timer_domain->timeout;
uint64_t ticks_set;
#ifndef __ZEPHYR__
uint64_t ticks_req = start + ticks_tout;
uint64_t ticks_req;
/* make sure to require for ticks later than tout from now */
ticks_req = MAX(start, platform_timer_get_atomic(timer_domain->timer) + ticks_tout);
ticks_set = platform_timer_set(timer_domain->timer, ticks_req);
#else
@ -276,6 +281,10 @@ static void timer_domain_set(struct ll_schedule_domain *domain, uint64_t start)
current - current % CYC_PER_TICK;
#endif
tr_dbg(&ll_tr, "timer_domain_set(): ticks_set %u ticks_req %u current %u",
(unsigned int)ticks_set, (unsigned int)ticks_req,
(unsigned int)platform_timer_get_atomic(timer_get()));
/* Was timer set to the value we requested? If no it means some
* delay occurred and we should report that in error log.
*/
@ -305,24 +314,17 @@ static bool timer_domain_is_pending(struct ll_schedule_domain *domain,
return task->start <= platform_timer_get_atomic(timer_get());
}
struct ll_schedule_domain *timer_domain_init(struct timer *timer, int clk,
uint64_t timeout)
struct ll_schedule_domain *timer_domain_init(struct timer *timer, int clk)
{
struct ll_schedule_domain *domain;
struct timer_domain *timer_domain;
if (timeout <= UINT_MAX)
tr_info(&ll_tr, "timer_domain_init clk %d timeout %u", clk,
(unsigned int)timeout);
else
tr_info(&ll_tr, "timer_domain_init clk %d timeout > %u", clk, UINT_MAX);
domain = domain_init(SOF_SCHEDULE_LL_TIMER, clk, false,
&timer_domain_ops);
timer_domain = rzalloc(SOF_MEM_ZONE_SYS_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*timer_domain));
timer_domain->timer = timer;
timer_domain->timeout = timeout;
timer_domain->timeout = LL_TIMER_SET_OVERHEAD_TICKS;
ll_sch_domain_set_pdata(domain, timer_domain);