From 466e197d9702224fc625d6b06bf4787b115d1d35 Mon Sep 17 00:00:00 2001 From: Kasin Lee Date: Sun, 22 Jun 2014 18:32:53 +0800 Subject: [PATCH] PD #80887: update work flow of DVFS for m8 --- mali/Kbuild | 14 +- mali/common/mali_group.c | 68 ++-- mali/common/mali_mmu.c | 5 - mali/common/mali_mmu.h | 4 - mali/common/mali_pp_scheduler.c | 4 +- mali/linux/mali_osk_irq.c | 12 + mali/linux/mali_sync.c | 5 + mali/platform/mali_clock.c | 83 ++-- mali/platform/mali_clock.h | 2 +- mali/platform/mali_scaling.h | 85 ++-- mali/platform/meson_m400/platform_mx.c | 23 +- mali/platform/meson_m450/platform_m6tvd.c | 66 ++- mali/platform/meson_m450/platform_m8.c | 159 ++++++-- mali/platform/meson_m450/platform_m8b.c | 155 +++++-- mali/platform/meson_m450/scaling.c | 381 ++++++++++++++++++ mali/platform/meson_m450/scaling_m8.c | 392 ------------------ mali/platform/meson_m450/scaling_m8b.c | 467 ---------------------- mali/platform/meson_main.c | 38 +- mali/platform/meson_main.h | 12 +- mali/platform/mpgpu.c | 199 ++++++--- 20 files changed, 970 insertions(+), 1204 deletions(-) mode change 100644 => 100755 mali/common/mali_mmu.c mode change 100644 => 100755 mali/common/mali_pp_scheduler.c mode change 100644 => 100755 mali/linux/mali_osk_irq.c mode change 100644 => 100755 mali/linux/mali_sync.c create mode 100755 mali/platform/meson_m450/scaling.c delete mode 100755 mali/platform/meson_m450/scaling_m8.c delete mode 100755 mali/platform/meson_m450/scaling_m8b.c diff --git a/mali/Kbuild b/mali/Kbuild index 8512ca1..cc72e1a 100755 --- a/mali/Kbuild +++ b/mali/Kbuild @@ -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. ################### diff --git a/mali/common/mali_group.c b/mali/common/mali_group.c index f1479e7..9c31e09 100755 --- a/mali/common/mali_group.c +++ b/mali/common/mali_group.c @@ -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 -#include -#include -#include -//#endif +#include +#include #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); diff --git a/mali/common/mali_mmu.c b/mali/common/mali_mmu.c old mode 100644 new mode 100755 index 6d73c02..c9d4b52 --- a/mali/common/mali_mmu.c +++ b/mali/common/mali_mmu.c @@ -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) { diff --git a/mali/common/mali_mmu.h b/mali/common/mali_mmu.h index 236923c..07d20c7 100755 --- a/mali/common/mali_mmu.h +++ b/mali/common/mali_mmu.h @@ -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); diff --git a/mali/common/mali_pp_scheduler.c b/mali/common/mali_pp_scheduler.c old mode 100644 new mode 100755 index 8dd8e3e..1b0dd67 --- a/mali/common/mali_pp_scheduler.c +++ b/mali/common/mali_pp_scheduler.c @@ -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(); diff --git a/mali/linux/mali_osk_irq.c b/mali/linux/mali_osk_irq.c old mode 100644 new mode 100755 index 3576599..bd213aa --- a/mali/linux/mali_osk_irq.c +++ b/mali/linux/mali_osk_irq.c @@ -13,6 +13,8 @@ * Implementation of the OS abstraction layer for the kernel device driver */ +#include +#include #include /* For memory allocation */ #include #include @@ -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 diff --git a/mali/linux/mali_sync.c b/mali/linux/mali_sync.c old mode 100644 new mode 100755 index d85d5bb..7ae5a88 --- a/mali/linux/mali_sync.c +++ b/mali/linux/mali_sync.c @@ -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)); diff --git a/mali/platform/mali_clock.c b/mali/platform/mali_clock.c index 8d2c43e..6b7f3c5 100755 --- a/mali/platform/mali_clock.c +++ b/mali/platform/mali_clock.c @@ -7,30 +7,37 @@ #include #include #include - #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 diff --git a/mali/platform/mali_clock.h b/mali/platform/mali_clock.h index 754c1bd..53ccda0 100755 --- a/mali/platform/mali_clock.h +++ b/mali/platform/mali_clock.h @@ -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); diff --git a/mali/platform/mali_scaling.h b/mali/platform/mali_scaling.h index bd4168e..a19618e 100755 --- a/mali/platform/mali_scaling.h +++ b/mali/platform/mali_scaling.h @@ -16,13 +16,64 @@ #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__ */ diff --git a/mali/platform/meson_m400/platform_mx.c b/mali/platform/meson_m400/platform_mx.c index 3aec708..5bd11cd 100755 --- a/mali/platform/meson_m400/platform_mx.c +++ b/mali/platform/meson_m400/platform_mx.c @@ -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. */ diff --git a/mali/platform/meson_m450/platform_m6tvd.c b/mali/platform/meson_m450/platform_m6tvd.c index 426ed28..bfd6791 100755 --- a/mali/platform/meson_m450/platform_m6tvd.c +++ b/mali/platform/meson_m450/platform_m6tvd.c @@ -1,6 +1,6 @@ /* * platform.c - * + * * clock source setting and resource config * * Created on: Dec 4, 2013 @@ -26,17 +26,15 @@ #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 */ + diff --git a/mali/platform/meson_m450/platform_m8.c b/mali/platform/meson_m450/platform_m8.c index b790a21..344708e 100755 --- a/mali/platform/meson_m450/platform_m8.c +++ b/mali/platform/meson_m450/platform_m8.c @@ -32,10 +32,10 @@ * */ -#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_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 */ diff --git a/mali/platform/meson_m450/platform_m8b.c b/mali/platform/meson_m450/platform_m8b.c index d78dcc0..b34d81c 100755 --- a/mali/platform/meson_m450/platform_m8b.c +++ b/mali/platform/meson_m450/platform_m8b.c @@ -19,22 +19,23 @@ #include #include #include - +#include +#include #include #include #include -#include -#include + #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_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 index 0000000..cf9edd5 --- /dev/null +++ b/mali/platform/meson_m450/scaling.c @@ -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 +#include +#include +#include +#include "mali_kernel_common.h" +#include "common/mali_osk_profiling.h" +#include "common/mali_kernel_utilization.h" +#include "common/mali_pp_scheduler.h" + +#include + +#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 index 1694ccf..0000000 --- a/mali/platform/meson_m450/scaling_m8.c +++ /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 -#include -#include -#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 index b05cad7..0000000 --- a/mali/platform/meson_m450/scaling_m8b.c +++ /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 -#include -#include "mali_kernel_common.h" -#include "common/mali_osk_profiling.h" -#include "common/mali_kernel_utilization.h" -#include "common/mali_pp_scheduler.h" - -#include - -#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); -} diff --git a/mali/platform/meson_main.c b/mali/platform/meson_main.c index e095995..69f579a 100755 --- a/mali/platform/meson_main.c +++ b/mali/platform/meson_main.c @@ -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"); diff --git a/mali/platform/meson_main.h b/mali/platform/meson_main.h index b47a67f..b30cfc7 100755 --- a/mali/platform/meson_main.h +++ b/mali/platform/meson_main.h @@ -18,15 +18,9 @@ #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); diff --git a/mali/platform/mpgpu.c b/mali/platform/mpgpu.c index 449ed33..3817bd5 100755 --- a/mali/platform/mpgpu.c +++ b/mali/platform/mpgpu.c @@ -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 "); -#endif - - -- 2.20.1