Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[linux-block.git] / include / linux / intel_rapl.h
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__ */