Merge back earlier 'pm-cpufreq' material.
This commit is contained in:
commit
72e2adcdcb
|
@ -181,7 +181,8 @@ config CPU_FREQ_GOV_CONSERVATIVE
|
||||||
|
|
||||||
config GENERIC_CPUFREQ_CPU0
|
config GENERIC_CPUFREQ_CPU0
|
||||||
tristate "Generic CPU0 cpufreq driver"
|
tristate "Generic CPU0 cpufreq driver"
|
||||||
depends on HAVE_CLK && REGULATOR && PM_OPP && OF
|
depends on HAVE_CLK && REGULATOR && OF
|
||||||
|
select PM_OPP
|
||||||
help
|
help
|
||||||
This adds a generic cpufreq driver for CPU0 frequency management.
|
This adds a generic cpufreq driver for CPU0 frequency management.
|
||||||
It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
|
It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
config ARM_BIG_LITTLE_CPUFREQ
|
config ARM_BIG_LITTLE_CPUFREQ
|
||||||
tristate "Generic ARM big LITTLE CPUfreq driver"
|
tristate "Generic ARM big LITTLE CPUfreq driver"
|
||||||
depends on ARM_CPU_TOPOLOGY && PM_OPP && HAVE_CLK
|
depends on ARM && ARM_CPU_TOPOLOGY && HAVE_CLK
|
||||||
|
select PM_OPP
|
||||||
help
|
help
|
||||||
This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
|
This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
|
||||||
|
|
||||||
|
@ -54,7 +55,8 @@ config ARM_EXYNOS5250_CPUFREQ
|
||||||
config ARM_EXYNOS5440_CPUFREQ
|
config ARM_EXYNOS5440_CPUFREQ
|
||||||
bool "SAMSUNG EXYNOS5440"
|
bool "SAMSUNG EXYNOS5440"
|
||||||
depends on SOC_EXYNOS5440
|
depends on SOC_EXYNOS5440
|
||||||
depends on HAVE_CLK && PM_OPP && OF
|
depends on HAVE_CLK && OF
|
||||||
|
select PM_OPP
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
This adds the CPUFreq driver for Samsung EXYNOS5440
|
This adds the CPUFreq driver for Samsung EXYNOS5440
|
||||||
|
|
|
@ -44,7 +44,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000);
|
freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000);
|
||||||
if (freq_Hz < 0)
|
if (freq_Hz <= 0)
|
||||||
freq_Hz = freq_table[index].frequency * 1000;
|
freq_Hz = freq_table[index].frequency * 1000;
|
||||||
|
|
||||||
freq_exact = freq_Hz;
|
freq_exact = freq_Hz;
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#define SAMPLE_COUNT 3
|
#define SAMPLE_COUNT 3
|
||||||
|
|
||||||
#define BYT_RATIOS 0x66a
|
#define BYT_RATIOS 0x66a
|
||||||
|
#define BYT_VIDS 0x66b
|
||||||
|
|
||||||
#define FRAC_BITS 8
|
#define FRAC_BITS 8
|
||||||
#define int_tofp(X) ((int64_t)(X) << FRAC_BITS)
|
#define int_tofp(X) ((int64_t)(X) << FRAC_BITS)
|
||||||
|
@ -64,6 +65,12 @@ struct pstate_data {
|
||||||
int turbo_pstate;
|
int turbo_pstate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct vid_data {
|
||||||
|
int32_t min;
|
||||||
|
int32_t max;
|
||||||
|
int32_t ratio;
|
||||||
|
};
|
||||||
|
|
||||||
struct _pid {
|
struct _pid {
|
||||||
int setpoint;
|
int setpoint;
|
||||||
int32_t integral;
|
int32_t integral;
|
||||||
|
@ -82,10 +89,9 @@ struct cpudata {
|
||||||
struct timer_list timer;
|
struct timer_list timer;
|
||||||
|
|
||||||
struct pstate_data pstate;
|
struct pstate_data pstate;
|
||||||
|
struct vid_data vid;
|
||||||
struct _pid pid;
|
struct _pid pid;
|
||||||
|
|
||||||
int min_pstate_count;
|
|
||||||
|
|
||||||
u64 prev_aperf;
|
u64 prev_aperf;
|
||||||
u64 prev_mperf;
|
u64 prev_mperf;
|
||||||
int sample_ptr;
|
int sample_ptr;
|
||||||
|
@ -106,7 +112,8 @@ struct pstate_funcs {
|
||||||
int (*get_max)(void);
|
int (*get_max)(void);
|
||||||
int (*get_min)(void);
|
int (*get_min)(void);
|
||||||
int (*get_turbo)(void);
|
int (*get_turbo)(void);
|
||||||
void (*set)(int pstate);
|
void (*set)(struct cpudata*, int pstate);
|
||||||
|
void (*get_vid)(struct cpudata *);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cpu_defaults {
|
struct cpu_defaults {
|
||||||
|
@ -358,6 +365,42 @@ static int byt_get_max_pstate(void)
|
||||||
return (value >> 16) & 0xFF;
|
return (value >> 16) & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void byt_set_pstate(struct cpudata *cpudata, int pstate)
|
||||||
|
{
|
||||||
|
u64 val;
|
||||||
|
int32_t vid_fp;
|
||||||
|
u32 vid;
|
||||||
|
|
||||||
|
val = pstate << 8;
|
||||||
|
if (limits.no_turbo)
|
||||||
|
val |= (u64)1 << 32;
|
||||||
|
|
||||||
|
vid_fp = cpudata->vid.min + mul_fp(
|
||||||
|
int_tofp(pstate - cpudata->pstate.min_pstate),
|
||||||
|
cpudata->vid.ratio);
|
||||||
|
|
||||||
|
vid_fp = clamp_t(int32_t, vid_fp, cpudata->vid.min, cpudata->vid.max);
|
||||||
|
vid = fp_toint(vid_fp);
|
||||||
|
|
||||||
|
val |= vid;
|
||||||
|
|
||||||
|
wrmsrl(MSR_IA32_PERF_CTL, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void byt_get_vid(struct cpudata *cpudata)
|
||||||
|
{
|
||||||
|
u64 value;
|
||||||
|
|
||||||
|
rdmsrl(BYT_VIDS, value);
|
||||||
|
cpudata->vid.min = int_tofp((value >> 8) & 0x7f);
|
||||||
|
cpudata->vid.max = int_tofp((value >> 16) & 0x7f);
|
||||||
|
cpudata->vid.ratio = div_fp(
|
||||||
|
cpudata->vid.max - cpudata->vid.min,
|
||||||
|
int_tofp(cpudata->pstate.max_pstate -
|
||||||
|
cpudata->pstate.min_pstate));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int core_get_min_pstate(void)
|
static int core_get_min_pstate(void)
|
||||||
{
|
{
|
||||||
u64 value;
|
u64 value;
|
||||||
|
@ -384,7 +427,7 @@ static int core_get_turbo_pstate(void)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void core_set_pstate(int pstate)
|
static void core_set_pstate(struct cpudata *cpudata, int pstate)
|
||||||
{
|
{
|
||||||
u64 val;
|
u64 val;
|
||||||
|
|
||||||
|
@ -425,7 +468,8 @@ static struct cpu_defaults byt_params = {
|
||||||
.get_max = byt_get_max_pstate,
|
.get_max = byt_get_max_pstate,
|
||||||
.get_min = byt_get_min_pstate,
|
.get_min = byt_get_min_pstate,
|
||||||
.get_turbo = byt_get_max_pstate,
|
.get_turbo = byt_get_max_pstate,
|
||||||
.set = core_set_pstate,
|
.set = byt_set_pstate,
|
||||||
|
.get_vid = byt_get_vid,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -462,7 +506,7 @@ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
|
||||||
|
|
||||||
cpu->pstate.current_pstate = pstate;
|
cpu->pstate.current_pstate = pstate;
|
||||||
|
|
||||||
pstate_funcs.set(pstate);
|
pstate_funcs.set(cpu, pstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps)
|
static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps)
|
||||||
|
@ -488,6 +532,9 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
|
||||||
cpu->pstate.max_pstate = pstate_funcs.get_max();
|
cpu->pstate.max_pstate = pstate_funcs.get_max();
|
||||||
cpu->pstate.turbo_pstate = pstate_funcs.get_turbo();
|
cpu->pstate.turbo_pstate = pstate_funcs.get_turbo();
|
||||||
|
|
||||||
|
if (pstate_funcs.get_vid)
|
||||||
|
pstate_funcs.get_vid(cpu);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* goto max pstate so we don't slow up boot if we are built-in if we are
|
* 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
|
* a module we will take care of it during normal operation
|
||||||
|
@ -568,15 +615,6 @@ static void intel_pstate_timer_func(unsigned long __data)
|
||||||
|
|
||||||
intel_pstate_sample(cpu);
|
intel_pstate_sample(cpu);
|
||||||
intel_pstate_adjust_busy_pstate(cpu);
|
intel_pstate_adjust_busy_pstate(cpu);
|
||||||
|
|
||||||
if (cpu->pstate.current_pstate == cpu->pstate.min_pstate) {
|
|
||||||
cpu->min_pstate_count++;
|
|
||||||
if (!(cpu->min_pstate_count % 5)) {
|
|
||||||
intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
cpu->min_pstate_count = 0;
|
|
||||||
|
|
||||||
intel_pstate_set_sample_time(cpu);
|
intel_pstate_set_sample_time(cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,6 +819,7 @@ static void copy_cpu_funcs(struct pstate_funcs *funcs)
|
||||||
pstate_funcs.get_min = funcs->get_min;
|
pstate_funcs.get_min = funcs->get_min;
|
||||||
pstate_funcs.get_turbo = funcs->get_turbo;
|
pstate_funcs.get_turbo = funcs->get_turbo;
|
||||||
pstate_funcs.set = funcs->set;
|
pstate_funcs.set = funcs->set;
|
||||||
|
pstate_funcs.get_vid = funcs->get_vid;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_ACPI)
|
#if IS_ENABLED(CONFIG_ACPI)
|
||||||
|
|
|
@ -138,7 +138,7 @@ static int spear_cpufreq_target(struct cpufreq_policy *policy,
|
||||||
}
|
}
|
||||||
|
|
||||||
newfreq = clk_round_rate(srcclk, newfreq * mult);
|
newfreq = clk_round_rate(srcclk, newfreq * mult);
|
||||||
if (newfreq < 0) {
|
if (newfreq <= 0) {
|
||||||
pr_err("clk_round_rate failed for cpu src clock\n");
|
pr_err("clk_round_rate failed for cpu src clock\n");
|
||||||
return newfreq;
|
return newfreq;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue