#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>
#include "mali_scaling.h"
#include "mali_clock.h"
#include "meson_main.h"
+#include "mali_executor.h"
/*
* For Meson 8 M2.
{
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
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);
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);
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);
+#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 */