PD #92212: tuning scaling in m8 baby
authorKasin Lee <kasin.li@amlogic.com>
Fri, 23 May 2014 02:08:16 +0000 (10:08 +0800)
committerKasin Lee <kasin.li@amlogic.com>
Fri, 23 May 2014 02:08:16 +0000 (10:08 +0800)
mali/platform/mali_clock.c
mali/platform/mali_clock.h
mali/platform/meson_m450/platform_m8.c
mali/platform/meson_m450/platform_m8b.c
mali/platform/meson_m450/scaling_m8b.c
mali/platform/meson_main.h
mali/platform/mpgpu.c

index 65dcbfa613105a7a60f15a69ff0c1b0280e3cf12..d40e92b2761ffea419d647b919f33ed72d2f30bb 100755 (executable)
 
 #include "meson_main.h"
 
+#define FCLK_MPLL2 (2 << 9)
 static DEFINE_SPINLOCK(lock);
 
+static u32 mali_extr_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)
 {
+#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
        return 0;
 }
 
@@ -32,10 +48,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
        return 0;
 }
 
@@ -68,3 +93,20 @@ u32 get_mali_freq(u32 idx)
 {
        return mali_dvfs_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;
+       } else if (data > 10) {
+               mali_dvfs_clk[get_mali_tbl_size() -1] = FCLK_MPLL2;
+       }
+#endif
+}
index fa534e89b57aa2b10f08a38b82e03e4092cd7dc4..754c1bd163aff319d8e95b8cff9c3f229c6ace16 100755 (executable)
@@ -9,4 +9,5 @@ int mali_clock_set(unsigned int index);
 void disable_clock(void);
 void enable_clock(void);
 u32 get_mali_freq(u32 idx);
+void set_str_src(u32 data);
 #endif /* _MALI_CLOCK_H_ */
index 32133edf3a8fb28482009e4095e9f200c74b71a2..1fd9eb9376438d9b478059ce77bc098c3369e456 100755 (executable)
@@ -59,6 +59,11 @@ u32 mali_dvfs_clk_sample[] = {
        637,     /* 637.5 Mhz */
 };
 
+u32 get_mali_tbl_size(void)
+{
+       return sizeof(mali_dvfs_clk) / sizeof(u32);
+}
+
 int get_mali_freq_level(int freq)
 {
        int i = 0, level = -1;
index 1003467d40365b7a06e212e6d74607ec050f8d78..8b2544e8eab5dce0c5d8b1ab33d505ab34b6c861 100755 (executable)
@@ -32,7 +32,7 @@
  */
  
 u32 mali_clock_turbo_index = 4;
-u32 mali_default_clock_idx = 3;
+u32 mali_default_clock_idx = 1;
 u32 mali_up_clock_idx = 3;
 
 /* fclk is 2550Mhz. */
@@ -42,21 +42,26 @@ u32 mali_up_clock_idx = 3;
 #define FCLK_DEV7 (4 << 9)             /*      364.3 Mhz  */
 
 u32 mali_dvfs_clk[] = {
-       FCLK_DEV7 | 1,     /* 182.1 Mhz */
-       FCLK_DEV4 | 1,     /* 318.7 Mhz */
+       FCLK_DEV5 | 1,     /* 255 Mhz */
+       FCLK_DEV7 | 0,     /* 364 Mhz */
        FCLK_DEV3 | 1,     /* 425 Mhz */
        FCLK_DEV5 | 0,     /* 510 Mhz */
        FCLK_DEV4 | 0,     /* 637.5 Mhz */
 };
 
 u32 mali_dvfs_clk_sample[] = {
-       182,     /* 182.1 Mhz */
-       319,     /* 318.7 Mhz */
+       255,     /* 182.1 Mhz */
+       364,     /* 318.7 Mhz */
        425,     /* 425 Mhz */
        510,     /* 510 Mhz */
        637,     /* 637.5 Mhz */
 };
 
+u32 get_mali_tbl_size(void)
+{
+       return sizeof(mali_dvfs_clk) / sizeof(u32);
+}
+
 #define MALI_PP_NUMBER 2
 
 static struct resource mali_gpu_resources[] =
@@ -70,11 +75,10 @@ static struct resource mali_gpu_resources[] =
 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 = 200,
        pdev->utilization_callback = mali_gpu_utilization_callback,
 
        /* for resource data. */
@@ -94,22 +98,12 @@ int mali_meson_uninit(struct platform_device* ptr_plt_dev)
        return 0;
 }
 
