Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bdk/soc/actmon.c
1476 views
1
/*
2
* Activity Monitor driver for Tegra X1
3
*
4
* Copyright (c) 2021 CTCaer
5
*
6
* This program is free software; you can redistribute it and/or modify it
7
* under the terms and conditions of the GNU General Public License,
8
* version 2, as published by the Free Software Foundation.
9
*
10
* This program is distributed in the hope it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13
* more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
#include "actmon.h"
20
#include "clock.h"
21
#include "t210.h"
22
23
/* Global registers */
24
#define ACTMON_GLB_STATUS 0x0
25
#define ACTMON_MCCPU_MON_ACT BIT(8)
26
#define ACTMON_MCALL_MON_ACT BIT(9)
27
#define ACTMON_CPU_FREQ_MON_ACT BIT(10)
28
#define ACTMON_APB_MON_ACT BIT(12)
29
#define ACTMON_AHB_MON_ACT BIT(13)
30
#define ACTMON_BPMP_MON_ACT BIT(14)
31
#define ACTMON_CPU_MON_ACT BIT(15)
32
#define ACTMON_MCCPU_INTR BIT(25)
33
#define ACTMON_MCALL_INTR BIT(26)
34
#define ACTMON_CPU_FREQ_INTR BIT(27)
35
#define ACTMON_APB_INTR BIT(28)
36
#define ACTMON_AHB_INTR BIT(29)
37
#define ACTMON_BPMP_INTR BIT(30)
38
#define ACTMON_CPU_INTR BIT(31)
39
#define ACTMON_GLB_PERIOD_CTRL 0x4
40
#define ACTMON_GLB_PERIOD_USEC BIT(8)
41
#define ACTMON_GLB_PERIOD_SAMPLE(n) (((n) - 1) & 0xFF)
42
43
/* Device Registers */
44
#define ACTMON_DEV_BASE ACTMON_BASE + 0x80
45
#define ACTMON_DEV_SIZE 0x40
46
/* CTRL */
47
#define ACTMON_DEV_CTRL_K_VAL(k) (((k) & 7) << 10)
48
#define ACTMON_DEV_CTRL_ENB_PERIODIC BIT(18)
49
#define ACTMON_DEV_CTRL_AT_END_EN BIT(19)
50
#define ACTMON_DEV_CTRL_AVG_BELOW_WMARK_EN BIT(20)
51
#define ACTMON_DEV_CTRL_AVG_ABOVE_WMARK_EN BIT(21)
52
#define ACTMON_DEV_CTRL_WHEN_OVERFLOW_EN BIT(22)
53
#define ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_NUM(n) (((n) & 7) << 23)
54
#define ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_NUM(n) (((n) & 7) << 26)
55
#define ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN BIT(29)
56
#define ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN BIT(30)
57
#define ACTMON_DEV_CTRL_ENB BIT(31)
58
/* INTR_STATUS */
59
#define ACTMON_DEV_ISTS_AVG_ABOVE_WMARK BIT(24)
60
#define ACTMON_DEV_ISTS_AVG_BELOW_WMARK BIT(25)
61
#define ACTMON_DEV_ISTS_WHEN_OVERFLOW BIT(26)
62
#define ACTMON_DEV_ISTS_AT_END BIT(29)
63
#define ACTMON_DEV_ISTS_CONSECUTIVE_LOWER BIT(30)
64
#define ACTMON_DEV_ISTS_CONSECUTIVE_UPPER BIT(31)
65
66
/* Histogram Registers */
67
#define ACTMON_HISTOGRAM_CONFIG 0x300
68
#define ACTMON_HIST_CFG_ACTIVE BIT(0)
69
#define ACTMON_HIST_CFG_LINEAR_MODE BIT(1)
70
#define ACTMON_HIST_CFG_NO_UNDERFLOW_BUCKET BIT(2)
71
#define ACTMON_HIST_CFG_STALL_ON_SINGLE_SATURATE BIT(3)
72
#define ACTMON_HIST_CFG_SHIFT(s) (((s) & 0x1F) << 4)
73
#define ACTMON_HIST_CFG_SOURCE(s) (((s) & 0xF) << 12)
74
#define ACTMON_HISTOGRAM_CTRL 0x304
75
#define ACTMON_HIST_CTRL_CLEAR_ALL BIT(0)
76
#define ACTMON_HISTOGRAM_DATA_BASE 0x380
77
#define ACTMON_HISTOGRAM_DATA_NUM 32
78
79
#define ACTMON_FREQ 19200000
80
#define ACTMON_PERIOD_MS 20
81
#define DEV_COUNT_WEIGHT 5
82
83
typedef struct _actmon_dev_reg_t
84
{
85
vu32 ctrl;
86
vu32 upper_wnark;
87
vu32 lower_wmark;
88
vu32 init_avg;
89
vu32 avg_upper_wmark;
90
vu32 avg_lower_wmark;
91
vu32 count_weight;
92
vu32 count;
93
vu32 avg_count;
94
vu32 intr_status;
95
vu32 ctrl2;
96
vu32 rsvd[5];
97
} actmon_dev_reg_t;
98
99
void actmon_hist_enable(actmon_hist_src_t src)
100
{
101
ACTMON(ACTMON_HISTOGRAM_CONFIG) = ACTMON_HIST_CFG_SOURCE(src) | ACTMON_HIST_CFG_ACTIVE;
102
ACTMON(ACTMON_HISTOGRAM_CTRL) = ACTMON_HIST_CTRL_CLEAR_ALL;
103
}
104
105
void actmon_hist_disable()
106
{
107
ACTMON(ACTMON_HISTOGRAM_CONFIG) = 0;
108
}
109
110
void actmon_hist_get(u32 *histogram)
111
{
112
if (histogram)
113
{
114
for (u32 i = 0; i < ACTMON_HISTOGRAM_DATA_NUM; i++)
115
histogram[i] = ACTMON(ACTMON_HISTOGRAM_DATA_BASE + i * sizeof(u32));
116
}
117
}
118
119
void actmon_dev_enable(actmon_dev_t dev)
120
{
121
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
122
123
regs->init_avg = ACTMON_FREQ * ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT / 100;
124
regs->count_weight = DEV_COUNT_WEIGHT;
125
126
regs->ctrl = ACTMON_DEV_CTRL_ENB | ACTMON_DEV_CTRL_ENB_PERIODIC | ACTMON_DEV_CTRL_K_VAL(7); // 128 samples average.
127
}
128
129
void actmon_dev_disable(actmon_dev_t dev)
130
{
131
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
132
133
regs->ctrl = 0;
134
}
135
136
u32 actmon_dev_get_load(actmon_dev_t dev)
137
{
138
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
139
140
// Get load-based sampling. 1 decimal point precision.
141
u32 load = regs->count * 100 / (ACTMON_FREQ / (ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT));
142
143
return load;
144
}
145
146
u32 actmon_dev_get_load_avg(actmon_dev_t dev)
147
{
148
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
149
150
// Get load-based sampling. 1 decimal point precision.
151
u32 avg_load = regs->avg_count * 100 / (ACTMON_FREQ / (ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT));
152
153
return avg_load;
154
}
155
156
void atmon_dev_all_disable()
157
{
158
// TODO: do a global reset?
159
}
160
161
void actmon_init()
162
{
163
clock_enable_actmon();
164
165
// Set period.
166
ACTMON(ACTMON_GLB_PERIOD_CTRL) = ACTMON_GLB_PERIOD_SAMPLE(ACTMON_PERIOD_MS);
167
}
168
169
void actmon_end()
170
{
171
clock_disable_actmon();
172
}
173