|
@@ -37,6 +37,7 @@
|
|
#define BYT_RATIOS 0x66a
|
|
#define BYT_RATIOS 0x66a
|
|
#define BYT_VIDS 0x66b
|
|
#define BYT_VIDS 0x66b
|
|
#define BYT_TURBO_RATIOS 0x66c
|
|
#define BYT_TURBO_RATIOS 0x66c
|
|
|
|
+#define BYT_TURBO_VIDS 0x66d
|
|
|
|
|
|
|
|
|
|
#define FRAC_BITS 6
|
|
#define FRAC_BITS 6
|
|
@@ -70,8 +71,9 @@ struct pstate_data {
|
|
};
|
|
};
|
|
|
|
|
|
struct vid_data {
|
|
struct vid_data {
|
|
- int32_t min;
|
|
|
|
- int32_t max;
|
|
|
|
|
|
+ int min;
|
|
|
|
+ int max;
|
|
|
|
+ int turbo;
|
|
int32_t ratio;
|
|
int32_t ratio;
|
|
};
|
|
};
|
|
|
|
|
|
@@ -359,14 +361,14 @@ static int byt_get_min_pstate(void)
|
|
{
|
|
{
|
|
u64 value;
|
|
u64 value;
|
|
rdmsrl(BYT_RATIOS, value);
|
|
rdmsrl(BYT_RATIOS, value);
|
|
- return (value >> 8) & 0xFF;
|
|
|
|
|
|
+ return (value >> 8) & 0x3F;
|
|
}
|
|
}
|
|
|
|
|
|
static int byt_get_max_pstate(void)
|
|
static int byt_get_max_pstate(void)
|
|
{
|
|
{
|
|
u64 value;
|
|
u64 value;
|
|
rdmsrl(BYT_RATIOS, value);
|
|
rdmsrl(BYT_RATIOS, value);
|
|
- return (value >> 16) & 0xFF;
|
|
|
|
|
|
+ return (value >> 16) & 0x3F;
|
|
}
|
|
}
|
|
|
|
|
|
static int byt_get_turbo_pstate(void)
|
|
static int byt_get_turbo_pstate(void)
|
|
@@ -393,6 +395,9 @@ static void byt_set_pstate(struct cpudata *cpudata, int pstate)
|
|
vid_fp = clamp_t(int32_t, vid_fp, cpudata->vid.min, cpudata->vid.max);
|
|
vid_fp = clamp_t(int32_t, vid_fp, cpudata->vid.min, cpudata->vid.max);
|
|
vid = fp_toint(vid_fp);
|
|
vid = fp_toint(vid_fp);
|
|
|
|
|
|
|
|
+ if (pstate > cpudata->pstate.max_pstate)
|
|
|
|
+ vid = cpudata->vid.turbo;
|
|
|
|
+
|
|
val |= vid;
|
|
val |= vid;
|
|
|
|
|
|
wrmsrl(MSR_IA32_PERF_CTL, val);
|
|
wrmsrl(MSR_IA32_PERF_CTL, val);
|
|
@@ -402,13 +407,17 @@ static void byt_get_vid(struct cpudata *cpudata)
|
|
{
|
|
{
|
|
u64 value;
|
|
u64 value;
|
|
|
|
|
|
|
|
+
|
|
rdmsrl(BYT_VIDS, value);
|
|
rdmsrl(BYT_VIDS, value);
|
|
- cpudata->vid.min = int_tofp((value >> 8) & 0x7f);
|
|
|
|
- cpudata->vid.max = int_tofp((value >> 16) & 0x7f);
|
|
|
|
|
|
+ cpudata->vid.min = int_tofp((value >> 8) & 0x3f);
|
|
|
|
+ cpudata->vid.max = int_tofp((value >> 16) & 0x3f);
|
|
cpudata->vid.ratio = div_fp(
|
|
cpudata->vid.ratio = div_fp(
|
|
cpudata->vid.max - cpudata->vid.min,
|
|
cpudata->vid.max - cpudata->vid.min,
|
|
int_tofp(cpudata->pstate.max_pstate -
|
|
int_tofp(cpudata->pstate.max_pstate -
|
|
cpudata->pstate.min_pstate));
|
|
cpudata->pstate.min_pstate));
|
|
|
|
+
|
|
|
|
+ rdmsrl(BYT_TURBO_VIDS, value);
|
|
|
|
+ cpudata->vid.turbo = value & 0x7f;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -545,12 +554,7 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
|
|
|
|
|
|
if (pstate_funcs.get_vid)
|
|
if (pstate_funcs.get_vid)
|
|
pstate_funcs.get_vid(cpu);
|
|
pstate_funcs.get_vid(cpu);
|
|
-
|
|
|
|
- /*
|
|
|
|
- * goto max pstate so we don't slow up boot if we are built-in if we are
|
|
|
|
- * a module we will take care of it during normal operation
|
|
|
|
- */
|
|
|
|
- intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate);
|
|
|
|
|
|
+ intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);
|
|
}
|
|
}
|
|
|
|
|
|
static inline void intel_pstate_calc_busy(struct cpudata *cpu,
|
|
static inline void intel_pstate_calc_busy(struct cpudata *cpu,
|
|
@@ -695,11 +699,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
|
|
cpu = all_cpu_data[cpunum];
|
|
cpu = all_cpu_data[cpunum];
|
|
|
|
|
|
intel_pstate_get_cpu_pstates(cpu);
|
|
intel_pstate_get_cpu_pstates(cpu);
|
|
- if (!cpu->pstate.current_pstate) {
|
|
|
|
- all_cpu_data[cpunum] = NULL;
|
|
|
|
- kfree(cpu);
|
|
|
|
- return -ENODATA;
|
|
|
|
- }
|
|
|
|
|
|
|
|
cpu->cpu = cpunum;
|
|
cpu->cpu = cpunum;
|
|
|
|
|
|
@@ -710,7 +709,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
|
|
cpu->timer.expires = jiffies + HZ/100;
|
|
cpu->timer.expires = jiffies + HZ/100;
|
|
intel_pstate_busy_pid_reset(cpu);
|
|
intel_pstate_busy_pid_reset(cpu);
|
|
intel_pstate_sample(cpu);
|
|
intel_pstate_sample(cpu);
|
|
- intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate);
|
|
|
|
|
|
|
|
add_timer_on(&cpu->timer, cpunum);
|
|
add_timer_on(&cpu->timer, cpunum);
|
|
|
|
|