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> 15 #include <linux/cpuhotplug.h> 16 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 */ 20 RAPL_IF_TPMI, /* RAPL I/F using TPMI registers */ 21 }; 22 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, 38 RAPL_DOMAIN_REG_PL4, 39 RAPL_DOMAIN_REG_UNIT, 40 RAPL_DOMAIN_REG_PL2, 41 RAPL_DOMAIN_REG_MAX, 42 }; 43 44 struct rapl_domain; 45 46 enum rapl_primitives { 47 POWER_LIMIT1, 48 POWER_LIMIT2, 49 POWER_LIMIT4, 50 ENERGY_COUNTER, 51 FW_LOCK, 52 FW_HIGH_LOCK, 53 PL1_LOCK, 54 PL2_LOCK, 55 PL4_LOCK, 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, 61 PL4_ENABLE, /* power limit 4, aka max peak power */ 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 73 PSYS_POWER_LIMIT1, 74 PSYS_POWER_LIMIT2, 75 PSYS_PL1_ENABLE, 76 PSYS_PL2_ENABLE, 77 PSYS_TIME_WINDOW1, 78 PSYS_TIME_WINDOW2, 79 /* below are not raw primitive data */ 80 NR_RAPL_PRIMITIVES, 81 }; 82 83 struct rapl_domain_data { 84 u64 primitives[NR_RAPL_PRIMITIVES]; 85 unsigned long timestamp; 86 }; 87 88 #define NR_POWER_LIMITS (POWER_LIMIT4 + 1) 89 90 struct rapl_power_limit { 91 struct powercap_zone_constraint *constraint; 92 struct rapl_domain *domain; 93 const char *name; 94 bool locked; 95 u64 last_power_limit; 96 }; 97 98 struct rapl_package; 99 100 #define RAPL_DOMAIN_NAME_LENGTH 16 101 102 union rapl_reg { 103 void __iomem *mmio; 104 u32 msr; 105 u64 val; 106 }; 107 108 struct rapl_domain { 109 char name[RAPL_DOMAIN_NAME_LENGTH]; 110 enum rapl_domain_type id; 111 union rapl_reg regs[RAPL_DOMAIN_REG_MAX]; 112 struct powercap_zone power_zone; 113 struct rapl_domain_data rdd; 114 struct rapl_power_limit rpl[NR_POWER_LIMITS]; 115 u64 attr_map; /* track capabilities */ 116 unsigned int state; 117 unsigned int power_unit; 118 unsigned int energy_unit; 119 unsigned int time_unit; 120 struct rapl_package *rp; 121 }; 122 123 struct reg_action { 124 union rapl_reg reg; 125 u64 mask; 126 u64 value; 127 int err; 128 }; 129 130 struct rapl_defaults { 131 u8 floor_freq_reg_addr; 132 int (*check_unit)(struct rapl_domain *rd); 133 void (*set_floor_freq)(struct rapl_domain *rd, bool mode); 134 u64 (*compute_time_window)(struct rapl_domain *rd, u64 val, bool to_raw); 135 unsigned int dram_domain_energy_unit; 136 unsigned int psys_domain_energy_unit; 137 bool spr_psys_bits; 138 bool msr_pl4_support; 139 bool msr_pmu_support; 140 }; 141 142 #define PRIMITIVE_INFO_INIT(p, m, s, i, u, f) { \ 143 .name = #p, \ 144 .mask = m, \ 145 .shift = s, \ 146 .id = i, \ 147 .unit = u, \ 148 .flag = f \ 149 } 150 151 enum unit_type { 152 ARBITRARY_UNIT, /* no translation */ 153 POWER_UNIT, 154 ENERGY_UNIT, 155 TIME_UNIT, 156 }; 157 158 /* per domain data. used to describe individual knobs such that access function 159 * can be consolidated into one instead of many inline functions. 160 */ 161 struct rapl_primitive_info { 162 const char *name; 163 u64 mask; 164 int shift; 165 enum rapl_domain_reg_id id; 166 enum unit_type unit; 167 u32 flag; 168 }; 169 170 /** 171 * struct rapl_if_priv: private data for different RAPL interfaces 172 * @control_type: Each RAPL interface must have its own powercap 173 * control type. 174 * @platform_rapl_domain: Optional. Some RAPL interface may have platform 175 * level RAPL control. 176 * @pcap_rapl_online: CPU hotplug state for each RAPL interface. 177 * @reg_unit: Register for getting energy/power/time unit. 178 * @regs: Register sets for different RAPL Domains. 179 * @limits: Number of power limits supported by each domain. 180 * @read_raw: Callback for reading RAPL interface specific 181 * registers. 182 * @write_raw: Callback for writing RAPL interface specific 183 * registers. 184 * @defaults: pointer to default settings 185 * @rpi: pointer to interface primitive info 186 */ 187 struct rapl_if_priv { 188 enum rapl_if_type type; 189 struct powercap_control_type *control_type; 190 enum cpuhp_state pcap_rapl_online; 191 union rapl_reg reg_unit; 192 union rapl_reg regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX]; 193 int limits[RAPL_DOMAIN_MAX]; 194 int (*read_raw)(int id, struct reg_action *ra, bool pmu_ctx); 195 int (*write_raw)(int id, struct reg_action *ra); 196 const struct rapl_defaults *defaults; 197 struct rapl_primitive_info *rpi; 198 }; 199 200 #ifdef CONFIG_PERF_EVENTS 201 /** 202 * struct rapl_package_pmu_data: Per package data for PMU support 203 * @scale: Scale of 2^-32 Joules for each energy counter increase. 204 * @lock: Lock to protect n_active and active_list. 205 * @n_active: Number of active events. 206 * @active_list: List of active events. 207 * @timer_interval: Maximum timer expiration time before counter overflow. 208 * @hrtimer: Periodically update the counter to prevent overflow. 209 */ 210 struct rapl_package_pmu_data { 211 u64 scale[RAPL_DOMAIN_MAX]; 212 raw_spinlock_t lock; 213 int n_active; 214 struct list_head active_list; 215 ktime_t timer_interval; 216 struct hrtimer hrtimer; 217 }; 218 #endif 219 220 /* maximum rapl package domain name: package-%d-die-%d */ 221 #define PACKAGE_DOMAIN_NAME_LENGTH 30 222 223 struct rapl_package { 224 unsigned int id; /* logical die id, equals physical 1-die systems */ 225 unsigned int nr_domains; 226 unsigned long domain_map; /* bit map of active domains */ 227 struct rapl_domain *domains; /* array of domains, sized at runtime */ 228 struct powercap_zone *power_zone; /* keep track of parent zone */ 229 unsigned long power_limit_irq; /* keep track of package power limit 230 * notify interrupt enable status. 231 */ 232 struct list_head plist; 233 int lead_cpu; /* one active cpu per package for access */ 234 /* Track active cpus */ 235 struct cpumask cpumask; 236 char name[PACKAGE_DOMAIN_NAME_LENGTH]; 237 struct rapl_if_priv *priv; 238 #ifdef CONFIG_PERF_EVENTS 239 bool has_pmu; 240 struct rapl_package_pmu_data pmu_data; 241 #endif 242 }; 243 244 struct rapl_package *rapl_find_package_domain_cpuslocked(int id, struct rapl_if_priv *priv, 245 bool id_is_cpu); 246 struct rapl_package *rapl_add_package_cpuslocked(int id, struct rapl_if_priv *priv, 247 bool id_is_cpu); 248 void rapl_remove_package_cpuslocked(struct rapl_package *rp); 249 250 struct rapl_package *rapl_find_package_domain(int id, struct rapl_if_priv *priv, bool id_is_cpu); 251 struct rapl_package *rapl_add_package(int id, struct rapl_if_priv *priv, bool id_is_cpu); 252 void rapl_remove_package(struct rapl_package *rp); 253 int rapl_default_check_unit(struct rapl_domain *rd); 254 void rapl_default_set_floor_freq(struct rapl_domain *rd, bool mode); 255 u64 rapl_default_compute_time_window(struct rapl_domain *rd, u64 value, bool to_raw); 256 257 #ifdef CONFIG_PERF_EVENTS 258 int rapl_package_add_pmu(struct rapl_package *rp); 259 int rapl_package_add_pmu_locked(struct rapl_package *rp); 260 void rapl_package_remove_pmu(struct rapl_package *rp); 261 void rapl_package_remove_pmu_locked(struct rapl_package *rp); 262 #else 263 static inline int rapl_package_add_pmu(struct rapl_package *rp) { return 0; } 264 static inline int rapl_package_add_pmu_locked(struct rapl_package *rp) { return 0; } 265 static inline void rapl_package_remove_pmu(struct rapl_package *rp) { } 266 static inline void rapl_package_remove_pmu_locked(struct rapl_package *rp) { } 267 #endif 268 269 #endif /* __INTEL_RAPL_H__ */ 270