Commit | Line | Data |
---|---|---|
ff956826 ZR |
1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* | |
3 | * Data types and headers for RAPL support | |
4 | * | |
5 | * Copyright (C) 2019 Intel Corporation. | |
6 | * | |
7 | * Author: Zhang Rui <rui.zhang@intel.com> | |
8 | */ | |
9 | ||
10 | #ifndef __INTEL_RAPL_H__ | |
11 | #define __INTEL_RAPL_H__ | |
12 | ||
13 | #include <linux/types.h> | |
14 | #include <linux/powercap.h> | |
8da04e05 | 15 | #include <linux/cpuhotplug.h> |
ff956826 | 16 | |
b4288ce7 ZR |
17 | enum rapl_if_type { |
18 | RAPL_IF_MSR, /* RAPL I/F using MSR registers */ | |
19 | RAPL_IF_MMIO, /* RAPL I/F using MMIO registers */ | |
e12dee18 | 20 | RAPL_IF_TPMI, /* RAPL I/F using TPMI registers */ |
b4288ce7 ZR |
21 | }; |
22 | ||
ff956826 ZR |
23 | enum rapl_domain_type { |
24 | RAPL_DOMAIN_PACKAGE, /* entire package/socket */ | |
25 | RAPL_DOMAIN_PP0, /* core power plane */ | |
26 | RAPL_DOMAIN_PP1, /* graphics uncore */ | |
27 | RAPL_DOMAIN_DRAM, /* DRAM control_type */ | |
28 | RAPL_DOMAIN_PLATFORM, /* PSys control_type */ | |
29 | RAPL_DOMAIN_MAX, | |
30 | }; | |
31 | ||
32 | enum rapl_domain_reg_id { | |
33 | RAPL_DOMAIN_REG_LIMIT, | |
34 | RAPL_DOMAIN_REG_STATUS, | |
35 | RAPL_DOMAIN_REG_PERF, | |
36 | RAPL_DOMAIN_REG_POLICY, | |
37 | RAPL_DOMAIN_REG_INFO, | |
8365a898 | 38 | RAPL_DOMAIN_REG_PL4, |
cb532e72 | 39 | RAPL_DOMAIN_REG_UNIT, |
e12dee18 | 40 | RAPL_DOMAIN_REG_PL2, |
ff956826 ZR |
41 | RAPL_DOMAIN_REG_MAX, |
42 | }; | |
43 | ||
35eb1f50 | 44 | struct rapl_domain; |
ff956826 ZR |
45 | |
46 | enum rapl_primitives { | |
ff956826 ZR |
47 | POWER_LIMIT1, |
48 | POWER_LIMIT2, | |
8365a898 | 49 | POWER_LIMIT4, |
045610c3 | 50 | ENERGY_COUNTER, |
ff956826 | 51 | FW_LOCK, |
f442bd27 | 52 | FW_HIGH_LOCK, |
e12dee18 ZR |
53 | PL1_LOCK, |
54 | PL2_LOCK, | |
55 | PL4_LOCK, | |
ff956826 ZR |
56 | |
57 | PL1_ENABLE, /* power limit 1, aka long term */ | |
58 | PL1_CLAMP, /* allow frequency to go below OS request */ | |
59 | PL2_ENABLE, /* power limit 2, aka short term, instantaneous */ | |
60 | PL2_CLAMP, | |
8365a898 | 61 | PL4_ENABLE, /* power limit 4, aka max peak power */ |
ff956826 ZR |
62 | |
63 | TIME_WINDOW1, /* long term */ | |
64 | TIME_WINDOW2, /* short term */ | |
65 | THERMAL_SPEC_POWER, | |
66 | MAX_POWER, | |
67 | ||
68 | MIN_POWER, | |
69 | MAX_TIME_WINDOW, | |
70 | THROTTLED_TIME, | |
71 | PRIORITY_LEVEL, | |
72 | ||
931da6a0 ZR |
73 | PSYS_POWER_LIMIT1, |
74 | PSYS_POWER_LIMIT2, | |
75 | PSYS_PL1_ENABLE, | |
76 | PSYS_PL2_ENABLE, | |
77 | PSYS_TIME_WINDOW1, | |
78 | PSYS_TIME_WINDOW2, | |
ff956826 ZR |
79 | /* below are not raw primitive data */ |
80 | AVERAGE_POWER, | |
81 | NR_RAPL_PRIMITIVES, | |
82 | }; | |
83 | ||
84 | struct rapl_domain_data { | |
85 | u64 primitives[NR_RAPL_PRIMITIVES]; | |
86 | unsigned long timestamp; | |
87 | }; | |
88 | ||
045610c3 ZR |
89 | #define NR_POWER_LIMITS (POWER_LIMIT4 + 1) |
90 | ||
ff956826 ZR |
91 | struct rapl_power_limit { |
92 | struct powercap_zone_constraint *constraint; | |
ff956826 ZR |
93 | struct rapl_domain *domain; |
94 | const char *name; | |
f442bd27 | 95 | bool locked; |
ff956826 ZR |
96 | u64 last_power_limit; |
97 | }; | |
98 | ||
99 | struct rapl_package; | |
100 | ||
f1e8d756 ZR |
101 | #define RAPL_DOMAIN_NAME_LENGTH 16 |
102 | ||
16e95a62 ZR |
103 | union rapl_reg { |
104 | void __iomem *mmio; | |
105 | u32 msr; | |
106 | u64 val; | |
107 | }; | |
108 | ||
ff956826 | 109 | struct rapl_domain { |
f1e8d756 | 110 | char name[RAPL_DOMAIN_NAME_LENGTH]; |
ff956826 | 111 | enum rapl_domain_type id; |
16e95a62 | 112 | union rapl_reg regs[RAPL_DOMAIN_REG_MAX]; |
ff956826 ZR |
113 | struct powercap_zone power_zone; |
114 | struct rapl_domain_data rdd; | |
115 | struct rapl_power_limit rpl[NR_POWER_LIMITS]; | |
116 | u64 attr_map; /* track capabilities */ | |
117 | unsigned int state; | |
cb532e72 ZR |
118 | unsigned int power_unit; |
119 | unsigned int energy_unit; | |
120 | unsigned int time_unit; | |
ff956826 ZR |
121 | struct rapl_package *rp; |
122 | }; | |
123 | ||
beea8df8 | 124 | struct reg_action { |
16e95a62 | 125 | union rapl_reg reg; |
beea8df8 ZR |
126 | u64 mask; |
127 | u64 value; | |
128 | int err; | |
129 | }; | |
130 | ||
7ebf8eff ZR |
131 | /** |
132 | * struct rapl_if_priv: private data for different RAPL interfaces | |
133 | * @control_type: Each RAPL interface must have its own powercap | |
134 | * control type. | |
135 | * @platform_rapl_domain: Optional. Some RAPL interface may have platform | |
136 | * level RAPL control. | |
137 | * @pcap_rapl_online: CPU hotplug state for each RAPL interface. | |
7fde2712 ZR |
138 | * @reg_unit: Register for getting energy/power/time unit. |
139 | * @regs: Register sets for different RAPL Domains. | |
0c2ddedd | 140 | * @limits: Number of power limits supported by each domain. |
beea8df8 ZR |
141 | * @read_raw: Callback for reading RAPL interface specific |
142 | * registers. | |
143 | * @write_raw: Callback for writing RAPL interface specific | |
144 | * registers. | |
e8e28c2a | 145 | * @defaults: internal pointer to interface default settings |
98ff639a | 146 | * @rpi: internal pointer to interface primitive info |
7ebf8eff ZR |
147 | */ |
148 | struct rapl_if_priv { | |
b4288ce7 | 149 | enum rapl_if_type type; |
7ebf8eff | 150 | struct powercap_control_type *control_type; |
7ebf8eff | 151 | enum cpuhp_state pcap_rapl_online; |
16e95a62 ZR |
152 | union rapl_reg reg_unit; |
153 | union rapl_reg regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX]; | |
0c2ddedd | 154 | int limits[RAPL_DOMAIN_MAX]; |
bf44b901 ZR |
155 | int (*read_raw)(int id, struct reg_action *ra); |
156 | int (*write_raw)(int id, struct reg_action *ra); | |
e8e28c2a | 157 | void *defaults; |
98ff639a | 158 | void *rpi; |
7ebf8eff ZR |
159 | }; |
160 | ||
575024a8 ZR |
161 | #ifdef CONFIG_PERF_EVENTS |
162 | /** | |
163 | * struct rapl_package_pmu_data: Per package data for PMU support | |
164 | * @scale: Scale of 2^-32 Joules for each energy counter increase. | |
165 | * @lock: Lock to protect n_active and active_list. | |
166 | * @n_active: Number of active events. | |
167 | * @active_list: List of active events. | |
168 | * @timer_interval: Maximum timer expiration time before counter overflow. | |
169 | * @hrtimer: Periodically update the counter to prevent overflow. | |
170 | */ | |
171 | struct rapl_package_pmu_data { | |
172 | u64 scale[RAPL_DOMAIN_MAX]; | |
173 | raw_spinlock_t lock; | |
174 | int n_active; | |
175 | struct list_head active_list; | |
176 | ktime_t timer_interval; | |
177 | struct hrtimer hrtimer; | |
178 | }; | |
179 | #endif | |
180 | ||
ff956826 ZR |
181 | /* maximum rapl package domain name: package-%d-die-%d */ |
182 | #define PACKAGE_DOMAIN_NAME_LENGTH 30 | |
183 | ||
184 | struct rapl_package { | |
185 | unsigned int id; /* logical die id, equals physical 1-die systems */ | |
186 | unsigned int nr_domains; | |
187 | unsigned long domain_map; /* bit map of active domains */ | |
ff956826 ZR |
188 | struct rapl_domain *domains; /* array of domains, sized at runtime */ |
189 | struct powercap_zone *power_zone; /* keep track of parent zone */ | |
190 | unsigned long power_limit_irq; /* keep track of package power limit | |
191 | * notify interrupt enable status. | |
192 | */ | |
193 | struct list_head plist; | |
194 | int lead_cpu; /* one active cpu per package for access */ | |
195 | /* Track active cpus */ | |
196 | struct cpumask cpumask; | |
197 | char name[PACKAGE_DOMAIN_NAME_LENGTH]; | |
7ebf8eff | 198 | struct rapl_if_priv *priv; |
575024a8 ZR |
199 | #ifdef CONFIG_PERF_EVENTS |
200 | bool has_pmu; | |
201 | struct rapl_package_pmu_data pmu_data; | |
202 | #endif | |
ff956826 ZR |
203 | }; |
204 | ||
1aa09b93 ZR |
205 | struct rapl_package *rapl_find_package_domain_cpuslocked(int id, struct rapl_if_priv *priv, |
206 | bool id_is_cpu); | |
207 | struct rapl_package *rapl_add_package_cpuslocked(int id, struct rapl_if_priv *priv, | |
208 | bool id_is_cpu); | |
209 | void rapl_remove_package_cpuslocked(struct rapl_package *rp); | |
210 | ||
bf44b901 ZR |
211 | struct rapl_package *rapl_find_package_domain(int id, struct rapl_if_priv *priv, bool id_is_cpu); |
212 | struct rapl_package *rapl_add_package(int id, struct rapl_if_priv *priv, bool id_is_cpu); | |
3382388d ZR |
213 | void rapl_remove_package(struct rapl_package *rp); |
214 | ||
575024a8 ZR |
215 | #ifdef CONFIG_PERF_EVENTS |
216 | int rapl_package_add_pmu(struct rapl_package *rp); | |
217 | void rapl_package_remove_pmu(struct rapl_package *rp); | |
218 | #else | |
219 | static inline int rapl_package_add_pmu(struct rapl_package *rp) { return 0; } | |
220 | static inline void rapl_package_remove_pmu(struct rapl_package *rp) { } | |
221 | #endif | |
222 | ||
ff956826 | 223 | #endif /* __INTEL_RAPL_H__ */ |