-static int mali_cri_pmu_on_off(size_t param)
+int mali_light_suspend(struct device *device)
 {
+       int ret = 0;
        struct mali_pmu_core *pmu;
 
-       MALI_DEBUG_PRINT(4, ("mali_os_suspend() called\n"));
        pmu = mali_pmu_get_global_pmu_core();
-       if (param == 0)
-               mali_pmu_power_down_all(pmu);
-       else
-               mali_pmu_power_up_all(pmu);
-       return 0;
-}
-
-int mali_light_suspend(struct device *device)
-{
-       int ret = 0;
 #ifdef CONFIG_MALI400_PROFILING
        _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
                                        MALI_PROFILING_EVENT_CHANNEL_GPU |
@@ -125,7 +119,7 @@ int mali_light_suspend(struct device *device)
        }
 
        /* clock scaling. Kasin..*/
-       mali_clock_critical(mali_cri_pmu_on_off, 0);
+       mali_pmu_power_down_all(pmu);
        //disable_clock();
        return ret;
 }
@@ -133,10 +127,10 @@ int mali_light_suspend(struct device *device)
 int mali_light_resume(struct device *device)
 {
        int ret = 0;
-       /* clock scaling. Kasin..*/
-       //enable_clock();
+       struct mali_pmu_core *pmu;
 
-       mali_clock_critical(mali_cri_pmu_on_off, 1);
+       pmu = mali_pmu_get_global_pmu_core();
+       mali_pmu_power_up_all(pmu);
 #ifdef CONFIG_MALI400_PROFILING
        _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
                                        MALI_PROFILING_EVENT_CHANNEL_GPU |
@@ -157,6 +151,9 @@ int mali_light_resume(struct device *device)
 int mali_deep_suspend(struct device *device)
 {
        int ret = 0;
+       struct mali_pmu_core *pmu;
+
+       pmu = mali_pmu_get_global_pmu_core();
        enable_clock();
        flush_scaling_job();
        if (NULL != device->driver &&
@@ -168,7 +165,7 @@ int mali_deep_suspend(struct device *device)
        }
 
        /* clock scaling off. Kasin... */
-       mali_clock_critical(mali_cri_pmu_on_off, 0);
+       mali_pmu_power_down_all(pmu);
        disable_clock();
        return ret;
 }
@@ -176,9 +173,11 @@ int mali_deep_suspend(struct device *device)
 int mali_deep_resume(struct device *device)
 {
        int ret = 0;
-       /* clock scaling up. Kasin.. */
+       struct mali_pmu_core *pmu;
+
+       pmu = mali_pmu_get_global_pmu_core();
        enable_clock();
-       mali_clock_critical(mali_cri_pmu_on_off, 1);
+       mali_pmu_power_up_all(pmu);
        if (NULL != device->driver &&
            NULL != device->driver->pm &&
            NULL != device->driver->pm->resume)
@@ -187,6 +186,5 @@ int mali_deep_resume(struct device *device)
                ret = device->driver->pm->resume(device);
        }
        return ret;
-
 }
 
index 32f376b059e912e7ff5f0c162a0bed88e1530a0a..662ca7d27c4a4a2e1b397b894f4ab03ca80690ef 100755 (executable)
 
 #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;
@@ -42,7 +50,6 @@ enum mali_scale_mode_t {
        MALI_SCALING_MODE_MAX
 };
 
-
 static int  scaling_mode = MALI_PP_FS_SCALING;
 
 enum enum_threshold_t {
@@ -65,16 +72,15 @@ static u32 mali_threshold [] = {
        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}
+               { 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)
@@ -217,25 +223,30 @@ void mali_pp_scaling_update(struct mali_gpu_utilization_data *data)
                schedule_work(&wq_work);
 }
 
