PD #80887: update work flow of DVFS for m8
authorKasin Lee <kasin.li@amlogic.com>
Sun, 22 Jun 2014 10:32:53 +0000 (18:32 +0800)
committereric <eric.zhong@amlogic.com>
Thu, 26 Jun 2014 09:24:40 +0000 (17:24 +0800)
20 files changed:
mali/Kbuild
mali/common/mali_group.c
mali/common/mali_mmu.c [changed mode: 0644->0755]
mali/common/mali_mmu.h
mali/common/mali_pp_scheduler.c [changed mode: 0644->0755]
mali/linux/mali_osk_irq.c [changed mode: 0644->0755]
mali/linux/mali_sync.c [changed mode: 0644->0755]
mali/platform/mali_clock.c
mali/platform/mali_clock.h
mali/platform/mali_scaling.h
mali/platform/meson_m400/platform_mx.c
mali/platform/meson_m450/platform_m6tvd.c
mali/platform/meson_m450/platform_m8.c
mali/platform/meson_m450/platform_m8b.c
mali/platform/meson_m450/scaling.c [new file with mode: 0755]
mali/platform/meson_m450/scaling_m8.c [deleted file]
mali/platform/meson_m450/scaling_m8b.c [deleted file]
mali/platform/meson_main.c
mali/platform/meson_main.h
mali/platform/mpgpu.c

index 8512ca1055afdd562cc58e104c097282c93f6b34..cc72e1a3625e26f7884c80fb93742058d291f191 100755 (executable)
@@ -160,17 +160,17 @@ endif
 
 ifeq ($(TARGET_PLATFORM),meson_m450)
 ccflags-y += -DCONFIG_MALI450=y
+mali-y += \
+       platform/meson_m450/scaling.o 
+
 mali-$(CONFIG_ARCH_MESON8) += \
-       platform/meson_m450/platform_m8.o \
-       platform/meson_m450/scaling_m8.o 
+       platform/meson_m450/platform_m8.o
 
 mali-$(CONFIG_ARCH_MESON6TVD) += \
-       platform/meson_m450/platform_m6tvd.o \
-       
-       
+       platform/meson_m450/platform_m6tvd.o
+
 mali-$(CONFIG_ARCH_MESON8B) += \
-       platform/meson_m450/platform_m8b.o \
-       platform/meson_m450/scaling_m8b.o 
+       platform/meson_m450/platform_m8b.o
 endif
 ##################### end Kasin Added. ###################
 
index f1479e7d8d94ec9b9e6737294b6dc29ec258c89e..9c31e0919a1a26a8d8d085b986b639ae6c6647d8 100755 (executable)
@@ -7,14 +7,9 @@
  * A copy of the licence is included with the program, and can also be obtained from Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
- //#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
-#include <linux/kernel.h>
-#include <asm/io.h>
-#include <mach/am_regs.h>
-#include <linux/module.h>
-//#endif
 
+#include <linux/types.h>
+#include <mach/cpu.h>
 #include "mali_kernel_common.h"
 #include "mali_group.h"
 #include "mali_osk.h"
@@ -1136,19 +1131,10 @@ static void mali_group_mmu_page_fault_and_unlock(struct mali_group *group)
 }
 
 #if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
-inline mali_bool mali_group_power_is_on_2(struct mali_group *group)
-{
-#ifdef DEBUG
-       if(_mali_osk_lock_get_owner(group->lock) == _mali_osk_get_tid())
-               return group->power_is_on;
-       else 
-               return MALI_FALSE;
-#else
-       return group->power_is_on;
-#endif
-}
+#define INT_MALI_PP2_MMU ( 6+32)
+struct _mali_osk_irq_t_struct;
+u32 get_irqnum(struct _mali_osk_irq_t_struct* irq);
 #endif
-
 _mali_osk_errcode_t mali_group_upper_half_mmu(void * data)
 {
        _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
@@ -1159,20 +1145,23 @@ _mali_osk_errcode_t mali_group_upper_half_mmu(void * data)
        MALI_DEBUG_ASSERT_POINTER(mmu);
 
 #if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
-       if ( MALI_FALSE == mali_group_power_is_on_2(group) )
-       {
-               if (mmu->id == 2)
-                       malifix_set_mmu_int_process_state(0, MMU_INT_NONE);
-               else if (mmu->id == 3)
-                       malifix_set_mmu_int_process_state(1, MMU_INT_NONE);
-               MALI_DEBUG_PRINT(4, ("Mali MMU: invalid interrupt. <<-- \n"));
+       if (MALI_FALSE == group->power_is_on)
                MALI_SUCCESS;
-       }
-#endif
-
-#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
-       if (MALI_FALSE == mali_pm_domain_lock_state(group->pm_domain)) {
-               goto out;
+       if (get_irqnum(mmu->irq) == INT_MALI_PP2_MMU)
+       {
+               if (group->pp_core->core_id == 0) {
+                       if (malifix_get_mmu_int_process_state(0) == MMU_INT_HIT)
+                               malifix_set_mmu_int_process_state(0, MMU_INT_TOP);
+                       else
+                               MALI_SUCCESS;
+               }
+               else if (group->pp_core->core_id == 1) {
+                       if (malifix_get_mmu_int_process_state(1) == MMU_INT_HIT)
+                               malifix_set_mmu_int_process_state(1, MMU_INT_TOP);
+                       else
+                               MALI_SUCCESS;
+               } else
+                       MALI_SUCCESS;
        }
 #endif
 
@@ -1239,10 +1228,17 @@ static void mali_group_bottom_half_mmu(void * data)
                return;
        }
 #if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
-       if (mmu->id == 2)
-               malifix_set_mmu_int_process_state(0, MMU_INT_NONE);
-       else if (mmu->id == 3)
-               malifix_set_mmu_int_process_state(1, MMU_INT_NONE);
+       if (get_irqnum(mmu->irq) == INT_MALI_PP2_MMU)
+       {
+               if (group->pp_core->core_id == 0) {
+                       if (malifix_get_mmu_int_process_state(0) == MMU_INT_TOP)
+                               malifix_set_mmu_int_process_state(0, MMU_INT_NONE);
+               }
+               else if (group->pp_core->core_id == 1) {
+                       if (malifix_get_mmu_int_process_state(1) == MMU_INT_TOP)
+                               malifix_set_mmu_int_process_state(1, MMU_INT_NONE);
+               }
+       }
 #endif 
 
        mali_group_unlock(group);
old mode 100644 (file)
new mode 100755 (executable)
index 6d73c02..c9d4b52
@@ -109,11 +109,6 @@ struct mali_mmu_core *mali_mmu_create(_mali_osk_resource_t *resource, struct mal
        mmu = _mali_osk_calloc(1,sizeof(struct mali_mmu_core));
        if (NULL != mmu)
        {
-#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
-               extern int static_pp_mmu_cnt;
-               mmu->id = static_pp_mmu_cnt++;
-               //MALI_DEBUG_PRINT(3, ("Mali MMU: mmu_id: %d\n", resource->mmu_id));
-#endif
                if (_MALI_OSK_ERR_OK == mali_hw_core_create(&mmu->hw_core, resource, MALI_MMU_REGISTERS_SIZE)) {
                        if (_MALI_OSK_ERR_OK == mali_group_add_mmu_core(group, mmu)) {
                                if (is_virtual) {
index 236923ca90eccb13527a53057cde3f4465803813..07d20c797f70a66fb62580b038ebe599a7f522e7 100755 (executable)
@@ -74,10 +74,6 @@ typedef enum mali_mmu_status_bits {
 struct mali_mmu_core {
        struct mali_hw_core hw_core; /**< Common for all HW cores */
        _mali_osk_irq_t *irq;        /**< IRQ handler */
-
-#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
-       u32 id;
-#endif
 };
 
 _mali_osk_errcode_t mali_mmu_initialize(void);
old mode 100644 (file)
new mode 100755 (executable)
index 8dd8e3e..1b0dd67
@@ -1728,7 +1728,7 @@ static void mali_pp_scheduler_notify_core_change(u32 num_cores)
 
 static void mali_pp_scheduler_core_scale_up(unsigned int target_core_nr)
 {
-       MALI_DEBUG_PRINT(2, ("Requesting %d cores: enabling %d cores\n", target_core_nr, target_core_nr - enabled_cores));
+       MALI_DEBUG_PRINT(3, ("Requesting %d cores: enabling %d cores\n", target_core_nr, target_core_nr - enabled_cores));
 
        _mali_osk_pm_dev_ref_add_no_power_on();
        _mali_osk_pm_dev_barrier();
@@ -1766,7 +1766,7 @@ static void mali_pp_scheduler_core_scale_up(unsigned int target_core_nr)
 
 static void mali_pp_scheduler_core_scale_down(unsigned int target_core_nr)
 {
-       MALI_DEBUG_PRINT(2, ("Requesting %d cores: disabling %d cores\n", target_core_nr, enabled_cores - target_core_nr));
+       MALI_DEBUG_PRINT(3, ("Requesting %d cores: disabling %d cores\n", target_core_nr, enabled_cores - target_core_nr));
 
        mali_pp_scheduler_suspend();
 
old mode 100644 (file)
new mode 100755 (executable)
index 3576599..bd213aa
@@ -13,6 +13,8 @@
  * Implementation of the OS abstraction layer for the kernel device driver
  */
 
+#include <linux/types.h>
+#include <mach/cpu.h>
 #include <linux/slab.h>        /* For memory allocation */
 #include <linux/interrupt.h>
 #include <linux/wait.h>
@@ -30,6 +32,16 @@ typedef struct _mali_osk_irq_t_struct {
 typedef irqreturn_t (*irq_handler_func_t)(int, void *, struct pt_regs *);
 static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ); /* , struct pt_regs *regs*/
 
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
+u32 get_irqnum(struct _mali_osk_irq_t_struct* irq)
+{
+       if (irq)
+               return irq->irqnum;
+       else
+               return 0;
+}
+#endif
+
 #if defined(DEBUG)
 #if 0
 
old mode 100644 (file)
new mode 100755 (executable)
index d85d5bb..7ae5a88
@@ -45,6 +45,11 @@ static struct sync_pt *timeline_dup(struct sync_pt *pt)
        struct sync_pt *new_pt;
 
        MALI_DEBUG_ASSERT_POINTER(pt);
+
+       if (NULL == pt) {
+               dump_stack();
+               return NULL;
+       }
        mpt = to_mali_sync_pt(pt);
 
        new_pt = sync_pt_create(pt->parent, sizeof(struct mali_sync_pt));
index 8d2c43e95e9d5f7d83905e282d70d2625c883edb..6b7f3c59afc8c87da94e1c350cc8b000ab0a9a1d 100755 (executable)
@@ -7,30 +7,37 @@
 #include <mach/io.h>
 #include <plat/io.h>
 #include <asm/io.h>
-
 #include "meson_main.h"
 
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
+
 #define FCLK_MPLL2 (2 << 9)
-static DEFINE_SPINLOCK(lock);
 
+static DEFINE_SPINLOCK(lock);
+static mali_plat_info_t* pmali_plat = NULL;
 static u32 mali_extr_backup = 0;
+static u32 mali_extr_sample_backup = 0;
 
-#if MESON_CPU_TYPE > MESON_CPU_TYPE_MESON8
-#define HAVE_MALI_CLOCK_SWITCH 1
-#endif
-
-int mali_clock_init(u32 def_clk_idx)
+int mali_clock_init(mali_plat_info_t* mali_plat)
 {
-#ifdef HAVE_MALI_CLOCK_SWITCH
-       writel((mali_dvfs_clk[def_clk_idx]<<16)|(mali_dvfs_clk[def_clk_idx]<<16), (u32*)P_HHI_MALI_CLK_CNTL);
-       setbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 24);
-       setbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 8);
-#else
-       mali_clock_set(def_clk_idx);
-#endif
-#if MESON_CPU_TYPE > MESON_CPU_TYPE_MESON8
-       mali_extr_backup = mali_dvfs_clk[get_mali_tbl_size() -1];
-#endif
+       u32 def_clk_data;
+       if (mali_plat == NULL) {
+               printk(" Mali platform data is NULL!!!\n");
+               return -1;
+       }
+
+       pmali_plat = mali_plat;
+       if (pmali_plat->have_switch) {
+               def_clk_data = pmali_plat->clk[pmali_plat->def_clock];
+               writel(def_clk_data | (def_clk_data << 16), (u32*)P_HHI_MALI_CLK_CNTL);
+               setbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 24);
+               setbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 8);
+       } else {
+               mali_clock_set(pmali_plat->def_clock);
+       }
+
+       mali_extr_backup = pmali_plat->clk[pmali_plat->clk_len - 1];
+       mali_extr_sample_backup = pmali_plat->clk_sample[pmali_plat->clk_len - 1];
        return 0;
 }
 
@@ -48,19 +55,19 @@ int mali_clock_critical(critical_t critical, size_t param)
 static int critical_clock_set(size_t param)
 {
        unsigned int idx = param;
-#ifdef HAVE_MALI_CLOCK_SWITCH
-       u32 clk_value;
-       setbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 31);
-       clk_value = readl((u32 *)P_HHI_MALI_CLK_CNTL) & 0xffff0000;
-       clk_value = clk_value | mali_dvfs_clk[idx] | (1 << 8);
-       writel(clk_value, (u32*)P_HHI_MALI_CLK_CNTL);
-       clrbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 31);
-#else
-       clrbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 8);
-       clrbits_le32((u32)P_HHI_MALI_CLK_CNTL, (0x7F | (0x7 << 9)));
-       writel(mali_dvfs_clk[idx], (u32*)P_HHI_MALI_CLK_CNTL); /* set clock to 333MHZ.*/
-       setbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 8);
-#endif
+       if (pmali_plat->have_switch) {
+               u32 clk_value;
+               setbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 31);
+               clk_value = readl((u32 *)P_HHI_MALI_CLK_CNTL) & 0xffff0000;
+               clk_value = clk_value | pmali_plat->clk[idx] | (1 << 8);
+               writel(clk_value, (u32*)P_HHI_MALI_CLK_CNTL);
+               clrbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 31);
+       } else {
+               clrbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 8);
+               clrbits_le32((u32)P_HHI_MALI_CLK_CNTL, (0x7F | (0x7 << 9)));
+               writel(pmali_plat->clk[idx], (u32*)P_HHI_MALI_CLK_CNTL);
+               setbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 8);
+       }
        return 0;
 }
 
