diff options
author | Ørjan Eide <orjan.eide@arm.com> | 2015-02-27 16:45:36 +0100 |
---|---|---|
committer | Jon Medhurst <tixy@linaro.org> | 2015-03-27 15:55:16 +0000 |
commit | 7ea06d36da23eee9ea68b75f3bb1bf9e5520e71a (patch) | |
tree | 246eeb719876fbc68ec3a138cc6b54b059e31f99 /drivers | |
parent | 28eedb0d97a4cd6d394c628d08fa5ccc2d14763a (diff) |
mali: Scale for temperature in juno static power model
Signed-off-by: Jon Medhurst <tixy@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/arm/midgard/platform/juno_soc/mali_kbase_config_vexpress.c | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/drivers/gpu/arm/midgard/platform/juno_soc/mali_kbase_config_vexpress.c b/drivers/gpu/arm/midgard/platform/juno_soc/mali_kbase_config_vexpress.c index a19199b8f7d4..9c776eb7ef6c 100644 --- a/drivers/gpu/arm/midgard/platform/juno_soc/mali_kbase_config_vexpress.c +++ b/drivers/gpu/arm/midgard/platform/juno_soc/mali_kbase_config_vexpress.c @@ -9,6 +9,7 @@ #include <linux/ioport.h> #include <linux/devfreq_cooling.h> +#include <linux/thermal.h> #include <mali_kbase.h> #include <mali_kbase_defs.h> #include <mali_kbase_config.h> @@ -56,16 +57,47 @@ static struct kbase_pm_callback_conf pm_callbacks = { .power_resume_callback = NULL }; +#define FALLBACK_STATIC_TEMPERATURE 55000 + static unsigned long juno_model_static_power(unsigned long voltage) { - /* Calculate power, corrected for voltage. - * Shifts are done to avoid overflow. */ - const unsigned long coefficient = - (410UL << 20) / (729000000UL >> 10); - const unsigned long voltage_cubed = - (voltage * voltage * voltage) >> 10; - - return (((coefficient * voltage_cubed) >> 20)); + struct thermal_zone_device *tz; + unsigned long temperature, temp; + unsigned long temp_squared, temp_cubed, temp_scaling_factor; + const unsigned long coefficient = (410UL << 20) / (729000000UL >> 10); + const unsigned long voltage_cubed = (voltage * voltage * voltage) >> 10; + + tz = thermal_zone_get_zone_by_name("gpu"); + if (IS_ERR(tz)) { + pr_warn_ratelimited("Error getting gpu thermal zone (%ld), not yet ready?\n", + PTR_ERR(tz)); + temperature = FALLBACK_STATIC_TEMPERATURE; + } else { + int ret; + + ret = tz->ops->get_temp(tz, &temperature); + if (ret) { + pr_warn_ratelimited("Error reading temperature for gpu thermal zone: %d\n", + ret); + temperature = FALLBACK_STATIC_TEMPERATURE; + } + } + + /* Calculate the temperature scaling factor. To be applied to the + * voltage scaled power. + */ + temp = temperature / 1000; + temp_squared = temp * temp; + temp_cubed = temp_squared * temp; + temp_scaling_factor = + (2 * temp_cubed) + - (80 * temp_squared) + + (4700 * temp) + + 32000; + + return (((coefficient * voltage_cubed) >> 20) + * temp_scaling_factor) + / 1000000; } static unsigned long juno_model_dynamic_power(unsigned long freq, |