PD#114881: add gpu cooling hooks for ipa
authorTao Zeng <tao.zeng@amlogic.com>
Thu, 5 Nov 2015 11:09:32 +0000 (19:09 +0800)
committerTao Zeng <tao.zeng@amlogic.com>
Tue, 17 Nov 2015 06:50:15 +0000 (14:50 +0800)
for t83x, using dev_freq as cooling driver

Change-Id: I9a8d582b858c4405dfa08cc0dd752bfa2a42ac32

mali/platform/meson_bu/platform_gx.c
t83x/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_config_devicetree.c
t83x/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_config_platform.h

index 9dc9952119c9c00c0ea45f22b1df8439b1f1696c..ee42d6476c76d96b582f4c0ab9107205f52c218e 100644 (file)
@@ -24,6 +24,8 @@
 #ifdef CONFIG_GPU_THERMAL
 #include <linux/gpu_cooling.h>
 #include <linux/gpucore_cooling.h>
+#include <linux/amlogic/aml_thermal_hw.h>
+#include <common/mali_ukk.h>
 #endif
 #include <common/mali_kernel_common.h>
 #include <common/mali_osk_profiling.h>
@@ -32,6 +34,7 @@
 #include "mali_scaling.h"
 #include "mali_clock.h"
 #include "meson_main.h"
+#include "mali_executor.h"
 
 /*
  *    For Meson 8 M2.
@@ -111,6 +114,11 @@ static u32 get_limit_mali_freq(void)
 {
     return mali_plat_data.scale_info.maxclk;
 }
+
+static u32 get_mali_utilization(void)
+{
+    return (_mali_ukk_utilization_pp() * 100) / 256;
+}
 #endif
 
 #ifdef CONFIG_GPU_THERMAL
@@ -128,6 +136,17 @@ static u32 set_limit_pp_num(u32 num)
 quit:
     return ret;
 }
+static u32 mali_get_online_pp(void)
+{
+    unsigned int val;
+    mali_plat_info_t* pmali_plat = get_mali_plat_data();
+
+    val = readl(pmali_plat->reg_base_aobus + 0xf0) & 0xff;
+    if (val == 0x07)    /* No pp is working */
+        return 0;
+
+    return mali_executor_get_num_cores_enabled();
+}
 #endif
 
 void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data);
@@ -314,7 +333,11 @@ void mali_post_init(void)
         gcdev->get_gpu_max_level = get_mali_max_level;
         gcdev->set_gpu_freq_idx = set_limit_mali_freq;
         gcdev->get_gpu_current_max_level = get_limit_mali_freq;
+        gcdev->get_gpu_freq = get_mali_freq;
+        gcdev->get_gpu_loading = get_mali_utilization;
+        gcdev->get_online_pp = mali_get_online_pp;
         err = gpufreq_cooling_register(gcdev);
+        aml_thermal_min_update(gcdev->cool_dev);
         if (err < 0)
             printk("register GPU  cooling error\n");
         printk("gpu cooling register okay with err=%d\n",err);
@@ -329,6 +352,7 @@ void mali_post_init(void)
         gccdev->max_gpu_core_num=mali_plat_data.cfg_pp;
         gccdev->set_max_pp_num=set_limit_pp_num;
         err = (int)gpucore_cooling_register(gccdev);
+        aml_thermal_min_update(gccdev->cool_dev);
         if (err < 0)
             printk("register GPU  cooling error\n");
         printk("gpu core cooling register okay with err=%d\n",err);
index 046302e8e41f7b0876eeda71e38eb41be0660340..59c36b45a5c6019cc8f6b78663a860a8684676da 100755 (executable)
 
 
 
+#ifdef CONFIG_DEVFREQ_THERMAL
+#include <linux/devfreq_cooling.h>
+#include <linux/thermal.h>
+
+#define FALLBACK_STATIC_TEMPERATURE 55000
+
+static unsigned long t83x_static_power(unsigned long voltage)
+{
+#if 0
+       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;
+#else
+       return 0;
+#endif
+}
+
+static unsigned long t83x_dynamic_power(unsigned long freq,
+               unsigned long voltage)
+{
+       /* The inputs: freq (f) is in Hz, and voltage (v) in mV.
+        * The coefficient (c) is in mW/(MHz mV mV).
+        *
+        * This function calculates the dynamic power after this formula:
+        * Pdyn (mW) = c (mW/(MHz*mV*mV)) * v (mV) * v (mV) * f (MHz)
+        */
+       const unsigned long v2 = (voltage * voltage) / 1000; /* m*(V*V) */
+       const unsigned long f_mhz = freq / 1000000; /* MHz */
+       const unsigned long coefficient = 3600; /* mW/(MHz*mV*mV) */
+
+       return (coefficient * v2 * f_mhz) / 1000000; /* mW */
+}
+
+struct devfreq_cooling_ops t83x_model_ops = {
+       .get_static_power = t83x_static_power,
+       .get_dynamic_power = t83x_dynamic_power,
+};
+
+#endif
+
 int kbase_platform_early_init(void)
 {
        /* Nothing needed at this stage */
index f92961c53a01eefd4f9e777820f70eb5190c01f4..0b31dac215692e2678a6f1e1478b738fda8a8c57 100755 (executable)
  *
  * Attached value: pointer to @ref mali_pa_model_ops
  */
+#ifdef CONFIG_DEVFREQ_THERMAL
+#define POWER_MODEL_CALLBACKS (&t83x_model_ops)
+extern struct devfreq_cooling_ops t83x_model_ops;
+#else
 #define POWER_MODEL_CALLBACKS (NULL)
-
+#endif
 extern struct kbase_pm_callback_conf pm_callbacks;
 
 /**