aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>2015-04-01 05:46:34 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-04-01 17:02:24 -0400
commit09a972d1620934142d30cfda455ffe429af751c4 (patch)
treed6a9e511a21462e3bb9b25fc4551f82058995a35
parent2f249358eedaf81cede7fb0927ed0bd9c1ae2de7 (diff)
cpufreq: powernv: Report cpu frequency throttling
The power and thermal safety of the system is taken care by an On-Chip-Controller (OCC) which is real-time subsystem embedded within the POWER8 processor. OCC continuously monitors the memory and core temperature, the total system power, state of power supply and fan. The cpu frequency can be throttled by OCC for the following reasons: 1)If a processor crosses its power and temperature limit then OCC will lower its Pmax to reduce the frequency and voltage. 2)If OCC crashes then the system is forced to Psafe frequency. 3)If OCC fails to recover then the kernel is not allowed to do any further frequency changes and the chip will remain in Psafe. The user can see a drop in performance when frequency is throttled and is unaware of throttling. So detect and report such a condition, so the user can check the OCC status to reboot the system or check for power supply or fan failures. The current status of the core is read from Power Management Status Register(PMSR) to check if any of the throttling condition is occurred and the appropriate throttling message is reported. Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> Reviewed-by: Preeti U Murthy <preeti@linux.vnet.ibm.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/cpufreq/powernv-cpufreq.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c
index 2dfd4fdb5a52..ebef0d8279c7 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -34,9 +34,13 @@
34#include <asm/smp.h> /* Required for cpu_sibling_mask() in UP configs */ 34#include <asm/smp.h> /* Required for cpu_sibling_mask() in UP configs */
35 35
36#define POWERNV_MAX_PSTATES 256 36#define POWERNV_MAX_PSTATES 256
37#define PMSR_PSAFE_ENABLE (1UL << 30)
38#define PMSR_SPR_EM_DISABLE (1UL << 31)
39#define PMSR_MAX(x) ((x >> 32) & 0xFF)
40#define PMSR_LP(x) ((x >> 48) & 0xFF)
37 41
38static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1]; 42static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1];
39static bool rebooting; 43static bool rebooting, throttled;
40 44
41/* 45/*
42 * Note: The set of pstates consists of contiguous integers, the 46 * Note: The set of pstates consists of contiguous integers, the
@@ -294,6 +298,44 @@ static inline unsigned int get_nominal_index(void)
294 return powernv_pstate_info.max - powernv_pstate_info.nominal; 298 return powernv_pstate_info.max - powernv_pstate_info.nominal;
295} 299}
296 300
301static void powernv_cpufreq_throttle_check(unsigned int cpu)
302{
303 unsigned long pmsr;
304 int pmsr_pmax, pmsr_lp;
305
306 pmsr = get_pmspr(SPRN_PMSR);
307
308 /* Check for Pmax Capping */
309 pmsr_pmax = (s8)PMSR_MAX(pmsr);
310 if (pmsr_pmax != powernv_pstate_info.max) {
311 throttled = true;
312 pr_info("CPU %d Pmax is reduced to %d\n", cpu, pmsr_pmax);
313 pr_info("Max allowed Pstate is capped\n");
314 }
315
316 /*
317 * Check for Psafe by reading LocalPstate
318 * or check if Psafe_mode_active is set in PMSR.
319 */
320 pmsr_lp = (s8)PMSR_LP(pmsr);
321 if ((pmsr_lp < powernv_pstate_info.min) ||
322 (pmsr & PMSR_PSAFE_ENABLE)) {
323 throttled = true;
324 pr_info("Pstate set to safe frequency\n");
325 }
326
327 /* Check if SPR_EM_DISABLE is set in PMSR */
328 if (pmsr & PMSR_SPR_EM_DISABLE) {
329 throttled = true;
330 pr_info("Frequency Control disabled from OS\n");
331 }
332
333 if (throttled) {
334 pr_info("PMSR = %16lx\n", pmsr);
335 pr_crit("CPU Frequency could be throttled\n");
336 }
337}
338
297/* 339/*
298 * powernv_cpufreq_target_index: Sets the frequency corresponding to 340 * powernv_cpufreq_target_index: Sets the frequency corresponding to
299 * the cpufreq table entry indexed by new_index on the cpus in the 341 * the cpufreq table entry indexed by new_index on the cpus in the
@@ -307,6 +349,9 @@ static int powernv_cpufreq_target_index(struct cpufreq_policy *policy,
307 if (unlikely(rebooting) && new_index != get_nominal_index()) 349 if (unlikely(rebooting) && new_index != get_nominal_index())
308 return 0; 350 return 0;
309 351
352 if (!throttled)
353 powernv_cpufreq_throttle_check(smp_processor_id());
354
310 freq_data.pstate_id = powernv_freqs[new_index].driver_data; 355 freq_data.pstate_id = powernv_freqs[new_index].driver_data;
311 356
312 /* 357 /*