add basic clock logic.
authorKasin Lee <kasin.li@amlogic.com>
Thu, 12 Sep 2013 17:07:57 +0000 (01:07 +0800)
committerKasin Lee <kasin.li@amlogic.com>
Thu, 12 Sep 2013 17:07:57 +0000 (01:07 +0800)
mali/platform/meson8/arm_core_scaling.c
mali/platform/meson8/arm_core_scaling.h
mali/platform/meson8/mali_clock.c [new file with mode: 0644]
mali/platform/meson8/mali_clock.h [new file with mode: 0644]
mali/platform/meson8/meson_main.c

index d7930a4d6012ee65e1e2f960c3d94c8991c5cc49..0df72bd6217e3d2579d8bcab4c505280ac1e6bda 100755 (executable)
 #include "mali_kernel_common.h"
 
 #include <linux/workqueue.h>
+#include "mali_clock.h"
 
 static int num_cores_total;
 static int num_cores_enabled;
+static current_mali_clock_index;
 
 static struct work_struct wq_work;
 
@@ -70,13 +72,14 @@ static void enable_max_num_cores(void)
        MALI_DEBUG_ASSERT(num_cores_total == num_cores_enabled);
 }
 
-void mali_core_scaling_init(int num_pp_cores)
+void mali_core_scaling_init(int num_pp_cores, int clock_rate_index)
 {
        INIT_WORK(&wq_work, set_num_cores);
 
        num_cores_total   = num_pp_cores;
        num_cores_enabled = num_pp_cores;
 
+       current_mali_clock_index = clock_rate_index;
        /* NOTE: Mali is not fully initialized at this point. */
 }
 
@@ -106,7 +109,7 @@ void mali_core_scaling_update(struct mali_gpu_utilization_data *data)
        /* NOTE: this function is normally called directly from the utilization callback which is in
         * timer context. */
 
-       if (     PERCENT_OF(90, 256) < data->utilization_pp)
+       if (PERCENT_OF(90, 256) < data->utilization_pp)
        {
                enable_max_num_cores();
        }
index 5c5def6063591901a3cc43c2f00fea3ea2dd067a..e06171569c962fda55569339b7414c48ebc1731e 100755 (executable)
@@ -25,7 +25,7 @@ struct mali_gpu_utilization_data;
  *
  * @param num_pp_cores Total number of PP cores.
  */
