aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/Kconfig3
-rw-r--r--drivers/cpufreq/Kconfig.arm6
-rw-r--r--drivers/cpufreq/cpufreq-cpu0.c2
-rw-r--r--drivers/cpufreq/intel_pstate.c69
-rw-r--r--drivers/cpufreq/spear-cpufreq.c2
5 files changed, 62 insertions, 20 deletions
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index 38093e272377..386dbc9ccdfd 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -181,7 +181,8 @@ config CPU_FREQ_GOV_CONSERVATIVE
181 181
182config GENERIC_CPUFREQ_CPU0 182config GENERIC_CPUFREQ_CPU0
183 tristate "Generic CPU0 cpufreq driver" 183 tristate "Generic CPU0 cpufreq driver"
184 depends on HAVE_CLK && REGULATOR && PM_OPP && OF 184 depends on HAVE_CLK && REGULATOR && OF
185 select PM_OPP
185 help 186 help
186 This adds a generic cpufreq driver for CPU0 frequency management. 187 This adds a generic cpufreq driver for CPU0 frequency management.
187 It supports both uniprocessor (UP) and symmetric multiprocessor (SMP) 188 It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index ce52ed949249..456ba5e1781c 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -4,7 +4,8 @@
4 4
5config ARM_BIG_LITTLE_CPUFREQ 5config ARM_BIG_LITTLE_CPUFREQ
6 tristate "Generic ARM big LITTLE CPUfreq driver" 6 tristate "Generic ARM big LITTLE CPUfreq driver"
7 depends on ARM_CPU_TOPOLOGY && PM_OPP && HAVE_CLK 7 depends on ARM && ARM_CPU_TOPOLOGY && HAVE_CLK
8 select PM_OPP
8 help 9 help
9 This enables the Generic CPUfreq driver for ARM big.LITTLE platforms. 10 This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
10 11
@@ -54,7 +55,8 @@ config ARM_EXYNOS5250_CPUFREQ
54config ARM_EXYNOS5440_CPUFREQ 55config ARM_EXYNOS5440_CPUFREQ
55 bool "SAMSUNG EXYNOS5440" 56 bool "SAMSUNG EXYNOS5440"
56 depends on SOC_EXYNOS5440 57 depends on SOC_EXYNOS5440
57 depends on HAVE_CLK && PM_OPP && OF 58 depends on HAVE_CLK && OF
59 select PM_OPP
58 default y 60 default y
59 help 61 help
60 This adds the CPUFreq driver for Samsung EXYNOS5440 62 This adds the CPUFreq driver for Samsung EXYNOS5440
diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
index d4585ce2346c..0faf756f6197 100644
--- a/drivers/cpufreq/cpufreq-cpu0.c
+++ b/drivers/cpufreq/cpufreq-cpu0.c
@@ -44,7 +44,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index)
44 int ret; 44 int ret;
45 45
46 freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000); 46 freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000);
47 if (freq_Hz < 0) 47 if (freq_Hz <= 0)
48 freq_Hz = freq_table[index].frequency * 1000; 48 freq_Hz = freq_table[index].frequency * 1000;
49 49
50 freq_exact = freq_Hz; 50 freq_exact = freq_Hz;
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index f9d561e198ab..0f63f5d598f7 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -35,6 +35,7 @@
35#define SAMPLE_COUNT 3 35#define SAMPLE_COUNT 3
36 36
37#define BYT_RATIOS 0x66a 37#define BYT_RATIOS 0x66a
38#define BYT_VIDS 0x66b
38 39
39#define FRAC_BITS 8 40#define FRAC_BITS 8
40#define int_tofp(X) ((int64_t)(X) << FRAC_BITS) 41#define int_tofp(X) ((int64_t)(X) << FRAC_BITS)
@@ -64,6 +65,12 @@ struct pstate_data {
64 int turbo_pstate; 65 int turbo_pstate;
65}; 66};
66 67
68struct vid_data {
69 int32_t min;
70 int32_t max;
71 int32_t ratio;
72};
73
67struct _pid { 74struct _pid {
68 int setpoint; 75 int setpoint;
69 int32_t integral; 76 int32_t integral;
@@ -82,10 +89,9 @@ struct cpudata {
82 struct timer_list timer; 89 struct timer_list timer;
83 90
84 struct pstate_data pstate; 91 struct pstate_data pstate;
92 struct vid_data vid;
85 struct _pid pid; 93 struct _pid pid;
86 94
87 int min_pstate_count;
88
89 u64 prev_aperf; 95 u64 prev_aperf;
90 u64 prev_mperf; 96 u64 prev_mperf;
91 int sample_ptr; 97 int sample_ptr;
@@ -106,7 +112,8 @@ struct pstate_funcs {
106 int (*get_max)(void); 112 int (*get_max)(void);
107 int (*get_min)(void); 113 int (*get_min)(void);
108 int (*get_turbo)(void); 114 int (*get_turbo)(void);
109 void (*set)(int pstate); 115 void (*set)(struct cpudata*, int pstate);
116 void (*get_vid)(struct cpudata *);
110}; 117};
111 118
112struct cpu_defaults { 119struct cpu_defaults {
@@ -358,6 +365,42 @@ static int byt_get_max_pstate(void)
358 return (value >> 16) & 0xFF; 365 return (value >> 16) & 0xFF;
359} 366}
360 367
368static void byt_set_pstate(struct cpudata *cpudata, int pstate)
369{
370 u64 val;
371 int32_t vid_fp;
372 u32 vid;
373
374 val = pstate << 8;
375 if (limits.no_turbo)
376 val |= (u64)1 << 32;
377
378 vid_fp = cpudata->vid.min + mul_fp(
379 int_tofp(pstate - cpudata->pstate.min_pstate),
380 cpudata->vid.ratio);
381
382 vid_fp = clamp_t(int32_t, vid_fp, cpudata->vid.min, cpudata->vid.max);
383 vid = fp_toint(vid_fp);
384
385 val |= vid;
386
387 wrmsrl(MSR_IA32_PERF_CTL, val);
388}
389
390static void byt_get_vid(struct cpudata *cpudata)
391{
392 u64 value;
393
394 rdmsrl(BYT_VIDS, value);
395 cpudata->vid.min = int_tofp((value >> 8) & 0x7f);
396 cpudata->vid.max = int_tofp((value >> 16) & 0x7f);
397 cpudata->vid.ratio = div_fp(
398 cpudata->vid.max - cpudata->vid.min,
399 int_tofp(cpudata->pstate.max_pstate -
400 cpudata->pstate.min_pstate));
401}
402
403
361static int core_get_min_pstate(void) 404static int core_get_min_pstate(void)
362{ 405{
363 u64 value; 406 u64 value;
@@ -384,7 +427,7 @@ static int core_get_turbo_pstate(void)
384 return ret; 427 return ret;
385} 428}
386 429
387static void core_set_pstate(int pstate) 430static void core_set_pstate(struct cpudata *cpudata, int pstate)
388{ 431{
389 u64 val; 432 u64 val;
390 433
@@ -425,7 +468,8 @@ static struct cpu_defaults byt_params = {
425 .get_max = byt_get_max_pstate, 468 .get_max = byt_get_max_pstate,
426 .get_min = byt_get_min_pstate, 469 .get_min = byt_get_min_pstate,
427 .get_turbo = byt_get_max_pstate, 470 .get_turbo = byt_get_max_pstate,
428 .set = core_set_pstate, 471 .set = byt_set_pstate,
472 .get_vid = byt_get_vid,
429 }, 473 },
430}; 474};
431 475
@@ -462,7 +506,7 @@ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
462 506
463 cpu->pstate.current_pstate = pstate; 507 cpu->pstate.current_pstate = pstate;
464 508
465 pstate_funcs.set(pstate); 509 pstate_funcs.set(cpu, pstate);
466} 510}
467 511
468static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps) 512static 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)
488 cpu->pstate.max_pstate = pstate_funcs.get_max(); 532 cpu->pstate.max_pstate = pstate_funcs.get_max();
489 cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(); 533 cpu->pstate.turbo_pstate = pstate_funcs.get_turbo();
490 534
535 if (pstate_funcs.get_vid)
536 pstate_funcs.get_vid(cpu);
537
491 /* 538 /*
492 * goto max pstate so we don't slow up boot if we are built-in if we are 539 * goto max pstate so we don't slow up boot if we are built-in if we are
493 * a module we will take care of it during normal operation 540 * a module we will take care of it during normal operation
@@ -568,15 +615,6 @@ static void intel_pstate_timer_func(unsigned long __data)
568 615
569 intel_pstate_sample(cpu); 616 intel_pstate_sample(cpu);
570 intel_pstate_adjust_busy_pstate(cpu); 617 intel_pstate_adjust_busy_pstate(cpu);
571
572 if (cpu->pstate.current_pstate == cpu->pstate.min_pstate) {
573 cpu->min_pstate_count++;
574 if (!(cpu->min_pstate_count % 5)) {
575 intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate);
576 }
577 } else
578 cpu->min_pstate_count = 0;
579
580 intel_pstate_set_sample_time(cpu); 618 intel_pstate_set_sample_time(cpu);
581} 619}
582 620
@@ -781,6 +819,7 @@ static void copy_cpu_funcs(struct pstate_funcs *funcs)
781 pstate_funcs.get_min = funcs->get_min; 819 pstate_funcs.get_min = funcs->get_min;
782 pstate_funcs.get_turbo = funcs->get_turbo; 820 pstate_funcs.get_turbo = funcs->get_turbo;
783 pstate_funcs.set = funcs->set; 821 pstate_funcs.set = funcs->set;
822 pstate_funcs.get_vid = funcs->get_vid;
784} 823}
785 824
786#if IS_ENABLED(CONFIG_ACPI) 825#if IS_ENABLED(CONFIG_ACPI)
diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c
index d02ccd19c9c4..45ea4c094542 100644
--- a/drivers/cpufreq/spear-cpufreq.c
+++ b/drivers/cpufreq/spear-cpufreq.c
@@ -138,7 +138,7 @@ static int spear_cpufreq_target(struct cpufreq_policy *policy,
138 } 138 }
139 139
140 newfreq = clk_round_rate(srcclk, newfreq * mult); 140 newfreq = clk_round_rate(srcclk, newfreq * mult);
141 if (newfreq < 0) { 141 if (newfreq <= 0) {
142 pr_err("clk_round_rate failed for cpu src clock\n"); 142 pr_err("clk_round_rate failed for cpu src clock\n");
143 return newfreq; 143 return newfreq;
144 } 144 }