schedule: introduce ll_schedule_domain

This patch introduces new structure called ll_schedule_domain.
It will be used to initialize ll scheduler with different
types of scheduling time domains. Right now it's only working
based on timer interrupts, but will be extended.

Signed-off-by: Tomasz Lauda <tomasz.lauda@linux.intel.com>
This commit is contained in:
Tomasz Lauda 2019-09-05 15:13:12 +02:00 committed by Liam Girdwood
parent 460c41aa66
commit 4ee233990e
1 changed files with 125 additions and 0 deletions

View File

@ -0,0 +1,125 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright(c) 2019 Intel Corporation. All rights reserved.
*
* Author: Tomasz Lauda <tomasz.lauda@linux.intel.com>
*/
#ifndef __SOF_SCHEDULE_LL_SCHEDULE_DOMAIN_H__
#define __SOF_SCHEDULE_LL_SCHEDULE_DOMAIN_H__
#include <sof/atomic.h>
#include <sof/debug/panic.h>
#include <sof/lib/alloc.h>
#include <sof/lib/cpu.h>
#include <sof/lib/clk.h>
#include <sof/spinlock.h>
#include <sof/trace/trace.h>
#include <ipc/topology.h>
#include <user/trace.h>
#include <stdbool.h>
#include <stdint.h>
struct ll_schedule_domain;
struct task;
struct ll_schedule_domain_ops {
int (*domain_register)(struct ll_schedule_domain *domain,
uint64_t period, struct task *task,
void (*handler)(void *arg), void *arg);
void (*domain_unregister)(struct ll_schedule_domain *domain,
uint32_t num_tasks);
void (*domain_enable)(struct ll_schedule_domain *domain, int core);
void (*domain_disable)(struct ll_schedule_domain *domain, int core);
void (*domain_set)(struct ll_schedule_domain *domain, uint64_t start);
void (*domain_clear)(struct ll_schedule_domain *domain);
bool (*domain_is_pending)(struct ll_schedule_domain *domain,
struct task *task);
};
struct ll_schedule_domain {
uint64_t last_tick;
spinlock_t *lock;
atomic_t total_num_tasks;
atomic_t num_clients;
bool registered[PLATFORM_CORE_COUNT];
uint32_t ticks_per_ms;
int type;
int clk;
const struct ll_schedule_domain_ops *ops;
void *private;
};
#define ll_sch_domain_set_pdata(domain, data) ((domain)->private = (data))
#define ll_sch_domain_get_pdata(domain) ((domain)->private)
static inline struct ll_schedule_domain *domain_init(int type, int clk,
const struct ll_schedule_domain_ops *ops)
{
struct ll_schedule_domain *domain;
domain = rzalloc(RZONE_SYS | RZONE_FLAG_UNCACHED, SOF_MEM_CAPS_RAM,
sizeof(*domain));
domain->type = type;
domain->clk = clk;
domain->ticks_per_ms = clock_ms_to_ticks(clk, 1);
domain->ops = ops;
spinlock_init(&domain->lock);
atomic_init(&domain->total_num_tasks, 0);
atomic_init(&domain->num_clients, 0);
return domain;
}
static inline int domain_register(struct ll_schedule_domain *domain,
uint64_t period, struct task *task,
void (*handler)(void *arg), void *arg)
{
assert(domain->ops->domain_register);
return domain->ops->domain_register(domain, period, task, handler, arg);
}
static inline void domain_unregister(struct ll_schedule_domain *domain,
uint32_t num_tasks)
{
assert(domain->ops->domain_unregister);
domain->ops->domain_unregister(domain, num_tasks);
}
static inline void domain_enable(struct ll_schedule_domain *domain, int core)
{
if (domain->ops->domain_enable)
domain->ops->domain_enable(domain, core);
}
static inline void domain_disable(struct ll_schedule_domain *domain, int core)
{
if (domain->ops->domain_disable)
domain->ops->domain_disable(domain, core);
}
static inline void domain_set(struct ll_schedule_domain *domain, uint64_t start)
{
if (domain->ops->domain_set)
domain->ops->domain_set(domain, start);
}
static inline void domain_clear(struct ll_schedule_domain *domain)
{
if (domain->ops->domain_clear)
domain->ops->domain_clear(domain);
}
static inline bool domain_is_pending(struct ll_schedule_domain *domain,
struct task *task)
{
assert(domain->ops->domain_is_pending);
return domain->ops->domain_is_pending(domain, task);
}
#endif /* __SOF_SCHEDULE_LL_SCHEDULE_DOMAIN_H__ */