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 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 89 #define NR_POWER_LIMITS (POWER_LIMIT4 + 1) 90 91 struct rapl_power_limit { 92 struct powercap_zone_constraint *constraint; 93 struct rapl_domain *domain; 94 const char *name; 95 bool locked; 96 u64 last_power_limit; 97 }; 98 99 struct rapl_package; 100 101 #define RAPL_DOMAIN_NAME_LENGTH 16 102 103 union rapl_reg { 104 void __iomem *mmio; 105 u32 msr; 106 u64 val; 107 }; 108 109 struct rapl_domain { 110 char name[RAPL_DOMAIN_NAME_LENGTH]; 111 enum rapl_domain_type id; 112 union rapl_reg regs[RAPL_DOMAIN_REG_MAX]; 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; 118 unsigned int power_unit; 119 unsigned int energy_unit; 120 unsigned int time_unit; 121 struct rapl_package *rp; 122 }; 123 124 struct reg_action { 125 union rapl_reg reg; 126 u64 mask; 127 u64 value; 128 int err; 129 }; 130 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. 138 * @reg_unit: Register for getting energy/power/time unit. 139 * @regs: Register sets for different RAPL Domains. 140 * @limits: Number of power limits supported by each domain. 141 * @read_raw: Callback for reading RAPL interface specific 142 * registers. 143 * @write_raw: Callback for writing RAPL interface specific 144 * registers. 145 * @defaults: internal pointer to interface default settings 146 * @rpi: internal pointer to interface primitive info 147 */ 148 struct rapl_if_priv { 149 enum rapl_if_type type; 150 struct powercap_control_type *control_type; 151 enum cpuhp_state pcap_rapl_online; 152 union rapl_reg reg_unit; 153 union rapl_reg regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX]; 154 int limits[RAPL_DOMAIN_MAX]; 155 int (*read_raw)(int id, struct reg_action *ra); 156 int (*write_raw)(int id, struct reg_action *ra); 157 void *defaults; 158 void *rpi; 159 }; 160 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 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 */ 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]; 198 struct rapl_if_priv *priv; 199 #ifdef CONFIG_PERF_EVENTS 200 bool has_pmu; 201 struct rapl_package_pmu_data pmu_data; 202 #endif 203 }; 204 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 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); 213 void rapl_remove_package(struct rapl_package *rp); 214 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 223 #endif /* __INTEL_RAPL_H__ */ 224
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.