mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 12:31:52 -04:00
powercap: intel_rapl: Allow interface drivers to configure rapl_defaults
RAPL default settings vary across different RAPL interfaces (MSR, TPMI,
MMIO). Currently, these defaults are stored in the common RAPL driver,
which requires interface-specific handling logic and makes the common
layer unnecessarily complex. There is no strong reason for the common
code to own these defaults, since they are inherently
interface-specific.
To prepare for moving default configuration into the individual
interface drivers,
1. Move struct rapl_defaults into a shared header so that interface
drivers can directly populate their own default settings.
2. Change the @defaults field in struct rapl_if_priv from void * to
const struct rapl_defaults * to improve type safety and readability
and update the common driver to use the typed defaults structure.
3. Update all internal getter functions and local pointers to use
const struct rapl_defaults * to maintain const-correctness.
4. Rename and export the common helper functions (check_unit,
set_floor_freq, compute_time_window) so interface drivers may
reuse or override them as appropriate.
No functional changes. This is a preparatory refactoring to allow
interface drivers to supply their own RAPL default settings.
Co-developed-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://patch.msgid.link/20260212233044.329790-9-sathyanarayanan.kuppuswamy@linux.intel.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
committed by
Rafael J. Wysocki
parent
90503f9ffe
commit
d7ca7d1488
@@ -221,20 +221,10 @@ static int get_pl_prim(struct rapl_domain *rd, int pl, enum pl_prims prim)
|
||||
#define power_zone_to_rapl_domain(_zone) \
|
||||
container_of(_zone, struct rapl_domain, power_zone)
|
||||
|
||||
struct rapl_defaults {
|
||||
u8 floor_freq_reg_addr;
|
||||
int (*check_unit)(struct rapl_domain *rd);
|
||||
void (*set_floor_freq)(struct rapl_domain *rd, bool mode);
|
||||
u64 (*compute_time_window)(struct rapl_domain *rd, u64 val,
|
||||
bool to_raw);
|
||||
unsigned int dram_domain_energy_unit;
|
||||
unsigned int psys_domain_energy_unit;
|
||||
bool spr_psys_bits;
|
||||
};
|
||||
static struct rapl_defaults *defaults_msr;
|
||||
static const struct rapl_defaults *defaults_msr;
|
||||
static const struct rapl_defaults defaults_tpmi;
|
||||
|
||||
static struct rapl_defaults *get_defaults(struct rapl_package *rp)
|
||||
static const struct rapl_defaults *get_defaults(struct rapl_package *rp)
|
||||
{
|
||||
return rp->priv->defaults;
|
||||
}
|
||||
@@ -351,7 +341,7 @@ static int find_nr_power_limit(struct rapl_domain *rd)
|
||||
static int set_domain_enable(struct powercap_zone *power_zone, bool mode)
|
||||
{
|
||||
struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone);
|
||||
struct rapl_defaults *defaults = get_defaults(rd->rp);
|
||||
const struct rapl_defaults *defaults = get_defaults(rd->rp);
|
||||
u64 val;
|
||||
int ret;
|
||||
|
||||
@@ -640,7 +630,7 @@ static u64 rapl_unit_xlate(struct rapl_domain *rd, enum unit_type type,
|
||||
u64 value, int to_raw)
|
||||
{
|
||||
u64 units = 1;
|
||||
struct rapl_defaults *defaults = get_defaults(rd->rp);
|
||||
const struct rapl_defaults *defaults = get_defaults(rd->rp);
|
||||
u64 scale = 1;
|
||||
|
||||
switch (type) {
|
||||
@@ -785,11 +775,11 @@ static int rapl_config(struct rapl_package *rp)
|
||||
/* MMIO I/F shares the same register layout as MSR registers */
|
||||
case RAPL_IF_MMIO:
|
||||
case RAPL_IF_MSR:
|
||||
rp->priv->defaults = (void *)defaults_msr;
|
||||
rp->priv->defaults = defaults_msr;
|
||||
rp->priv->rpi = (void *)rpi_msr;
|
||||
break;
|
||||
case RAPL_IF_TPMI:
|
||||
rp->priv->defaults = (void *)&defaults_tpmi;
|
||||
rp->priv->defaults = &defaults_tpmi;
|
||||
rp->priv->rpi = (void *)rpi_tpmi;
|
||||
break;
|
||||
default:
|
||||
@@ -806,7 +796,7 @@ static int rapl_config(struct rapl_package *rp)
|
||||
static enum rapl_primitives
|
||||
prim_fixups(struct rapl_domain *rd, enum rapl_primitives prim)
|
||||
{
|
||||
struct rapl_defaults *defaults = get_defaults(rd->rp);
|
||||
const struct rapl_defaults *defaults = get_defaults(rd->rp);
|
||||
|
||||
if (!defaults->spr_psys_bits)
|
||||
return prim;
|
||||
@@ -951,7 +941,7 @@ static int rapl_write_pl_data(struct rapl_domain *rd, int pl,
|
||||
* power unit : microWatts : Represented in milliWatts by default
|
||||
* time unit : microseconds: Represented in seconds by default
|
||||
*/
|
||||
static int rapl_check_unit_core(struct rapl_domain *rd)
|
||||
int rapl_default_check_unit(struct rapl_domain *rd)
|
||||
{
|
||||
struct reg_action ra;
|
||||
u32 value;
|
||||
@@ -978,6 +968,7 @@ static int rapl_check_unit_core(struct rapl_domain *rd)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(rapl_default_check_unit, "INTEL_RAPL");
|
||||
|
||||
static int rapl_check_unit_atom(struct rapl_domain *rd)
|
||||
{
|
||||
@@ -1071,7 +1062,7 @@ static void package_power_limit_irq_restore(struct rapl_package *rp)
|
||||
wrmsr_safe(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
|
||||
}
|
||||
|
||||
static void set_floor_freq_default(struct rapl_domain *rd, bool mode)
|
||||
void rapl_default_set_floor_freq(struct rapl_domain *rd, bool mode)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1085,11 +1076,12 @@ static void set_floor_freq_default(struct rapl_domain *rd, bool mode)
|
||||
rapl_write_pl_data(rd, i, PL_CLAMP, mode);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(rapl_default_set_floor_freq, "INTEL_RAPL");
|
||||
|
||||
static void set_floor_freq_atom(struct rapl_domain *rd, bool enable)
|
||||
{
|
||||
static u32 power_ctrl_orig_val;
|
||||
struct rapl_defaults *defaults = get_defaults(rd->rp);
|
||||
const struct rapl_defaults *defaults = get_defaults(rd->rp);
|
||||
u32 mdata;
|
||||
|
||||
if (!defaults->floor_freq_reg_addr) {
|
||||
@@ -1110,8 +1102,7 @@ static void set_floor_freq_atom(struct rapl_domain *rd, bool enable)
|
||||
defaults->floor_freq_reg_addr, mdata);
|
||||
}
|
||||
|
||||
static u64 rapl_compute_time_window_core(struct rapl_domain *rd, u64 value,
|
||||
bool to_raw)
|
||||
u64 rapl_default_compute_time_window(struct rapl_domain *rd, u64 value, bool to_raw)
|
||||
{
|
||||
u64 f, y; /* fraction and exp. used for time unit */
|
||||
|
||||
@@ -1142,6 +1133,7 @@ static u64 rapl_compute_time_window_core(struct rapl_domain *rd, u64 value,
|
||||
}
|
||||
return value;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(rapl_default_compute_time_window, "INTEL_RAPL");
|
||||
|
||||
static u64 rapl_compute_time_window_atom(struct rapl_domain *rd, u64 value,
|
||||
bool to_raw)
|
||||
@@ -1187,28 +1179,28 @@ static int rapl_check_unit_tpmi(struct rapl_domain *rd)
|
||||
static const struct rapl_defaults defaults_tpmi = {
|
||||
.check_unit = rapl_check_unit_tpmi,
|
||||
/* Reuse existing logic, ignore the PL_CLAMP failures and enable all Power Limits */
|
||||
.set_floor_freq = set_floor_freq_default,
|
||||
.compute_time_window = rapl_compute_time_window_core,
|
||||
.set_floor_freq = rapl_default_set_floor_freq,
|
||||
.compute_time_window = rapl_default_compute_time_window,
|
||||
};
|
||||
|
||||
static const struct rapl_defaults rapl_defaults_core = {
|
||||
.floor_freq_reg_addr = 0,
|
||||
.check_unit = rapl_check_unit_core,
|
||||
.set_floor_freq = set_floor_freq_default,
|
||||
.compute_time_window = rapl_compute_time_window_core,
|
||||
.check_unit = rapl_default_check_unit,
|
||||
.set_floor_freq = rapl_default_set_floor_freq,
|
||||
.compute_time_window = rapl_default_compute_time_window,
|
||||
};
|
||||
|
||||
static const struct rapl_defaults rapl_defaults_hsw_server = {
|
||||
.check_unit = rapl_check_unit_core,
|
||||
.set_floor_freq = set_floor_freq_default,
|
||||
.compute_time_window = rapl_compute_time_window_core,
|
||||
.check_unit = rapl_default_check_unit,
|
||||
.set_floor_freq = rapl_default_set_floor_freq,
|
||||
.compute_time_window = rapl_default_compute_time_window,
|
||||
.dram_domain_energy_unit = 15300,
|
||||
};
|
||||
|
||||
static const struct rapl_defaults rapl_defaults_spr_server = {
|
||||
.check_unit = rapl_check_unit_core,
|
||||
.set_floor_freq = set_floor_freq_default,
|
||||
.compute_time_window = rapl_compute_time_window_core,
|
||||
.check_unit = rapl_default_check_unit,
|
||||
.set_floor_freq = rapl_default_set_floor_freq,
|
||||
.compute_time_window = rapl_default_compute_time_window,
|
||||
.psys_domain_energy_unit = NANOJOULE_PER_JOULE,
|
||||
.spr_psys_bits = true,
|
||||
};
|
||||
@@ -1242,7 +1234,7 @@ static const struct rapl_defaults rapl_defaults_cht = {
|
||||
};
|
||||
|
||||
static const struct rapl_defaults rapl_defaults_amd = {
|
||||
.check_unit = rapl_check_unit_core,
|
||||
.check_unit = rapl_default_check_unit,
|
||||
};
|
||||
|
||||
static const struct x86_cpu_id rapl_ids[] __initconst = {
|
||||
@@ -1448,7 +1440,7 @@ static int rapl_check_domain(int domain, struct rapl_package *rp)
|
||||
*/
|
||||
static int rapl_get_domain_unit(struct rapl_domain *rd)
|
||||
{
|
||||
struct rapl_defaults *defaults = get_defaults(rd->rp);
|
||||
const struct rapl_defaults *defaults = get_defaults(rd->rp);
|
||||
int ret;
|
||||
|
||||
if (!rd->regs[RAPL_DOMAIN_REG_UNIT].val) {
|
||||
@@ -2341,7 +2333,7 @@ static int __init rapl_init(void)
|
||||
|
||||
id = x86_match_cpu(rapl_ids);
|
||||
if (id) {
|
||||
defaults_msr = (struct rapl_defaults *)id->driver_data;
|
||||
defaults_msr = (const struct rapl_defaults *)id->driver_data;
|
||||
|
||||
rapl_msr_platdev = platform_device_alloc("intel_rapl_msr", 0);
|
||||
if (!rapl_msr_platdev)
|
||||
|
||||
@@ -128,6 +128,16 @@ struct reg_action {
|
||||
int err;
|
||||
};
|
||||
|
||||
struct rapl_defaults {
|
||||
u8 floor_freq_reg_addr;
|
||||
int (*check_unit)(struct rapl_domain *rd);
|
||||
void (*set_floor_freq)(struct rapl_domain *rd, bool mode);
|
||||
u64 (*compute_time_window)(struct rapl_domain *rd, u64 val, bool to_raw);
|
||||
unsigned int dram_domain_energy_unit;
|
||||
unsigned int psys_domain_energy_unit;
|
||||
bool spr_psys_bits;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct rapl_if_priv: private data for different RAPL interfaces
|
||||
* @control_type: Each RAPL interface must have its own powercap
|
||||
@@ -142,7 +152,7 @@ struct reg_action {
|
||||
* registers.
|
||||
* @write_raw: Callback for writing RAPL interface specific
|
||||
* registers.
|
||||
* @defaults: internal pointer to interface default settings
|
||||
* @defaults: pointer to default settings
|
||||
* @rpi: internal pointer to interface primitive info
|
||||
*/
|
||||
struct rapl_if_priv {
|
||||
@@ -154,7 +164,7 @@ struct rapl_if_priv {
|
||||
int limits[RAPL_DOMAIN_MAX];
|
||||
int (*read_raw)(int id, struct reg_action *ra, bool pmu_ctx);
|
||||
int (*write_raw)(int id, struct reg_action *ra);
|
||||
void *defaults;
|
||||
const struct rapl_defaults *defaults;
|
||||
void *rpi;
|
||||
};
|
||||
|
||||
@@ -211,6 +221,9 @@ void rapl_remove_package_cpuslocked(struct rapl_package *rp);
|
||||
struct rapl_package *rapl_find_package_domain(int id, struct rapl_if_priv *priv, bool id_is_cpu);
|
||||
struct rapl_package *rapl_add_package(int id, struct rapl_if_priv *priv, bool id_is_cpu);
|
||||
void rapl_remove_package(struct rapl_package *rp);
|
||||
int rapl_default_check_unit(struct rapl_domain *rd);
|
||||
void rapl_default_set_floor_freq(struct rapl_domain *rd, bool mode);
|
||||
u64 rapl_default_compute_time_window(struct rapl_domain *rd, u64 value, bool to_raw);
|
||||
|
||||
#ifdef CONFIG_PERF_EVENTS
|
||||
int rapl_package_add_pmu(struct rapl_package *rp);
|
||||
|
||||
Reference in New Issue
Block a user