@@ -72,6 +79,7 @@ int mali_clock_set(unsigned int clock)
 void disable_clock(void)
 {
        unsigned long flags;
+
        spin_lock_irqsave(&lock, flags);
        clrbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 8);
        spin_unlock_irqrestore(&lock, flags);
@@ -79,8 +87,9 @@ void disable_clock(void)
 
 void enable_clock(void)
 {
-       u32 ret = 0;
+       u32 ret;
        unsigned long flags;
+
        spin_lock_irqsave(&lock, flags);
        setbits_le32((u32)P_HHI_MALI_CLK_CNTL, 1 << 8);
        ret = readl((u32 *)P_HHI_MALI_CLK_CNTL) & (1 << 8);
@@ -89,22 +98,22 @@ void enable_clock(void)
 
 u32 get_mali_freq(u32 idx)
 {
-       return mali_dvfs_clk_sample[idx];
+       return pmali_plat->clk_sample[idx];
 }
 
 void set_str_src(u32 data)
 {
-#if MESON_CPU_TYPE > MESON_CPU_TYPE_MESON8
        if (data == 11) {
                writel(0x0004d000, (u32*)P_HHI_MPLL_CNTL9);
        } else if (data > 11) {
                writel(data, (u32*)P_HHI_MPLL_CNTL9);
        }
-
        if (data == 0) {
-               mali_dvfs_clk[get_mali_tbl_size() -1] = mali_extr_backup;
+               pmali_plat->clk[pmali_plat->clk_len - 1] = mali_extr_backup;
+               pmali_plat->clk_sample[pmali_plat->clk_len - 1] = mali_extr_sample_backup;
        } else if (data > 10) {
-               mali_dvfs_clk[get_mali_tbl_size() -1] = FCLK_MPLL2;
+               pmali_plat->clk_sample[pmali_plat->clk_len - 1] = 600;
+               pmali_plat->clk[pmali_plat->clk_len - 1] = FCLK_MPLL2;
        }
-#endif
 }
+#endif
index 754c1bd163aff319d8e95b8cff9c3f229c6ace16..53ccda064d7d818c8c39ddc7edc7bb7c6ded73e4 100755 (executable)
@@ -4,7 +4,7 @@
 typedef int (*critical_t)(size_t param);
 int mali_clock_critical(critical_t critical, size_t param);
 
-int mali_clock_init(u32 def_clk_idx);
+int mali_clock_init(mali_plat_info_t*);
 int mali_clock_set(unsigned int index);
 void disable_clock(void);
 void enable_clock(void);
index bd4168e7b613d568f58de503991f6aa794a74be4..a19618e796268f2e8484c7d1f99b968933e56820 100755 (executable)
 #ifndef __ARM_CORE_SCALING_H__
 #define __ARM_CORE_SCALING_H__
 
+enum mali_scale_mode_t {
+       MALI_PP_SCALING = 0,
+       MALI_PP_FS_SCALING,
+       MALI_SCALING_DISABLE,
+       MALI_TURBO_MODE,
+       MALI_SCALING_MODE_MAX
+};
+
 typedef struct mali_dvfs_threshold_table {
        unsigned int freq_index;
        unsigned int voltage;
        unsigned int keep_count;
        unsigned int downthreshold;
        unsigned int upthreshold;
-} mali_dvfs_threshold_table_t;
+} mali_dvfs_threshold_table;
+
+/**
+ *  restrictions on frequency and number of pp.
+ */
+typedef struct mali_scale_info_t {
+       u32 minpp;
+       u32 maxpp;
+       u32 minclk;
+       u32 maxclk;
+} mali_scale_info_t;
+
+/**
+ * Platform spesific data for meson chips.
+ */
+typedef struct mali_plat_info_t {
+       u32 cfg_pp; /* number of pp. */
+       u32 cfg_min_pp;
+       u32 turbo_clock; /* reserved clock src. */
+       u32 def_clock; /* gpu clock used most of time.*/
+       u32 cfg_clock; /* max clock could be used.*/
+       u32 cfg_min_clock;
+
+       u32  sc_mpp; /* number of pp used most of time.*/
+       u32  bst_gpu; /* threshold for boosting gpu. */
+       u32  bst_pp; /* threshold for boosting PP. */
+
+       u32 *clk;
+       u32 *clk_sample;
+       u32 clk_len;
+       u32 have_switch; /* have clock gate switch or not. */
+
+       mali_dvfs_threshold_table *dvfs_table;
+       u32 dvfs_table_size;
+
+       mali_scale_info_t scale_info;
+
+       /* set upper limit of pp or frequency, for THERMAL thermal or band width saving.*/
+       u32 limit_on;
+
+       /* for boost up gpu by user. */
+       void (*plat_preheat)(void);
+} mali_plat_info_t;
+mali_plat_info_t* get_mali_plat_data(void);
 
 /**
  * Initialize core scaling policy.
@@ -31,47 +82,29 @@ typedef struct mali_dvfs_threshold_table {
  *
  * @param num_pp_cores Total number of PP cores.
  */
-void mali_core_scaling_init(int pp, int clock_idx);
+int mali_core_scaling_init(mali_plat_info_t*);
 
 /**
  * Terminate core scaling policy.
  */
 void mali_core_scaling_term(void);
 
-/**
- * Update core scaling policy with new utilization data.
- *
- * @param data Utilization data.
- */
-
 /**
  * cancel and flush scaling job queue.
  */
 void flush_scaling_job(void);
 
-u32 set_mali_dvfs_tbl_size(u32 size);
-u32 get_max_dvfs_tbl_size(void);
-uint32_t* get_mali_dvfs_tbl_addr(void);
-
-/* get or set the max/min number of pp cores. */
-u32 get_max_pp_num(void);
-u32 set_max_pp_num(u32 num);
-u32 get_min_pp_num(void);
-u32 set_min_pp_num(u32 num);
-
-/* get or set the max/min frequency of GPU. */
-u32 get_max_mali_freq(void);
-u32 set_max_mali_freq(u32 idx);
-u32 get_min_mali_freq(void);
-u32 set_min_mali_freq(u32 idx);
+/* get current state(pp, clk). */
+void get_mali_rt_clkpp(u32* clk, u32* pp);
+u32 set_mali_rt_clkpp(u32 clk, u32 pp, u32 flush);
+void revise_mali_rt(void);
 
 /* get or set the scale mode. */
 u32 get_mali_schel_mode(void);
 void set_mali_schel_mode(u32 mode);
 
-/* preheat of the GPU. */
-void mali_plat_preheat(void);
-
 /* for frequency reporter in DS-5 streamline. */
 u32 get_current_frequency(void);
+
+extern int mali_pm_statue;
 #endif /* __ARM_CORE_SCALING_H__ */
index 3aec708264d8992779d12f29088854b2543d8ca3..5bd11cdb4d6f35ccbe5d281098b2ba7288fa188f 100755 (executable)
@@ -40,23 +40,6 @@ u32 mali_dvfs_clk_sample[1];
 
 static struct mali_dvfs_threshold_table mali_dvfs_threshold[1];
 
-u32 set_mali_dvfs_tbl_size(u32 size)
-{
-       return 0;
-}
-
-u32 get_max_dvfs_tbl_size(void)
-{
-       return 0;
-}
-
-uint32_t* get_mali_dvfs_tbl_addr(void)
-{
-       return mali_dvfs_threshold;
-}
-
-
-
 #if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6TV
 #undef INT_MALI_GP
 #undef INT_MALI_GP_MMU
@@ -103,8 +86,6 @@ static struct resource meson_mali_resources[] =
 
 #elif MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
 
-int static_pp_mmu_cnt;
-
 #undef INT_MALI_GP
 #undef INT_MALI_GP_MMU
 #undef INT_MALI_PP
@@ -150,6 +131,10 @@ void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data)
 
 }
 
+mali_plat_info_t mali_plat_data = {
+
+};
+
 int mali_meson_init_start(struct platform_device* ptr_plt_dev)
 {
        /* for mali platform data. */
index 426ed28a94de71a8580b67fa0821b59837f701ed..bfd67910a62e480bd07eb4368ff194020f7a5436 100755 (executable)
@@ -1,6 +1,6 @@
 /*
  * platform.c
- * 
+ *
  * clock source setting and resource config
  *
  *  Created on: Dec 4, 2013
 
 #include "meson_main.h"
 
-/**
- *    For Meson 6tvd.
- * 
+/*
+ *    For Meson 8TVD.
+ *
  */
 
-#ifdef MESON_CPU_TYPE_MESON6TVD
-#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6TVD
-
-u32 mali_clock_turbo_index = 3;
-u32 mali_default_clock_idx = 3;
-u32 mali_up_clock_idx = 3;
+#define CFG_PP 2
+#define CFG_CLOCK 3
+#define CFG_MIN_PP 1
+#define CFG_MIN_CLOCK 0
 
 /* fclk is 2Ghz. */
 #define FCLK_DEV5 (7 << 9)             /*      400   Mhz  */
@@ -52,14 +50,25 @@ u32 mali_dvfs_clk[] = {
 };
 
 u32 mali_dvfs_clk_sample[] = {
-       182,     /* 182.1 Mhz */
-       319,     /* 318.7 Mhz */
-       425,     /* 425 Mhz */
-       510,     /* 510 Mhz */
-       637,     /* 637.5 Mhz */
+       100,     /* 182.1 Mhz */
+       200,     /* 318.7 Mhz */
+       333,     /* 425 Mhz */
+       400,     /* 510 Mhz */
+};
+
+static mali_plat_info_t mali_plat_data = {
+       .cfg_pp = CFG_PP,  /* number of pp. */
+       .cfg_min_pp = CFG_MIN_PP,
+       .def_clock = CFG_CLOCK, /* gpu clock used most of time.*/
+       .cfg_clock = CFG_CLOCK, /* max gpu clock. */
+       .cfg_min_clock = CFG_MIN_CLOCK,
+
+       .clk = mali_dvfs_clk, /* clock source table. */
+       .clk_sample = mali_dvfs_clk_sample, /* freqency table for show. */
+       .clk_len = sizeof(mali_dvfs_clk) / sizeof(mali_dvfs_clk[0]),
+       .have_switch = 0,
 };
 
-#define MALI_PP_NUMBER 2
 #define MALI_USER_PP0  AM_IRQ4(31)
 
 static struct resource mali_gpu_resources[] =
@@ -74,7 +83,7 @@ int mali_meson_init_start(struct platform_device* ptr_plt_dev)
 {
        ptr_plt_dev->num_resources = ARRAY_SIZE(mali_gpu_resources);
        ptr_plt_dev->resource = mali_gpu_resources;
-       return mali_clock_init(mali_default_clock_idx);
+       return mali_clock_init(&mali_plat_data);
 }
 
 int mali_meson_init_finish(struct platform_device* ptr_plt_dev)
@@ -87,26 +96,6 @@ int mali_meson_uninit(struct platform_device* ptr_plt_dev)
        return 0;
 }
 
-u32 set_mali_dvfs_tbl_size(u32 size)
-{
-       return 0;
-}
-
-u32 get_max_dvfs_tbl_size(void)
-{
-       return 0;
-}
-
-uint32_t* get_mali_dvfs_tbl_addr(void)
-{
-       return NULL;
-}
-
-void mali_core_scaling_term(void)
-{
-
-}
-
 static int mali_cri_pmu_on_off(size_t param)
 {
        struct mali_pmu_core *pmu;
@@ -202,5 +191,4 @@ int mali_deep_resume(struct device *device)
        return ret;
 
 }
