Lines Matching +full:opp +full:- +full:table
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
33 * @freq_table: Pointer to a table with the frequencies sorted in descending
34 * order. You can index the table by cooling device state
65 struct devfreq_cooling_device *dfc = cdev->devdata; in devfreq_cooling_get_max_state()
67 *state = dfc->max_state; in devfreq_cooling_get_max_state()
75 struct devfreq_cooling_device *dfc = cdev->devdata; in devfreq_cooling_get_cur_state()
77 *state = dfc->cooling_state; in devfreq_cooling_get_cur_state()
85 struct devfreq_cooling_device *dfc = cdev->devdata; in devfreq_cooling_set_cur_state()
86 struct devfreq *df = dfc->devfreq; in devfreq_cooling_set_cur_state()
87 struct device *dev = df->dev.parent; in devfreq_cooling_set_cur_state()
91 if (state == dfc->cooling_state) in devfreq_cooling_set_cur_state()
96 if (state > dfc->max_state) in devfreq_cooling_set_cur_state()
97 return -EINVAL; in devfreq_cooling_set_cur_state()
99 if (dfc->em_pd) { in devfreq_cooling_set_cur_state()
100 perf_idx = dfc->max_state - state; in devfreq_cooling_set_cur_state()
101 freq = dfc->em_pd->table[perf_idx].frequency * 1000; in devfreq_cooling_set_cur_state()
103 freq = dfc->freq_table[state]; in devfreq_cooling_set_cur_state()
106 dev_pm_qos_update_request(&dfc->req_max_freq, in devfreq_cooling_set_cur_state()
109 dfc->cooling_state = state; in devfreq_cooling_set_cur_state()
115 * get_perf_idx() - get the performance index corresponding to a frequency
120 * -EINVAL if it wasn't found.
126 for (i = 0; i < em_pd->nr_perf_states; i++) { in get_perf_idx()
127 if (em_pd->table[i].frequency == freq) in get_perf_idx()
131 return -EINVAL; in get_perf_idx()
136 struct device *dev = df->dev.parent; in get_voltage()
138 struct dev_pm_opp *opp; in get_voltage() local
140 opp = dev_pm_opp_find_freq_exact(dev, freq, true); in get_voltage()
141 if (PTR_ERR(opp) == -ERANGE) in get_voltage()
142 opp = dev_pm_opp_find_freq_exact(dev, freq, false); in get_voltage()
144 if (IS_ERR(opp)) { in get_voltage()
145 dev_err_ratelimited(dev, "Failed to find OPP for frequency %lu: %ld\n", in get_voltage()
146 freq, PTR_ERR(opp)); in get_voltage()
150 voltage = dev_pm_opp_get_voltage(opp) / 1000; /* mV */ in get_voltage()
151 dev_pm_opp_put(opp); in get_voltage()
164 if (status->total_time > 0xfffff) { in _normalize_load()
165 status->total_time >>= 10; in _normalize_load()
166 status->busy_time >>= 10; in _normalize_load()
169 status->busy_time <<= 10; in _normalize_load()
170 status->busy_time /= status->total_time ? : 1; in _normalize_load()
172 status->busy_time = status->busy_time ? : 1; in _normalize_load()
173 status->total_time = 1024; in _normalize_load()
179 struct devfreq_cooling_device *dfc = cdev->devdata; in devfreq_cooling_get_requested_power()
180 struct devfreq *df = dfc->devfreq; in devfreq_cooling_get_requested_power()
187 mutex_lock(&df->lock); in devfreq_cooling_get_requested_power()
188 status = df->last_status; in devfreq_cooling_get_requested_power()
189 mutex_unlock(&df->lock); in devfreq_cooling_get_requested_power()
193 if (dfc->power_ops && dfc->power_ops->get_real_power) { in devfreq_cooling_get_requested_power()
196 res = -EINVAL; in devfreq_cooling_get_requested_power()
200 res = dfc->power_ops->get_real_power(df, power, freq, voltage); in devfreq_cooling_get_requested_power()
202 state = dfc->capped_state; in devfreq_cooling_get_requested_power()
203 dfc->res_util = dfc->em_pd->table[state].power; in devfreq_cooling_get_requested_power()
204 dfc->res_util *= SCALE_ERROR_MITIGATION; in devfreq_cooling_get_requested_power()
207 dfc->res_util /= *power; in devfreq_cooling_get_requested_power()
213 perf_idx = get_perf_idx(dfc->em_pd, freq / 1000); in devfreq_cooling_get_requested_power()
215 res = -EAGAIN; in devfreq_cooling_get_requested_power()
222 *power = dfc->em_pd->table[perf_idx].power; in devfreq_cooling_get_requested_power()
232 dfc->res_util = SCALE_ERROR_MITIGATION; in devfreq_cooling_get_requested_power()
239 struct devfreq_cooling_device *dfc = cdev->devdata; in devfreq_cooling_state2power()
242 if (state > dfc->max_state) in devfreq_cooling_state2power()
243 return -EINVAL; in devfreq_cooling_state2power()
245 perf_idx = dfc->max_state - state; in devfreq_cooling_state2power()
246 *power = dfc->em_pd->table[perf_idx].power; in devfreq_cooling_state2power()
254 struct devfreq_cooling_device *dfc = cdev->devdata; in devfreq_cooling_power2state()
255 struct devfreq *df = dfc->devfreq; in devfreq_cooling_power2state()
261 mutex_lock(&df->lock); in devfreq_cooling_power2state()
262 status = df->last_status; in devfreq_cooling_power2state()
263 mutex_unlock(&df->lock); in devfreq_cooling_power2state()
267 if (dfc->power_ops && dfc->power_ops->get_real_power) { in devfreq_cooling_power2state()
269 est_power = power * dfc->res_util; in devfreq_cooling_power2state()
280 * budget. The EM power table is sorted ascending. in devfreq_cooling_power2state()
282 for (i = dfc->max_state; i > 0; i--) in devfreq_cooling_power2state()
283 if (est_power >= dfc->em_pd->table[i].power) in devfreq_cooling_power2state()
286 *state = dfc->max_state - i; in devfreq_cooling_power2state()
287 dfc->capped_state = *state; in devfreq_cooling_power2state()
300 * devfreq_cooling_gen_tables() - Generate frequency table.
304 * Generate frequency table which holds the frequencies in descending
313 struct devfreq *df = dfc->devfreq; in devfreq_cooling_gen_tables()
314 struct device *dev = df->dev.parent; in devfreq_cooling_gen_tables()
318 dfc->freq_table = kcalloc(num_opps, sizeof(*dfc->freq_table), in devfreq_cooling_gen_tables()
320 if (!dfc->freq_table) in devfreq_cooling_gen_tables()
321 return -ENOMEM; in devfreq_cooling_gen_tables()
323 for (i = 0, freq = ULONG_MAX; i < num_opps; i++, freq--) { in devfreq_cooling_gen_tables()
324 struct dev_pm_opp *opp; in devfreq_cooling_gen_tables() local
326 opp = dev_pm_opp_find_freq_floor(dev, &freq); in devfreq_cooling_gen_tables()
327 if (IS_ERR(opp)) { in devfreq_cooling_gen_tables()
328 kfree(dfc->freq_table); in devfreq_cooling_gen_tables()
329 return PTR_ERR(opp); in devfreq_cooling_gen_tables()
332 dev_pm_opp_put(opp); in devfreq_cooling_gen_tables()
333 dfc->freq_table[i] = freq; in devfreq_cooling_gen_tables()
340 * of_devfreq_cooling_register_power() - Register devfreq cooling device,
359 struct device *dev = df->dev.parent; in of_devfreq_cooling_register_power()
366 return ERR_PTR(-ENOMEM); in of_devfreq_cooling_register_power()
368 dfc->devfreq = df; in of_devfreq_cooling_register_power()
370 dfc->em_pd = em_pd_get(dev); in of_devfreq_cooling_register_power()
371 if (dfc->em_pd) { in of_devfreq_cooling_register_power()
377 dfc->power_ops = dfc_power; in of_devfreq_cooling_register_power()
379 num_opps = em_pd_nr_perf_states(dfc->em_pd); in of_devfreq_cooling_register_power()
392 err = -EINVAL; in of_devfreq_cooling_register_power()
397 dfc->max_state = num_opps - 1; in of_devfreq_cooling_register_power()
399 err = dev_pm_qos_add_request(dev, &dfc->req_max_freq, in of_devfreq_cooling_register_power()
405 err = -ENOMEM; in of_devfreq_cooling_register_power()
406 name = kasprintf(GFP_KERNEL, "devfreq-%s", dev_name(dev)); in of_devfreq_cooling_register_power()
422 dfc->cdev = cdev; in of_devfreq_cooling_register_power()
427 dev_pm_qos_remove_request(&dfc->req_max_freq); in of_devfreq_cooling_register_power()
429 kfree(dfc->freq_table); in of_devfreq_cooling_register_power()
438 * of_devfreq_cooling_register() - Register devfreq cooling device,
451 * devfreq_cooling_register() - Register devfreq cooling device.
461 * devfreq_cooling_em_register() - Register devfreq cooling device with
471 * "dynamic-power-coefficient" a devicetree property. To not break drivers
485 return ERR_PTR(-EINVAL); in devfreq_cooling_em_register()
487 dev = df->dev.parent; in devfreq_cooling_em_register()
494 cdev = of_devfreq_cooling_register_power(dev->of_node, df, dfc_power); in devfreq_cooling_em_register()
504 * devfreq_cooling_unregister() - Unregister devfreq cooling device.
518 dfc = cdev->devdata; in devfreq_cooling_unregister()
519 dev = dfc->devfreq->dev.parent; in devfreq_cooling_unregister()
521 thermal_cooling_device_unregister(dfc->cdev); in devfreq_cooling_unregister()
522 dev_pm_qos_remove_request(&dfc->req_max_freq); in devfreq_cooling_unregister()
526 kfree(dfc->freq_table); in devfreq_cooling_unregister()