Commit 0c2ddedd authored by Zhang Rui's avatar Zhang Rui Committed by Rafael J. Wysocki

intel_rapl: support two power limits for every RAPL domain

RAPL MSR interface supports 2 power limits for package domain, and 1 power
limit for other domains, while RAPL MMIO interface supports 2 power limits
for both package and dram domains.
And when 2 power limits are supported, the FW_LOCK bit is in bit 63 of the
register, instead of bit 31.

Remove the assumption that only pakcage domain supports 2 power limits.
And allow the RAPL interface driver to specify the number of power limits
supported, for every single RAPL domain it owns..
Reviewed-by: default avatarPandruvada, Srinivas <srinivas.pandruvada@intel.com>
Tested-by: default avatarPandruvada, Srinivas <srinivas.pandruvada@intel.com>
Signed-off-by: default avatarZhang Rui <rui.zhang@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent d978e755
...@@ -38,8 +38,8 @@ ...@@ -38,8 +38,8 @@
#define POWER_LIMIT2_MASK (0x7FFFULL<<32) #define POWER_LIMIT2_MASK (0x7FFFULL<<32)
#define POWER_LIMIT2_ENABLE BIT_ULL(47) #define POWER_LIMIT2_ENABLE BIT_ULL(47)
#define POWER_LIMIT2_CLAMP BIT_ULL(48) #define POWER_LIMIT2_CLAMP BIT_ULL(48)
#define POWER_PACKAGE_LOCK BIT_ULL(63) #define POWER_HIGH_LOCK BIT_ULL(63)
#define POWER_PP_LOCK BIT(31) #define POWER_LOW_LOCK BIT(31)
#define TIME_WINDOW1_MASK (0x7FULL<<17) #define TIME_WINDOW1_MASK (0x7FULL<<17)
#define TIME_WINDOW2_MASK (0x7FULL<<49) #define TIME_WINDOW2_MASK (0x7FULL<<49)
...@@ -513,60 +513,38 @@ static const struct powercap_zone_constraint_ops constraint_ops = { ...@@ -513,60 +513,38 @@ static const struct powercap_zone_constraint_ops constraint_ops = {
/* called after domain detection and package level data are set */ /* called after domain detection and package level data are set */
static void rapl_init_domains(struct rapl_package *rp) static void rapl_init_domains(struct rapl_package *rp)
{ {
int i; enum rapl_domain_type i;
enum rapl_domain_reg_id j;
struct rapl_domain *rd = rp->domains; struct rapl_domain *rd = rp->domains;
for (i = 0; i < RAPL_DOMAIN_MAX; i++) { for (i = 0; i < RAPL_DOMAIN_MAX; i++) {
unsigned int mask = rp->domain_map & (1 << i); unsigned int mask = rp->domain_map & (1 << i);
rd->regs[RAPL_DOMAIN_REG_LIMIT] = if (!mask)
rp->priv->regs[i][RAPL_DOMAIN_REG_LIMIT]; continue;
rd->regs[RAPL_DOMAIN_REG_STATUS] =
rp->priv->regs[i][RAPL_DOMAIN_REG_STATUS]; rd->rp = rp;
rd->regs[RAPL_DOMAIN_REG_PERF] = rd->name = rapl_domain_names[i];
rp->priv->regs[i][RAPL_DOMAIN_REG_PERF]; rd->id = i;
rd->regs[RAPL_DOMAIN_REG_POLICY] = rd->rpl[0].prim_id = PL1_ENABLE;
rp->priv->regs[i][RAPL_DOMAIN_REG_POLICY]; rd->rpl[0].name = pl1_name;
rd->regs[RAPL_DOMAIN_REG_INFO] = /* some domain may support two power limits */
rp->priv->regs[i][RAPL_DOMAIN_REG_INFO]; if (rp->priv->limits[i] == 2) {
switch (mask) {
case BIT(RAPL_DOMAIN_PACKAGE):
rd->name = rapl_domain_names[RAPL_DOMAIN_PACKAGE];
rd->id = RAPL_DOMAIN_PACKAGE;
rd->rpl[0].prim_id = PL1_ENABLE;
rd->rpl[0].name = pl1_name;
rd->rpl[1].prim_id = PL2_ENABLE; rd->rpl[1].prim_id = PL2_ENABLE;
rd->rpl[1].name = pl2_name; rd->rpl[1].name = pl2_name;
break; }
case BIT(RAPL_DOMAIN_PP0):
rd->name = rapl_domain_names[RAPL_DOMAIN_PP0]; for (j = 0; j < RAPL_DOMAIN_REG_MAX; j++)
rd->id = RAPL_DOMAIN_PP0; rd->regs[j] = rp->priv->regs[i][j];
rd->rpl[0].prim_id = PL1_ENABLE;
rd->rpl[0].name = pl1_name; if (i == RAPL_DOMAIN_DRAM) {
break;
case BIT(RAPL_DOMAIN_PP1):
rd->name = rapl_domain_names[RAPL_DOMAIN_PP1];
rd->id = RAPL_DOMAIN_PP1;
rd->rpl[0].prim_id = PL1_ENABLE;
rd->rpl[0].name = pl1_name;
break;
case BIT(RAPL_DOMAIN_DRAM):
rd->name = rapl_domain_names[RAPL_DOMAIN_DRAM];
rd->id = RAPL_DOMAIN_DRAM;
rd->rpl[0].prim_id = PL1_ENABLE;
rd->rpl[0].name = pl1_name;
rd->domain_energy_unit = rd->domain_energy_unit =
rapl_defaults->dram_domain_energy_unit; rapl_defaults->dram_domain_energy_unit;
if (rd->domain_energy_unit) if (rd->domain_energy_unit)
pr_info("DRAM domain energy unit %dpj\n", pr_info("DRAM domain energy unit %dpj\n",
rd->domain_energy_unit); rd->domain_energy_unit);
break;
}
if (mask) {
rd->rp = rp;
rd++;
} }
rd++;
} }
} }
...@@ -613,7 +591,7 @@ static struct rapl_primitive_info rpi[] = { ...@@ -613,7 +591,7 @@ static struct rapl_primitive_info rpi[] = {
RAPL_DOMAIN_REG_LIMIT, POWER_UNIT, 0), RAPL_DOMAIN_REG_LIMIT, POWER_UNIT, 0),
PRIMITIVE_INFO_INIT(POWER_LIMIT2, POWER_LIMIT2_MASK, 32, PRIMITIVE_INFO_INIT(POWER_LIMIT2, POWER_LIMIT2_MASK, 32,
RAPL_DOMAIN_REG_LIMIT, POWER_UNIT, 0), RAPL_DOMAIN_REG_LIMIT, POWER_UNIT, 0),
PRIMITIVE_INFO_INIT(FW_LOCK, POWER_PP_LOCK, 31, PRIMITIVE_INFO_INIT(FW_LOCK, POWER_LOW_LOCK, 31,
RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0), RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0),
PRIMITIVE_INFO_INIT(PL1_ENABLE, POWER_LIMIT1_ENABLE, 15, PRIMITIVE_INFO_INIT(PL1_ENABLE, POWER_LIMIT1_ENABLE, 15,
RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0), RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0),
...@@ -675,9 +653,9 @@ static int rapl_read_data_raw(struct rapl_domain *rd, ...@@ -675,9 +653,9 @@ static int rapl_read_data_raw(struct rapl_domain *rd,
cpu = rd->rp->lead_cpu; cpu = rd->rp->lead_cpu;
/* special-case package domain, which uses a different bit */ /* domain with 2 limits has different bit */
if (prim == FW_LOCK && rd->id == RAPL_DOMAIN_PACKAGE) { if (prim == FW_LOCK && rd->rp->priv->limits[rd->id] == 2) {
rp->mask = POWER_PACKAGE_LOCK; rp->mask = POWER_HIGH_LOCK;
rp->shift = 63; rp->shift = 63;
} }
/* non-hardware data are collected by the polling thread */ /* non-hardware data are collected by the polling thread */
......
...@@ -41,6 +41,7 @@ static struct rapl_if_priv rapl_msr_priv = { ...@@ -41,6 +41,7 @@ static struct rapl_if_priv rapl_msr_priv = {
MSR_DRAM_POWER_LIMIT, MSR_DRAM_ENERGY_STATUS, MSR_DRAM_PERF_STATUS, 0, MSR_DRAM_POWER_INFO }, MSR_DRAM_POWER_LIMIT, MSR_DRAM_ENERGY_STATUS, MSR_DRAM_PERF_STATUS, 0, MSR_DRAM_POWER_INFO },
.regs[RAPL_DOMAIN_PLATFORM] = { .regs[RAPL_DOMAIN_PLATFORM] = {
MSR_PLATFORM_POWER_LIMIT, MSR_PLATFORM_ENERGY_STATUS, 0, 0, 0}, MSR_PLATFORM_POWER_LIMIT, MSR_PLATFORM_ENERGY_STATUS, 0, 0, 0},
.limits[RAPL_DOMAIN_PACKAGE] = 2,
}; };
/* Handles CPU hotplug on multi-socket systems. /* Handles CPU hotplug on multi-socket systems.
......
...@@ -104,6 +104,7 @@ struct reg_action { ...@@ -104,6 +104,7 @@ struct reg_action {
* @pcap_rapl_online: CPU hotplug state for each RAPL interface. * @pcap_rapl_online: CPU hotplug state for each RAPL interface.
* @reg_unit: Register for getting energy/power/time unit. * @reg_unit: Register for getting energy/power/time unit.
* @regs: Register sets for different RAPL Domains. * @regs: Register sets for different RAPL Domains.
* @limits: Number of power limits supported by each domain.
* @read_raw: Callback for reading RAPL interface specific * @read_raw: Callback for reading RAPL interface specific
* registers. * registers.
* @write_raw: Callback for writing RAPL interface specific * @write_raw: Callback for writing RAPL interface specific
...@@ -115,6 +116,7 @@ struct rapl_if_priv { ...@@ -115,6 +116,7 @@ struct rapl_if_priv {
enum cpuhp_state pcap_rapl_online; enum cpuhp_state pcap_rapl_online;
u64 reg_unit; u64 reg_unit;
u64 regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX]; u64 regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX];
int limits[RAPL_DOMAIN_MAX];
int (*read_raw)(int cpu, struct reg_action *ra); int (*read_raw)(int cpu, struct reg_action *ra);
int (*write_raw)(int cpu, struct reg_action *ra); int (*write_raw)(int cpu, struct reg_action *ra);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment