Lines Matching +full:dynamic +full:- +full:power +full:- +full:coefficient
1 // SPDX-License-Identifier: GPL-2.0
6 * Copyright (C) 2014-2015 ARM Limited
9 * - If OPPs are added or removed after devfreq cooling has
28 * struct devfreq_cooling_device - Devfreq cooling device
39 * @res_util: Resource utilization scaling factor for the power.
41 * for estimation of the power budget instead of using
43 * The 'res_util' range is from 100 to power * 100 for the
45 * @capped_state: index to cooling state with in dynamic power budget
67 struct devfreq_cooling_device *dfc = cdev->devdata; in devfreq_cooling_get_max_state()
69 *state = dfc->max_state; in devfreq_cooling_get_max_state()
77 struct devfreq_cooling_device *dfc = cdev->devdata; in devfreq_cooling_get_cur_state()
79 *state = dfc->cooling_state; in devfreq_cooling_get_cur_state()
87 struct devfreq_cooling_device *dfc = cdev->devdata; in devfreq_cooling_set_cur_state()
88 struct devfreq *df = dfc->devfreq; in devfreq_cooling_set_cur_state()
89 struct device *dev = df->dev.parent; in devfreq_cooling_set_cur_state()
93 if (state == dfc->cooling_state) in devfreq_cooling_set_cur_state()
98 if (state > dfc->max_state) in devfreq_cooling_set_cur_state()
99 return -EINVAL; in devfreq_cooling_set_cur_state()
101 if (dfc->em_pd) { in devfreq_cooling_set_cur_state()
102 perf_idx = dfc->max_state - state; in devfreq_cooling_set_cur_state()
103 freq = dfc->em_pd->table[perf_idx].frequency * 1000; in devfreq_cooling_set_cur_state()
105 freq = dfc->freq_table[state]; in devfreq_cooling_set_cur_state()
108 dev_pm_qos_update_request(&dfc->req_max_freq, in devfreq_cooling_set_cur_state()
111 dfc->cooling_state = state; in devfreq_cooling_set_cur_state()
117 * get_perf_idx() - get the performance index corresponding to a frequency
122 * -EINVAL if it wasn't found.
128 for (i = 0; i < em_pd->nr_perf_states; i++) { in get_perf_idx()
129 if (em_pd->table[i].frequency == freq) in get_perf_idx()
133 return -EINVAL; in get_perf_idx()
138 struct device *dev = df->dev.parent; in get_voltage()
143 if (PTR_ERR(opp) == -ERANGE) in get_voltage()
166 if (status->total_time > 0xfffff) { in _normalize_load()
167 status->total_time >>= 10; in _normalize_load()
168 status->busy_time >>= 10; in _normalize_load()
171 status->busy_time <<= 10; in _normalize_load()
172 status->busy_time /= status->total_time ? : 1; in _normalize_load()
174 status->busy_time = status->busy_time ? : 1; in _normalize_load()
175 status->total_time = 1024; in _normalize_load()
179 u32 *power) in devfreq_cooling_get_requested_power() argument
181 struct devfreq_cooling_device *dfc = cdev->devdata; in devfreq_cooling_get_requested_power()
182 struct devfreq *df = dfc->devfreq; in devfreq_cooling_get_requested_power()
189 mutex_lock(&df->lock); in devfreq_cooling_get_requested_power()
190 status = df->last_status; in devfreq_cooling_get_requested_power()
191 mutex_unlock(&df->lock); in devfreq_cooling_get_requested_power()
195 if (dfc->power_ops && dfc->power_ops->get_real_power) { in devfreq_cooling_get_requested_power()
198 res = -EINVAL; in devfreq_cooling_get_requested_power()
202 res = dfc->power_ops->get_real_power(df, power, freq, voltage); in devfreq_cooling_get_requested_power()
204 state = dfc->capped_state; in devfreq_cooling_get_requested_power()
206 /* Convert EM power into milli-Watts first */ in devfreq_cooling_get_requested_power()
207 dfc->res_util = dfc->em_pd->table[state].power; in devfreq_cooling_get_requested_power()
208 dfc->res_util /= MICROWATT_PER_MILLIWATT; in devfreq_cooling_get_requested_power()
210 dfc->res_util *= SCALE_ERROR_MITIGATION; in devfreq_cooling_get_requested_power()
212 if (*power > 1) in devfreq_cooling_get_requested_power()
213 dfc->res_util /= *power; in devfreq_cooling_get_requested_power()
219 perf_idx = get_perf_idx(dfc->em_pd, freq / 1000); in devfreq_cooling_get_requested_power()
221 res = -EAGAIN; in devfreq_cooling_get_requested_power()
227 /* Convert EM power into milli-Watts first */ in devfreq_cooling_get_requested_power()
228 *power = dfc->em_pd->table[perf_idx].power; in devfreq_cooling_get_requested_power()
229 *power /= MICROWATT_PER_MILLIWATT; in devfreq_cooling_get_requested_power()
230 /* Scale power for utilization */ in devfreq_cooling_get_requested_power()
231 *power *= status.busy_time; in devfreq_cooling_get_requested_power()
232 *power >>= 10; in devfreq_cooling_get_requested_power()
235 trace_thermal_power_devfreq_get_power(cdev, &status, freq, *power); in devfreq_cooling_get_requested_power()
240 dfc->res_util = SCALE_ERROR_MITIGATION; in devfreq_cooling_get_requested_power()
245 unsigned long state, u32 *power) in devfreq_cooling_state2power() argument
247 struct devfreq_cooling_device *dfc = cdev->devdata; in devfreq_cooling_state2power()
250 if (state > dfc->max_state) in devfreq_cooling_state2power()
251 return -EINVAL; in devfreq_cooling_state2power()
253 perf_idx = dfc->max_state - state; in devfreq_cooling_state2power()
254 *power = dfc->em_pd->table[perf_idx].power; in devfreq_cooling_state2power()
255 *power /= MICROWATT_PER_MILLIWATT; in devfreq_cooling_state2power()
261 u32 power, unsigned long *state) in devfreq_cooling_power2state() argument
263 struct devfreq_cooling_device *dfc = cdev->devdata; in devfreq_cooling_power2state()
264 struct devfreq *df = dfc->devfreq; in devfreq_cooling_power2state()
270 mutex_lock(&df->lock); in devfreq_cooling_power2state()
271 status = df->last_status; in devfreq_cooling_power2state()
272 mutex_unlock(&df->lock); in devfreq_cooling_power2state()
276 if (dfc->power_ops && dfc->power_ops->get_real_power) { in devfreq_cooling_power2state()
278 est_power = power * dfc->res_util; in devfreq_cooling_power2state()
281 /* Scale dynamic power for utilization */ in devfreq_cooling_power2state()
283 est_power = power << 10; in devfreq_cooling_power2state()
288 * Find the first cooling state that is within the power in devfreq_cooling_power2state()
289 * budget. The EM power table is sorted ascending. in devfreq_cooling_power2state()
291 for (i = dfc->max_state; i > 0; i--) { in devfreq_cooling_power2state()
292 /* Convert EM power to milli-Watts to make safe comparison */ in devfreq_cooling_power2state()
293 em_power_mw = dfc->em_pd->table[i].power; in devfreq_cooling_power2state()
299 *state = dfc->max_state - i; in devfreq_cooling_power2state()
300 dfc->capped_state = *state; in devfreq_cooling_power2state()
302 trace_thermal_power_devfreq_limit(cdev, freq, *state, power); in devfreq_cooling_power2state()
307 * devfreq_cooling_gen_tables() - Generate frequency table.
320 struct devfreq *df = dfc->devfreq; in devfreq_cooling_gen_tables()
321 struct device *dev = df->dev.parent; in devfreq_cooling_gen_tables()
325 dfc->freq_table = kcalloc(num_opps, sizeof(*dfc->freq_table), in devfreq_cooling_gen_tables()
327 if (!dfc->freq_table) in devfreq_cooling_gen_tables()
328 return -ENOMEM; in devfreq_cooling_gen_tables()
330 for (i = 0, freq = ULONG_MAX; i < num_opps; i++, freq--) { in devfreq_cooling_gen_tables()
335 kfree(dfc->freq_table); in devfreq_cooling_gen_tables()
340 dfc->freq_table[i] = freq; in devfreq_cooling_gen_tables()
347 * of_devfreq_cooling_register_power() - Register devfreq cooling device,
348 * with OF and power information.
357 * power extensions. For the power extensions to work correctly,
366 struct device *dev = df->dev.parent; in of_devfreq_cooling_register_power()
376 return ERR_PTR(-ENOMEM); in of_devfreq_cooling_register_power()
378 dfc->devfreq = df; in of_devfreq_cooling_register_power()
380 ops = &dfc->cooling_ops; in of_devfreq_cooling_register_power()
381 ops->get_max_state = devfreq_cooling_get_max_state; in of_devfreq_cooling_register_power()
382 ops->get_cur_state = devfreq_cooling_get_cur_state; in of_devfreq_cooling_register_power()
383 ops->set_cur_state = devfreq_cooling_set_cur_state; in of_devfreq_cooling_register_power()
387 dfc->em_pd = em; in of_devfreq_cooling_register_power()
388 ops->get_requested_power = in of_devfreq_cooling_register_power()
390 ops->state2power = devfreq_cooling_state2power; in of_devfreq_cooling_register_power()
391 ops->power2state = devfreq_cooling_power2state; in of_devfreq_cooling_register_power()
393 dfc->power_ops = dfc_power; in of_devfreq_cooling_register_power()
395 num_opps = em_pd_nr_perf_states(dfc->em_pd); in of_devfreq_cooling_register_power()
408 err = -EINVAL; in of_devfreq_cooling_register_power()
413 dfc->max_state = num_opps - 1; in of_devfreq_cooling_register_power()
415 err = dev_pm_qos_add_request(dev, &dfc->req_max_freq, in of_devfreq_cooling_register_power()
421 err = -ENOMEM; in of_devfreq_cooling_register_power()
422 name = kasprintf(GFP_KERNEL, "devfreq-%s", dev_name(dev)); in of_devfreq_cooling_register_power()
437 dfc->cdev = cdev; in of_devfreq_cooling_register_power()
442 dev_pm_qos_remove_request(&dfc->req_max_freq); in of_devfreq_cooling_register_power()
444 kfree(dfc->freq_table); in of_devfreq_cooling_register_power()
453 * of_devfreq_cooling_register() - Register devfreq cooling device,
466 * devfreq_cooling_register() - Register devfreq cooling device.
476 * devfreq_cooling_em_register() - Register devfreq cooling device with
477 * power information and automatically register Energy Model (EM)
485 * power extensions. It is using the simple Energy Model which requires
486 * "dynamic-power-coefficient" a devicetree property. To not break drivers
500 return ERR_PTR(-EINVAL); in devfreq_cooling_em_register()
502 dev = df->dev.parent; in devfreq_cooling_em_register()
509 cdev = of_devfreq_cooling_register_power(dev->of_node, df, dfc_power); in devfreq_cooling_em_register()
519 * devfreq_cooling_unregister() - Unregister devfreq cooling device.
533 dfc = cdev->devdata; in devfreq_cooling_unregister()
534 dev = dfc->devfreq->dev.parent; in devfreq_cooling_unregister()
536 thermal_cooling_device_unregister(dfc->cdev); in devfreq_cooling_unregister()
537 dev_pm_qos_remove_request(&dfc->req_max_freq); in devfreq_cooling_unregister()
541 kfree(dfc->freq_table); in devfreq_cooling_unregister()