-#endif /* MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8 */
-#endif /* define MESON_CPU_TYPE_MESON6TVD */
+
index b790a21a8ba85f2d3e42421167c945d381a10acb..344708ec2e0486ea0cc5c446f690fb67f3d6ac15 100755 (executable)
  *
  */
 
-#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8
-u32 mali_clock_turbo_index = 4;
-u32 mali_default_clock_idx = 0;
-u32 mali_up_clock_idx = 3;
+#define CFG_PP 6
+#define CFG_CLOCK 3
+#define CFG_MIN_PP 1
+#define CFG_MIN_CLOCK 0
 
 /* fclk is 2550Mhz. */
 #define FCLK_DEV3 (6 << 9)             /*      850   Mhz  */
@@ -43,7 +43,7 @@ u32 mali_up_clock_idx = 3;
 #define FCLK_DEV5 (7 << 9)             /*      510   Mhz  */
 #define FCLK_DEV7 (4 << 9)             /*      364.3 Mhz  */
 
-u32 mali_dvfs_clk[] = {
+static u32 mali_dvfs_clk[] = {
        FCLK_DEV7 | 1,     /* 182.1 Mhz */
        FCLK_DEV4 | 1,     /* 318.7 Mhz */
        FCLK_DEV3 | 1,     /* 425 Mhz */
@@ -51,7 +51,7 @@ u32 mali_dvfs_clk[] = {
        FCLK_DEV4 | 0,     /* 637.5 Mhz */
 };
 
-u32 mali_dvfs_clk_sample[] = {
+static u32 mali_dvfs_clk_sample[] = {
        182,     /* 182.1 Mhz */
        319,     /* 318.7 Mhz */
        425,     /* 425 Mhz */
@@ -59,25 +59,84 @@ u32 mali_dvfs_clk_sample[] = {
        637,     /* 637.5 Mhz */
 };
 
-u32 get_mali_tbl_size(void)
+static mali_dvfs_threshold_table mali_dvfs_table[]={
+               { 0, 0, 3,  70, 180}, /* for 182.1  */
+               { 1, 1, 3, 108, 205}, /* for 318.7  */
+               { 2, 2, 3, 150, 215}, /* for 425.0  */
+               { 3, 3, 3, 170, 253}, /* for 510.0  */
+               { 4, 4, 3, 230, 256},  /* for 637.5  */
+               { 0, 0, 3,   0,   0}
+};
+
+static void mali_plat_preheat(void);
+static mali_plat_info_t mali_plat_data = {
+       .cfg_pp = CFG_PP,  /* number of pp. */
+       .cfg_min_pp = CFG_MIN_PP,
+       .turbo_clock = 4, /* reserved clock src. */
+       .def_clock = 2, /* gpu clock used most of time.*/
+       .cfg_clock = CFG_CLOCK, /* max gpu clock. */
+       .cfg_min_clock = CFG_MIN_CLOCK,
+
+       .sc_mpp = 3, /* number of pp used most of time.*/
+       .bst_gpu = 210, /* threshold for boosting gpu. */
+       .bst_pp = 160, /* threshold for boosting PP. */
+
+       .clk = mali_dvfs_clk, /* clock source table. */
+       .clk_sample = mali_dvfs_clk_sample, /* freqency table for show. */
+       .clk_len = sizeof(mali_dvfs_clk) / sizeof(mali_dvfs_clk[0]),
+       .have_switch = 0,
+
+       .dvfs_table = mali_dvfs_table, /* DVFS table. */
+       .dvfs_table_size = sizeof(mali_dvfs_table) / sizeof(mali_dvfs_threshold_table),
+
+       .scale_info = {
+               CFG_MIN_PP, /* minpp */
+               CFG_PP, /* maxpp, should be same as cfg_pp */ 
+               CFG_MIN_CLOCK, /* minclk */ 
+               CFG_CLOCK, /* maxclk should be same as cfg_clock */ 
+       },
+
+       .limit_on = 1,
+       .plat_preheat = mali_plat_preheat,
+};
+
+static void mali_plat_preheat(void)
 {
-       return sizeof(mali_dvfs_clk) / sizeof(u32);
+       u32 pre_fs;
+       u32 clk, pp;
+
+       if (get_mali_schel_mode() != MALI_PP_FS_SCALING)
+               return;
+
+       get_mali_rt_clkpp(&clk, &pp);
+       pre_fs = mali_plat_data.def_clock + 1;
+       if (clk < pre_fs)
+               clk = pre_fs;
+       if (pp < mali_plat_data.sc_mpp)
+               pp = mali_plat_data.sc_mpp;
+       set_mali_rt_clkpp(clk, pp, 1);
+}
+
+mali_plat_info_t* get_mali_plat_data(void) {
+       return &mali_plat_data;
 }
 
 int get_mali_freq_level(int freq)
 {
        int i = 0, level = -1;
+       int mali_freq_num;
+
        if(freq < 0)
                return level;
-       int mali_freq_num = sizeof(mali_dvfs_clk_sample) / sizeof(mali_dvfs_clk_sample[0]) - 1;
-       if(freq <= mali_dvfs_clk_sample[0])
+       mali_freq_num = mali_plat_data.dvfs_table_size - 1;
+       if(freq <= mali_plat_data.clk_sample[0])
                level = mali_freq_num-1;
-       if(freq >= mali_dvfs_clk_sample[mali_freq_num - 1])
+       if(freq >= mali_plat_data.clk_sample[mali_freq_num - 1])
                level = 0;
        for(i=0; i<mali_freq_num - 1 ;i++) {
-               if(freq >= mali_dvfs_clk_sample[i] && freq<=mali_dvfs_clk_sample[i+1]) {
+               if(freq >= mali_plat_data.clk_sample[i] && freq<=mali_plat_data.clk_sample[i + 1]) {
                        level = i;
-                       level = mali_freq_num-level-1;
+                       level = mali_freq_num-level - 1;
                }
        }
        return level;
@@ -85,12 +144,9 @@ int get_mali_freq_level(int freq)
 
 unsigned int get_mali_max_level(void)
 {
-       int mali_freq_num = sizeof(mali_dvfs_clk_sample) / sizeof(mali_dvfs_clk_sample[0]);
-       return mali_freq_num - 1;
+       return mali_plat_data.dvfs_table_size - 1;
 }
 
-#define MALI_PP_NUMBER 6
-
 static struct resource mali_gpu_resources[] =
 {
        MALI_GPU_RESOURCES_MALI450_MP6_PMU(IO_MALI_APB_PHY_BASE, INT_MALI_GP, INT_MALI_GP_MMU,
@@ -103,15 +159,51 @@ static struct resource mali_gpu_resources[] =
                                INT_MALI_PP)
 };
 
+static void set_limit_mali_freq(u32 idx)
+{
+       if (mali_plat_data.limit_on == 0)
+               return;
+       if (idx > mali_plat_data.turbo_clock || idx < mali_plat_data.scale_info.minclk)
+               return;
+       mali_plat_data.scale_info.maxclk= idx;
+       revise_mali_rt();
+}
+
+static u32 get_limit_mali_freq(void)
+{
+       return mali_plat_data.scale_info.maxclk;
+}
+
+static u32 set_limit_pp_num(u32 num)
+{
+       u32 ret = -1;
+       if (mali_plat_data.limit_on == 0)
+               goto quit;
+       if (num > mali_plat_data.cfg_pp ||
+                               num < mali_plat_data.scale_info.minpp)
+               goto quit;
+       mali_plat_data.scale_info.maxpp = num;
+       revise_mali_rt();
+       ret = 0;
+quit:
+       return ret;
+}
+
 #ifdef CONFIG_AM_VDEC_H264_4K2K
+static u32 grd_pp_bk = CFG_PP;
 static void mali_4k2k_enter(void)
 {
-       set_max_pp_num(1);
+       if (mali_plat_data.limit_on == 0)
+               return;
+       grd_pp_bk = mali_plat_data.scale_info.maxpp;
+       set_limit_pp_num(mali_plat_data.scale_info.minpp);
 }
 
 static void mali_4k2k_exit(void)
 {
-       set_max_pp_num(6);
+       if (mali_plat_data.limit_on == 0)
+               return;
+       set_limit_pp_num(grd_pp_bk);
 }
 
 void vh264_4k2k_register_module_callback(void(*enter_func)(void), void(*remove_func)(void));
@@ -120,17 +212,16 @@ void vh264_4k2k_register_module_callback(void(*enter_func)(void), void(*remove_f
 void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data);
 int mali_meson_init_start(struct platform_device* ptr_plt_dev)
 {
-
        struct mali_gpu_device_data* pdev = ptr_plt_dev->dev.platform_data;
 
        /* for mali platform data. */
-       pdev->utilization_interval = 500,
+       pdev->utilization_interval = 300,
        pdev->utilization_callback = mali_gpu_utilization_callback,
 
        /* for resource data. */
        ptr_plt_dev->num_resources = ARRAY_SIZE(mali_gpu_resources);
        ptr_plt_dev->resource = mali_gpu_resources;
-       return mali_clock_init(mali_default_clock_idx);
+       return mali_clock_init(&mali_plat_data);
 }
 
 int mali_meson_init_finish(struct platform_device* ptr_plt_dev)
@@ -138,8 +229,14 @@ int mali_meson_init_finish(struct platform_device* ptr_plt_dev)
 #ifdef CONFIG_GPU_THERMAL
        int err;
        struct gpufreq_cooling_device *gcdev = NULL;
+       struct gpucore_cooling_device *gccdev = NULL;
+#endif
+       if (mali_core_scaling_init(&mali_plat_data) < 0)
+               return -1;
+
+#ifdef CONFIG_GPU_THERMAL
        gcdev = gpufreq_cooling_alloc();
-    register_gpu_freq_info(get_current_frequency);
+       register_gpu_freq_info(get_current_frequency);
        if(IS_ERR(gcdev))
                printk("malloc gpu cooling buffer error!!\n");
        else if(!gcdev)
@@ -147,30 +244,28 @@ int mali_meson_init_finish(struct platform_device* ptr_plt_dev)
        else {
                gcdev->get_gpu_freq_level = get_mali_freq_level;
                gcdev->get_gpu_max_level = get_mali_max_level;
-               gcdev->set_gpu_freq_idx = set_max_mali_freq;
-               gcdev->get_gpu_current_max_level = get_max_mali_freq;
+               gcdev->set_gpu_freq_idx = set_limit_mali_freq;
+               gcdev->get_gpu_current_max_level = get_limit_mali_freq;
                err = gpufreq_cooling_register(gcdev);
                if(err < 0)
                        printk("register GPU  cooling error\n");
                printk("gpu cooling register okay with err=%d\n",err);
        }
-       
-       struct gpucore_cooling_device *gccdev=NULL;
+
        gccdev=gpucore_cooling_alloc();
        if(IS_ERR(gccdev))
                printk("malloc gpu core cooling buffer error!!\n");
        else if(!gccdev)
                printk("system does not enable thermal driver\n");
        else {
-               gccdev->max_gpu_core_num=MALI_PP_NUMBER;
-               gccdev->set_max_pp_num=set_max_pp_num;
-               err=gpucore_cooling_register(gccdev);
+               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);
                if(err < 0)
                        printk("register GPU  cooling error\n");
                printk("gpu core cooling register okay with err=%d\n",err);
        }
 #endif
-       mali_core_scaling_init(MALI_PP_NUMBER, mali_default_clock_idx);
 #ifdef CONFIG_AM_VDEC_H264_4K2K
        vh264_4k2k_register_module_callback(mali_4k2k_enter, mali_4k2k_exit);
 #endif /* CONFIG_AM_VDEC_H264_4K2K */
@@ -294,7 +389,6 @@ int mali_light_resume(struct device *device)
                                        MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
                                        get_current_frequency(), 0,     0,      0,      0);
 #endif
-
        return ret;
 }
 
@@ -320,5 +414,4 @@ int mali_deep_resume(struct device *device)
        return ret;
 
 }
-#endif /* MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8 */
 
index d78dcc0c3d3000adcefca668a7d9b4c239db2d86..b34d81c3b6e13a2310cdfa19997067e3f02264d2 100755 (executable)
 #include <mach/io.h>
 #include <asm/io.h>
 #include <linux/mali/mali_utgard.h>
-
+#include <linux/gpu_cooling.h>
+#include <linux/gpucore_cooling.h>
 #include <common/mali_kernel_common.h>
 #include <common/mali_osk_profiling.h>
 #include <common/mali_pmu.h>
-#include <linux/gpu_cooling.h>
-#include <linux/gpucore_cooling.h>
+
 #include "meson_main.h"
 
-/**
- *    For Meson 8.
+/*
+ *    For Meson 8B.
  *
  */
-u32 mali_clock_turbo_index = 4;
-u32 mali_default_clock_idx = 1;
-u32 mali_up_clock_idx = 3;
+
+#define CFG_PP 2
+#define CFG_CLOCK 3
+#define CFG_MIN_PP 1
+#define CFG_MIN_CLOCK 0
 
 /* fclk is 2550Mhz. */
 #define FCLK_DEV3 (6 << 9)             /*      850   Mhz  */
@@ -58,25 +59,84 @@ u32 mali_dvfs_clk_sample[] = {
        637,     /* 637.5 Mhz */
 };
 
-u32 get_mali_tbl_size(void)
+static mali_dvfs_threshold_table mali_dvfs_table[]={
+               { 0, 0, 5, 0  , 180}, /* for 255  */
+               { 1, 1, 5, 152, 205}, /* for 364  */
+               { 2, 2, 5, 180, 212}, /* for 425  */
+               { 3, 3, 5, 205, 236}, /* for 510  */
+               { 4, 4, 5, 230, 256}, /* for 637  */
+               { 0, 0, 5,   0,   0}
+};
+
+static void mali_plat_preheat(void);
+static mali_plat_info_t mali_plat_data = {
+       .cfg_pp = CFG_PP,  /* number of pp. */
+       .cfg_min_pp = CFG_MIN_PP,
+       .turbo_clock = 4, /* reserved clock src. */
+       .def_clock = 2, /* gpu clock used most of time.*/
+       .cfg_clock = CFG_CLOCK, /* max gpu clock. */
+       .cfg_min_clock = CFG_MIN_CLOCK,
+
+       .sc_mpp = 2, /* number of pp used most of time.*/
+       .bst_gpu = 210, /* threshold for boosting gpu. */
+       .bst_pp = 160, /* threshold for boosting PP. */
+
+       .clk = mali_dvfs_clk, /* clock source table. */
+       .clk_sample = mali_dvfs_clk_sample, /* freqency table for show. */
+       .clk_len = sizeof(mali_dvfs_clk) / sizeof(mali_dvfs_clk[0]),
+       .have_switch = 1,
+
+       .dvfs_table = mali_dvfs_table, /* DVFS table. */
+       .dvfs_table_size = sizeof(mali_dvfs_table) / sizeof(mali_dvfs_threshold_table),
+
+       .scale_info = {
+               CFG_MIN_PP, /* minpp */
+               CFG_PP, /* maxpp, should be same as cfg_pp */ 
+               CFG_MIN_CLOCK, /* minclk */ 
+               CFG_CLOCK, /* maxclk should be same as cfg_clock */ 
+       },
+
+       .limit_on = 1,
+       .plat_preheat = mali_plat_preheat,
+};
+
+static void mali_plat_preheat(void)
 {
-       return sizeof(mali_dvfs_clk) / sizeof(u32);
+       u32 pre_fs;
+       u32 clk, pp;
+
+       if (get_mali_schel_mode() != MALI_PP_FS_SCALING)
+               return;
+
+       get_mali_rt_clkpp(&clk, &pp);
+       pre_fs = mali_plat_data.def_clock + 1;
+       if (clk < pre_fs)
+               clk = pre_fs;
+       if (pp < mali_plat_data.sc_mpp)
+               pp = mali_plat_data.sc_mpp;
+       set_mali_rt_clkpp(clk, pp, 1);
+}
+
+mali_plat_info_t* get_mali_plat_data(void) {
+       return &mali_plat_data;
 }
 
 int get_mali_freq_level(int freq)
 {
        int i = 0, level = -1;
+       int mali_freq_num;
+
        if(freq < 0)
                return level;
-       int mali_freq_num = sizeof(mali_dvfs_clk_sample) / sizeof(mali_dvfs_clk_sample[0]) - 1;
-       if(freq <= mali_dvfs_clk_sample[0])
+       mali_freq_num = mali_plat_data.dvfs_table_size - 1;
+       if(freq <= mali_plat_data.clk_sample[0])
                level = mali_freq_num-1;
-       if(freq >= mali_dvfs_clk_sample[mali_freq_num - 1])
+       if(freq >= mali_plat_data.clk_sample[mali_freq_num - 1])
                level = 0;
        for(i=0; i<mali_freq_num - 1 ;i++) {
-               if(freq >= mali_dvfs_clk_sample[i] && freq<=mali_dvfs_clk_sample[i+1]) {
+               if(freq >= mali_plat_data.clk_sample[i] && freq<=mali_plat_data.clk_sample[i + 1]) {
                        level = i;
-                       level = mali_freq_num-level-1;
+                       level = mali_freq_num-level - 1;
                }
        }
        return level;
@@ -84,10 +144,8 @@ int get_mali_freq_level(int freq)
 
 unsigned int get_mali_max_level(void)
 {
-       int mali_freq_num = sizeof(mali_dvfs_clk_sample) / sizeof(mali_dvfs_clk_sample[0]);
-       return mali_freq_num - 1;
+       return mali_plat_data.dvfs_table_size - 1;
 }
-#define MALI_PP_NUMBER 2
 
 static struct resource mali_gpu_resources[] =
 {
@@ -97,6 +155,36 @@ static struct resource mali_gpu_resources[] =
                                INT_MALI_PP)
 };
 
+static void set_limit_mali_freq(u32 idx)
+{
+       if (mali_plat_data.limit_on == 0)
+               return;
+       if (idx > mali_plat_data.turbo_clock || idx < mali_plat_data.scale_info.minclk)
+               return;
+       mali_plat_data.scale_info.maxclk= idx;
+       revise_mali_rt();
+}
+
+static u32 get_limit_mali_freq(void)
+{
+       return mali_plat_data.scale_info.maxclk;
+}
+
+static u32 set_limit_pp_num(u32 num)
+{
+       u32 ret = -1;
+       if (mali_plat_data.limit_on == 0)
+               goto quit;
+       if (num > mali_plat_data.cfg_pp ||
+                               num < mali_plat_data.scale_info.minpp)
+               goto quit;
+       mali_plat_data.scale_info.maxpp = num;
+       revise_mali_rt();
+       ret = 0;
+quit:
+       return ret;
+}
+
 void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data);
 int mali_meson_init_start(struct platform_device* ptr_plt_dev)
 {
@@ -109,15 +197,19 @@ int mali_meson_init_start(struct platform_device* ptr_plt_dev)
        /* for resource data. */
        ptr_plt_dev->num_resources = ARRAY_SIZE(mali_gpu_resources);
        ptr_plt_dev->resource = mali_gpu_resources;
-       return mali_clock_init(mali_default_clock_idx);
+       return mali_clock_init(&mali_plat_data);
 }
 
 int mali_meson_init_finish(struct platform_device* ptr_plt_dev)
 {
-       mali_core_scaling_init(MALI_PP_NUMBER, mali_default_clock_idx);
 #ifdef CONFIG_GPU_THERMAL
        int err;
        struct gpufreq_cooling_device *gcdev = NULL;
+#endif
+       if (mali_core_scaling_init(&mali_plat_data) < 0)
+               return -1;
+
+#ifdef CONFIG_GPU_THERMAL
        gcdev = gpufreq_cooling_alloc();
        if(IS_ERR(gcdev))
                printk("malloc gpu cooling buffer error!!\n");
@@ -126,29 +218,14 @@ int mali_meson_init_finish(struct platform_device* ptr_plt_dev)
        else {
                gcdev->get_gpu_freq_level = get_mali_freq_level;
                gcdev->get_gpu_max_level = get_mali_max_level;
-               gcdev->set_gpu_freq_idx = set_max_mali_freq;
-               gcdev->get_gpu_current_max_level = get_max_mali_freq;
+               gcdev->set_gpu_freq_idx = set_limit_mali_freq;
+               gcdev->get_gpu_current_max_level = get_limit_mali_freq;
                err = gpufreq_cooling_register(gcdev);
                if(err < 0)
                        printk("register GPU  cooling error\n");
                printk("gpu cooling register okay with err=%d\n",err);
        }
-#if 0
-       struct gpucore_cooling_device *gccdev=NULL;
-       gccdev=gpucore_cooling_alloc();
-       if(IS_ERR(gccdev))
-               printk("malloc gpu core cooling buffer error!!\n");
-       else if(!gccdev)
-               printk("system does not enable thermal driver\n");
-       else {
-               gccdev->max_gpu_core_num=MALI_PP_NUMBER;
-               gccdev->set_max_pp_num=set_max_pp_num;
-               err=gpucore_cooling_register(gccdev);
-               if(err < 0)
-                       printk("register GPU  cooling error\n");
-               printk("gpu core cooling register okay with err=%d\n",err);
-       }
-#endif
+
 #endif
        return 0;
 }
diff --git a/mali/platform/meson_m450/scaling.c b/mali/platform/meson_m450/scaling.c
new file mode 100755 (executable)
index 0000000..cf9edd5
--- /dev/null
@@ -0,0 +1,381 @@
+/*
+ * Copyright (C) 2013 ARM Limited. All rights reserved.
+ * 
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ * 
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * @file arm_core_scaling.c
+ * Example core scaling policy.
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+#include <linux/mali/mali_utgard.h>
+#include "mali_kernel_common.h"
+#include "common/mali_osk_profiling.h"
+#include "common/mali_kernel_utilization.h"
+#include "common/mali_pp_scheduler.h"
+
+#include <meson_main.h>
+
+#define LOG_MALI_SCALING 0
+
+static int num_cores_enabled;
+static int currentStep;
+static int lastStep;
+static struct work_struct wq_work;
+static mali_plat_info_t* pmali_plat = NULL;
+static int  scaling_mode = MALI_PP_FS_SCALING;
+
+static void do_scaling(struct work_struct *work)
+{
+       mali_dvfs_threshold_table * pdvfs = pmali_plat->dvfs_table;
+       int err = mali_perf_set_num_pp_cores(num_cores_enabled);
+       MALI_DEBUG_ASSERT(0 == err);
+       MALI_IGNORE(err);
+       if (pdvfs[currentStep].freq_index != pdvfs[lastStep].freq_index) {
+               mali_dev_pause();
+               mali_clock_set(pdvfs[currentStep].freq_index);
+               mali_dev_resume();
+               lastStep = currentStep;
+       }
+#ifdef CONFIG_MALI400_PROFILING
+       _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
+                                       MALI_PROFILING_EVENT_CHANNEL_GPU |
+                                       MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
+                                       get_current_frequency(),
+                                       0,      0,      0,      0);
+#endif
+}
+
+u32 revise_set_clk(u32 val, u32 flush)
+{
+       mali_scale_info_t* pinfo;
+       u32 ret = 0;
+
+       pinfo = &pmali_plat->scale_info;
+
+       if (val < pinfo->minclk)
+               val = pinfo->minclk;
+       else if (val >  pinfo->maxclk)
+               val =  pinfo->maxclk;
+
+       if (val != currentStep) {
+               currentStep = val;
+               if (flush)
+                       schedule_work(&wq_work);
+               else
+                       ret = 1;
+       }
+
+       return ret;
+}
+
+void get_mali_rt_clkpp(u32* clk, u32* pp)
+{
+       *clk = currentStep;
+       *pp = num_cores_enabled;
+}
+
+u32 set_mali_rt_clkpp(u32 clk, u32 pp, u32 flush)
+{
+       mali_scale_info_t* pinfo;
+       u32 ret = 0;
+       u32 flush_work = 0;
+
+       pinfo = &pmali_plat->scale_info;
+       if (clk < pinfo->minclk)
+               clk = pinfo->minclk;
+       else if (clk >  pinfo->maxclk)
+               clk =  pinfo->maxclk;
+
+       if (clk != currentStep) {
+               currentStep = clk;
+               if (flush)
+                       flush_work++;
+               else
+                       ret = 1;
+       }
+       if (pp < pinfo->minpp)
+               pp = pinfo->minpp;
+       else if (pp > pinfo->maxpp)
+               pp = pinfo->maxpp;
+
+       if (pp != num_cores_enabled) {
+               num_cores_enabled = pp;
+               if (flush)
+                       flush_work++;
+               else
+                       ret = 1;
+       }
+
+       if (flush_work)
+               schedule_work(&wq_work);
+       return ret;
+}
+
+void revise_mali_rt(void)
+{
+       set_mali_rt_clkpp(currentStep, num_cores_enabled, 1);
+}
+
+void flush_scaling_job(void)
+{
+       cancel_work_sync(&wq_work);
+}
+
+static u32 enable_one_core(void)
+{
+       return set_mali_rt_clkpp(currentStep, num_cores_enabled + 1, 0);
+}
+
+static u32 disable_one_core(void)
+{
+       return set_mali_rt_clkpp(currentStep, num_cores_enabled - 1, 0);
+}
+
+static u32 enable_max_num_cores(void)
+{
+       return set_mali_rt_clkpp(currentStep, pmali_plat->scale_info.maxpp, 0);
+}
+
+static u32 enable_pp_cores(u32 val)
+{
+       return set_mali_rt_clkpp(currentStep, val, 0);
+}
+
+int mali_core_scaling_init(mali_plat_info_t *mali_plat)
+{
+       if (mali_plat == NULL) {
+               printk(" Mali platform data is NULL!!!\n");
+               return -1;
+       }
+
+       pmali_plat = mali_plat;
+       num_cores_enabled = pmali_plat->sc_mpp;
+
+       currentStep = pmali_plat->def_clock;
+       lastStep = currentStep;
+       INIT_WORK(&wq_work, do_scaling);
+
+       return 0;
+       /* NOTE: Mali is not fully initialized at this point. */
+}
+
+void mali_core_scaling_term(void)
+{
+       flush_scheduled_work();
+}
+
+static u32 mali_threshold [] = {
+       102, /* 40% */
+       128, /* 50% */
+       230, /* 90% */
+};
+
+void mali_pp_scaling_update(struct mali_gpu_utilization_data *data)
+{
+       int ret = 0;
+
+       if (mali_threshold[2] < data->utilization_pp)
+               ret = enable_max_num_cores();
+       else if (mali_threshold[1]< data->utilization_pp)
+               ret = enable_one_core();
+       else if (0 < data->utilization_pp)
+               ret = disable_one_core();
+       if (ret == 1)
+               schedule_work(&wq_work);
+}
+
+#if LOG_MALI_SCALING
+void trace_utilization(struct mali_gpu_utilization_data *data, u32 current_idx, u32 next,
+       u32 current_pp, u32 next_pp)
+{
+       char direction;
+       if (next > current_idx)
+               direction = '>';
+       else if ((current_idx > pmali_plat->scale_info.minpp) && (next < current_idx))
+               direction = '<';
+       else
+               direction = '~';
+
+       printk("[SCALING]%c (%3d-->%3d)@%3d{%3d - %3d}. pp:(%d-->%d)\n",
+                               direction,
+                               get_mali_freq(current_idx),
+                               get_mali_freq(next),
+                               data->utilization_gpu,
+                               pmali_plat->dvfs_table[current_idx].downthreshold,
+                               pmali_plat->dvfs_table[current_idx].upthreshold,
+                               current_pp, next_pp);
+}
+#endif
+
+static int mali_stay_count = 0;
+static void mali_decide_next_status(struct mali_gpu_utilization_data *data, int* next_fs_idx,
+                                                               int* pp_change_flag)
+{
+       u32 utilization, mali_up_limit, decided_fs_idx;
+       u32 ld_left, ld_right;
+       u32 ld_up, ld_down;
+       char change_mode;
+
+       *pp_change_flag = 0;
+       change_mode = 0;
+       utilization = data->utilization_gpu;
+
+       mali_up_limit = (scaling_mode ==  MALI_TURBO_MODE) ?
+                               pmali_plat->turbo_clock : pmali_plat->scale_info.maxclk;
+       decided_fs_idx = currentStep;
+
+       ld_up = pmali_plat->dvfs_table[currentStep].upthreshold;
+       ld_down = pmali_plat->dvfs_table[currentStep].downthreshold;
+       if (utilization >= ld_up) { /* go up */
+               if (currentStep < mali_up_limit) {
+                       change_mode = 1;
+                       if ((currentStep < pmali_plat->def_clock) && (utilization > pmali_plat->bst_gpu))
+                               decided_fs_idx = pmali_plat->def_clock;
+                       else
+                               decided_fs_idx++;
+               }
+               if ((data->utilization_pp > ld_up) &&
+                               (num_cores_enabled < pmali_plat->scale_info.maxpp)) {
+                       if ((num_cores_enabled < pmali_plat->sc_mpp) && (data->utilization_pp >= pmali_plat->bst_pp)) {
+                               *pp_change_flag = 1;
+                               change_mode = 1;
+                       } else if (change_mode == 0) {
+                               *pp_change_flag = 2;
+                               change_mode = 1;
+                       }
+               }
+       } else if (utilization <= ld_down) { /* go down */
+               if (mali_stay_count > 0) {
+                       *next_fs_idx = decided_fs_idx;
+                       mali_stay_count--;
+                       return;
+               }
+
+               if (num_cores_enabled > pmali_plat->sc_mpp) {
+                       change_mode = 1;
+                       if (data->utilization_pp <= ld_down) {
+                               ld_left = data->utilization_pp * num_cores_enabled;
+                               ld_right = (pmali_plat->dvfs_table[currentStep].upthreshold) *
+                                                               (num_cores_enabled - 1);
+                               if (ld_left < ld_right) {
+                                       change_mode = 2;
+                               }
+                       }
+               } else if (currentStep > pmali_plat->scale_info.minpp) {
+                       change_mode = 1;
+               } else if (num_cores_enabled > 1) { /* decrease PPS */
+                       if (data->utilization_pp <= ld_down) {
+                               ld_left = data->utilization_pp * num_cores_enabled;
+                               ld_right = (pmali_plat->dvfs_table[currentStep].upthreshold) *
+                                                               (num_cores_enabled - 1);
+                               if (ld_left < ld_right) {
+                                       change_mode = 2;
+                               }
+                       }
+               }
+
+               if (change_mode == 1) {
+                       decided_fs_idx--;
+               } else if (change_mode == 2) { /* decrease PPS */
+                       *pp_change_flag = -1;
+               }
+       }
+       if (change_mode)
+               mali_stay_count = pmali_plat->dvfs_table[decided_fs_idx].keep_count;
+       *next_fs_idx = decided_fs_idx;
+}
+
+void mali_pp_fs_scaling_update(struct mali_gpu_utilization_data *data)
+{
+       int ret = 0;
+       int pp_change_flag = 0;
+       u32 next_idx = 0;
+       
+#if LOG_MALI_SCALING
+       u32 last_pp = num_cores_enabled;
+#endif
+       mali_decide_next_status(data, &next_idx, &pp_change_flag);
+
+       if (pp_change_flag == 1)
+               ret = enable_pp_cores(pmali_plat->sc_mpp);
+       else if (pp_change_flag == 2)
+               ret = enable_one_core();
+       else if (pp_change_flag == -1) {
+               ret = disable_one_core();
+       }
+
+#if LOG_MALI_SCALING
+       if (pp_change_flag || (next_idx != currentStep))
+               trace_utilization(data, currentStep, next_idx, last_pp, num_cores_enabled);
+#endif
+
+       if (next_idx != currentStep) {
+               ret = 1;
+               currentStep = next_idx;
+       }
+
+       if (ret == 1)
+               schedule_work(&wq_work);
+#ifdef CONFIG_MALI400_PROFILING
+       else
+               _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
+                                               MALI_PROFILING_EVENT_CHANNEL_GPU |
+                                               MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
+                                               get_current_frequency(),
+                                               0,      0,      0,      0);
+#endif
+}
+
+u32 get_mali_schel_mode(void)
+{
+       return scaling_mode;
+}
+
+void set_mali_schel_mode(u32 mode)
+{
+       MALI_DEBUG_ASSERT(mode < MALI_SCALING_MODE_MAX);
+       if (mode >= MALI_SCALING_MODE_MAX)
+               return;
+       scaling_mode = mode;
+       if (scaling_mode != MALI_PP_FS_SCALING) {
+               pmali_plat->scale_info.minclk = pmali_plat->cfg_min_clock;
+               pmali_plat->scale_info.maxclk = pmali_plat->cfg_clock;
+               pmali_plat->scale_info.minpp = pmali_plat->cfg_min_pp;
+               pmali_plat->scale_info.maxpp = pmali_plat->cfg_pp;
+       }
+       if (scaling_mode == MALI_TURBO_MODE) {
+               currentStep = pmali_plat->turbo_clock;
+               pmali_plat->scale_info.maxclk = currentStep;
+       } else
+               currentStep = pmali_plat->scale_info.maxclk;
+       enable_max_num_cores();
+       schedule_work(&wq_work);
+}
+
+u32 get_current_frequency(void)
+{
+       return get_mali_freq(currentStep);
+}
+
+void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data)
+{
+       switch (scaling_mode) {
+       case MALI_PP_FS_SCALING:
+               mali_pp_fs_scaling_update(data);
+               break;
+       case MALI_PP_SCALING:
+               mali_pp_scaling_update(data);
+               break;
+       default:
+               break;
+       }
+}
diff --git a/mali/platform/meson_m450/scaling_m8.c b/mali/platform/meson_m450/scaling_m8.c
deleted file mode 100755 (executable)
index 1694ccf..0000000
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * Copyright (C) 2013 ARM Limited. All rights reserved.
- * 
- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- * 
- * A copy of the licence is included with the program, and can also be obtained from Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-/**
- * @file arm_core_scaling.c
- * Example core scaling policy.
- */
-#include <linux/workqueue.h>
-#include <linux/mali/mali_utgard.h>
-#include <mach/smp.h>
-#include "mali_kernel_common.h"
-#include "common/mali_osk_profiling.h"
-#include "common/mali_kernel_utilization.h"
-#include "common/mali_pp_scheduler.h"
-
-#include "meson_main.h"
-
-#define MALI_TABLE_SIZE 6
-
-static int num_cores_total;
-static int num_cores_enabled;
-static int currentStep;
-static int lastStep;
-static struct work_struct wq_work;
-
-unsigned int min_mali_clock = 0;
-unsigned int max_mali_clock = 3;
-unsigned int min_pp_num = 1;
-
-/* Configure dvfs mode */
-enum mali_scale_mode_t {
-       MALI_PP_SCALING = 0,
-       MALI_PP_FS_SCALING,
-       MALI_SCALING_DISABLE,
-       MALI_TURBO_MODE,
-       MALI_SCALING_MODE_MAX
-};
-
-
-static int  scaling_mode = MALI_PP_FS_SCALING;
-
-enum mali_pp_scale_threshold_t {
-       MALI_PP_THRESHOLD_20,
-       MALI_PP_THRESHOLD_30,
-       MALI_PP_THRESHOLD_40,
-       MALI_PP_THRESHOLD_50,
-       MALI_PP_THRESHOLD_60,
-       MALI_PP_THRESHOLD_80,
-       MALI_PP_THRESHOLD_90,
-       MALI_PP_THRESHOLD_MAX,
-};
-static u32 mali_pp_scale_threshold [] = {
-       51,  /* 20% */
-       77,  /* 30% */
-       102, /* 40% */
-       128, /* 50% */
-       154, /* 60% */
-       205, /* 80% */
-       230, /* 90% */
-};
-
-
-static u32 mali_dvfs_table_size = MALI_TABLE_SIZE;
-
-static struct mali_dvfs_threshold_table mali_dvfs_threshold[MALI_TABLE_SIZE]={
-               { 0, 0, 2, 0  , 200}, /* for 182.1  */
-               { 1, 1, 2, 152, 205}, /* for 318.7  */
-               { 2, 2, 2, 180, 212}, /* for 425.0  */
-               { 3, 3, 2, 205, 236}, /* for 510.0  */
-               { 4, 4, 2, 230, 256},  /* for 637.5  */
-               { 0, 0, 2,   0,   0}
-};
-
-u32 set_mali_dvfs_tbl_size(u32 size)
-{
-       if (size <= 0 && size > MALI_TABLE_SIZE) return -1;
-       mali_dvfs_table_size = size;
-       return 0;
-}
-
-u32 get_max_dvfs_tbl_size(void)
-{
-       return MALI_TABLE_SIZE;
-}
-
-uint32_t* get_mali_dvfs_tbl_addr(void)
-{
-       return (uint32_t*)mali_dvfs_threshold;
-}
-
-static void do_scaling(struct work_struct *work)
-{
-       int err = mali_perf_set_num_pp_cores(num_cores_enabled);
-       MALI_DEBUG_ASSERT(0 == err);
-       MALI_IGNORE(err);
-       if (mali_dvfs_threshold[currentStep].freq_index != mali_dvfs_threshold[lastStep].freq_index) {
-               mali_dev_pause();
-               mali_clock_set(mali_dvfs_threshold[currentStep].freq_index);
-               mali_dev_resume();
-               lastStep = currentStep;
-       }
-#ifdef CONFIG_MALI400_PROFILING
-       _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
-                                       MALI_PROFILING_EVENT_CHANNEL_GPU |
-                                       MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
-                                       get_current_frequency(),
-                                       0,      0,      0,      0);
-#endif
-}
-
-void flush_scaling_job(void)
-{
-       cancel_work_sync(&wq_work);
-}
-
-static u32 enable_one_core(void)
-{
-       u32 ret = 0;
-       if (num_cores_enabled < num_cores_total)
-       {
-               ++num_cores_enabled;
-               ret = 1;
-               MALI_DEBUG_PRINT(3, ("Core scaling: Enabling one more core\n"));
-       }
-
-       MALI_DEBUG_ASSERT(              1 <= num_cores_enabled);
-       MALI_DEBUG_ASSERT(num_cores_total >= num_cores_enabled);
-       return ret;
-}
-
-static u32 disable_one_core(void)
-{
-       u32 ret = 0;
-       if (min_pp_num < num_cores_enabled)
-       {
-               --num_cores_enabled;
-               ret = 1;
-               MALI_DEBUG_PRINT(3, ("Core scaling: Disabling one core\n"));
-       }
-
-       MALI_DEBUG_ASSERT(min_pp_num <= num_cores_enabled);
-       MALI_DEBUG_ASSERT(num_cores_total >= num_cores_enabled);
-       return ret;
-}
-
-static u32 enable_max_num_cores(void)
-{
-       u32 ret = 0;
-       if (num_cores_enabled < num_cores_total)
-       {
-               num_cores_enabled = num_cores_total;
-               ret = 1;
-               MALI_DEBUG_PRINT(3, ("Core scaling: Enabling maximum number of cores\n"));
-       }
-
-       MALI_DEBUG_ASSERT(num_cores_total == num_cores_enabled);
-       return ret;
-}
-
-void mali_core_scaling_init(int pp, int clock_idx)
-{
-       INIT_WORK(&wq_work, do_scaling);
-
-       num_cores_total   = pp;
-       num_cores_enabled = num_cores_total;
-
-       currentStep = clock_idx;
-       lastStep = currentStep;
-       /* NOTE: Mali is not fully initialized at this point. */
-}
-
-void mali_core_scaling_term(void)
-{
-       flush_scheduled_work();
-}
-
-void mali_pp_scaling_update(struct mali_gpu_utilization_data *data)
-{
-       int ret = 0;
-       currentStep = mali_up_clock_idx;
-
-       MALI_DEBUG_PRINT(3, ("Utilization: (%3d, %3d, %3d), cores enabled: %d/%d\n", data->utilization_gpu, data->utilization_gp, data->utilization_pp, num_cores_enabled, num_cores_total));
-
-       /* NOTE: this function is normally called directly from the utilization callback which is in
-        * timer context. */
-
-       if (mali_pp_scale_threshold[MALI_PP_THRESHOLD_90] < data->utilization_pp)
-       {
-               ret = enable_max_num_cores();
-       }
-       else if (mali_pp_scale_threshold[MALI_PP_THRESHOLD_50]< data->utilization_pp)
-       {
-               ret = enable_one_core();
-       }
-       else if (mali_pp_scale_threshold[MALI_PP_THRESHOLD_40]< data->utilization_pp)
-       {
-               #if 0
-               currentStep = MALI_CLOCK_425;
-               schedule_work(&wq_work);
-               #endif
-       }
-       else if (0 < data->utilization_pp)
-       {
-               ret = disable_one_core();
-       }
-       else
-       {
-               /* do nothing */
-       }
-       if (ret == 1)
-               schedule_work(&wq_work);
-}
-
-void mali_pp_fs_scaling_update(struct mali_gpu_utilization_data *data)
-{
-       u32 ret = 0;
-       u32 utilization = data->utilization_gpu;
-       //(data->utilization_pp < data->utilization_gp)?data->utilization_gp:data->utilization_pp;
-       u32 loading_complete = (1<<16);//mali_utilization_bw_get_period();
-       u32 mali_up_limit = (scaling_mode == MALI_TURBO_MODE) ? mali_clock_turbo_index : max_mali_clock;
-
-       if (loading_complete > (2<<16) &&
-                       currentStep > min_mali_clock) {
-               currentStep --;
-               MALI_DEBUG_PRINT(3, (" active time vs command complete:%d\n", loading_complete));
-               goto exit;
-       }
-
-       if (utilization >= mali_dvfs_threshold[currentStep].upthreshold) {
-               if (utilization < mali_pp_scale_threshold[MALI_PP_THRESHOLD_80] && currentStep < mali_up_limit)
-                       currentStep ++;
-               else
-                       currentStep = mali_up_limit;
-
-               if (data->utilization_pp > MALI_PP_THRESHOLD_80) {
-                       enable_max_num_cores();
-               } else {
-                       enable_one_core();
-               }
-               MALI_DEBUG_PRINT(3, ("  > utilization:%d  currentStep:%d.pp:%d. upthreshold:%d.\n",
-                                       utilization, currentStep, num_cores_enabled, mali_dvfs_threshold[currentStep].upthreshold ));
-       } else if (utilization < mali_dvfs_threshold[currentStep].downthreshold && currentStep > min_mali_clock) {
-               currentStep--;
-               MALI_DEBUG_PRINT(3, (" <  utilization:%d  currentStep:%d. downthreshold:%d.\n",
-                                       utilization, currentStep,mali_dvfs_threshold[currentStep].downthreshold ));
-       } else {
-               if (data->utilization_pp < mali_pp_scale_threshold[MALI_PP_THRESHOLD_30])
-                       ret = disable_one_core();
-               MALI_DEBUG_PRINT(3, (" <  utilization:%d  currentStep:%d. downthreshold:%d.pp:%d\n",
-                                       utilization, currentStep,mali_dvfs_threshold[currentStep].downthreshold, num_cores_enabled));
-       }
-
-exit:
-       if ((num_cores_enabled != num_cores_total) ||
-                       (mali_dvfs_threshold[currentStep].freq_index != mali_dvfs_threshold[lastStep].freq_index))
-               schedule_work(&wq_work);
-#ifdef CONFIG_MALI400_PROFILING
-       else
-               _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
-                                               MALI_PROFILING_EVENT_CHANNEL_GPU |
-                                               MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
-                                               get_current_frequency(),
-                                               0,      0,      0,      0);
-#endif
-}
-
-static void reset_mali_scaling_stat(void)
-{
-       if (scaling_mode == MALI_TURBO_MODE)
-               currentStep = mali_clock_turbo_index;
-       else
-               currentStep = max_mali_clock;
-       enable_max_num_cores();
-       schedule_work(&wq_work);
-}
-
-u32 get_max_pp_num(void)
-{
-       return num_cores_total;
-}
-u32 set_max_pp_num(u32 num)
-{
-       if (num < min_pp_num)
-               return -1;
-       num_cores_total = num;
-       if (num_cores_enabled > num_cores_total) {
-               num_cores_enabled = num_cores_total;
-               schedule_work(&wq_work);
-       }
-
-       return 0;
-}
-
-u32 get_min_pp_num(void)
-{
-       return min_pp_num;
-}
-u32 set_min_pp_num(u32 num)
-{
-       if (num > num_cores_total)
-               return -1;
-       min_pp_num = num;
-       if (num_cores_enabled < min_pp_num) {
-               num_cores_enabled = min_pp_num;
-               schedule_work(&wq_work);
-       }
-
-       return 0;
-}
-
-u32 get_max_mali_freq(void)
-{
-       return max_mali_clock;
-}
-u32 set_max_mali_freq(u32 idx)
-{
-       if (idx >= mali_clock_turbo_index || idx < min_mali_clock )
-               return -1;
-       max_mali_clock = idx;
-       if (currentStep > max_mali_clock) {
-               currentStep = max_mali_clock;
-               schedule_work(&wq_work);
-       }
-
-       return 0;
-}
-
-u32 get_min_mali_freq(void)
-{
-       return min_mali_clock;
-}
-u32 set_min_mali_freq(u32 idx)
-{
-       if (idx > max_mali_clock)
-               return -1;
-       min_mali_clock = idx;
-       if (currentStep < min_mali_clock) {
-               currentStep = min_mali_clock;
-               schedule_work(&wq_work);
-       }
-
-       return 0;
-}
-
-void mali_plat_preheat(void)
-{
-       //printk(" aml mali test*************\n");
-       int ret;
-       ret = enable_max_num_cores();
-       if (ret)
-               schedule_work(&wq_work);
-}
-
-void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data)
-{
-       switch (scaling_mode) {
-       case MALI_PP_FS_SCALING:
-               mali_pp_fs_scaling_update(data);
-               break;
-       case MALI_PP_SCALING:
-               mali_pp_scaling_update(data);
-               break;
-       default:
-               break;
-       }
-}
-
-u32 get_mali_schel_mode(void)
-{
-       return scaling_mode;
-}
-
-void set_mali_schel_mode(u32 mode)
-{
-       MALI_DEBUG_ASSERT(mode < MALI_SCALING_MODE_MAX);
-       if (mode >= MALI_SCALING_MODE_MAX)return;
-       scaling_mode = mode;
-       reset_mali_scaling_stat();
-}
-
-u32 get_current_frequency(void)
-{
-       return get_mali_freq(currentStep);
-}
-
diff --git a/mali/platform/meson_m450/scaling_m8b.c b/mali/platform/meson_m450/scaling_m8b.c
deleted file mode 100755 (executable)
index b05cad7..0000000
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * Copyright (C) 2013 ARM Limited. All rights reserved.
- * 
- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- * 
- * A copy of the licence is included with the program, and can also be obtained from Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-/**
- * @file arm_core_scaling.c
- * Example core scaling policy.
- */
-#include <linux/workqueue.h>
-#include <linux/mali/mali_utgard.h>
-#include "mali_kernel_common.h"
-#include "common/mali_osk_profiling.h"
-#include "common/mali_kernel_utilization.h"
-#include "common/mali_pp_scheduler.h"
-
-#include <meson_main.h>
-
-#define MALI_TABLE_SIZE 6
-
-#define LOG_MALI_SCALING 0
-#define LOG_SCALING_CHANGE 0
-#if LOG_SCALING_CHANGE
-# define TRACE_STAY() MALI_DEBUG_PRINT(2, ("[SCALING]stay_count:%d\n", stay_count));
-#else
-# define TRACE_STAY()
-#endif
-
-static int num_cores_total;
-static int num_cores_enabled;
-static int currentStep;
-static int lastStep;
-static struct work_struct wq_work;
-
-unsigned int min_mali_clock = 0;
-unsigned int max_mali_clock = 3;
-unsigned int min_pp_num = 1;
-
-/* Configure dvfs mode */
-enum mali_scale_mode_t {
-       MALI_PP_SCALING = 0,
-       MALI_PP_FS_SCALING,
-       MALI_SCALING_DISABLE,
-       MALI_TURBO_MODE,
-       MALI_SCALING_MODE_MAX
-};
-
-static int  scaling_mode = MALI_PP_FS_SCALING;
-
-enum enum_threshold_t {
-       THRESHOLD_20,
-       THRESHOLD_30,
-       THRESHOLD_40,
-       THRESHOLD_50,
-       THRESHOLD_60,
-       THRESHOLD_80,
-       THRESHOLD_90,
-       THRESHOLD_MAX,
-};
-static u32 mali_threshold [] = {
-       51,  /* 20% */
-       77,  /* 30% */
-       102, /* 40% */
-       128, /* 50% */
-       154, /* 60% */
-       205, /* 80% */
-       230, /* 90% */
-};
-
-static u32 mali_dvfs_table_size = MALI_TABLE_SIZE;
-
-static struct mali_dvfs_threshold_table mali_dvfs_threshold[MALI_TABLE_SIZE]={
-               { 0, 0, 5, 0  , 180}, /* for 255  */
-               { 1, 1, 5, 152, 205}, /* for 364  */
-               { 2, 2, 5, 180, 212}, /* for 425  */
-               { 3, 3, 5, 205, 236}, /* for 510  */
-               { 4, 4, 5, 230, 256}, /* for 637  */
-               { 0, 0, 5,   0,   0}
-};
-
-u32 set_mali_dvfs_tbl_size(u32 size)
-{
-       if (size <= 0 && size > MALI_TABLE_SIZE) return -1;
-       mali_dvfs_table_size = size;
-       return 0;
-}
-
-u32 get_max_dvfs_tbl_size(void)
-{
-       return MALI_TABLE_SIZE;
-}
-
-uint32_t* get_mali_dvfs_tbl_addr(void)
-{
-       return (uint32_t*)mali_dvfs_threshold;
-}
-
-static void do_scaling(struct work_struct *work)
-{
-       int err = mali_perf_set_num_pp_cores(num_cores_enabled);
-
-       if (mali_pm_statue == 0) {
-               printk("skip none clock test.\n");
-               return;
-       }
-       MALI_DEBUG_ASSERT(0 == err);
-       MALI_IGNORE(err);
-       if (mali_dvfs_threshold[currentStep].freq_index != mali_dvfs_threshold[lastStep].freq_index) {
-               mali_dev_pause();
-               mali_clock_set(mali_dvfs_threshold[currentStep].freq_index);
-               mali_dev_resume();
-               lastStep = currentStep;
-       }
-#ifdef CONFIG_MALI400_PROFILING
-       _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
-                                       MALI_PROFILING_EVENT_CHANNEL_GPU |
-                                       MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
-                                       get_current_frequency(),
-                                       0,      0,      0,      0);
-#endif
-}
-
-void flush_scaling_job(void)
-{
-       cancel_work_sync(&wq_work);
-}
-
-static u32 enable_one_core(void)
-{
-       u32 ret = 0;
-       if (num_cores_enabled < num_cores_total)
-       {
-               ++num_cores_enabled;
-               ret = 1;
-               MALI_DEBUG_PRINT(3, ("Core scaling: Enabling one more core\n"));
-       }
-
-       MALI_DEBUG_ASSERT(              1 <= num_cores_enabled);
-       MALI_DEBUG_ASSERT(num_cores_total >= num_cores_enabled);
-       return ret;
-}
-
-static u32 disable_one_core(void)
-{
-       u32 ret = 0;
-       if (min_pp_num < num_cores_enabled)
-       {
-               --num_cores_enabled;
-               ret = 1;
-               MALI_DEBUG_PRINT(3, ("Core scaling: Disabling one core\n"));
-       }
-
-       MALI_DEBUG_ASSERT(min_pp_num <= num_cores_enabled);
-       MALI_DEBUG_ASSERT(num_cores_total >= num_cores_enabled);
-       return ret;
-}
-
-static u32 enable_max_num_cores(void)
-{
-       u32 ret = 0;
-       if (num_cores_enabled < num_cores_total)
-       {
-               num_cores_enabled = num_cores_total;
-               ret = 1;
-               MALI_DEBUG_PRINT(3, ("Core scaling: Enabling maximum number of cores\n"));
-       }
-
-       MALI_DEBUG_ASSERT(num_cores_total == num_cores_enabled);
-       return ret;
-}
-
-void mali_core_scaling_init(int pp, int clock_idx)
-{
-       INIT_WORK(&wq_work, do_scaling);
-
-       num_cores_total   = pp;
-       num_cores_enabled = num_cores_total;
-
-       currentStep = clock_idx;
-       lastStep = currentStep;
-       /* NOTE: Mali is not fully initialized at this point. */
-}
-
-void mali_core_scaling_term(void)
-{
-       flush_scheduled_work();
-}
-
-void mali_pp_scaling_update(struct mali_gpu_utilization_data *data)
-{
-       int ret = 0;
-       currentStep = mali_up_clock_idx;
-
-       MALI_DEBUG_PRINT(3, ("Utilization: (%3d, %3d, %3d), cores enabled: %d/%d\n", data->utilization_gpu, data->utilization_gp, data->utilization_pp, num_cores_enabled, num_cores_total));
-
-       /* NOTE: this function is normally called directly from the utilization callback which is in
-        * timer context. */
-
-       if (mali_threshold[THRESHOLD_90] < data->utilization_pp)
-       {
-               ret = enable_max_num_cores();
-       }
-       else if (mali_threshold[THRESHOLD_50]< data->utilization_pp)
-       {
-               ret = enable_one_core();
-       }
-       else if (mali_threshold[THRESHOLD_40]< data->utilization_pp)
-       {
-               #if 0
-               currentStep = MALI_CLOCK_425;
-               schedule_work(&wq_work);
-               #endif
-       }
-       else if (0 < data->utilization_pp)
-       {
-               ret = disable_one_core();
-       }
-       else
-       {
-               /* do nothing */
-       }
-       if (ret == 1)
-               schedule_work(&wq_work);
-}
-
-#if LOG_MALI_SCALING
-void trace_utilization(struct mali_gpu_utilization_data *data, u32 current_idx,
-                       u32 next, u32 count)
-{
-       char direction;
-       if (next > current_idx)
-               direction = '>';
-       else if ((current_idx > min_mali_clock) && (current_idx < next))
-               direction = '<';
-       else
-               direction = '~';
-       
-       if (count == 0) {
-               MALI_DEBUG_PRINT(2, ("[SCALING]%c (%1d-->%1d)@%d{%3d - %3d}. pp:%d\n",
-                                       direction,
-                                       current_idx,
-                                       next,
-                                       data->utilization_gpu,
-                                       mali_dvfs_threshold[lastStep].downthreshold,
-                                       mali_dvfs_threshold[lastStep].upthreshold,
-                                       num_cores_enabled));
-       }
-}
-#endif
-
-static void mali_decide_next_status(struct mali_gpu_utilization_data *data, int* next_fs_idx,
-                                                               int* pp_change_flag)
-{
-       u32 utilization, mali_up_limit, decided_fs_idx;
-       u32 ld_left, ld_right;
-
-       utilization = data->utilization_gpu;
-       mali_up_limit = scaling_mode ==  MALI_TURBO_MODE? mali_clock_turbo_index : max_mali_clock;
-       decided_fs_idx = currentStep;
-       *pp_change_flag = 0;
-
-       if (utilization >= mali_dvfs_threshold[currentStep].upthreshold) {
-               if (utilization < mali_threshold[THRESHOLD_80] && currentStep < mali_up_limit)
-                       decided_fs_idx++;
-               else
-                       decided_fs_idx = mali_up_limit;
-
-               *pp_change_flag = 1;
-       } else if ((utilization < mali_dvfs_threshold[currentStep].downthreshold) &&
-                                               (currentStep > min_mali_clock)) {
-               decided_fs_idx--;
-       } else if (num_cores_enabled > 1) {
-               ld_left = data->utilization_pp * num_cores_enabled;
-               ld_right = (mali_dvfs_threshold[currentStep].upthreshold) * (num_cores_enabled - 1);
-
-               if ((ld_left < ld_right) && (num_cores_enabled > min_pp_num))
-                       *pp_change_flag = -1;
-       }
-       *next_fs_idx = decided_fs_idx;
-}
-
-void mali_pp_fs_scaling_update(struct mali_gpu_utilization_data *data)
-{
-       static int stay_count = 0;
-       int ret = 0;
-       int pp_change_flag = 0;
-       u32 next_idx = 0;
-
-       mali_decide_next_status(data, &next_idx, &pp_change_flag);
-
-       if (pp_change_flag == 1)
-               ret = enable_max_num_cores();
-
-       if (next_idx > currentStep) {
-               ret = 1;
-               currentStep = next_idx;
-               stay_count = mali_dvfs_threshold[currentStep].keep_count;
-       }
-
-#if LOG_MALI_SCALING
-       trace_utilization(data, currentStep, next_idx, stay_count);
-#endif
-
-       if((next_idx <= currentStep) || (pp_change_flag == -1)) {
-               if (stay_count  == 0) {
-                       if (pp_change_flag == -1) {
-                               ret = disable_one_core();
-                               stay_count = mali_dvfs_threshold[currentStep].keep_count;
-                       }
-
-                       if (next_idx < currentStep) {
-                               ret = 1;
-                               currentStep = next_idx;
-                               stay_count = mali_dvfs_threshold[next_idx].keep_count;
-                       }
-               } else {
-                       stay_count--;
-               }
-       }
-
-       TRACE_STAY()
-       if (ret == 1)
-               schedule_work(&wq_work);
-#ifdef CONFIG_MALI400_PROFILING
-       else
-               _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
-                                               MALI_PROFILING_EVENT_CHANNEL_GPU |
-                                               MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
-                                               get_current_frequency(),
-                                               0,      0,      0,      0);
-#endif
-}
-
-static void reset_mali_scaling_stat(void)
-{
-       if (scaling_mode == MALI_TURBO_MODE)
-               currentStep = mali_clock_turbo_index;
-       else
-               currentStep = max_mali_clock;
-       enable_max_num_cores();
-       schedule_work(&wq_work);
-}
-
-u32 get_max_pp_num(void)
-{
-       return num_cores_total;
-}
-u32 set_max_pp_num(u32 num)
-{
-       if (num < min_pp_num)
-               return -1;
-       num_cores_total = num;
-       if (num_cores_enabled > num_cores_total) {
-               num_cores_enabled = num_cores_total;
-               schedule_work(&wq_work);
-       }
-
-       return 0;
-}
-
-u32 get_min_pp_num(void)
-{
-       return min_pp_num;
-}
-u32 set_min_pp_num(u32 num)
-{
-       if (num > num_cores_total)
-               return -1;
-       min_pp_num = num;
-       if (num_cores_enabled < min_pp_num) {
-               num_cores_enabled = min_pp_num;
-               schedule_work(&wq_work);
-       }
-
-       return 0;
-}
-
-u32 get_max_mali_freq(void)
-{
-       return max_mali_clock;
-}
-u32 set_max_mali_freq(u32 idx)
-{
-       if (idx >= mali_clock_turbo_index || idx < min_mali_clock )
-               return -1;
-       max_mali_clock = idx;
-       if (currentStep > max_mali_clock) {
-               currentStep = max_mali_clock;
-               schedule_work(&wq_work);
-       }
-
-       return 0;
-}
-
-u32 get_min_mali_freq(void)
-{
-       return min_mali_clock;
-}
-u32 set_min_mali_freq(u32 idx)
-{
-       if (idx > max_mali_clock)
-               return -1;
-       min_mali_clock = idx;
-       if (currentStep < min_mali_clock) {
-               currentStep = min_mali_clock;
-               schedule_work(&wq_work);
-       }
-
-       return 0;
-}
-
-void mali_plat_preheat(void)
-{
-       int ret1, ret2 = 0;
-#if 0
-       printk(" aml mali test*************\n");
-#endif
-       if (currentStep < mali_default_clock_idx) {
-               ret2 = 1;
-               currentStep = mali_default_clock_idx;
-       }
-       ret1 = enable_max_num_cores();
-       if (ret1 || ret2)
-               schedule_work(&wq_work);
-}
-
-void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data)
-{
-
-       if (mali_pm_statue == 0) {
-               printk("skip none clock scaling.\n");
-               return;
-       }
-       switch (scaling_mode) {
-       case MALI_PP_FS_SCALING:
-               mali_pp_fs_scaling_update(data);
-               break;
-       case MALI_PP_SCALING:
-               mali_pp_scaling_update(data);
-               break;
-       default:
-               break;
-       }
-}
-
-u32 get_mali_schel_mode(void)
-{
-       return scaling_mode;
-}
-
-void set_mali_schel_mode(u32 mode)
-{
-       MALI_DEBUG_ASSERT(mode < MALI_SCALING_MODE_MAX);
-       if (mode >= MALI_SCALING_MODE_MAX)return;
-       scaling_mode = mode;
-       reset_mali_scaling_stat();
-}
-
-u32 get_current_frequency(void)
-{
-       return get_mali_freq(currentStep);
-}
index e09599584196f962c32a018f49ba93846d5226be..69f579a5f8c761c0ed1e144e69d7d3706b765b23 100755 (executable)
@@ -27,8 +27,8 @@
 #include "common/mali_pmu.h"
 #include "common/mali_osk_profiling.h"
 
