/** @time_last_update: Last update time. */
ktime_t time_last_update;
/** @last_busy_state: True if the GPU was busy last time we updated the state. */ bool last_busy_state;
/** * @lock: Lock used to protect busy_time, idle_time, time_last_update and * last_busy_state. * * These fields can be accessed concurrently by panthor_devfreq_get_dev_status() * and panthor_devfreq_record_{busy,idle}().
*/
spinlock_t lock;
};
int panthor_devfreq_init(struct panthor_device *ptdev)
{ /* There's actually 2 regulators (mali and sram), but the OPP core only * supports one. * * We assume the sram regulator is coupled with the mali one and let * the coupling logic deal with voltage updates.
*/ staticconstchar * const reg_names[] = { "mali", NULL }; struct thermal_cooling_device *cooling; struct device *dev = ptdev->base.dev; struct panthor_devfreq *pdevfreq; struct dev_pm_opp *opp; unsignedlong cur_freq; unsignedlong freq = ULONG_MAX; int ret;
pdevfreq = drmm_kzalloc(&ptdev->base, sizeof(*ptdev->devfreq), GFP_KERNEL); if (!pdevfreq) return -ENOMEM;
ptdev->devfreq = pdevfreq;
ret = devm_pm_opp_set_regulators(dev, reg_names); if (ret) { if (ret != -EPROBE_DEFER)
DRM_DEV_ERROR(dev, "Couldn't set OPP regulators\n");
return ret;
}
ret = devm_pm_opp_of_add_table(dev); if (ret) return ret;
spin_lock_init(&pdevfreq->lock);
panthor_devfreq_reset(pdevfreq);
cur_freq = clk_get_rate(ptdev->clks.core);
/* Regulator coupling only takes care of synchronizing/balancing voltage * updates, but the coupled regulator needs to be enabled manually. * * We use devm_regulator_get_enable_optional() and keep the sram supply * enabled until the device is removed, just like we do for the mali * supply, which is enabled when dev_pm_opp_set_opp(dev, opp) is called, * and disabled when the opp_table is torn down, using the devm action. * * If we really care about disabling regulators on suspend, we should: * - use devm_regulator_get_optional() here * - call dev_pm_opp_set_opp(dev, NULL) before leaving this function * (this disables the regulator passed to the OPP layer) * - call dev_pm_opp_set_opp(dev, NULL) and * regulator_disable(ptdev->regulators.sram) in * panthor_devfreq_suspend() * - call dev_pm_opp_set_opp(dev, default_opp) and * regulator_enable(ptdev->regulators.sram) in * panthor_devfreq_resume() * * But without knowing if it's beneficial or not (in term of power * consumption), or how much it slows down the suspend/resume steps, * let's just keep regulators enabled for the device lifetime.
*/
ret = devm_regulator_get_enable_optional(dev, "sram"); if (ret && ret != -ENODEV) { if (ret != -EPROBE_DEFER)
DRM_DEV_ERROR(dev, "Couldn't retrieve/enable sram supply\n"); return ret;
}
opp = devfreq_recommended_opp(dev, &cur_freq, 0); if (IS_ERR(opp)) return PTR_ERR(opp);
/* * Set the recommend OPP this will enable and configure the regulator * if any and will avoid a switch off by regulator_late_cleanup()
*/
ret = dev_pm_opp_set_opp(dev, opp);
dev_pm_opp_put(opp); if (ret) {
DRM_DEV_ERROR(dev, "Couldn't set recommended OPP\n"); return ret;
}
/* Find the fastest defined rate */
opp = dev_pm_opp_find_freq_floor(dev, &freq); if (IS_ERR(opp)) return PTR_ERR(opp);
ptdev->fast_rate = freq;
dev_pm_opp_put(opp);
/* * Setup default thresholds for the simple_ondemand governor. * The values are chosen based on experiments.
*/
pdevfreq->gov_data.upthreshold = 45;
pdevfreq->gov_data.downdifferential = 5;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.