From e275f55ca4cc34fc5726794359e35f3d91f0671d Mon Sep 17 00:00:00 2001 From: Jiyu Yang Date: Thu, 9 Jul 2015 15:18:26 +0800 Subject: [PATCH] PD#108267 set mali clock as the john's method Change-Id: Ibf29281170b3d348c2dbb33095d3e09f85070f6f Signed-off-by: John Thodiyil Signed-off-by: Jiyu Yang --- mali/Kbuild | 24 +- mali/platform/mali_scaling.h | 10 + mali/platform/meson_bu/mali_clock.c | 351 ++++++++++++++++++--------- mali/platform/meson_bu/mali_dvfs.c | 212 ++++++++++++++++ mali/platform/meson_bu/meson_main2.c | 14 +- mali/platform/meson_bu/meson_main2.h | 2 + mali/platform/meson_bu/mpgpu.c | 6 +- mali/platform/meson_bu/platform_gx.c | 113 +-------- mali/platform/meson_bu/scaling.c | 30 ++- 9 files changed, 503 insertions(+), 259 deletions(-) create mode 100644 mali/platform/meson_bu/mali_dvfs.c diff --git a/mali/Kbuild b/mali/Kbuild index bc68d7f..7cc2225 100755 --- a/mali/Kbuild +++ b/mali/Kbuild @@ -16,6 +16,12 @@ ifndef CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH endif #ifeq ($(CONFIG_ARCH_MESON),y) ccflags-y += -DCONFIG_MALI450=y +#ifeq ($(CONFIG_MALI450),m) +#ccflags-y += -DCONFIG_MALI450=y +#endif +#ifeq ($(CONFIG_MALI450),y) +#ccflags-y += -DCONFIG_MALI450=y +#endif ccflags-y += -DCONFIG_MALI_DT=y ccflags-y += -DMESON_CPU_TYPE=0x80 ccflags-y += -DMESON_CPU_TYPE_MESON6=0x60 @@ -45,9 +51,14 @@ OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 16 #USING_GPU_UTILIZATION ?= 0 #PROFILING_SKIP_PP_JOBS ?= 0 #PROFILING_SKIP_PP_AND_GP_JOBS ?= 0 - -USING_GPU_UTILIZATION=1 -USING_DVFS=0 +ifeq ($(CONFIG_MALI_DVFS),y) + ccflags-y += -DCONFIG_MALI_DVFS + USING_GPU_UTILIZATION=0 + USING_DVFS=1 +else + USING_GPU_UTILIZATION=1 + USING_DVFS=0 +endif PROFILING_SKIP_PP_JOBS ?= 0 PROFILING_SKIP_PP_AND_GP_JOBS ?= 0 ############## Kasin Added, for platform. ################ @@ -179,11 +190,14 @@ mali-y += \ platform/mali_pm_device.o \ platform/meson_bu/meson_main2.o \ platform/meson_bu/mali_clock.o \ - platform/meson_bu/scaling.o \ platform/meson_bu/mpgpu.o \ platform/meson_bu/platform_gx.o endif - +ifeq ($(CONFIG_MALI_DVFS),y) + mali-y += platform/meson_bu/mali_dvfs.o +else + mali-y += platform/meson_bu/scaling.o +endif ifeq ($(TARGET_PLATFORM),meson_m400) MALI_PLATFORM_FILES:= \ diff --git a/mali/platform/mali_scaling.h b/mali/platform/mali_scaling.h index 5aeab8e..e8c6cb1 100644 --- a/mali/platform/mali_scaling.h +++ b/mali/platform/mali_scaling.h @@ -17,6 +17,8 @@ #define __ARM_CORE_SCALING_H__ #include +#include +#include enum mali_scale_mode_t { MALI_PP_SCALING = 0, @@ -34,6 +36,7 @@ typedef struct mali_dvfs_threshold_table { uint32_t upthreshold; uint32_t clk_freq; const char *clk_parent; + struct clk *clkp_handle; uint32_t clkp_freq; } mali_dvfs_threshold_table; @@ -69,6 +72,7 @@ typedef struct mali_plat_info_t { u32 have_switch; /* have clock gate switch or not. */ mali_dvfs_threshold_table *dvfs_table; + struct mali_gpu_clk_item *clk_items; u32 dvfs_table_size; mali_scale_info_t scale_info; @@ -80,6 +84,12 @@ typedef struct mali_plat_info_t { void (*plat_preheat)(void); struct platform_device *pdev; + void __iomem *reg_base_hiubus; + void __iomem *reg_base_aobus; + struct work_struct wq_work; + struct clk *clk_mali; + struct clk *clk_mali_0; + struct clk *clk_mali_1; } mali_plat_info_t; mali_plat_info_t* get_mali_plat_data(void); diff --git a/mali/platform/meson_bu/mali_clock.c b/mali/platform/meson_bu/mali_clock.c index 40d922d..b72631e 100644 --- a/mali/platform/meson_bu/mali_clock.c +++ b/mali/platform/meson_bu/mali_clock.c @@ -1,51 +1,68 @@ #include +#include +#include +#include +#include +#include #include "mali_scaling.h" #include "mali_clock.h" -#if 1 -#ifndef CLK_DVFS_TBL_SIZE -#define CLK_DVFS_TBL_SIZE 5 + +#ifndef AML_CLK_LOCK_ERROR +#define AML_CLK_LOCK_ERROR 1 #endif + +#define HHI_MALI_CLK_CNTL 0x6C +#define mplt_read(r) readl((pmali_plat->reg_base_hiubus) + ((r)<<2)) +#define mplt_write(r, v) writel((v), ((pmali_plat->reg_base_hiubus) + ((r)<<2))) +#define mplt_setbits(r, m) mplt_write((r), (mplt_read(r) | (m))); +#define mplt_clrbits(r, m) mplt_write((r), (mplt_read(r) & (~(m)))); + +static unsigned gpu_dbg_level = 0; +module_param(gpu_dbg_level, uint, 0644); +MODULE_PARM_DESC(gpu_dbg_level, "gpu debug level"); + +#define gpu_dbg(level, fmt, arg...) \ + do { \ + if (gpu_dbg_level >= (level)) \ + printk("gpu_debug"fmt , ## arg); \ + } while (0) + +#define GPU_CLK_DBG(fmt, arg...) \ + do { \ + gpu_dbg(1, "line(%d), clk_cntl=0x%08x\n" fmt, __LINE__, mplt_read(HHI_MALI_CLK_CNTL), ## arg);\ + } while (0) + //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; +struct timeval start; +struct timeval end; int mali_clock_init_clk_tree(struct platform_device* pdev) { - struct clk *clk_mali_0_parent; - struct clk *clk_mali_0; - struct clk *clk_mali; - - clk_mali = clk_get(&pdev->dev, "clk_mali"); - clk_mali_0 = clk_get(&pdev->dev, "clk_mali_0"); - clk_mali_0_parent = clk_get(&pdev->dev, "fclk_div4"); - - if (!clk_mali) { - printk("could not get clk_mali\n"); - return 0; - } - if (!clk_mali_0) { - printk("could not get clk_mali_0\n"); - return 0; - } - if (!clk_mali_0_parent) { - printk("could not get clk_mali_0_parent\n"); - return 0; - } + mali_dvfs_threshold_table *dvfs_tbl = &pmali_plat->dvfs_table[pmali_plat->def_clock]; + struct clk *clk_mali_0_parent = dvfs_tbl->clkp_handle; + struct clk *clk_mali_0 = pmali_plat->clk_mali_0; +#ifdef AML_CLK_LOCK_ERROR + struct clk *clk_mali_1 = pmali_plat->clk_mali_1; +#endif + struct clk *clk_mali = pmali_plat->clk_mali; clk_set_parent(clk_mali_0, clk_mali_0_parent); - clk_prepare_enable(clk_mali_0_parent); - //ret = clk_set_rate(clk_mali, 425000000); - clk_prepare_enable(clk_mali_0); clk_set_parent(clk_mali, clk_mali_0); - clk_prepare_enable(clk_mali); +#ifdef AML_CLK_LOCK_ERROR + clk_set_parent(clk_mali_1, clk_mali_0_parent); + clk_prepare_enable(clk_mali_1); +#endif - printk(" clk_mali_0_parent =%p, clk_mali_0=%p, clk_mali=%p\n ", - clk_mali_0_parent, clk_mali_0, clk_mali); + GPU_CLK_DBG("%s:enable(%d), %s:enable(%d)\n", + clk_mali_0->name, clk_mali_0->enable_count, + clk_mali_0_parent->name, clk_mali_0_parent->enable_count); printk("pdev->drvdata=%p\n", dev_get_drvdata(&pdev->dev)); @@ -72,63 +89,61 @@ static int critical_clock_set(size_t param) { int ret = 0; unsigned int idx = param; - uint32_t pre_clk_rate = 0; - struct platform_device *pdev = pmali_plat->pdev; mali_dvfs_threshold_table *dvfs_tbl = &pmali_plat->dvfs_table[idx]; - struct clk *clk_mali_0_parent = NULL; - struct clk *clk_mali_0 = NULL; - struct clk *clk_mali_1 = NULL; - struct clk *clk_mali = NULL; + struct clk *clk_mali_0 = pmali_plat->clk_mali_0; + struct clk *clk_mali_1 = pmali_plat->clk_mali_1; + struct clk *clk_mali_x = NULL; + struct clk *clk_mali_x_parent = NULL; + struct clk *clk_mali_x_old = NULL; + struct clk *clk_mali = pmali_plat->clk_mali; + unsigned long time_use=0; - clk_mali = clk_get(&pdev->dev, "clk_mali"); - if (!clk_mali) { - printk("could not get clk_mali\n"); - return 0; - } - clk_mali_0 = clk_get(&pdev->dev, "clk_mali_0"); - if (!clk_mali_0) { - printk("could not get clk_mali_0\n"); + clk_mali_x_old = clk_get_parent(clk_mali); + + if (!clk_mali_x_old) { + printk("could not get clk_mali_x_old or clk_mali_x_old\n"); return 0; } - clk_mali_1 = clk_get(&pdev->dev, "clk_mali_1"); - if (!clk_mali_1) { - printk("could not get clk_mali_1\n"); + if (clk_mali_x_old == clk_mali_0) { + clk_mali_x = clk_mali_1; + } else if (clk_mali_x_old == clk_mali_1) { + clk_mali_x = clk_mali_0; + } else { + printk("unmatched clk_mali_x_old\n"); return 0; } - clk_mali_0_parent = clk_get_parent(clk_mali_0); - if (!clk_mali_0_parent) { - printk("could not get clk_mali_0_parent\n"); - return 0; - } - clk_set_parent(clk_mali_1, clk_mali_0_parent); - pre_clk_rate = clk_get_rate(clk_mali_0); - ret = clk_set_rate(clk_mali_1, pre_clk_rate); - clk_prepare_enable(clk_mali_1); - clk_set_parent(clk_mali, clk_mali_1); - clk_prepare_enable(clk_mali); - clk_mali_0_parent = clk_get(&pdev->dev, - dvfs_tbl->clk_parent); - if (!clk_mali_0_parent) { - printk("could not get clk_mali_0_parent\n"); + GPU_CLK_DBG("idx=%d, clk_freq=%d\n", idx, dvfs_tbl->clk_freq); + clk_mali_x_parent = dvfs_tbl->clkp_handle; + if (!clk_mali_x_parent) { + printk("could not get clk_mali_x_parent\n"); return 0; } - ret = clk_set_rate(clk_mali_0_parent, dvfs_tbl->clkp_freq); - clk_set_parent(clk_mali_0, clk_mali_0_parent); - clk_prepare_enable(clk_mali_0_parent); - ret = clk_set_rate(clk_mali, dvfs_tbl->clk_freq); - - clk_prepare_enable(clk_mali_0); - - clk_set_parent(clk_mali, clk_mali_0); - - clk_prepare_enable(clk_mali); - clk_put(clk_mali); - clk_put(clk_mali_0); - clk_put(clk_mali_1); - clk_put(clk_mali_0_parent); + GPU_CLK_DBG(); + ret = clk_set_rate(clk_mali_x_parent, dvfs_tbl->clkp_freq); + GPU_CLK_DBG(); + ret = clk_set_parent(clk_mali_x, clk_mali_x_parent); + GPU_CLK_DBG(); + ret = clk_set_rate(clk_mali_x, dvfs_tbl->clk_freq); + GPU_CLK_DBG(); +#ifndef AML_CLK_LOCK_ERROR + ret = clk_prepare_enable(clk_mali_x); +#endif + GPU_CLK_DBG("new %s:enable(%d)\n", clk_mali_x->name, clk_mali_x->enable_count); + do_gettimeofday(&start); + udelay(1);// delay 10ns + do_gettimeofday(&end); + ret = clk_set_parent(clk_mali, clk_mali_x); + GPU_CLK_DBG(); + +#ifndef AML_CLK_LOCK_ERROR + clk_disable_unprepare(clk_mali_x_old); +#endif + GPU_CLK_DBG("old %s:enable(%d)\n", clk_mali_x_old->name, clk_mali_x_old->enable_count); + time_use = (end.tv_sec - start.tv_sec)*1000000 + end.tv_usec - start.tv_usec; + GPU_CLK_DBG("step 1, mali_mux use: %ld us\n", time_use); return 0; } @@ -140,37 +155,28 @@ int mali_clock_set(unsigned int clock) void disable_clock(void) { - struct platform_device *pdev = pmali_plat->pdev; - struct clk *clk_mali_0 = NULL; - struct clk *clk_mali_1 = NULL; - - clk_mali_0 = clk_get(&pdev->dev, "clk_mali_0"); - clk_mali_1 = clk_get(&pdev->dev, "clk_mali_1"); - if (!clk_mali_0 || ! clk_mali_1) { - printk("could not get clk_mali_1 or clk_mali_0\n"); - return ; - } + struct clk *clk_mali = pmali_plat->clk_mali; + struct clk *clk_mali_x = NULL; - clk_disable_unprepare(clk_mali_0); - clk_disable_unprepare(clk_mali_1); + clk_mali_x = clk_get_parent(clk_mali); + GPU_CLK_DBG(); +#ifndef AML_CLK_LOCK_ERROR + clk_disable_unprepare(clk_mali_x); +#endif + GPU_CLK_DBG(); } void enable_clock(void) { + struct clk *clk_mali = pmali_plat->clk_mali; + struct clk *clk_mali_x = NULL; - struct platform_device *pdev = pmali_plat->pdev; - struct clk *clk_mali_0 = NULL; - struct clk *clk_mali_1 = NULL; - - clk_mali_0 = clk_get(&pdev->dev, "clk_mali_0"); - clk_mali_1 = clk_get(&pdev->dev, "clk_mali_1"); - if (!clk_mali_0 || ! clk_mali_1) { - printk("could not get clk_mali_1 or clk_mali_0\n"); - return ; - } - - clk_prepare_enable(clk_mali_0); - clk_prepare_enable(clk_mali_1); + clk_mali_x = clk_get_parent(clk_mali); + GPU_CLK_DBG(); +#ifndef AML_CLK_LOCK_ERROR + clk_prepare_enable(clk_mali_x); +#endif + GPU_CLK_DBG(); } u32 get_mali_freq(u32 idx) @@ -191,45 +197,135 @@ int mali_dt_info(struct platform_device *pdev, struct mali_plat_info_t *mpdata) { struct device_node *gpu_dn = pdev->dev.of_node; struct device_node *gpu_clk_dn; - phandle dvfs_tbl_hdl; - phandle dvfs_clk_hdl[CLK_DVFS_TBL_SIZE]; - mali_dvfs_threshold_table *dvfs_tbl = mpdata->dvfs_table; - uint32_t *clk_sample = mpdata->clk_sample; + struct mali_gpu_clk_item *clk_item; + phandle dvfs_clk_hdl; + mali_dvfs_threshold_table *dvfs_tbl = NULL; + uint32_t *clk_sample = NULL; + + struct property *prop; + const __be32 *p; + int length = 0, i = 0; + u32 u; - int i = 0; int ret = 0; if (!gpu_dn) { printk("gpu device node not right\n"); + return -ENODEV; } ret = of_property_read_u32(gpu_dn,"num_of_pp", &mpdata->cfg_pp); + if (ret) { + printk("read max pp failed\n"); + mpdata->cfg_pp = 6; + } mpdata->scale_info.maxpp = mpdata->cfg_pp; + printk("max pp is %d\n", mpdata->scale_info.maxpp); - ret = of_property_read_u32(gpu_dn,"dvfs_tbl", - &dvfs_tbl_hdl); - gpu_dn = of_find_node_by_phandle(dvfs_tbl_hdl); - if (!gpu_dn) { - printk("failed to find gpu dvfs table\n"); + ret = of_property_read_u32(gpu_dn,"min_pp", + &mpdata->cfg_min_pp); + if (ret) { + printk("read min pp failed\n"); + mpdata->cfg_min_pp = 1; + } + mpdata->scale_info.minpp = mpdata->cfg_min_pp; + printk("min pp is %d\n", mpdata->scale_info.minpp); + + ret = of_property_read_u32(gpu_dn,"min_clk", + &mpdata->cfg_min_clock); + if (ret) { + printk("read min clk failed\n"); + mpdata->cfg_min_clock = 0; } + mpdata->scale_info.minclk = mpdata->cfg_min_clock; + printk("min clk is %d\n", mpdata->scale_info.minclk); + + mpdata->reg_base_hiubus = of_iomap(gpu_dn, 1); + printk("hiu io source 0x%p\n", mpdata->reg_base_hiubus); + + mpdata->reg_base_aobus = of_iomap(gpu_dn, 2); + printk("hiu io source 0x%p\n", mpdata->reg_base_aobus); ret = of_property_read_u32(gpu_dn,"sc_mpp", &mpdata->sc_mpp); + if (ret) { + printk("read min clk failed\n"); + mpdata->cfg_min_clock = mpdata->cfg_pp; + } + printk("num of pp used most of time %d\n", mpdata->sc_mpp); + + of_get_property(gpu_dn, "tbl", &length); - ret = of_property_read_u32_array(gpu_dn,"tbl", - &dvfs_clk_hdl[0], CLK_DVFS_TBL_SIZE); + length = length /sizeof(u32); + printk("clock dvfs table size is %d\n", length); + + ret = of_property_read_u32(gpu_dn,"max_clk", + &mpdata->cfg_clock); + if (ret) { + printk("read max clk failed\n"); + mpdata->cfg_clock = length-2; + } - for (i = 0; icfg_clock_bkup = mpdata->cfg_clock; + mpdata->scale_info.maxclk = mpdata->cfg_clock; + printk("max clk is %d\n", mpdata->scale_info.maxclk); + + ret = of_property_read_u32(gpu_dn,"turbo_clk", + &mpdata->turbo_clock); + if (ret) { + printk("read turbo clk failed\n"); + mpdata->turbo_clock = length-1; + } + printk("turbo clk is %d\n", mpdata->turbo_clock); + + ret = of_property_read_u32(gpu_dn,"def_clk", + &mpdata->def_clock); + if (ret) { + printk("read default clk failed\n"); + mpdata->def_clock = length/2 - 1; + } + printk("default clk is %d\n", mpdata->def_clock); + + mpdata->dvfs_table = devm_kzalloc(&pdev->dev, + sizeof(struct mali_dvfs_threshold_table)*length, + GFP_KERNEL); + dvfs_tbl = mpdata->dvfs_table; + if (mpdata->dvfs_table == NULL) { + printk("failed to alloc dvfs table\n"); + return -ENOMEM; + } + mpdata->dvfs_table_size = length; + mpdata->clk_sample = devm_kzalloc(&pdev->dev, sizeof(u32)*length, GFP_KERNEL); + if (mpdata->clk_sample == NULL) { + printk("failed to alloc clk_sample table\n"); + return -ENOMEM; + } + clk_sample = mpdata->clk_sample; +/////////// + mpdata->clk_items = devm_kzalloc(&pdev->dev, sizeof(struct mali_gpu_clk_item) * length, GFP_KERNEL); + if (mpdata->clk_items == NULL) { + printk("failed to alloc clk_item table\n"); + return -ENOMEM; + } + clk_item = mpdata->clk_items; +// + + of_property_for_each_u32(gpu_dn, "tbl", prop, p, u) { + dvfs_clk_hdl = (phandle) u; + gpu_clk_dn = of_find_node_by_phandle(dvfs_clk_hdl); ret = of_property_read_u32(gpu_clk_dn,"clk_freq", &dvfs_tbl->clk_freq); if (ret) { printk("read clk_freq failed\n"); } ret = of_property_read_string(gpu_clk_dn,"clk_parent", - &dvfs_tbl->clk_parent); + &dvfs_tbl->clk_parent); if (ret) { printk("read clk_parent failed\n"); } + dvfs_tbl->clkp_handle = devm_clk_get(&pdev->dev, dvfs_tbl->clk_parent); + if (IS_ERR(dvfs_tbl->clkp_handle)) { + printk("failed to get %s's clock pointer\n", dvfs_tbl->clk_parent); + } ret = of_property_read_u32(gpu_clk_dn,"clkp_freq", &dvfs_tbl->clkp_freq); if (ret) { printk("read clk_parent freq failed\n"); @@ -244,30 +340,43 @@ int mali_dt_info(struct platform_device *pdev, struct mali_plat_info_t *mpdata) } //downthreshold and upthreshold shall be u32 ret = of_property_read_u32_array(gpu_clk_dn,"threshold", - &dvfs_tbl->downthreshold, 2); + &dvfs_tbl->downthreshold, 2); if (ret) { printk("read threshold failed\n"); } dvfs_tbl->freq_index = i; + clk_item->clock = dvfs_tbl->clk_freq / 1000000; + clk_item->vol = dvfs_tbl->voltage; + *clk_sample = dvfs_tbl->clk_freq / 1000000; + dvfs_tbl ++; + clk_item ++; clk_sample ++; + i++; } dvfs_tbl = mpdata->dvfs_table; clk_sample = mpdata->clk_sample; - for (i = 0; i\n, clk_sample=%d\n", - dvfs_tbl->clk_freq, dvfs_tbl->clk_parent, - dvfs_tbl->voltage, dvfs_tbl->keep_count, - dvfs_tbl->downthreshold, dvfs_tbl->upthreshold, *clk_sample); + dvfs_tbl->clk_freq, dvfs_tbl->clk_parent, + dvfs_tbl->voltage, dvfs_tbl->keep_count, + dvfs_tbl->downthreshold, dvfs_tbl->upthreshold, *clk_sample); dvfs_tbl ++; clk_sample ++; } + mpdata->clk_mali = devm_clk_get(&pdev->dev, "clk_mali"); + mpdata->clk_mali_0 = devm_clk_get(&pdev->dev, "clk_mali_0"); + mpdata->clk_mali_1 = devm_clk_get(&pdev->dev, "clk_mali_1"); + if (IS_ERR(mpdata->clk_mali) || IS_ERR(mpdata->clk_mali_0) || IS_ERR(mpdata->clk_mali_1)) { + dev_err(&pdev->dev, "failed to get clock pointer\n"); + return -EFAULT; + } + pmali_plat = mpdata; mpdata->pdev = pdev; return 0; } -#endif diff --git a/mali/platform/meson_bu/mali_dvfs.c b/mali/platform/meson_bu/mali_dvfs.c new file mode 100644 index 0000000..340e650 --- /dev/null +++ b/mali/platform/meson_bu/mali_dvfs.c @@ -0,0 +1,212 @@ +/* + * 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 +#include +#include + +#include +#include "meson_main2.h" + + +static int currentStep; +static int scaling_mode = MALI_PP_FS_SCALING; +//static int scaling_mode = MALI_SCALING_DISABLE; +//static int scaling_mode = MALI_PP_SCALING; + +//static struct gp_pll_user_handle_s *gp_pll_user_gpu; +//static int is_gp_pll_get; +//static int is_gp_pll_put; + +static unsigned scaling_dbg_level = 0; +module_param(scaling_dbg_level, uint, 0644); +MODULE_PARM_DESC(scaling_dbg_level , "scaling debug level"); + +static mali_plat_info_t* pmali_plat = NULL; +static struct workqueue_struct *mali_scaling_wq = NULL; +//static DEFINE_SPINLOCK(lock); + +static int cur_gpu_clk_index = 0; +static int exec_gpu_clk_index = 0; +#define scalingdbg(level, fmt, arg...) \ + do { \ + if (scaling_dbg_level >= (level)) \ + printk(fmt , ## arg); \ + } while (0) + +struct mali_gpu_clock meson_gpu_clk_info = { + .item = NULL, + .num_of_steps = 0, +}; + +u32 revise_set_clk(u32 val, u32 flush) +{ + u32 ret = 0; + return ret; +} + +void get_mali_rt_clkpp(u32* clk, u32* pp) +{ +} + +u32 set_mali_rt_clkpp(u32 clk, u32 pp, u32 flush) +{ + u32 ret = 0; + return ret; +} + +void revise_mali_rt(void) +{ +} + +static void do_scaling(struct work_struct *work) +{ + //unsigned long flags; + mali_plat_info_t *pinfo = container_of(work, struct mali_plat_info_t, wq_work); + + *pinfo = *pinfo; + //mali_dev_pause(); + //spin_lock_irqsave(&lock, flags); + mali_clock_set(exec_gpu_clk_index); + cur_gpu_clk_index = exec_gpu_clk_index; + //spin_unlock_irqrestore(&lock, flags); + //mali_dev_resume(); +} +void flush_scaling_job(void) +{ + if (mali_scaling_wq == NULL) return; + + flush_workqueue(mali_scaling_wq); + printk("%s, %d\n", __func__, __LINE__); +} + + +int mali_core_scaling_init(mali_plat_info_t *mali_plat) +{ + pmali_plat = mali_plat; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) + mali_scaling_wq = alloc_workqueue("gpu_scaling_wq", WQ_HIGHPRI | WQ_UNBOUND, 0); +#else + mali_scaling_wq = create_workqueue("gpu_scaling_wq"); +#endif + INIT_WORK(&pmali_plat->wq_work, do_scaling); + if (mali_scaling_wq == NULL) printk("Unable to create gpu scaling workqueue\n"); + + meson_gpu_clk_info.num_of_steps = pmali_plat->scale_info.maxclk; + + return 0; +} + +void mali_core_scaling_term(void) +{ + flush_scaling_job(); + destroy_workqueue(mali_scaling_wq); + mali_scaling_wq = NULL; +} + +void mali_pp_scaling_update(struct mali_gpu_utilization_data *data) +{ +} + +void mali_pp_fs_scaling_update(struct mali_gpu_utilization_data *data) +{ +} + +u32 get_mali_schel_mode(void) +{ + return scaling_mode; +} + +void set_mali_schel_mode(u32 mode) +{ + scaling_mode = mode; + if (scaling_mode == MALI_TURBO_MODE) { + printk ("turbo mode\n"); + pmali_plat->limit_on = 0; + meson_gpu_clk_info.num_of_steps = pmali_plat->turbo_clock; + } else { + printk ("not turbo mode\n"); + pmali_plat->limit_on = 1; + meson_gpu_clk_info.num_of_steps = pmali_plat->scale_info.maxclk; + } + + printk("total_enable_steps = %d\n", meson_gpu_clk_info.num_of_steps); +} + +u32 get_current_frequency(void) +{ + return get_mali_freq(currentStep); +} + +void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data) +{ +} + +void mali_dev_restore(void) +{ + //TO add this + //mali_perf_set_num_pp_cores(num_cores_enabled); + if (pmali_plat && pmali_plat->pdev) { + mali_clock_init_clk_tree(pmali_plat->pdev); + } else { + printk("error: init clock failed, pmali_plat=%p, pmali_plat->pdev=%p\n", + pmali_plat, pmali_plat == NULL ? NULL: pmali_plat->pdev); + } +} + +/* Function that platfrom report it's clock info which driver can set, needed when CONFIG_MALI_DVFS enabled */ +static void meson_platform_get_clock_info(struct mali_gpu_clock **data) { + if (pmali_plat) { + meson_gpu_clk_info.item = pmali_plat->clk_items; + meson_gpu_clk_info.num_of_steps = pmali_plat->scale_info.maxclk; + printk("get clock info\n"); + } else { + printk("error pmali_plat is null"); + } + *data = &meson_gpu_clk_info; +} + +/* Function that get the current clock info, needed when CONFIG_MALI_DVFS enabled */ +static int meson_platform_get_freq(void) { + scalingdbg(1, "cur_gpu_clk_index =%d\n", cur_gpu_clk_index); + //dynamically changed the num of steps; + return cur_gpu_clk_index; +} + +/* Fuction that platform callback for freq setting, needed when CONFIG_MALI_DVFS enabled */ +static int meson_platform_set_freq(int setting_clock_step) { + + if (exec_gpu_clk_index == setting_clock_step) { + return 0; + } + + queue_work(mali_scaling_wq, &pmali_plat->wq_work); + exec_gpu_clk_index = setting_clock_step; + scalingdbg(1, "set cur_gpu_clk_index =%d\n", cur_gpu_clk_index); + return 0; +} + +int mali_meson_get_gpu_data(struct mali_gpu_device_data *mgpu_data) +{ + mgpu_data->get_clock_info = meson_platform_get_clock_info, + mgpu_data->get_freq = meson_platform_get_freq, + mgpu_data->set_freq = meson_platform_set_freq, + mgpu_data->utilization_callback = NULL; + return 0; +} diff --git a/mali/platform/meson_bu/meson_main2.c b/mali/platform/meson_bu/meson_main2.c index bca9175..98f29b7 100644 --- a/mali/platform/meson_bu/meson_main2.c +++ b/mali/platform/meson_bu/meson_main2.c @@ -28,12 +28,6 @@ #include "mali_clock.h" #include "meson_main2.h" -#define CLK_DVFS_TBL_SIZE 5 - -#if 0 -static int mali_core_scaling_enable = 0; -#endif - int mali_pm_statue = 0; extern void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data); @@ -54,10 +48,6 @@ static struct mali_gpu_device_data mali_gpu_data = { .fb_size = 0x01000000, #endif .control_interval = 200, /* 1000ms */ - .utilization_callback = mali_gpu_utilization_callback, - .get_clock_info = NULL, - .get_freq = NULL, - .set_freq = NULL, }; int mali_platform_device_init(struct platform_device *device) @@ -66,6 +56,8 @@ int mali_platform_device_init(struct platform_device *device) err = mali_meson_init_start(device); if (0 != err) printk("mali init failed\n"); + err = mali_meson_get_gpu_data(&mali_gpu_data); + if (0 != err) printk("mali get gpu data failed\n"); err = platform_device_add_data(device, &mali_gpu_data, sizeof(mali_gpu_data)); @@ -76,7 +68,6 @@ int mali_platform_device_init(struct platform_device *device) pm_runtime_set_autosuspend_delay(&device->dev, 1000); pm_runtime_use_autosuspend(&device->dev); #endif - pm_runtime_enable(&(device->dev)); pm_runtime_enable(&device->dev); #endif mali_meson_init_finish(device); @@ -95,7 +86,6 @@ int mali_platform_device_deinit(struct platform_device *device) printk("%s, %d\n", __FILE__, __LINE__); MALI_DEBUG_PRINT(4, ("mali_platform_device_deinit() called\n")); - mali_core_scaling_term(); mali_meson_uninit(device); diff --git a/mali/platform/meson_bu/meson_main2.h b/mali/platform/meson_bu/meson_main2.h index a67441f..5a65cb2 100644 --- a/mali/platform/meson_bu/meson_main2.h +++ b/mali/platform/meson_bu/meson_main2.h @@ -13,6 +13,7 @@ #ifdef CONFIG_PM_RUNTIME #include #endif +#include #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 29)) #include #endif @@ -27,6 +28,7 @@ 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_get_gpu_data(struct mali_gpu_device_data *mgpu_data); int mali_meson_init_finish(struct platform_device* ptr_plt_dev); int mali_meson_uninit(struct platform_device* ptr_plt_dev); int mali_light_suspend(struct device *device); diff --git a/mali/platform/meson_bu/mpgpu.c b/mali/platform/meson_bu/mpgpu.c index cadb61f..794e23b 100644 --- a/mali/platform/meson_bu/mpgpu.c +++ b/mali/platform/meson_bu/mpgpu.c @@ -35,14 +35,12 @@ static ssize_t domain_stat_read(struct class *class, struct class_attribute *attr, char *buf) { -#if 0 unsigned int val; + mali_plat_info_t* pmali_plat = get_mali_plat_data(); - val = readl((u32 *)(IO_AOBUS_BASE + 0xf0)) & 0xff; + val = readl(pmali_plat->reg_base_aobus + 0xf0) & 0xff; return sprintf(buf, "%x\n", val>>4); -#else return 0; -#endif } #define PREHEAT_CMD "preheat" diff --git a/mali/platform/meson_bu/platform_gx.c b/mali/platform/meson_bu/platform_gx.c index 77da53d..9dc9952 100644 --- a/mali/platform/meson_bu/platform_gx.c +++ b/mali/platform/meson_bu/platform_gx.c @@ -37,87 +37,11 @@ * For Meson 8 M2. * */ - -#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 */ -#define FCLK_DEV4 (5 << 9) /* 637.5 Mhz */ -#define FCLK_DEV5 (7 << 9) /* 510 Mhz */ -#define FCLK_DEV7 (4 << 9) /* 364.3 Mhz */ - - -static u32 mali_dvfs_clk[] = { - FCLK_DEV7 | 1, /* 182.1 Mhz */ - FCLK_DEV4 | 1, /* 318.7 Mhz */ - FCLK_DEV3 | 1, /* 425 Mhz */ - FCLK_DEV5 | 0, /* 510 Mhz */ - FCLK_DEV4 | 0, /* 637.5 Mhz */ -}; - -static u32 mali_dvfs_clk_sample[] = { - 182, /* 182.1 Mhz */ - 319, /* 318.7 Mhz */ - 425, /* 425 Mhz */ - 510, /* 510 Mhz */ - 637, /* 637.5 Mhz */ -}; -////////////////////////////////////// -//for dvfs -struct mali_gpu_clk_item meson_gpu_clk[] = { - {182, 1150}, /* 182.1 Mhz, 1150mV */ - {319, 1150}, /* 318.7 Mhz */ - {425, 1150}, /* 425 Mhz */ - {510, 1150}, /* 510 Mhz */ - {637, 1150}, /* 637.5 Mhz */ -}; -struct mali_gpu_clock meson_gpu_clk_info = { - .item = meson_gpu_clk, - .num_of_steps = ARRAY_SIZE(meson_gpu_clk), -}; -static int cur_gpu_clk_index = 0; -////////////////////////////////////// -static mali_dvfs_threshold_table mali_dvfs_table[]={ - { 0, 0, 3, 30, 80}, /* for 182.1 */ - { 1, 1, 3, 40, 205}, /* for 318.7 */ - { 2, 2, 3, 150, 215}, /* for 425.0 */ - { 3, 3, 3, 170, 253}, /* for 510.0 */ - { 4, 4, 3, 230, 255}, /* 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_clock_bkup = CFG_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 = 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, }; @@ -207,33 +131,6 @@ quit: #endif void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data); - -/* Function that platfrom report it's clock info which driver can set, needed when CONFIG_MALI_DVFS enabled */ -void meson_platform_get_clock_info(struct mali_gpu_clock **data) { - *data = &meson_gpu_clk_info; -} - -/* Function that get the current clock info, needed when CONFIG_MALI_DVFS enabled */ -int meson_platform_get_freq(void) { - printk("get cur_gpu_clk_index =%d\n", cur_gpu_clk_index); - return cur_gpu_clk_index; -} - -/* Fuction that platform callback for freq setting, needed when CONFIG_MALI_DVFS enabled */ -int meson_platform_set_freq(int setting_clock_step) { - - if (cur_gpu_clk_index == setting_clock_step) { - return 0; - } - - mali_clock_set(setting_clock_step); - - cur_gpu_clk_index = setting_clock_step; - printk("set cur_gpu_clk_index =%d\n", cur_gpu_clk_index); - - return 0; -} - int mali_meson_init_start(struct platform_device* ptr_plt_dev) { dev_set_drvdata(&ptr_plt_dev->dev, &mali_plat_data); @@ -244,17 +141,14 @@ int mali_meson_init_start(struct platform_device* ptr_plt_dev) int mali_meson_init_finish(struct platform_device* ptr_plt_dev) { -#ifndef CONFIG_MALI_DVFS if (mali_core_scaling_init(&mali_plat_data) < 0) return -1; -#else - printk("disable meson own dvfs\n"); -#endif return 0; } int mali_meson_uninit(struct platform_device* ptr_plt_dev) { + mali_core_scaling_term(); return 0; } @@ -355,6 +249,7 @@ int mali_light_suspend(struct device *device) 0, 0, 0, 0, 0); #endif + flush_scaling_job(); /* clock scaling. Kasin..*/ ret = mali_clock_critical(mali_cri_light_suspend, (size_t)device); disable_clock(); @@ -380,10 +275,8 @@ int mali_deep_suspend(struct device *device) int ret = 0; mali_pm_statue = 1; - enable_clock(); -#ifndef CONFIG_MALI_DVFS flush_scaling_job(); -#endif + /* clock scaling off. Kasin... */ ret = mali_clock_critical(mali_cri_deep_suspend, (size_t)device); diff --git a/mali/platform/meson_bu/scaling.c b/mali/platform/meson_bu/scaling.c index 57ebf3f..871dd87 100644 --- a/mali/platform/meson_bu/scaling.c +++ b/mali/platform/meson_bu/scaling.c @@ -20,10 +20,10 @@ #include #include -#include #include #define LOG_MALI_SCALING 1 - +#include "meson_main2.h" +#include "mali_clock.h" static int currentStep; #ifndef CONFIG_MALI_DVFS @@ -467,6 +467,12 @@ void set_mali_schel_mode(u32 mode) return; scaling_mode = mode; + //disable thermal in turbo mode + if (scaling_mode == MALI_TURBO_MODE) { + pmali_plat->limit_on = 0; + } else { + pmali_plat->limit_on = 1; + } /* set default performance range. */ pmali_plat->scale_info.minclk = pmali_plat->cfg_min_clock; pmali_plat->scale_info.maxclk = pmali_plat->cfg_clock; @@ -515,10 +521,20 @@ void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data) void mali_dev_restore(void) { -#ifndef CONFIG_MALI_DVFS - mali_dvfs_threshold_table * pdvfs = pmali_plat->dvfs_table; + mali_perf_set_num_pp_cores(num_cores_enabled); + if (pmali_plat && pmali_plat->pdev) { + mali_clock_init_clk_tree(pmali_plat->pdev); + } else { + printk("error: init clock failed, pmali_plat=%p, pmali_plat->pdev=%p\n", + pmali_plat, pmali_plat == NULL ? NULL: pmali_plat->pdev); + } +} - //mali_perf_set_num_pp_cores(num_cores_enabled); - mali_clock_set(pdvfs[currentStep].freq_index); -#endif +int mali_meson_get_gpu_data(struct mali_gpu_device_data *mgpu_data) +{ + mgpu_data->get_clock_info = NULL; + mgpu_data->get_freq = NULL; + mgpu_data->set_freq = NULL; + mgpu_data->utilization_callback = mali_gpu_utilization_callback; + return 0; } -- 2.20.1