-static void mali_platform_device_release(struct device *device);
 int mali_pm_statue = 1;
+
 static struct mali_gpu_device_data mali_gpu_data =
 {
        .shared_mem_size = 1024 * 1024 * 1024,
@@ -37,6 +37,7 @@ static struct mali_gpu_device_data mali_gpu_data =
        .pmu_domain_config = {0x1, 0x2, 0x4, 0x4, 0x4, 0x8, 0x8, 0x8, 0x8, 0x1, 0x2, 0x8},
 };
 
+static void mali_platform_device_release(struct device *device);
 static struct platform_device mali_gpu_device =
 {
        .name = MALI_GPU_NAME_UTGARD,
@@ -75,41 +76,15 @@ int mali_pdev_dts_init(struct platform_device* mali_gpu_device)
        struct device_node     *child;
        u32 prop_value;
        int err;
-       mali_dvfs_threshold_table_t* tbl = NULL;
-       u32 tbl_size;
-       u32 tbl_size_in_byte;
 
        for_each_child_of_node(cfg_node, child) {
-       err = of_property_read_u32(child, "shared_memory", &prop_value);
-       if (err == 0) {
-               MALI_DEBUG_PRINT(2, ("shared_memory configurate  %d\n", prop_value));
-               mali_gpu_data.shared_mem_size = prop_value * 1024 * 1024;
-       }
-
-       err = of_property_read_u32(child, "dvfs_size", &prop_value);
-       if (err != 0 || prop_value < 0 || prop_value > get_max_dvfs_tbl_size()) {
-               MALI_DEBUG_PRINT(2, ("invalid recorde_number is.\n"));
-               goto def_start;
-       }
-
-       tbl_size = sizeof(mali_dvfs_threshold_table_t) * prop_value;
-       tbl_size_in_byte = tbl_size / sizeof(u32);
-       tbl = kzalloc(tbl_size, GFP_KERNEL);
-               if (!tbl)
-                       goto def_start;
-
-               err = of_property_read_u32_array(child,
-                                               "dvfs_table",
-                                               (u32*)tbl,
-                                               tbl_size_in_byte);
+               err = of_property_read_u32(child, "shared_memory", &prop_value);
                if (err == 0) {
-                       memcpy(get_mali_dvfs_tbl_addr(), tbl, tbl_size);
-                       set_mali_dvfs_tbl_size(prop_value);
-                       kfree(tbl);
+                       MALI_DEBUG_PRINT(2, ("shared_memory configurate  %d\n", prop_value));
+                       mali_gpu_data.shared_mem_size = prop_value * 1024 * 1024;
                }
        }
 
-def_start:
        err = mali_pdev_pre_init(mali_gpu_device);
        if (err == 0)
                mali_pdev_post_init(mali_gpu_device);
@@ -141,6 +116,3 @@ static void mali_platform_device_release(struct device *device)
        MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n"));
 }
 
