@@ -32,6 +32,7 @@
#include <asm/processor.h>
#include <asm/cpu_device_id.h>
+#include <asm/iosf_mbi.h>
/* bitmasks for RAPL MSRs, used by primitive access functions */
#define ENERGY_STATUS_MASK 0xffffffff
@@ -336,11 +337,17 @@ static int find_nr_power_limit(struct rapl_domain *rd)
return i;
}
+#define VLV_CPU_POWER_BUDGET_CTL (0x2)
+static const struct x86_cpu_id valleyview_id[] = {
+ { X86_VENDOR_INTEL, 6, 0x37},
+ {}
+};
+
static int set_domain_enable(struct powercap_zone *power_zone, bool mode)
{
struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone);
int nr_powerlimit;
-
+ u32 mdata = 0;
if (rd->state & DOMAIN_STATE_BIOS_LOCKED)
return -EACCES;
get_online_cpus();
@@ -350,7 +357,16 @@ static int set_domain_enable(struct powercap_zone *power_zone, bool mode)
/* always enable clamp such that p-state can go below OS requested
* range. power capping priority over guranteed frequency.
*/
- rapl_write_data_raw(rd, PL1_CLAMP, mode);
+ if (x86_match_cpu(valleyview_id)) {
+ iosf_mbi_read(BT_MBI_UNIT_PMC, BT_MBI_PMC_READ,
+ VLV_CPU_POWER_BUDGET_CTL, &mdata);
+ mdata &= ~(0x7f << 8);
+ mdata |= 1 << 8;
+ iosf_mbi_write(BT_MBI_UNIT_PMC, BT_MBI_PMC_WRITE,
+ VLV_CPU_POWER_BUDGET_CTL, mdata);
+ } else
+ rapl_write_data_raw(rd, PL1_CLAMP, mode);
+
/* some domains have pl2 */
if (nr_powerlimit > 1) {
rapl_write_data_raw(rd, PL2_ENABLE, mode);
@@ -833,11 +849,6 @@ static int rapl_write_data_raw(struct rapl_domain *rd,
return 0;
}
-static const struct x86_cpu_id energy_unit_quirk_ids[] = {
- { X86_VENDOR_INTEL, 6, 0x37},/* Valleyview */
- {}
-};
-
static int rapl_check_unit(struct rapl_package *rp, int cpu)
{
u64 msr_val;
@@ -859,7 +870,7 @@ static int rapl_check_unit(struct rapl_package *rp, int cpu)
*/
value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET;
/* some CPUs have different way to calculate energy unit */
- if (x86_match_cpu(energy_unit_quirk_ids))
+ if (x86_match_cpu(valleyview_id))
rp->energy_unit_divisor = 1000000 / (1 << value);
else
rp->energy_unit_divisor = 1 << value;