aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/cpufreq/powernv-cpufreq.c177
1 files changed, 102 insertions, 75 deletions
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c
index 2a2920c4fdf9..0f138b050e9a 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -64,12 +64,14 @@
64/** 64/**
65 * struct global_pstate_info - Per policy data structure to maintain history of 65 * struct global_pstate_info - Per policy data structure to maintain history of
66 * global pstates 66 * global pstates
67 * @highest_lpstate: The local pstate from which we are ramping down 67 * @highest_lpstate_idx: The local pstate index from which we are
68 * ramping down
68 * @elapsed_time: Time in ms spent in ramping down from 69 * @elapsed_time: Time in ms spent in ramping down from
69 * highest_lpstate 70 * highest_lpstate_idx
70 * @last_sampled_time: Time from boot in ms when global pstates were 71 * @last_sampled_time: Time from boot in ms when global pstates were
71 * last set 72 * last set
72 * @last_lpstate,last_gpstate: Last set values for local and global pstates 73 * @last_lpstate_idx, Last set value of local pstate and global
74 * last_gpstate_idx pstate in terms of cpufreq table index
73 * @timer: Is used for ramping down if cpu goes idle for 75 * @timer: Is used for ramping down if cpu goes idle for
74 * a long time with global pstate held high 76 * a long time with global pstate held high
75 * @gpstate_lock: A spinlock to maintain synchronization between 77 * @gpstate_lock: A spinlock to maintain synchronization between
@@ -77,11 +79,11 @@
77 * governer's target_index calls 79 * governer's target_index calls
78 */ 80 */
79struct global_pstate_info { 81struct global_pstate_info {
80 int highest_lpstate; 82 int highest_lpstate_idx;
81 unsigned int elapsed_time; 83 unsigned int elapsed_time;
82 unsigned int last_sampled_time; 84 unsigned int last_sampled_time;
83 int last_lpstate; 85 int last_lpstate_idx;
84 int last_gpstate; 86 int last_gpstate_idx;
85 spinlock_t gpstate_lock; 87 spinlock_t gpstate_lock;
86 struct timer_list timer; 88 struct timer_list timer;
87}; 89};
@@ -124,29 +126,47 @@ static int nr_chips;
124static DEFINE_PER_CPU(struct chip *, chip_info); 126static DEFINE_PER_CPU(struct chip *, chip_info);
125 127
126/* 128/*
127 * Note: The set of pstates consists of contiguous integers, the 129 * Note:
128 * smallest of which is indicated by powernv_pstate_info.min, the 130 * The set of pstates consists of contiguous integers.
129 * largest of which is indicated by powernv_pstate_info.max. 131 * powernv_pstate_info stores the index of the frequency table for
132 * max, min and nominal frequencies. It also stores number of
133 * available frequencies.
130 * 134 *
131 * The nominal pstate is the highest non-turbo pstate in this 135 * powernv_pstate_info.nominal indicates the index to the highest
132 * platform. This is indicated by powernv_pstate_info.nominal. 136 * non-turbo frequency.
133 */ 137 */
134static struct powernv_pstate_info { 138static struct powernv_pstate_info {
135 int min; 139 unsigned int min;
136 int max; 140 unsigned int max;
137 int nominal; 141 unsigned int nominal;
138 int nr_pstates; 142 unsigned int nr_pstates;
139} powernv_pstate_info; 143} powernv_pstate_info;
140 144
145/* Use following macros for conversions between pstate_id and index */
146static inline int idx_to_pstate(unsigned int i)
147{
148 return powernv_freqs[i].driver_data;
149}
150
151static inline unsigned int pstate_to_idx(int pstate)
152{
153 /*
154 * abs() is deliberately used so that is works with
155 * both monotonically increasing and decreasing
156 * pstate values
157 */
158 return abs(pstate - idx_to_pstate(powernv_pstate_info.max));
159}
160
141static inline void reset_gpstates(struct cpufreq_policy *policy) 161static inline void reset_gpstates(struct cpufreq_policy *policy)
142{ 162{
143 struct global_pstate_info *gpstates = policy->driver_data; 163 struct global_pstate_info *gpstates = policy->driver_data;
144 164
145 gpstates->highest_lpstate = 0; 165 gpstates->highest_lpstate_idx = 0;
146 gpstates->elapsed_time = 0; 166 gpstates->elapsed_time = 0;
147 gpstates->last_sampled_time = 0; 167 gpstates->last_sampled_time = 0;
148 gpstates->last_lpstate = 0; 168 gpstates->last_lpstate_idx = 0;
149 gpstates->last_gpstate = 0; 169 gpstates->last_gpstate_idx = 0;
150} 170}
151 171
152/* 172/*
@@ -156,9 +176,10 @@ static inline void reset_gpstates(struct cpufreq_policy *policy)
156static int init_powernv_pstates(void) 176static int init_powernv_pstates(void)
157{ 177{
158 struct device_node *power_mgt; 178 struct device_node *power_mgt;
159 int i, pstate_min, pstate_max, pstate_nominal, nr_pstates = 0; 179 int i, nr_pstates = 0;
160 const __be32 *pstate_ids, *pstate_freqs; 180 const __be32 *pstate_ids, *pstate_freqs;
161 u32 len_ids, len_freqs; 181 u32 len_ids, len_freqs;
182 u32 pstate_min, pstate_max, pstate_nominal;
162 183
163 power_mgt = of_find_node_by_path("/ibm,opal/power-mgt"); 184 power_mgt = of_find_node_by_path("/ibm,opal/power-mgt");
164 if (!power_mgt) { 185 if (!power_mgt) {
@@ -208,6 +229,7 @@ static int init_powernv_pstates(void)
208 return -ENODEV; 229 return -ENODEV;
209 } 230 }
210 231
232 powernv_pstate_info.nr_pstates = nr_pstates;
211 pr_debug("NR PStates %d\n", nr_pstates); 233 pr_debug("NR PStates %d\n", nr_pstates);
212 for (i = 0; i < nr_pstates; i++) { 234 for (i = 0; i < nr_pstates; i++) {
213 u32 id = be32_to_cpu(pstate_ids[i]); 235 u32 id = be32_to_cpu(pstate_ids[i]);
@@ -216,15 +238,17 @@ static int init_powernv_pstates(void)
216 pr_debug("PState id %d freq %d MHz\n", id, freq); 238 pr_debug("PState id %d freq %d MHz\n", id, freq);
217 powernv_freqs[i].frequency = freq * 1000; /* kHz */ 239 powernv_freqs[i].frequency = freq * 1000; /* kHz */
218 powernv_freqs[i].driver_data = id; 240 powernv_freqs[i].driver_data = id;
241
242 if (id == pstate_max)
243 powernv_pstate_info.max = i;
244 else if (id == pstate_nominal)
245 powernv_pstate_info.nominal = i;
246 else if (id == pstate_min)
247 powernv_pstate_info.min = i;
219 } 248 }
249
220 /* End of list marker entry */ 250 /* End of list marker entry */
221 powernv_freqs[i].frequency = CPUFREQ_TABLE_END; 251 powernv_freqs[i].frequency = CPUFREQ_TABLE_END;
222
223 powernv_pstate_info.min = pstate_min;
224 powernv_pstate_info.max = pstate_max;
225 powernv_pstate_info.nominal = pstate_nominal;
226 powernv_pstate_info.nr_pstates = nr_pstates;
227
228 return 0; 252 return 0;
229} 253}
230 254
@@ -233,12 +257,12 @@ static unsigned int pstate_id_to_freq(int pstate_id)
233{ 257{
234 int i; 258 int i;
235 259
236 i = powernv_pstate_info.max - pstate_id; 260 i = pstate_to_idx(pstate_id);
237 if (i >= powernv_pstate_info.nr_pstates || i < 0) { 261 if (i >= powernv_pstate_info.nr_pstates || i < 0) {
238 pr_warn("PState id %d outside of PState table, " 262 pr_warn("PState id %d outside of PState table, "
239 "reporting nominal id %d instead\n", 263 "reporting nominal id %d instead\n",
240 pstate_id, powernv_pstate_info.nominal); 264 pstate_id, idx_to_pstate(powernv_pstate_info.nominal));
241 i = powernv_pstate_info.max - powernv_pstate_info.nominal; 265 i = powernv_pstate_info.nominal;
242 } 266 }
243 267
244 return powernv_freqs[i].frequency; 268 return powernv_freqs[i].frequency;
@@ -252,7 +276,7 @@ static ssize_t cpuinfo_nominal_freq_show(struct cpufreq_policy *policy,
252 char *buf) 276 char *buf)
253{ 277{
254 return sprintf(buf, "%u\n", 278 return sprintf(buf, "%u\n",
255 pstate_id_to_freq(powernv_pstate_info.nominal)); 279 powernv_freqs[powernv_pstate_info.nominal].frequency);
256} 280}
257 281
258struct freq_attr cpufreq_freq_attr_cpuinfo_nominal_freq = 282struct freq_attr cpufreq_freq_attr_cpuinfo_nominal_freq =
@@ -426,7 +450,7 @@ static void set_pstate(void *data)
426 */ 450 */
427static inline unsigned int get_nominal_index(void) 451static inline unsigned int get_nominal_index(void)
428{ 452{
429 return powernv_pstate_info.max - powernv_pstate_info.nominal; 453 return powernv_pstate_info.nominal;
430} 454}
431 455
432static void powernv_cpufreq_throttle_check(void *data) 456static void powernv_cpufreq_throttle_check(void *data)
@@ -435,20 +459,22 @@ static void powernv_cpufreq_throttle_check(void *data)
435 unsigned int cpu = smp_processor_id(); 459 unsigned int cpu = smp_processor_id();
436 unsigned long pmsr; 460 unsigned long pmsr;
437 int pmsr_pmax; 461 int pmsr_pmax;
462 unsigned int pmsr_pmax_idx;
438 463
439 pmsr = get_pmspr(SPRN_PMSR); 464 pmsr = get_pmspr(SPRN_PMSR);
440 chip = this_cpu_read(chip_info); 465 chip = this_cpu_read(chip_info);
441 466
442 /* Check for Pmax Capping */ 467 /* Check for Pmax Capping */
443 pmsr_pmax = (s8)PMSR_MAX(pmsr); 468 pmsr_pmax = (s8)PMSR_MAX(pmsr);
444 if (pmsr_pmax != powernv_pstate_info.max) { 469 pmsr_pmax_idx = pstate_to_idx(pmsr_pmax);
470 if (pmsr_pmax_idx != powernv_pstate_info.max) {
445 if (chip->throttled) 471 if (chip->throttled)
446 goto next; 472 goto next;
447 chip->throttled = true; 473 chip->throttled = true;
448 if (pmsr_pmax < powernv_pstate_info.nominal) { 474 if (pmsr_pmax_idx > powernv_pstate_info.nominal) {
449 pr_warn_once("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n", 475 pr_warn_once("CPU %d on Chip %u has Pmax(%d) reduced below nominal frequency(%d)\n",
450 cpu, chip->id, pmsr_pmax, 476 cpu, chip->id, pmsr_pmax,
451 powernv_pstate_info.nominal); 477 idx_to_pstate(powernv_pstate_info.nominal));
452 chip->throttle_sub_turbo++; 478 chip->throttle_sub_turbo++;
453 } else { 479 } else {
454 chip->throttle_turbo++; 480 chip->throttle_turbo++;
@@ -484,34 +510,35 @@ next:
484 510
485/** 511/**
486 * calc_global_pstate - Calculate global pstate 512 * calc_global_pstate - Calculate global pstate
487 * @elapsed_time: Elapsed time in milliseconds 513 * @elapsed_time: Elapsed time in milliseconds
488 * @local_pstate: New local pstate 514 * @local_pstate_idx: New local pstate
489 * @highest_lpstate: pstate from which its ramping down 515 * @highest_lpstate_idx: pstate from which its ramping down
490 * 516 *
491 * Finds the appropriate global pstate based on the pstate from which its 517 * Finds the appropriate global pstate based on the pstate from which its
492 * ramping down and the time elapsed in ramping down. It follows a quadratic 518 * ramping down and the time elapsed in ramping down. It follows a quadratic
493 * equation which ensures that it reaches ramping down to pmin in 5sec. 519 * equation which ensures that it reaches ramping down to pmin in 5sec.
494 */ 520 */
495static inline int calc_global_pstate(unsigned int elapsed_time, 521static inline int calc_global_pstate(unsigned int elapsed_time,
496 int highest_lpstate, int local_pstate) 522 int highest_lpstate_idx,
523 int local_pstate_idx)
497{ 524{
498 int pstate_diff; 525 int index_diff;
499 526
500 /* 527 /*
501 * Using ramp_down_percent we get the percentage of rampdown 528 * Using ramp_down_percent we get the percentage of rampdown
502 * that we are expecting to be dropping. Difference between 529 * that we are expecting to be dropping. Difference between
503 * highest_lpstate and powernv_pstate_info.min will give a absolute 530 * highest_lpstate_idx and powernv_pstate_info.min will give a absolute
504 * number of how many pstates we will drop eventually by the end of 531 * number of how many pstates we will drop eventually by the end of
505 * 5 seconds, then just scale it get the number pstates to be dropped. 532 * 5 seconds, then just scale it get the number pstates to be dropped.
506 */ 533 */
507 pstate_diff = ((int)ramp_down_percent(elapsed_time) * 534 index_diff = ((int)ramp_down_percent(elapsed_time) *
508 (highest_lpstate - powernv_pstate_info.min)) / 100; 535 (powernv_pstate_info.min - highest_lpstate_idx)) / 100;
509 536
510 /* Ensure that global pstate is >= to local pstate */ 537 /* Ensure that global pstate is >= to local pstate */
511 if (highest_lpstate - pstate_diff < local_pstate) 538 if (highest_lpstate_idx + index_diff >= local_pstate_idx)
512 return local_pstate; 539 return local_pstate_idx;
513 else 540 else
514 return highest_lpstate - pstate_diff; 541 return highest_lpstate_idx + index_diff;
515} 542}
516 543
517static inline void queue_gpstate_timer(struct global_pstate_info *gpstates) 544static inline void queue_gpstate_timer(struct global_pstate_info *gpstates)
@@ -547,7 +574,7 @@ void gpstate_timer_handler(unsigned long data)
547{ 574{
548 struct cpufreq_policy *policy = (struct cpufreq_policy *)data; 575 struct cpufreq_policy *policy = (struct cpufreq_policy *)data;
549 struct global_pstate_info *gpstates = policy->driver_data; 576 struct global_pstate_info *gpstates = policy->driver_data;
550 int gpstate_id; 577 int gpstate_idx;
551 unsigned int time_diff = jiffies_to_msecs(jiffies) 578 unsigned int time_diff = jiffies_to_msecs(jiffies)
552 - gpstates->last_sampled_time; 579 - gpstates->last_sampled_time;
553 struct powernv_smp_call_data freq_data; 580 struct powernv_smp_call_data freq_data;
@@ -557,29 +584,29 @@ void gpstate_timer_handler(unsigned long data)
557 584
558 gpstates->last_sampled_time += time_diff; 585 gpstates->last_sampled_time += time_diff;
559 gpstates->elapsed_time += time_diff; 586 gpstates->elapsed_time += time_diff;
560 freq_data.pstate_id = gpstates->last_lpstate; 587 freq_data.pstate_id = idx_to_pstate(gpstates->last_lpstate_idx);
561 588
562 if ((gpstates->last_gpstate == freq_data.pstate_id) || 589 if ((gpstates->last_gpstate_idx == gpstates->last_lpstate_idx) ||
563 (gpstates->elapsed_time > MAX_RAMP_DOWN_TIME)) { 590 (gpstates->elapsed_time > MAX_RAMP_DOWN_TIME)) {
564 gpstate_id = freq_data.pstate_id; 591 gpstate_idx = pstate_to_idx(freq_data.pstate_id);
565 reset_gpstates(policy); 592 reset_gpstates(policy);
566 gpstates->highest_lpstate = freq_data.pstate_id; 593 gpstates->highest_lpstate_idx = gpstate_idx;
567 } else { 594 } else {
568 gpstate_id = calc_global_pstate(gpstates->elapsed_time, 595 gpstate_idx = calc_global_pstate(gpstates->elapsed_time,
569 gpstates->highest_lpstate, 596 gpstates->highest_lpstate_idx,
570 freq_data.pstate_id); 597 freq_data.pstate_id);
571 } 598 }
572 599
573 /* 600 /*
574 * If local pstate is equal to global pstate, rampdown is over 601 * If local pstate is equal to global pstate, rampdown is over
575 * So timer is not required to be queued. 602 * So timer is not required to be queued.
576 */ 603 */
577 if (gpstate_id != freq_data.pstate_id) 604 if (gpstate_idx != gpstates->last_lpstate_idx)
578 queue_gpstate_timer(gpstates); 605 queue_gpstate_timer(gpstates);
579 606
580 freq_data.gpstate_id = gpstate_id; 607 freq_data.gpstate_id = idx_to_pstate(gpstate_idx);
581 gpstates->last_gpstate = freq_data.gpstate_id; 608 gpstates->last_gpstate_idx = pstate_to_idx(freq_data.gpstate_id);
582 gpstates->last_lpstate = freq_data.pstate_id; 609 gpstates->last_lpstate_idx = pstate_to_idx(freq_data.pstate_id);
583 610
584 spin_unlock(&gpstates->gpstate_lock); 611 spin_unlock(&gpstates->gpstate_lock);
585 612
@@ -596,7 +623,7 @@ static int powernv_cpufreq_target_index(struct cpufreq_policy *policy,
596 unsigned int new_index) 623 unsigned int new_index)
597{ 624{
598 struct powernv_smp_call_data freq_data; 625 struct powernv_smp_call_data freq_data;
599 unsigned int cur_msec, gpstate_id; 626 unsigned int cur_msec, gpstate_idx;
600 struct global_pstate_info *gpstates = policy->driver_data; 627 struct global_pstate_info *gpstates = policy->driver_data;
601 628
602 if (unlikely(rebooting) && new_index != get_nominal_index()) 629 if (unlikely(rebooting) && new_index != get_nominal_index())
@@ -608,15 +635,15 @@ static int powernv_cpufreq_target_index(struct cpufreq_policy *policy,
608 cur_msec = jiffies_to_msecs(get_jiffies_64()); 635 cur_msec = jiffies_to_msecs(get_jiffies_64());
609 636
610 spin_lock(&gpstates->gpstate_lock); 637 spin_lock(&gpstates->gpstate_lock);
611 freq_data.pstate_id = powernv_freqs[new_index].driver_data; 638 freq_data.pstate_id = idx_to_pstate(new_index);
612 639
613 if (!gpstates->last_sampled_time) { 640 if (!gpstates->last_sampled_time) {
614 gpstate_id = freq_data.pstate_id; 641 gpstate_idx = new_index;
615 gpstates->highest_lpstate = freq_data.pstate_id; 642 gpstates->highest_lpstate_idx = new_index;
616 goto gpstates_done; 643 goto gpstates_done;
617 } 644 }
618 645
619 if (gpstates->last_gpstate > freq_data.pstate_id) { 646 if (gpstates->last_gpstate_idx < new_index) {
620 gpstates->elapsed_time += cur_msec - 647 gpstates->elapsed_time += cur_msec -
621 gpstates->last_sampled_time; 648 gpstates->last_sampled_time;
622 649
@@ -627,34 +654,34 @@ static int powernv_cpufreq_target_index(struct cpufreq_policy *policy,
627 */ 654 */
628 if (gpstates->elapsed_time > MAX_RAMP_DOWN_TIME) { 655 if (gpstates->elapsed_time > MAX_RAMP_DOWN_TIME) {
629 reset_gpstates(policy); 656 reset_gpstates(policy);
630 gpstates->highest_lpstate = freq_data.pstate_id; 657 gpstates->highest_lpstate_idx = new_index;
631 gpstate_id = freq_data.pstate_id; 658 gpstate_idx = new_index;
632 } else { 659 } else {
633 /* Elaspsed_time is less than 5 seconds, continue to rampdown */ 660 /* Elaspsed_time is less than 5 seconds, continue to rampdown */
634 gpstate_id = calc_global_pstate(gpstates->elapsed_time, 661 gpstate_idx = calc_global_pstate(gpstates->elapsed_time,
635 gpstates->highest_lpstate, 662 gpstates->highest_lpstate_idx,
636 freq_data.pstate_id); 663 new_index);
637 } 664 }
638 } else { 665 } else {
639 reset_gpstates(policy); 666 reset_gpstates(policy);
640 gpstates->highest_lpstate = freq_data.pstate_id; 667 gpstates->highest_lpstate_idx = new_index;
641 gpstate_id = freq_data.pstate_id; 668 gpstate_idx = new_index;
642 } 669 }
643 670
644 /* 671 /*
645 * If local pstate is equal to global pstate, rampdown is over 672 * If local pstate is equal to global pstate, rampdown is over
646 * So timer is not required to be queued. 673 * So timer is not required to be queued.
647 */ 674 */
648 if (gpstate_id != freq_data.pstate_id) 675 if (gpstate_idx != new_index)
649 queue_gpstate_timer(gpstates); 676 queue_gpstate_timer(gpstates);
650 else 677 else
651 del_timer_sync(&gpstates->timer); 678 del_timer_sync(&gpstates->timer);
652 679
653gpstates_done: 680gpstates_done:
654 freq_data.gpstate_id = gpstate_id; 681 freq_data.gpstate_id = idx_to_pstate(gpstate_idx);
655 gpstates->last_sampled_time = cur_msec; 682 gpstates->last_sampled_time = cur_msec;
656 gpstates->last_gpstate = freq_data.gpstate_id; 683 gpstates->last_gpstate_idx = gpstate_idx;
657 gpstates->last_lpstate = freq_data.pstate_id; 684 gpstates->last_lpstate_idx = new_index;
658 685
659 spin_unlock(&gpstates->gpstate_lock); 686 spin_unlock(&gpstates->gpstate_lock);
660 687
@@ -846,8 +873,8 @@ static void powernv_cpufreq_stop_cpu(struct cpufreq_policy *policy)
846 struct powernv_smp_call_data freq_data; 873 struct powernv_smp_call_data freq_data;
847 struct global_pstate_info *gpstates = policy->driver_data; 874 struct global_pstate_info *gpstates = policy->driver_data;
848 875
849 freq_data.pstate_id = powernv_pstate_info.min; 876 freq_data.pstate_id = idx_to_pstate(powernv_pstate_info.min);
850 freq_data.gpstate_id = powernv_pstate_info.min; 877 freq_data.gpstate_id = idx_to_pstate(powernv_pstate_info.min);
851 smp_call_function_single(policy->cpu, set_pstate, &freq_data, 1); 878 smp_call_function_single(policy->cpu, set_pstate, &freq_data, 1);
852 del_timer_sync(&gpstates->timer); 879 del_timer_sync(&gpstates->timer);
853} 880}