-static int  dbg_parm = 0;
-module_param(dbg_parm, int, 0664);
-MODULE_PARM_DESC(dbg_parm, "Internal debug");
index b47a67f74b9d8b7100aa89e245c9d8125d593a73..b30cfc786809b9fe3ab2b2eabeca561ab55a0a94 100755 (executable)
 #include "mali_clock.h"
 
 extern struct device_type mali_pm_device;
-extern u32 mali_dvfs_clk[];
-extern u32 mali_dvfs_clk_sample[];
-extern u32 mali_clock_turbo_index;
-extern u32 mali_default_clock_idx;
-extern u32 mali_up_clock_idx;
-extern u32 set_max_mali_freq(u32 idx);
-extern u32 get_max_mali_freq(void);
-extern u32 get_mali_tbl_size(void);
-extern int mali_pm_statue;
+
+u32 set_max_mali_freq(u32 idx);
+u32 get_max_mali_freq(void);
 
 int mali_meson_init_start(struct platform_device* ptr_plt_dev);
 int mali_meson_init_finish(struct platform_device* ptr_plt_dev);
index 449ed33303b15e1e0bb46b7fc047a5ac5b175478..3817bd5a8823f524bf174e095b3d8a271ac9d6e8 100755 (executable)
@@ -43,19 +43,71 @@ static ssize_t domain_stat_read(struct class *class,
 }
 
 #if MESON_CPU_TYPE > MESON_CPU_TYPE_MESON6TVD