-void trace_utilization(struct mali_gpu_utilization_data *data)
+#if LOG_MALI_SCALING
+void trace_utilization(struct mali_gpu_utilization_data *data, u32 current_idx,
+                       u32 next, u32 count)
 {
        char direction;
-       if (currentStep > lastStep)
+       if (next > current_idx)
                direction = '>';
-       else if ((currentStep > min_mali_clock) && (currentStep < lastStep))
+       else if ((current_idx > min_mali_clock) && (current_idx < next))
                direction = '<';
        else
                direction = '~';
-
-       MALI_DEBUG_PRINT(2, ("%c [%d-->%d]@%d{%d - %d}. pp:%d\n",
-                               direction,
-                               lastStep,
-                               currentStep,
-                               data->utilization_gpu,
-                               mali_dvfs_threshold[lastStep].downthreshold,
-                               mali_dvfs_threshold[lastStep].upthreshold,
-                               num_cores_enabled));
+       
+       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)
@@ -262,7 +273,7 @@ static void mali_decide_next_status(struct mali_gpu_utilization_data *data, int*
                ld_left = data->utilization_pp * num_cores_enabled;
                ld_right = (mali_dvfs_threshold[currentStep].upthreshold) * (num_cores_enabled - 1);
 
-               if (ld_left < ld_right)
+               if ((ld_left < ld_right) && (num_cores_enabled > min_pp_num))
                        *pp_change_flag = -1;
        }
        *next_fs_idx = decided_fs_idx;
@@ -284,28 +295,32 @@ void mali_pp_fs_scaling_update(struct mali_gpu_utilization_data *data)
                ret = 1;
                currentStep = next_idx;
                stay_count = mali_dvfs_threshold[currentStep].keep_count;
-               /* if (ret ) printk("__scaling__%d__\n", __LINE__); */
        }
 
-       if((next_idx < currentStep) || (pp_change_flag == -1)) {
-               if (stay_count  == 0) {
-                       stay_count = mali_dvfs_threshold[currentStep].keep_count;
-                       ret = 1;
+#if LOG_MALI_SCALING
+       trace_utilization(data, currentStep, next_idx, stay_count);
+#endif
 
-                       if (pp_change_flag == -1)
+       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)
+                       if (next_idx < currentStep) {
+                               ret = 1;
                                currentStep = next_idx;
+                               stay_count = mali_dvfs_threshold[next_idx].keep_count;
+                       }
                } else {
                        stay_count--;
                }
        }
 
-       if (ret == 1) {
-               trace_utilization(data);
+       TRACE_STAY()
+       if (ret == 1)
                schedule_work(&wq_work);
-       }
 #ifdef CONFIG_MALI400_PROFILING
        else
                _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
@@ -396,10 +411,16 @@ u32 set_min_mali_freq(u32 idx)
 
 void mali_plat_preheat(void)
 {
-       //printk(" aml mali test*************\n");
-       int ret;
-       ret = enable_max_num_cores();
-       if (ret)
+       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);
 }
 
index 94b17000683a28eff943c7e9ffda7a90d88ce7fb..f9fb3c512709cb56647be104c5cc9638fc5bef82 100755 (executable)
@@ -25,6 +25,7 @@ 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);
 
 int mali_meson_init_start(struct platform_device* ptr_plt_dev);
 int mali_meson_init_finish(struct platform_device* ptr_plt_dev);
index aa2cf8202639fb19c406e89cb16560aa2c8ee38c..8497b3ce4812ed31f62b9e44c9a7d7daf420bf79 100755 (executable)
@@ -166,6 +166,29 @@ static ssize_t min_freq_write(struct class *class,
 
        return count;
 }
+
+static ssize_t read_extr_src(struct class *class,
+                       struct class_attribute *attr, char *buf)
+{
+       return sprintf(buf, "usage echo 0(restore), 1(set fix src), xxx user mode\n");
+}
+
+static ssize_t write_extr_src(struct class *class,
+                       struct class_attribute *attr, const char *buf, size_t count)
+{
+       int ret;
+       unsigned int val;
+
+       ret = kstrtouint(buf, 10, &val);
+       if (0 != ret)
+       {
+               return -EINVAL;
+       }
+
+       set_str_src(val);
+
+       return count;
+}
 #endif
 
 
@@ -178,6 +201,7 @@ static struct class_attribute mali_class_attrs[] = {
        __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),
 #endif
 };