aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorØrjan Eide <orjan.eide@arm.com>2015-02-27 16:45:36 +0100
committerJon Medhurst <tixy@linaro.org>2015-03-27 15:55:16 +0000
commit7ea06d36da23eee9ea68b75f3bb1bf9e5520e71a (patch)
tree246eeb719876fbc68ec3a138cc6b54b059e31f99 /drivers
parent28eedb0d97a4cd6d394c628d08fa5ccc2d14763a (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.c48
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,