-static ssize_t mpgpu_read(struct class *class,
-                       struct class_attribute *attr, char *buf)
-{
-    return 0;
-}
-
 #define PREHEAT_CMD "preheat"
+#define PLL2_CMD "mpl2"  /* mpl2 [11] or [0xxxxxxx] */
+#define SCMPP_CMD "scmpp"  /* scmpp [number of pp your want in most of time]. */
+#define BSTGPU_CMD "bstgpu"  /* bstgpu [0-256] */
+#define BSTPP_CMD "bstpp"  /* bstpp [0-256] */
+#define LIMIT_CMD "lmt"  /* lmt [0 or 1] */
+#define MAX_TOKEN 20
+#define FULL_UTILIZATION 256
 
 static ssize_t mpgpu_write(struct class *class,
                        struct class_attribute *attr, const char *buf, size_t count)
 {
-       if(!strncmp(buf,PREHEAT_CMD,strlen(PREHEAT_CMD)))
-               mali_plat_preheat();
+       char *pstart, *cprt = NULL;
+       u32 val = 0;
+       mali_plat_info_t* pmali_plat = get_mali_plat_data();
+
+       cprt = skip_spaces(buf);
+       pstart = strsep(&cprt," ");
+       if (strlen(pstart) < 1)
+               goto quit;
+
+       if(!strncmp(pstart, PREHEAT_CMD, MAX_TOKEN)) {
+               if (pmali_plat->plat_preheat) {
+                       pmali_plat->plat_preheat();
+               }
+       } else if (!strncmp(pstart, PLL2_CMD, MAX_TOKEN)) {
+               int base = 10;
+               if ((strlen(cprt) > 2) && (cprt[0] == '0') &&
+                               (cprt[1] == 'x' || cprt[1] == 'X'))
+                       base = 16;
+               if (kstrtouint(cprt, base, &val) <0)
+                       goto quit;
+               set_str_src(val);
+       } else if (!strncmp(pstart, SCMPP_CMD, MAX_TOKEN)) {
+               if ((kstrtouint(cprt, 10, &val) <0) || pmali_plat == NULL)
+                       goto quit;
+               if ((val > 0) && (val < pmali_plat->cfg_pp)) {
+                       pmali_plat->sc_mpp = val;
+               }
+       } else if (!strncmp(pstart, BSTGPU_CMD, MAX_TOKEN)) {
+               if ((kstrtouint(cprt, 10, &val) <0) || pmali_plat == NULL)
+                       goto quit;
+               if ((val > 0) && (val < FULL_UTILIZATION)) {
+                       pmali_plat->bst_gpu = val;
+               }
+       } else if (!strncmp(pstart, BSTPP_CMD, MAX_TOKEN)) {
+               if ((kstrtouint(cprt, 10, &val) <0) || pmali_plat == NULL)
+                       goto quit;
+               if ((val > 0) && (val < FULL_UTILIZATION)) {
+                       pmali_plat->bst_pp = val;
+               }
+       } else if (!strncmp(pstart, LIMIT_CMD, MAX_TOKEN)) {
+               if ((kstrtouint(cprt, 10, &val) <0) || pmali_plat == NULL)
+                       goto quit;
+               
+               if (val < 2) {
+                       pmali_plat->limit_on = val;
+                       if (val == 0) {
+                               pmali_plat->scale_info.maxclk = pmali_plat->cfg_clock;
+                               pmali_plat->scale_info.maxpp = pmali_plat->cfg_pp;
+                               revise_mali_rt();
+                       }
+               }
+       }
+quit:
        return count;
 }
 
