forked from thesofproject/sof
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcpu-clk-manager.c
More file actions
94 lines (74 loc) · 1.96 KB
/
cpu-clk-manager.c
File metadata and controls
94 lines (74 loc) · 1.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// SPDX-License-Identifier: BSD-3-Clause
//
// Copyright(c) 2022 Intel Corporation. All rights reserved.
//
// Author: Krzysztof Frydryk <frydryk.krzysztof@intel.com>
#include <rtos/spinlock.h>
#include <rtos/sof.h>
#include <stdint.h>
#include <sof/lib/cpu-clk-manager.h>
#include <rtos/clk.h>
#include <sof/math/numbers.h>
#include <errno.h>
#ifdef __ZEPHYR__
#include <zephyr/sys/util.h>
#endif /* __ZEPHYR__ */
static struct kcps_budget_data kcps_data;
static int request_freq_change(unsigned int core, int freq)
{
int current_freq;
int selected_freq_id;
struct clock_info *clk;
clk = clocks_get() + core;
for (selected_freq_id = 0; selected_freq_id < clk->freqs_num; selected_freq_id++) {
if (freq < clk->freqs[selected_freq_id].freq)
break;
}
/* don't change clock frequency if already using proper clock */
current_freq = clock_get_freq(core);
if (clk->freqs[selected_freq_id].freq != current_freq)
clock_set_freq(core, freq);
return 0;
}
static int max_core_consumption(void)
{
int result = 0;
unsigned int core;
for (core = 0; core < CONFIG_CORE_COUNT; core++)
result = MAX(result, kcps_data.kcps_consumption[core]);
return result;
}
int core_kcps_adjust(int adjusted_core_id, int kcps_delta)
{
k_spinlock_key_t key;
int freq;
unsigned int core_id;
int ret = 0;
key = k_spin_lock(&kcps_data.lock);
kcps_data.kcps_consumption[adjusted_core_id] += kcps_delta;
/* set clock according to maximum requested mcps budget */
freq = max_core_consumption();
for (core_id = 0; core_id < CONFIG_CORE_COUNT; core_id++) {
/* Convert kcps to cps */
ret = request_freq_change(core_id, freq * 1000);
if (ret < 0)
goto out;
}
out:
k_spin_unlock(&kcps_data.lock, key);
return ret;
}
int core_kcps_get(int core)
{
k_spinlock_key_t key;
int ret;
key = k_spin_lock(&kcps_data.lock);
ret = kcps_data.kcps_consumption[core];
k_spin_unlock(&kcps_data.lock, key);
return ret;
}
int kcps_budget_init(void)
{
k_spinlock_init(&kcps_data.lock);
return 0;
}