-void mali_core_scaling_init(int num_pp_cores);
+void mali_core_scaling_init(int num_pp_cores, int clock_rate_index);
 
 /**
  * Terminate core scaling policy.
diff --git a/mali/platform/meson8/mali_clock.c b/mali/platform/meson8/mali_clock.c
new file mode 100644 (file)
index 0000000..925e6d6
--- /dev/null
@@ -0,0 +1,77 @@
+#include <linux/platform_device.h>
+#include <linux/version.h>
+#include <linux/pm.h>
+#include <mach/register.h>
+#include <mach/irqs.h>
+#include <linux/io.h>
+#include <mach/io.h>
+#include <plat/io.h>
+#include <asm/io.h>
+#include <linux/mali/mali_utgard.h>
+#include "mali_kernel_common.h"
+
+#include "arm_core_scaling.h"
+#include "mali_clock.h"
+
+static DEFINE_SPINLOCK(lock);
+
+/* fclk is 2550Mhz. */
+#define FCLK_DEV3 (6 << 9)             /*      850   Mhz  */
+#define FCLK_DEV4 (5 << 9)             /*      637.5 Mhz  */
+#define FCLK_DEV5 (7 << 9)             /*      510   Mhz  */
+#define FCLK_DEV7 (4 << 9)             /*      364.3 Mhz  */
+
+unsigned int mali_dvfs_clk[MALI_DVFS_STEPS] = {
+                FCLK_DEV7 | 3,     /* 91  Mhz */
+                FCLK_DEV7 | 1,     /* 182.1 Mhz */
+                FCLK_DEV4 | 1,     /* 318.7 Mhz */
+                FCLK_DEV3 | 1,     /* 425 Mhz */
+                FCLK_DEV4 | 0,     /* 637.5 Mhz */
+};
+
+mali_dvfs_threshold_table mali_dvfs_threshold[MALI_DVFS_STEPS]={
+        {0, 180},      //0%-70%
+        {154, 230},    //%60-90%
+        {218, 230},    //%85-%90
+        {218, 230},    //%85-%90
+        {243, 256}  //%95-%100
+};
+
+int top_clk_limit = 4;
+
+void set_mali_clock(unsigned int utilization_pp)
+{
+       static int currentStep = MALI_DVFS_STEPS;
+       static int lastStep = MALI_DVFS_STEPS;
+
+       if (utilization_pp > mali_dvfs_threshold[currentStep].upthreshold) {
+               currentStep = MALI_DVFS_STEPS - 1;
+       } else if (utilization_pp < mali_dvfs_threshold[currentStep].downthreshold && currentStep > 0) {
+               currentStep--;
+       } else {
+               return;
+       }
+
+       if (currentStep != lastStep) {
+               int current_indx;
+
+               if (currentStep > top_clk_limit && top_clk_limit >= 0 && top_clk_limit < MALI_DVFS_STEPS) {
+                       current_indx = top_clk_limit;
+               } else {
+                       current_indx = currentStep;
+               }
+               mali_clock_set (current_indx);
+               lastStep = currentStep;
+       }
+}
+
+int inline mali_clock_set(int index) {
+       unsigned long flags;
+       
+       spin_lock_irqsave(&lock, flags);
+       clrbits_le32(P_HHI_MALI_CLK_CNTL, 1 << 8);
+       writel(mali_dvfs_clk[index], P_HHI_MALI_CLK_CNTL); /* set clock to 333MHZ.*/
+       readl(P_HHI_MALI_CLK_CNTL);
+       setbits_le32(P_HHI_MALI_CLK_CNTL, 1 << 8);
+       spin_unlock_irqrestore(&lock, flags);
+}
diff --git a/mali/platform/meson8/mali_clock.h b/mali/platform/meson8/mali_clock.h
new file mode 100644 (file)
index 0000000..8fe6f8e
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef _MALI_CLOCK_H_
+#define _MALI_CLOCK_H_
+
+enum mali_clock_rate {
+       MALI_CLOCK_91,
+       MALI_CLOCK_182,
+       MALI_CLOCK_318,
+       MALI_CLOCK_425,
+       MALI_CLOCK_637,
+       
+       MALI_CLOCK_INDX_MAX
+};
+
+#define MALI_DVFS_STEPS 5
+
+typedef struct mali_dvfs_Tag{
+       unsigned int step;
+       unsigned int mali_clk;
+}mali_dvfs_table;
+
+typedef struct mali_dvfs_thresholdTag{
+       unsigned int downthreshold;
+       unsigned int upthreshold;
+}mali_dvfs_threshold_table;
+
+void set_mali_clock(unsigned int utilization_pp);
+
+extern unsigned int mali_clock_table;
+extern int mali_clock_set(int index);
+
+#endif /* _MALI_CLOCK_H_ */
index 2db55735afb384502e2d009739ee1d360059d035..5883fdec17ee910cb15cc72ef5c401223e39614a 100755 (executable)
@@ -13,9 +13,7 @@
 #include <linux/pm.h>
 #include <mach/register.h>
 #include <mach/irqs.h>
-#include <linux/io.h>
 #include <mach/io.h>
-#include <plat/io.h>
 #ifdef CONFIG_PM_RUNTIME
 #include <linux/pm_runtime.h>
 #endif
@@ -24,6 +22,7 @@
 #include "mali_kernel_common.h"
 
 #include "arm_core_scaling.h"
+#include "mali_clock.h"
 
 static void mali_platform_device_release(struct device *device);
 static void mali_platform_device_release(struct device *device);
@@ -36,11 +35,10 @@ static int mali_runtime_suspend(struct device *device);
 static int mali_runtime_resume(struct device *device);
 static int mali_runtime_idle(struct device *device);
 #endif
-
-static DEFINE_SPINLOCK(lock);
-
 void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data);
 
+#define MALI_PP_NUMBER 6
+
 static struct resource mali_gpu_resources_m450[] =
 {
 #if 1
@@ -108,16 +106,10 @@ static struct mali_gpu_device_data mali_gpu_data =
 
 int mali_platform_device_register(void)
 {
-       unsigned long flags;
        int err = -1;
-       int num_pp_cores = 6;
+       int num_pp_cores = MALI_PP_NUMBER;
 
-       spin_lock_irqsave(&lock, flags);
-       clrbits_le32(P_HHI_MALI_CLK_CNTL, 1 << 8);
-       writel((5 << 9 | 0), P_HHI_MALI_CLK_CNTL); /* set clock to 333MHZ.*/
-       readl(P_HHI_MALI_CLK_CNTL);
-       setbits_le32(P_HHI_MALI_CLK_CNTL, 1 << 8);
-       spin_unlock_irqrestore(&lock, flags);
+       mali_clock_set(MALI_CLOCK_637);
 
        if (mali_gpu_data.shared_mem_size < 10) {
                MALI_DEBUG_PRINT(2, ("mali os memory didn't configered, set to default(512M)\n"));
@@ -145,7 +137,7 @@ int mali_platform_device_register(void)
                                pm_runtime_enable(&(mali_gpu_device.dev));
 #endif
                                MALI_DEBUG_ASSERT(0 < num_pp_cores);
-                               mali_core_scaling_init(num_pp_cores);
+                               mali_core_scaling_init(num_pp_cores, MALI_CLOCK_637);
 
                                return 0;
                        }