#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;
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. */
}
/* 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();
}
*
* @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.
--- /dev/null
+#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);
+}
--- /dev/null
+#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_ */
#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
#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);
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
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"));
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;
}