@@ -76,6 +128,7 @@ static ssize_t scale_mode_write(struct class *class,
        {
                return -EINVAL;
        }
+
        set_mali_schel_mode(val);
 
        return count;
@@ -84,7 +137,8 @@ static ssize_t scale_mode_write(struct class *class,
 static ssize_t max_pp_read(struct class *class,
                        struct class_attribute *attr, char *buf)
 {
-       return sprintf(buf, "%d\n", get_max_pp_num());
+       mali_plat_info_t* pmali_plat = get_mali_plat_data();
+       return sprintf(buf, "%d\n", pmali_plat->scale_info.maxpp);
 }
 
 static ssize_t max_pp_write(struct class *class,
@@ -92,13 +146,18 @@ static ssize_t max_pp_write(struct class *class,
 {
        int ret;
        unsigned int val;
+       mali_plat_info_t* pmali_plat;
+       mali_scale_info_t* pinfo;
+
+       pmali_plat = get_mali_plat_data();
+       pinfo = &pmali_plat->scale_info;
 
        ret = kstrtouint(buf, 10, &val);
-       if (0 != ret)
-       {
+       if ((0 != ret) || (val > pmali_plat->cfg_pp) || (val < pinfo->minpp))
                return -EINVAL;
-       }
-       ret = set_max_pp_num(val);
+
+       pinfo->maxpp = val;
+       revise_mali_rt();
 
        return count;
 }
@@ -106,8 +165,8 @@ static ssize_t max_pp_write(struct class *class,
 static ssize_t min_pp_read(struct class *class,
                        struct class_attribute *attr, char *buf)
 {
-
-       return sprintf(buf, "%d\n", get_min_pp_num());
+       mali_plat_info_t* pmali_plat = get_mali_plat_data();
+       return sprintf(buf, "%d\n", pmali_plat->scale_info.minpp);
 }
 
 static ssize_t min_pp_write(struct class *class,
@@ -115,13 +174,18 @@ static ssize_t min_pp_write(struct class *class,
 {
        int ret;
        unsigned int val;
+       mali_plat_info_t* pmali_plat;
+       mali_scale_info_t* pinfo;
+
+       pmali_plat = get_mali_plat_data();
+       pinfo = &pmali_plat->scale_info;
 
        ret = kstrtouint(buf, 10, &val);
-       if (0 != ret)
-       {
+       if ((0 != ret) || (val > pinfo->maxpp) || (val < 1))
                return -EINVAL;
-       }
-       ret = set_min_pp_num(val);
+
+       pinfo->minpp = val;
+       revise_mali_rt();
 
        return count;
 }
@@ -129,7 +193,8 @@ static ssize_t min_pp_write(struct class *class,
 static ssize_t max_freq_read(struct class *class,
                        struct class_attribute *attr, char *buf)
 {
-       return sprintf(buf, "%d\n", get_max_mali_freq());
+       mali_plat_info_t* pmali_plat = get_mali_plat_data();
+       return sprintf(buf, "%d\n", pmali_plat->scale_info.maxclk);
 }
 
 static ssize_t max_freq_write(struct class *class,
@@ -137,13 +202,18 @@ static ssize_t max_freq_write(struct class *class,
 {
        int ret;
        unsigned int val;
+       mali_plat_info_t* pmali_plat;
+       mali_scale_info_t* pinfo;
+
+       pmali_plat = get_mali_plat_data();
+       pinfo = &pmali_plat->scale_info;
 
        ret = kstrtouint(buf, 10, &val);
-       if (0 != ret)
-       {
+       if ((0 != ret) || (val > pmali_plat->cfg_clock) || (val < pinfo->minclk))
                return -EINVAL;
-       }
-       ret = set_max_mali_freq(val);
+
+       pinfo->maxclk = val;
+       revise_mali_rt();
 
        return count;
 }
@@ -151,7 +221,8 @@ static ssize_t max_freq_write(struct class *class,
 static ssize_t min_freq_read(struct class *class,
                        struct class_attribute *attr, char *buf)
 {
-       return sprintf(buf, "%d\n", get_min_mali_freq());
+       mali_plat_info_t* pmali_plat = get_mali_plat_data();
+       return sprintf(buf, "%d\n", pmali_plat->scale_info.minclk);
 }
 
 static ssize_t min_freq_write(struct class *class,
@@ -159,52 +230,90 @@ static ssize_t min_freq_write(struct class *class,
 {
        int ret;
        unsigned int val;
+       mali_plat_info_t* pmali_plat;
+       mali_scale_info_t* pinfo;
+
+       pmali_plat = get_mali_plat_data();
+       pinfo = &pmali_plat->scale_info;
+
+       ret = kstrtouint(buf, 10, &val);
+       if ((0 != ret) || (val > pinfo->maxclk))
+               return -EINVAL;
+
+       pinfo->minclk = val;
+       revise_mali_rt();
+
+       return count;
+}
+
+static ssize_t freq_read(struct class *class,
+                       struct class_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%d\n", get_current_frequency());
+}
+
+static ssize_t freq_write(struct class *class,
+                       struct class_attribute *attr, const char *buf, size_t count)
+{
+       int ret;
+       unsigned int val;
+       u32 clk, pp;
+       get_mali_rt_clkpp(&clk, &pp);
 
        ret = kstrtouint(buf, 10, &val);
        if (0 != ret)
-       {
                return -EINVAL;
-       }
-       ret = set_min_mali_freq(val);
+
+       set_mali_rt_clkpp(val, pp, 1);
 
        return count;
 }
 
-static ssize_t read_extr_src(struct class *class,
+static ssize_t current_pp_read(struct class *class,
                        struct class_attribute *attr, char *buf)
 {
-       return sprintf(buf, "usage echo 0(restore), 1(set fix src), xxx user mode\n");
+       u32 clk, pp;
+       get_mali_rt_clkpp(&clk, &pp);
+       return sprintf(buf, "%d\n", pp);
 }
 
-static ssize_t write_extr_src(struct class *class,
+static ssize_t current_pp_write(struct class *class,
                        struct class_attribute *attr, const char *buf, size_t count)
 {
        int ret;
        unsigned int val;
+       u32 clk, pp;
 
+       get_mali_rt_clkpp(&clk, &pp);
        ret = kstrtouint(buf, 10, &val);
        if (0 != ret)
        {
                return -EINVAL;
        }
 
-       set_str_src(val);
+       ret = kstrtouint(buf, 10, &val);
+       if (0 != ret)
+               return -EINVAL;
+
+       set_mali_rt_clkpp(clk, val, 1);
 
        return count;
 }
+
 #endif
 
 
 static struct class_attribute mali_class_attrs[] = {
-       __ATTR(domain_stat,     0644, domain_stat_read, NULL),
 #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
-       __ATTR(mpgpucmd,        0644, mpgpu_read,       mpgpu_write),
+       __ATTR(domain_stat,     0644, domain_stat_read, NULL),
+       __ATTR(mpgpucmd,        0644, NULL,             mpgpu_write),
        __ATTR(scale_mode,      0644, scale_mode_read,  scale_mode_write),
        __ATTR(min_freq,        0644, min_freq_read,    min_freq_write),
        __ATTR(max_freq,        0644, max_freq_read,    max_freq_write),
        __ATTR(min_pp,          0644, min_pp_read,      min_pp_write),
        __ATTR(max_pp,          0644, max_pp_read,      max_pp_write),
-       __ATTR(extr_src,        0644, read_extr_src,    write_extr_src),
+       __ATTR(cur_freq,        0644, freq_read,        freq_write),
+       __ATTR(cur_pp,          0644, current_pp_read,  current_pp_write),
 #endif
 };
 
@@ -237,23 +346,3 @@ void  mpgpu_class_exit(void)
        class_unregister(&mpgpu_class);
 }
 
-#if 0
-static int __init mpgpu_init(void)
-{
-       return mpgpu_class_init();
-}
-
-static void __exit mpgpu_exit(void)
-{
-       mpgpu_class_exit();
-}
-
-fs_initcall(mpgpu_init);
-module_exit(mpgpu_exit);
-
-MODULE_DESCRIPTION("AMLOGIC  mpgpu driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("aml-sh <kasin.li@amlogic.com>");
-#endif
-
-