Lines Matching +full:ramp +full:- +full:down
1 // SPDX-License-Identifier: GPL-2.0-or-later
10 #define pr_fmt(fmt) "powernv-cpufreq: " fmt
44 * On an idle system we want the global pstate to ramp-down from max value to
45 * min over a span of ~5 secs. Also we want it to initially ramp-down slowly and
46 * then ramp-down rapidly later on.
57 /* Interval after which the timer is queued to bring down global pstate */
61 * struct global_pstate_info - Per policy data structure to maintain history of
64 * ramping down
65 * @elapsed_time: Time in ms spent in ramping down from
71 * @timer: Is used for ramping down if cpu goes idle for
155 * non-turbo frequency.
209 if (revmap_data->pstate_id == pstate) in pstate_to_idx()
210 return revmap_data->cpufreq_table_idx; in pstate_to_idx()
219 struct global_pstate_info *gpstates = policy->driver_data; in reset_gpstates()
221 gpstates->highest_lpstate_idx = 0; in reset_gpstates()
222 gpstates->elapsed_time = 0; in reset_gpstates()
223 gpstates->last_sampled_time = 0; in reset_gpstates()
224 gpstates->last_lpstate_idx = 0; in reset_gpstates()
225 gpstates->last_gpstate_idx = 0; in reset_gpstates()
230 * from the firmware passed via device-tree
240 int rc = -ENODEV; in init_powernv_pstates()
242 power_mgt = of_find_node_by_path("/ibm,opal/power-mgt"); in init_powernv_pstates()
244 pr_warn("power-mgt node not found\n"); in init_powernv_pstates()
245 return -ENODEV; in init_powernv_pstates()
248 if (of_property_read_u32(power_mgt, "ibm,pstate-min", &pstate_min)) { in init_powernv_pstates()
249 pr_warn("ibm,pstate-min node not found\n"); in init_powernv_pstates()
253 if (of_property_read_u32(power_mgt, "ibm,pstate-max", &pstate_max)) { in init_powernv_pstates()
254 pr_warn("ibm,pstate-max node not found\n"); in init_powernv_pstates()
258 if (of_property_read_u32(power_mgt, "ibm,pstate-nominal", in init_powernv_pstates()
260 pr_warn("ibm,pstate-nominal not found\n"); in init_powernv_pstates()
264 if (of_property_read_u32(power_mgt, "ibm,pstate-ultra-turbo", in init_powernv_pstates()
270 if (of_property_read_u32(power_mgt, "ibm,pstate-turbo", in init_powernv_pstates()
287 pstate_ids = of_get_property(power_mgt, "ibm,pstate-ids", &len_ids); in init_powernv_pstates()
289 pr_warn("ibm,pstate-ids not found\n"); in init_powernv_pstates()
293 pstate_freqs = of_get_property(power_mgt, "ibm,pstate-frequencies-mhz", in init_powernv_pstates()
296 pr_warn("ibm,pstate-frequencies-mhz not found\n"); in init_powernv_pstates()
301 pr_warn("Entries in ibm,pstate-ids and " in init_powernv_pstates()
302 "ibm,pstate-frequencies-mhz does not match\n"); in init_powernv_pstates()
326 rc = -ENOMEM; in init_powernv_pstates()
330 revmap_data->pstate_id = id & 0xFF; in init_powernv_pstates()
331 revmap_data->cpufreq_table_idx = i; in init_powernv_pstates()
332 key = (revmap_data->pstate_id) % POWERNV_MAX_PSTATES; in init_powernv_pstates()
333 hash_add(pstate_revmap, &revmap_data->hentry, key); in init_powernv_pstates()
345 for (j = i - 1; j >= (int)powernv_pstate_info.max; j--) in init_powernv_pstates()
376 * cpuinfo_nominal_freq_show - Show the nominal CPU frequency as indicated by
397 struct chip *chip = per_cpu(chip_info, policy->cpu); \
399 return sprintf(buf, "%u\n", chip->member); \
482 * ((struct powernv_smp_call_data *)arg)->freq;
490 freq_data->pstate_id = extract_local_pstate(pmspr_val); in powernv_read_cpu_freq()
491 freq_data->freq = pstate_id_to_freq(freq_data->pstate_id); in powernv_read_cpu_freq()
494 raw_smp_processor_id(), pmspr_val, freq_data->pstate_id, in powernv_read_cpu_freq()
495 freq_data->freq); in powernv_read_cpu_freq()
520 * on this CPU should be present in freq_data->pstate_id.
526 unsigned long pstate_ul = freq_data->pstate_id; in set_pstate()
527 unsigned long gpstate_ul = freq_data->gpstate_id; in set_pstate()
567 if (chip->throttled) in powernv_cpufreq_throttle_check()
569 chip->throttled = true; in powernv_cpufreq_throttle_check()
572 cpu, chip->id, pmsr_pmax, in powernv_cpufreq_throttle_check()
574 chip->throttle_sub_turbo++; in powernv_cpufreq_throttle_check()
576 chip->throttle_turbo++; in powernv_cpufreq_throttle_check()
578 trace_powernv_throttle(chip->id, in powernv_cpufreq_throttle_check()
579 throttle_reason[chip->throttle_reason], in powernv_cpufreq_throttle_check()
581 } else if (chip->throttled) { in powernv_cpufreq_throttle_check()
582 chip->throttled = false; in powernv_cpufreq_throttle_check()
583 trace_powernv_throttle(chip->id, in powernv_cpufreq_throttle_check()
584 throttle_reason[chip->throttle_reason], in powernv_cpufreq_throttle_check()
608 * calc_global_pstate - Calculate global pstate
611 * @highest_lpstate_idx: pstate from which its ramping down
614 * ramping down and the time elapsed in ramping down. It follows a quadratic
615 * equation which ensures that it reaches ramping down to pmin in 5sec.
631 (powernv_pstate_info.min - highest_lpstate_idx)) / 100; in calc_global_pstate()
646 * if it exceeds MAX_RAMP_DOWN_TIME ms for ramp down time. in queue_gpstate_timer()
648 * seconds of ramp down time. in queue_gpstate_timer()
650 if ((gpstates->elapsed_time + GPSTATE_TIMER_INTERVAL) in queue_gpstate_timer()
652 timer_interval = MAX_RAMP_DOWN_TIME - gpstates->elapsed_time; in queue_gpstate_timer()
656 mod_timer(&gpstates->timer, jiffies + msecs_to_jiffies(timer_interval)); in queue_gpstate_timer()
664 * This handler brings down the global pstate closer to the local pstate
671 struct cpufreq_policy *policy = gpstates->policy; in gpstate_timer_handler()
675 - gpstates->last_sampled_time; in gpstate_timer_handler()
678 if (!spin_trylock(&gpstates->gpstate_lock)) in gpstate_timer_handler()
682 * it back to one of the policy->cpus in gpstate_timer_handler()
684 if (!cpumask_test_cpu(raw_smp_processor_id(), policy->cpus)) { in gpstate_timer_handler()
685 gpstates->timer.expires = jiffies + msecs_to_jiffies(1); in gpstate_timer_handler()
686 add_timer_on(&gpstates->timer, cpumask_first(policy->cpus)); in gpstate_timer_handler()
687 spin_unlock(&gpstates->gpstate_lock); in gpstate_timer_handler()
693 * We may have wrong in gpstate->last_lpstate_idx in gpstate_timer_handler()
701 spin_unlock(&gpstates->gpstate_lock); in gpstate_timer_handler()
705 gpstates->last_sampled_time += time_diff; in gpstate_timer_handler()
706 gpstates->elapsed_time += time_diff; in gpstate_timer_handler()
708 if (gpstates->elapsed_time > MAX_RAMP_DOWN_TIME) { in gpstate_timer_handler()
712 gpstates->highest_lpstate_idx = gpstate_idx; in gpstate_timer_handler()
715 gpstate_idx = calc_global_pstate(gpstates->elapsed_time, in gpstate_timer_handler()
716 gpstates->highest_lpstate_idx, in gpstate_timer_handler()
720 gpstates->last_gpstate_idx = gpstate_idx; in gpstate_timer_handler()
721 gpstates->last_lpstate_idx = lpstate_idx; in gpstate_timer_handler()
726 if (gpstate_idx != gpstates->last_lpstate_idx) in gpstate_timer_handler()
730 spin_unlock(&gpstates->gpstate_lock); in gpstate_timer_handler()
736 * mask policy->cpus
743 struct global_pstate_info *gpstates = policy->driver_data; in powernv_cpufreq_target_index()
765 spin_lock(&gpstates->gpstate_lock); in powernv_cpufreq_target_index()
767 if (!gpstates->last_sampled_time) { in powernv_cpufreq_target_index()
769 gpstates->highest_lpstate_idx = new_index; in powernv_cpufreq_target_index()
773 if (gpstates->last_gpstate_idx < new_index) { in powernv_cpufreq_target_index()
774 gpstates->elapsed_time += cur_msec - in powernv_cpufreq_target_index()
775 gpstates->last_sampled_time; in powernv_cpufreq_target_index()
778 * If its has been ramping down for more than MAX_RAMP_DOWN_TIME in powernv_cpufreq_target_index()
782 if (gpstates->elapsed_time > MAX_RAMP_DOWN_TIME) { in powernv_cpufreq_target_index()
784 gpstates->highest_lpstate_idx = new_index; in powernv_cpufreq_target_index()
788 gpstate_idx = calc_global_pstate(gpstates->elapsed_time, in powernv_cpufreq_target_index()
789 gpstates->highest_lpstate_idx, in powernv_cpufreq_target_index()
794 gpstates->highest_lpstate_idx = new_index; in powernv_cpufreq_target_index()
805 timer_delete_sync(&gpstates->timer); in powernv_cpufreq_target_index()
809 gpstates->last_sampled_time = cur_msec; in powernv_cpufreq_target_index()
810 gpstates->last_gpstate_idx = gpstate_idx; in powernv_cpufreq_target_index()
811 gpstates->last_lpstate_idx = new_index; in powernv_cpufreq_target_index()
813 spin_unlock(&gpstates->gpstate_lock); in powernv_cpufreq_target_index()
819 * if current CPU is within policy->cpus (core) in powernv_cpufreq_target_index()
821 smp_call_function_any(policy->cpus, set_pstate, &freq_data, 1); in powernv_cpufreq_target_index()
831 base = cpu_first_thread_sibling(policy->cpu); in powernv_cpufreq_cpu_init()
834 cpumask_set_cpu(base + i, policy->cpus); in powernv_cpufreq_cpu_init()
836 kn = kernfs_find_and_get(policy->kobj.sd, throttle_attr_grp.name); in powernv_cpufreq_cpu_init()
840 ret = sysfs_create_group(&policy->kobj, &throttle_attr_grp); in powernv_cpufreq_cpu_init()
843 policy->cpu); in powernv_cpufreq_cpu_init()
850 policy->freq_table = powernv_freqs; in powernv_cpufreq_cpu_init()
851 policy->fast_switch_possible = true; in powernv_cpufreq_cpu_init()
856 /* Initialise Gpstate ramp-down timer only on POWER8 */ in powernv_cpufreq_cpu_init()
859 return -ENOMEM; in powernv_cpufreq_cpu_init()
861 policy->driver_data = gpstates; in powernv_cpufreq_cpu_init()
864 gpstates->policy = policy; in powernv_cpufreq_cpu_init()
865 timer_setup(&gpstates->timer, gpstate_timer_handler, in powernv_cpufreq_cpu_init()
867 gpstates->timer.expires = jiffies + in powernv_cpufreq_cpu_init()
869 spin_lock_init(&gpstates->gpstate_lock); in powernv_cpufreq_cpu_init()
877 struct global_pstate_info *gpstates = policy->driver_data; in powernv_cpufreq_cpu_exit()
881 smp_call_function_single(policy->cpu, set_pstate, &freq_data, 1); in powernv_cpufreq_cpu_exit()
883 timer_delete_sync(&gpstates->timer); in powernv_cpufreq_cpu_exit()
885 kfree(policy->driver_data); in powernv_cpufreq_cpu_exit()
918 cpumask_and(&mask, &chip->mask, cpu_online_mask); in powernv_cpufreq_work_fn()
922 if (!chip->restore) in powernv_cpufreq_work_fn()
925 chip->restore = false; in powernv_cpufreq_work_fn()
932 index = cpufreq_table_find_index_c(policy, policy->cur, false); in powernv_cpufreq_work_fn()
934 cpumask_andnot(&mask, &mask, policy->cpus); in powernv_cpufreq_work_fn()
951 omsg.type = be64_to_cpu(msg->params[0]); in powernv_cpufreq_occ_msg()
956 pr_info("OCC (On Chip Controller - enforces hard thermal/power limits) Resetting\n"); in powernv_cpufreq_occ_msg()
974 omsg.chip = be64_to_cpu(msg->params[1]); in powernv_cpufreq_occ_msg()
975 omsg.throttle_status = be64_to_cpu(msg->params[2]); in powernv_cpufreq_occ_msg()
1029 .name = "powernv-cpufreq",
1050 return -ENOMEM; in init_chip_info()
1055 ret = -ENOMEM; in init_chip_info()
1066 cpumask_set_cpu(cpu, &chip_cpu_mask[nr_chips-1]); in init_chip_info()
1071 ret = -ENOMEM; in init_chip_info()
1114 return -ENODEV; in powernv_cpufreq_init()