From: chenzhen Date: Fri, 4 Mar 2016 13:50:45 +0000 (+0800) Subject: MALI: rockchip: tidy 'platform specific code'. X-Git-Tag: firefly_0821_release~3250 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=457a0b7e49c625dd87b3f9d7fd7cc4d9d59430d8;p=firefly-linux-kernel-4.4.55.git MALI: rockchip: tidy 'platform specific code'. We use devfreq to implement DVFS of GPU, instead of 'legacy_dvfs'. Change-Id: If5c8ef05c8f37c88a5c22779468b21315d71eda0 Signed-off-by: chenzhen --- diff --git a/drivers/gpu/arm/midgard/platform/rk/Kbuild b/drivers/gpu/arm/midgard/platform/rk/Kbuild index 0e323b2c3256..700fd4341da5 100755 --- a/drivers/gpu/arm/midgard/platform/rk/Kbuild +++ b/drivers/gpu/arm/midgard/platform/rk/Kbuild @@ -13,12 +13,13 @@ # ccflags-y += -I$(srctree)/drivers/staging/android + ifeq ($(CONFIG_MALI_MIDGARD),y) obj-y += mali_kbase_config_rk.o -obj-y += mali_kbase_dvfs.o -obj-y += mali_kbase_platform.o +# obj-y += mali_kbase_dvfs.o +# obj-y += mali_kbase_platform.o else ifeq ($(CONFIG_MALI_MIDGARD),m) SRC += platform/rk/mali_kbase_config_rk.c -SRC += platform/rk/mali_kbase_dvfs.c -SRC += platform/rk/mali_kbase_platform.c +# SRC += platform/rk/mali_kbase_dvfs.c +# SRC += platform/rk/mali_kbase_platform.c endif diff --git a/drivers/gpu/arm/midgard/platform/rk/custom_log.h b/drivers/gpu/arm/midgard/platform/rk/custom_log.h index 6dc9c0553f65..644aff664f0d 100755 --- a/drivers/gpu/arm/midgard/platform/rk/custom_log.h +++ b/drivers/gpu/arm/midgard/platform/rk/custom_log.h @@ -1,222 +1,208 @@ -/* -------------------------------------------------------------------------------------------------------- - * File: custom_log.h - * - * Desc: ChenZhen 偏好的 log 输出的定制实现. - * - * ----------------------------------------------------------------------------------- - * < 习语 和 缩略语 > : - * - * ----------------------------------------------------------------------------------- - * Usage: - * - * Note: - * - * Author: ChenZhen - * - * -------------------------------------------------------------------------------------------------------- - * Version: - * v1.0 - * -------------------------------------------------------------------------------------------------------- - * Log: - ----Fri Nov 19 15:20:28 2010 v1.0 - * - * -------------------------------------------------------------------------------------------------------- - */ - - -#ifndef __CUSTOM_LOG_H__ -#define __CUSTOM_LOG_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* --------------------------------------------------------------------------------------------------------- - * Include Files - * --------------------------------------------------------------------------------------------------------- - */ -#include - - -/* --------------------------------------------------------------------------------------------------------- - * Macros Definition - * --------------------------------------------------------------------------------------------------------- - */ - -/** 若下列 macro 有被定义, 才 使能 log 输出. */ -// #define ENABLE_DEBUG_LOG - -/** .! : 若需要全局地关闭 D log, 可以使能下面的代码. */ -/* -#undef ENABLE_DEBUG_LOG -#warning "custom debug log is disabled globally!" -*/ - -#define LOGD(fmt, args...) \ - printk(KERN_DEBUG fmt "\n", ## args) - -/*---------------------------------------------------------------------------*/ - -#ifdef ENABLE_VERBOSE_LOG -/** Verbose log. */ -#define V(fmt, args...) \ - { printk(KERN_DEBUG "V : [File] : %s; [Line] : %d; [Func] : %s(); " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ## args); } -#else -#define V(...) ((void)0) -#endif - - -#ifdef ENABLE_DEBUG_LOG -/** Debug log. */ -#define D(fmt, args...) \ - { printk(KERN_DEBUG "D : [File] : %s; [Line] : %d; [Func] : %s(); " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ## args); } -#else -#define D(...) ((void)0) -#endif - -#define I(fmt, args...) \ - { printk(KERN_INFO "I : [File] : %s; [Line] : %d; [Func] : %s(); " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ## args); } - -#define W(fmt, args...) \ - { printk(KERN_WARNING "W : [File] : %s; [Line] : %d; [Func] : %s(); " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ## args); } - -#define E(fmt, args...) \ - { printk(KERN_ERR "E : [File] : %s; [Line] : %d; [Func] : %s(); " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ## args); } - -/*-------------------------------------------------------*/ - -/** 使用 D(), 以十进制的形式打印变量 'var' 的 value. */ -#define D_DEC(var) D(#var " = %d.", var); - -#define E_DEC(var) E(#var " = %d.", var); - -/** 使用 D(), 以十六进制的形式打印变量 'var' 的 value. */ -#define D_HEX(var) D(#var " = 0x%x.", var); - -#define E_HEX(var) E(#var " = 0x%x.", var); - -/** 使用 D(), 以十六进制的形式 打印指针类型变量 'ptr' 的 value. */ -#define D_PTR(ptr) D(#ptr " = %p.", ptr); - -#define E_PTR(ptr) E(#ptr " = %p.", ptr); - -/** 使用 D(), 打印 char 字串. */ -#define D_STR(pStr) \ -{\ - if ( NULL == pStr )\ - {\ - D(#pStr" = NULL.");\ - }\ - else\ - {\ - D(#pStr" = '%s'.", pStr);\ - }\ -} - -#define E_STR(pStr) \ -{\ - if ( NULL == pStr )\ - {\ - E(#pStr" = NULL.");\ - }\ - else\ - {\ - E(#pStr" = '%s'.", pStr);\ - }\ -} - -#ifdef ENABLE_DEBUG_LOG -/** - * log 从 'pStart' 地址开始的 'len' 个字节的数据. - */ -#define D_MEM(pStart, len) \ - {\ - int i = 0;\ - char* p = (char*)pStart;\ - D("dump memory from addr of '" #pStart "', from %p, length %d' : ", pStart, len); \ - printk("\t\t");\ - for ( i = 0; i < len ; i++ )\ - {\ - printk("0x%02x, ", p[i] );\ - }\ - printk("\n");\ - } -#else -#define D_MEM(...) ((void)0) -#endif - -/*-------------------------------------------------------*/ - -#define EXIT_FOR_DEBUG \ -{\ - E("To exit for debug.");\ - return 1;\ -} - -/*-------------------------------------------------------*/ - -/** - * 调用函数, 并检查返回值, 根据返回值决定是否跳转到指定的错误处理代码. - * @param functionCall - * 对特定函数的调用, 该函数的返回值必须是 表征 成功 or err 的 整型数. - * 这里, 被调用函数 "必须" 是被定义为 "返回 0 表示操作成功". - * @param result - * 用于记录函数返回的 error code 的 整型变量, 通常是 "ret" or "result" 等. - * @param label - * 若函数返回错误, 程序将要跳转到的 错误处理处的 标号, 通常就是 "EXIT". - */ -#define CHECK_FUNC_CALL(functionCall, result, label) \ -{\ - if ( 0 != ( (result) = (functionCall) ) )\ - {\ - E("Function call returned error : " #result " = %d.", result);\ - goto label;\ - }\ -} - -/** - * 在特定条件下, 判定 error 发生, 对变量 'retVar' 设置 'errCode', - * Log 输出对应的 Error Caution, 然后跳转 'label' 指定的代码处执行. - * @param msg - * 纯字串形式的提示信息. - * @param retVar - * 标识函数执行状态或者结果的变量, 将被设置具体的 Error Code. - * 通常是 'ret' or 'result'. - * @param errCode - * 表征特定 error 的常数标识, 通常是 宏的形态. - * @param label - * 程序将要跳转到的错误处理代码的标号, 通常就是 'EXIT'. - * @param args... - * 对应 'msgFmt' 实参中 '%s', '%d', ... 等 转换说明符 的具体可变长实参. - */ -#define SET_ERROR_AND_JUMP(msgFmt, retVar, errCode, label, args...) \ -{\ - E("To set '" #retVar "' to %d('" #errCode "'), because : " msgFmt, (errCode), ## args);\ - (retVar) = (errCode);\ - goto label;\ -} - - -/* --------------------------------------------------------------------------------------------------------- - * Types and Structures Definition - * --------------------------------------------------------------------------------------------------------- - */ - - -/* --------------------------------------------------------------------------------------------------------- - * Global Functions' Prototype - * --------------------------------------------------------------------------------------------------------- - */ - - -/* --------------------------------------------------------------------------------------------------------- - * Inline Functions Implementation - * --------------------------------------------------------------------------------------------------------- - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __CUSTOM_LOG_H__ */ - +/* ---------------------------------------------------------------------------- + * File: custom_log.h + * + * Desc: ChenZhen 偏好的 log 输出的定制实现. + * + * -------------------------------------------------------------------- + * < 习语 和 缩略语 > : + * + * -------------------------------------------------------------------- + * Usage: + * + * Note: + * + * Author: ChenZhen + * + * ---------------------------------------------------------------------------- + * Version: + * v1.0 + * ---------------------------------------------------------------------------- + * Log: + ----Fri Nov 19 15:20:28 2010 v1.0 + * + * ---------------------------------------------------------------------------- + */ + +#ifndef __CUSTOM_LOG_H__ +#define __CUSTOM_LOG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ----------------------------------------------------------------------------- + * Include Files + * ----------------------------------------------------------------------------- + */ +#include +#include + +/* ----------------------------------------------------------------------------- + * Macros Definition + * ----------------------------------------------------------------------------- + */ + +/** 若下列 macro 有被定义, 才 使能 log 输出. */ +/* #define ENABLE_DEBUG_LOG */ + +/*----------------------------------------------------------------------------*/ + +#ifdef ENABLE_VERBOSE_LOG +/** Verbose log. */ +#define V(fmt, args...) \ + pr_debug("V : [File] : %s; [Line] : %d; [Func] : %s(); " fmt \ + "\n", \ + __FILE__, \ + __LINE__, \ + __func__, \ + ## args) +#else +#define V(...) ((void)0) +#endif + +#ifdef ENABLE_DEBUG_LOG +/** Debug log. */ +#define D(fmt, args...) \ + pr_debug("D : [File] : %s; [Line] : %d; [Func] : %s(); " fmt \ + "\n", \ + __FILE__, \ + __LINE__, \ + __func__, \ + ## args) +#else +#define D(...) ((void)0) +#endif + +#define I(fmt, args...) \ + pr_info("I : [File] : %s; [Line] : %d; [Func] : %s(); " fmt \ + "\n", \ + __FILE__, \ + __LINE__, \ + __func__, \ + ## args) + +#define W(fmt, args...) \ + pr_warn("W : [File] : %s; [Line] : %d; [Func] : %s(); " \ + fmt "\n", \ + __FILE__, \ + __LINE__, \ + __func__, \ + ## args) + +#define E(fmt, args...) \ + pr_err("E : [File] : %s; [Line] : %d; [Func] : %s(); " fmt \ + "\n", \ + __FILE__, \ + __LINE__, \ + __func__, \ + ## args) + +/*-------------------------------------------------------*/ + +/** 使用 D(), 以十进制的形式打印变量 'var' 的 value. */ +#define D_DEC(var) D(#var " = %d.", var) + +#define E_DEC(var) E(#var " = %d.", var) + +/** 使用 D(), 以十六进制的形式打印变量 'var' 的 value. */ +#define D_HEX(var) D(#var " = 0x%x.", var) + +#define E_HEX(var) E(#var " = 0x%x.", var) + +/** + * 使用 D(), 以十六进制的形式, + * 打印指针类型变量 'ptr' 的 value. + */ +#define D_PTR(ptr) D(#ptr " = %p.", ptr) + +#define E_PTR(ptr) E(#ptr " = %p.", ptr) + +/** 使用 D(), 打印 char 字串. */ +#define D_STR(p_str) \ +do { \ + if (!p_str) { \ + D(#p_str" = NULL."); \ + else \ + D(#p_str" = '%s'.", p_str); \ +} while (0) + +#define E_STR(p_str) \ +do { \ + if (!p_str) \ + E(#p_str" = NULL."); \ + else \ + E(#p_str" = '%s'.", p_str); \ +} while (0) + +#ifdef ENABLE_DEBUG_LOG +/** + * log 从 'p_start' 地址开始的 'len' 个字节的数据. + */ +#define D_MEM(p_start, len) \ +do { \ + int i = 0; \ + char *p = (char *)(p_start); \ + D("dump memory from addr of '" #p_start "', from %p, length %d' : ", \ + (p_start), \ + (len)); \ + pr_debug("\t\t"); \ + for (i = 0; i < (len); i++) \ + pr_debug("0x%02x, ", p[i]); \ + pr_debug("\n"); \ +} while (0) +#else +#define D_MEM(...) ((void)0) +#endif + +/*-------------------------------------------------------*/ + +/** + * 在特定条件下, 判定 error 发生, + * 将变量 'ret_var' 设置 'err_code', + * log 输出对应的 Error Caution, + * 然后跳转 'label' 指定的代码处执行. + * @param msg + * 纯字串形式的提示信息. + * @param ret_var + * 标识函数执行状态或者结果的变量, + * 将被设置具体的 Error Code. + * 通常是 'ret' or 'result'. + * @param err_code + * 表征特定 error 的常数标识, + * 通常是 宏的形态. + * @param label + * 程序将要跳转到的错误处理代码的标号, + * 通常就是 'EXIT'. + * @param args... + * 对应 'msg_fmt' 实参中, + * '%s', '%d', ... 等转换说明符的具体可变长实参. + */ +#define SET_ERROR_AND_JUMP(msg_fmt, ret_var, err_code, label, args...) \ +do { \ + E("To set '" #ret_var "' to %d('" #err_code "'), because : " msg_fmt, \ + (err_code), \ + ## args); \ + (ret_var) = (err_code); \ + goto label; \ +} while (0) + +/* ----------------------------------------------------------------------------- + * Types and Structures Definition + * ----------------------------------------------------------------------------- + */ + +/* ----------------------------------------------------------------------------- + * Global Functions' Prototype + * ----------------------------------------------------------------------------- + */ + +/* ----------------------------------------------------------------------------- + * Inline Functions Implementation + * ----------------------------------------------------------------------------- + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CUSTOM_LOG_H__ */ diff --git a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_platform.h b/drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_platform.h index 7def683e74fa..07c5b6f8a760 100644 --- a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_platform.h +++ b/drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_platform.h @@ -6,26 +6,17 @@ * 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 mali_kbase_config_platform.h * 声明 platform_config_of_rk (platform_rk 的 platform_config). - * - * 参见 文档 'mali_midgard_ddk_r6p0_integration_manual_DIT0023P_en' 中的 3.4.1. */ /** - * Maximum frequency - * GPU will be clocked at. + * Maximum frequency GPU will be clocked at. * Given in kHz. - * This must be specified - * as there is no default value. + * This must be specified as there is no default value. * * Attached value: number in kHz * Default value: NA @@ -33,10 +24,9 @@ #define GPU_FREQ_KHZ_MAX (5000) /** - * Minimum frequency GPU will be clocked at. - * Given in kHz. - * This must be specified - * as there is no default value. + * Minimum frequency GPU will be clocked at. + * Given in kHz. + * This must be specified as there is no default value. * * Attached value: number in kHz * Default value: NA @@ -44,12 +34,11 @@ #define GPU_FREQ_KHZ_MIN (5000) /** - * CPU_SPEED_FUNC - * - A pointer to a function that calculates the CPU clock + * CPU_SPEED_FUNC + * - A pointer to a function that calculates the CPU clock * - * CPU clock speed of the platform is in MHz - * - see kbase_cpu_clk_speed_func - * for the function prototype. + * CPU clock speed of the platform is in MHz + * - see kbase_cpu_clk_speed_func for the function prototype. * * Attached value: A kbase_cpu_clk_speed_func. * Default Value: NA @@ -57,11 +46,10 @@ #define CPU_SPEED_FUNC (NULL) /** - * GPU_SPEED_FUNC - * - A pointer to a function - * that calculates the GPU clock + * GPU_SPEED_FUNC + * - A pointer to a function that calculates the GPU clock * - * GPU clock speed of the platform in MHz + * GPU clock speed of the platform in MHz * - see kbase_gpu_clk_speed_func for the function prototype. * * Attached value: A kbase_gpu_clk_speed_func. @@ -72,9 +60,9 @@ /** * Power management configuration * - * Attached value: + * Attached value: * pointer to @ref kbase_pm_callback_conf - * Default value: + * Default value: * See @ref kbase_pm_callback_conf */ #define POWER_MANAGEMENT_CALLBACKS (&pm_callbacks) @@ -83,21 +71,14 @@ extern struct kbase_pm_callback_conf pm_callbacks; /** * Platform specific configuration functions * - * Attached value: + * Attached value: * pointer to @ref kbase_platform_funcs_conf - * Default value: + * Default value: * See @ref kbase_platform_funcs_conf */ #define PLATFORM_FUNCS (&platform_funcs) extern struct kbase_platform_funcs_conf platform_funcs; -/** Power model for IPA - * - * Attached value: pointer to @ref mali_pa_model_ops - */ -#define POWER_MODEL_CALLBACKS (NULL) - - /** * Secure mode switch * diff --git a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_rk.c b/drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_rk.c index 68125f97e37c..5f522971aa4c 100755 --- a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_rk.c +++ b/drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_rk.c @@ -6,334 +6,100 @@ * 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. - * */ -// #define ENABLE_DEBUG_LOG +#define ENABLE_DEBUG_LOG #include "custom_log.h" -#include #include #include #include -#ifdef CONFIG_UMP -#include -#endif /* CONFIG_UMP */ -#include -#include + #include #include -#include + /** * @file mali_kbase_config_rk.c * 对 platform_config_of_rk 的具体实现. - * - * mali_device_driver 包含两部分 : - * .DP : platform_dependent_part_in_mdd : 依赖 platform 部分, 源码在 /platform/ 目录下. - * 在 mali_device_driver 内部, 记为 platform_dependent_part. - * .DP : common_parts_in_mdd : arm 实现的通用的部分, 源码在 目录下. - * 在 mali_device_driver 内部, 记为 common_parts. - */ - -int get_cpu_clock_speed(u32 *cpu_clock); - -#define HZ_IN_MHZ (1000000) -#ifdef CONFIG_MALI_MIDGARD_RT_PM -#define RUNTIME_PM_DELAY_TIME 50 -#endif - -/* Versatile Express (VE) configuration defaults shared between config_attributes[] - * and config_attributes_hw_issue_8408[]. Settings are not shared for - * JS_HARD_STOP_TICKS_SS and JS_RESET_TICKS_SS. + * + * mali_device_driver 包含两部分 : + * .DP : platform_dependent_part_in_mdd : + * 依赖 platform 部分, + * 源码在 /platform// + * 在 mali_device_driver 内部, + * 记为 platform_dependent_part, + * 也被记为 platform_specific_code. + * .DP : common_parts_in_mdd : + * arm 实现的通用的部分, + * 源码在 / 下. + * 在 mali_device_driver 内部, 记为 common_parts. */ -#define KBASE_VE_MEMORY_PER_PROCESS_LIMIT (512 * 1024 * 1024UL) /* 512MB */ -#define KBASE_VE_MEMORY_OS_SHARED_MAX (2048 * 1024 * 1024UL) /* 768MB */ -#define KBASE_VE_MEMORY_OS_SHARED_PERF_GPU KBASE_MEM_PERF_FAST/*KBASE_MEM_PERF_SLOW*/ -#define KBASE_VE_GPU_FREQ_KHZ_MAX 500000 -#define KBASE_VE_GPU_FREQ_KHZ_MIN 100000 -#ifdef CONFIG_UMP -#define KBASE_VE_UMP_DEVICE UMP_DEVICE_Z_SHIFT -#endif /* CONFIG_UMP */ - -#define KBASE_VE_JS_SCHEDULING_TICK_NS_DEBUG 15000000u /* 15ms, an agressive tick for testing purposes. This will reduce performance significantly */ -#define KBASE_VE_JS_SOFT_STOP_TICKS_DEBUG 1 /* between 15ms and 30ms before soft-stop a job */ -#define KBASE_VE_JS_HARD_STOP_TICKS_SS_DEBUG 333 /* 5s before hard-stop */ -#define KBASE_VE_JS_HARD_STOP_TICKS_SS_8401_DEBUG 2000 /* 30s before hard-stop, for a certain GLES2 test at 128x128 (bound by combined vertex+tiler job) - for issue 8401 */ -#define KBASE_VE_JS_HARD_STOP_TICKS_NSS_DEBUG 100000 /* 1500s (25mins) before NSS hard-stop */ -#define KBASE_VE_JS_RESET_TICKS_SS_DEBUG 500 /* 45s before resetting GPU, for a certain GLES2 test at 128x128 (bound by combined vertex+tiler job) */ -#define KBASE_VE_JS_RESET_TICKS_SS_8401_DEBUG 3000 /* 7.5s before resetting GPU - for issue 8401 */ -#define KBASE_VE_JS_RESET_TICKS_NSS_DEBUG 100166 /* 1502s before resetting GPU */ - -#define KBASE_VE_JS_SCHEDULING_TICK_NS 2500000000u /* 2.5s */ -#define KBASE_VE_JS_SOFT_STOP_TICKS 1 /* 2.5s before soft-stop a job */ -#define KBASE_VE_JS_HARD_STOP_TICKS_SS 2 /* 5s before hard-stop */ -#define KBASE_VE_JS_HARD_STOP_TICKS_SS_8401 12 /* 30s before hard-stop, for a certain GLES2 test at 128x128 (bound by combined vertex+tiler job) - for issue 8401 */ -#define KBASE_VE_JS_HARD_STOP_TICKS_NSS 600 /* 1500s before NSS hard-stop */ -#define KBASE_VE_JS_RESET_TICKS_SS 3 /* 7.5s before resetting GPU */ -#define KBASE_VE_JS_RESET_TICKS_SS_8401 18 /* 45s before resetting GPU, for a certain GLES2 test at 128x128 (bound by combined vertex+tiler job) - for issue 8401 */ -#define KBASE_VE_JS_RESET_TICKS_NSS 601 /* 1502s before resetting GPU */ - -#define KBASE_VE_JS_RESET_TIMEOUT_MS 500 /* 3s before cancelling stuck jobs */ -#define KBASE_VE_JS_CTX_TIMESLICE_NS 1000000 /* 1ms - an agressive timeslice for testing purposes (causes lots of scheduling out for >4 ctxs) */ -#define KBASE_VE_SECURE_BUT_LOSS_OF_PERFORMANCE ((uintptr_t)MALI_FALSE) /* By default we prefer performance over security on r0p0-15dev0 and KBASE_CONFIG_ATTR_ earlier */ -/*#define KBASE_VE_POWER_MANAGEMENT_CALLBACKS ((uintptr_t)&pm_callbacks)*/ -#define KBASE_VE_CPU_SPEED_FUNC ((uintptr_t)&get_cpu_clock_speed) - -static int mali_pm_notifier(struct notifier_block *nb,unsigned long event,void* cmd); -static struct notifier_block mali_pm_nb = { - .notifier_call = mali_pm_notifier -}; -static int mali_reboot_notifier_event(struct notifier_block *this, unsigned long event, void *ptr) -{ - - pr_info("%s enter\n",__func__); - if (kbase_platform_dvfs_enable(false, MALI_DVFS_CURRENT_FREQ)!= MALI_TRUE) - return -EPERM; - pr_info("%s exit\n",__func__); - return NOTIFY_OK; -} - -static struct notifier_block mali_reboot_notifier = { - .notifier_call = mali_reboot_notifier_event, -}; - -#ifndef CONFIG_OF -static kbase_io_resources io_resources = { - .job_irq_number = 68, - .mmu_irq_number = 69, - .gpu_irq_number = 70, - .io_memory_region = { - .start = 0xFC010000, - .end = 0xFC010000 + (4096 * 5) - 1} -}; -#endif - -int get_cpu_clock_speed(u32 *cpu_clock) -{ -#if 0 - struct clk *cpu_clk; - u32 freq = 0; - cpu_clk = clk_get(NULL, "armclk"); - if (IS_ERR(cpu_clk)) - return 1; - freq = clk_get_rate(cpu_clk); - *cpu_clock = (freq / HZ_IN_MHZ); -#endif - return 0; -} -static int mali_pm_notifier(struct notifier_block *nb,unsigned long event,void* cmd) -{ - int err = NOTIFY_OK; - switch (event) { - case PM_SUSPEND_PREPARE: -#ifdef CONFIG_MALI_MIDGARD_DVFS - /* - pr_info("%s,PM_SUSPEND_PREPARE\n",__func__); - */ - if (kbase_platform_dvfs_enable(false, p_mali_dvfs_infotbl[0].clock)!= MALI_TRUE) - err = NOTIFY_BAD; -#endif - break; - case PM_POST_SUSPEND: -#ifdef CONFIG_MALI_MIDGARD_DVFS - /* - pr_info("%s,PM_POST_SUSPEND\n",__func__); - */ - if (kbase_platform_dvfs_enable(true, p_mali_dvfs_infotbl[0].clock)!= MALI_TRUE) - err = NOTIFY_BAD; -#endif - break; - default: - break; - } - return err; -} +/*---------------------------------------------------------------------------*/ -/* - rk3288 hardware specific initialization - */ int kbase_platform_rk_init(struct kbase_device *kbdev) { - if(MALI_ERROR_NONE == kbase_platform_init(kbdev)) - { - if (register_pm_notifier(&mali_pm_nb)) { - E("fail to register pm_notifier."); - return -1; - } - - pr_info("%s,register_reboot_notifier\n",__func__); - register_reboot_notifier(&mali_reboot_notifier); - return 0; - } - - E("fail to init platform."); - return -1; + return 0; } -/* - rk3288 hardware specific termination -*/ void kbase_platform_rk_term(struct kbase_device *kbdev) { - unregister_pm_notifier(&mali_pm_nb); -#ifdef CONFIG_MALI_MIDGARD_DEBUG_SYS - kbase_platform_remove_sysfs_file(kbdev->dev); -#endif /* CONFIG_MALI_MIDGARD_DEBUG_SYS */ - kbase_platform_term(kbdev); } -struct kbase_platform_funcs_conf platform_funcs = -{ +struct kbase_platform_funcs_conf platform_funcs = { .platform_init_func = &kbase_platform_rk_init, .platform_term_func = &kbase_platform_rk_term, }; -#ifdef CONFIG_MALI_MIDGARD_RT_PM +/*---------------------------------------------------------------------------*/ + static int pm_callback_power_on(struct kbase_device *kbdev) { - int result; - int ret_val; - struct device *dev = kbdev->dev; - struct rk_context *platform; - platform = (struct rk_context *)kbdev->platform_context; - - /* 若 mali_device 是 suspended 的, 则... */ - if (pm_runtime_status_suspended(dev)) - { - /* 预置返回 1, 表征 gpu_state 可能已经 lost 了. */ - ret_val = 1; - } - else - { - ret_val = 0; - } - - if(dev->power.disable_depth > 0) { - if(platform->cmu_pmu_status == 0) - { - /* 使能 gpu_power_domain 和 clk_of_gpu_dvfs_node. */ - kbase_platform_cmu_pmu_control(kbdev, 1); - } - return ret_val; - } - - result = pm_runtime_resume(dev); - - // if (result < 0 && result == -EAGAIN) - if ( -EAGAIN == result ) - kbase_platform_cmu_pmu_control(kbdev, 1); - else if (result < 0) - printk(KERN_ERR "pm_runtime_get_sync failed (%d)\n", result); - - return ret_val; + return 0; } static void pm_callback_power_off(struct kbase_device *kbdev) { - struct device *dev = kbdev->dev; - pm_schedule_suspend(dev, RUNTIME_PM_DELAY_TIME); } int kbase_device_runtime_init(struct kbase_device *kbdev) { - pm_suspend_ignore_children(kbdev->dev, true); - /* 对 mali_device 使能 runtime_pm. */ - pm_runtime_enable(kbdev->dev); -#ifdef CONFIG_MALI_MIDGARD_DEBUG_SYS - if (kbase_platform_create_sysfs_file(kbdev->dev)) - return MALI_ERROR_FUNCTION_FAILED; -#endif /* CONFIG_MALI_MIDGARD_DEBUG_SYS */ - return MALI_ERROR_NONE; + return 0; } void kbase_device_runtime_disable(struct kbase_device *kbdev) { - pm_runtime_disable(kbdev->dev); } static int pm_callback_runtime_on(struct kbase_device *kbdev) { -#ifdef CONFIG_MALI_MIDGARD_DVFS - struct rk_context *platform = (struct rk_context *)kbdev->platform_context; - unsigned long flags; - unsigned int clock; -#endif - - kbase_platform_power_on(kbdev); - - kbase_platform_clock_on(kbdev); -#ifdef CONFIG_MALI_MIDGARD_DVFS - if (platform->dvfs_enabled) { - if(platform->gpu_in_touch) { - clock = p_mali_dvfs_infotbl[MALI_DVFS_STEP-1].clock; - spin_lock_irqsave(&platform->gpu_in_touch_lock, flags); - platform->gpu_in_touch = false; - spin_unlock_irqrestore(&platform->gpu_in_touch_lock, flags); - } else { - clock = MALI_DVFS_CURRENT_FREQ; - } - /* - pr_info("%s,clock = %d\n",__func__,clock); - */ - if (kbase_platform_dvfs_enable(true, clock)!= MALI_TRUE) - return -EPERM; - - } else { - if (kbase_platform_dvfs_enable(false, MALI_DVFS_CURRENT_FREQ)!= MALI_TRUE) - return -EPERM; - } -#endif return 0; } static void pm_callback_runtime_off(struct kbase_device *kbdev) { -#ifdef CONFIG_MALI_MIDGARD_DVFS - struct rk_context *platform = (struct rk_context *)kbdev->platform_context; - unsigned long flags; -#endif - - kbase_platform_clock_off(kbdev); - kbase_platform_power_off(kbdev); -#ifdef CONFIG_MALI_MIDGARD_DVFS - if (platform->dvfs_enabled) - { - /*printk("%s\n",__func__);*/ - if (kbase_platform_dvfs_enable(false, p_mali_dvfs_infotbl[0].clock)!= MALI_TRUE) - printk("[err] disabling dvfs is faled\n"); - spin_lock_irqsave(&platform->gpu_in_touch_lock, flags); - platform->gpu_in_touch = false; - spin_unlock_irqrestore(&platform->gpu_in_touch_lock, flags); - } -#endif } struct kbase_pm_callback_conf pm_callbacks = { - .power_on_callback = pm_callback_power_on, + .power_on_callback = pm_callback_power_on, .power_off_callback = pm_callback_power_off, -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM .power_runtime_init_callback = kbase_device_runtime_init, .power_runtime_term_callback = kbase_device_runtime_disable, .power_runtime_on_callback = pm_callback_runtime_on, .power_runtime_off_callback = pm_callback_runtime_off, - -#else /* CONFIG_PM_RUNTIME */ +#else /* CONFIG_PM */ .power_runtime_init_callback = NULL, .power_runtime_term_callback = NULL, .power_runtime_on_callback = NULL, .power_runtime_off_callback = NULL, -#endif /* CONFIG_PM_RUNTIME */ +#endif /* CONFIG_PM */ }; -#endif int kbase_platform_early_init(void) { /* Nothing needed at this stage */ return 0; } + diff --git a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_dvfs.c b/drivers/gpu/arm/midgard/platform/rk/mali_kbase_dvfs.c deleted file mode 100755 index 13cd2dd7ea5f..000000000000 --- a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_dvfs.c +++ /dev/null @@ -1,941 +0,0 @@ -/* drivers/gpu/t6xx/kbase/src/platform/manta/mali_kbase_dvfs.c - * - * - * Rockchip SoC Mali-T764 DVFS driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software FoundatIon. - */ - -/** - * @file mali_kbase_dvfs.c - * DVFS - */ - -// #define ENABLE_DEBUG_LOG -#include "custom_log.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -/***********************************************************/ -/* This table and variable are using the check time share of GPU Clock */ -/***********************************************************/ -extern int rockchip_tsadc_get_temp(int chn); -/** gpu 温度上限. */ -#define gpu_temp_limit 110 -/** 经过 gpu_temp_statis_time 次测量记录之后, 对温度数据取平均. */ -#define gpu_temp_statis_time 1 - -#define level0_min 0 -#define level0_max 70 -#define levelf_max 100 - -static u32 div_dvfs = 0 ; - -/** - * .DP : mali_dvfs_level_table. - * 其中的 level_items 的 gpu_clk_freq 从低到高. - * - * 运行时初始化阶段, 将从 'mali_freq_table' 进行运行时初始化, - * 若获取 'mali_freq_table' 失败, 则使用这里的 缺省配置. - * 参见 kbase_platform_dvfs_init. - */ -static mali_dvfs_info mali_dvfs_infotbl[] = { - {925000, 100000, 0, 70, 0}, - {925000, 160000, 50, 65, 0}, - {1025000, 266000, 60, 78, 0}, - {1075000, 350000, 65, 75, 0}, - {1125000, 400000, 70, 75, 0}, - {1200000, 500000, 90, 100, 0}, -}; -/** - * pointer_to_mali_dvfs_level_table. - */ -mali_dvfs_info *p_mali_dvfs_infotbl = NULL; - -/** - * num_of_mali_dvfs_levels : mali_dvfs_level_table 中有效的 level_item 的数量. - */ -unsigned int MALI_DVFS_STEP = ARRAY_SIZE(mali_dvfs_infotbl); - -/** - * mali_dvfs_level_table 中可以容纳的 level_items 的最大数量. - */ -const unsigned int MAX_NUM_OF_MALI_DVFS_LEVELS = ARRAY_SIZE(mali_dvfs_infotbl); - -/** - * gpu_clk_freq_table_from_system_dvfs_module, 从 system_dvfs_module 得到的 gpu_clk 的 频点表. - * 原始的 频点配置信息在 .dts 文件中. - */ -static struct cpufreq_frequency_table *mali_freq_table = NULL; -#ifdef CONFIG_MALI_MIDGARD_DVFS - -/** mali_dvfs_status_t. */ -typedef struct _mali_dvfs_status_type { - struct kbase_device *kbdev; - /** - * .DP : current_dvfs_level : 当前使用的 mali_dvfs_level 在 mali_dvfs_level_table 中的 index. - * 参见 mali_dvfs_infotbl. - */ - int step; - /** 最新的 由 metrics_system 报告的 current_calculated_utilisation. */ - int utilisation; - /** 最近一次完成的 temperature_record_section 记录得到的温度数据. */ - u32 temperature; - /** 当前 temperature_record_section 中, 已经记录温度的次数. */ - u32 temperature_time; -#ifdef CONFIG_MALI_MIDGARD_FREQ_LOCK - /** - * gpu_freq_upper_limit, 即 dvfs_level_upper_limit. - * 量纲是 index of mali_dvfs_level_table. - * 若是 -1, 则表示当前未设置 dvfs_level_upper_limit. - */ - int upper_lock; - /** - * gpu_freq_lower_limit, 即 dvfs_level_lower_limit. - * 量纲是 index of mali_dvfs_level_table. - * 若是 -1, 则表示当前未设置 dvfs_level_lower_limit. - */ - int under_lock; -#endif - -} mali_dvfs_status; - -static struct workqueue_struct *mali_dvfs_wq = 0; - -/** - * 用来在并发环境下, 保护 mali_dvfs_status_current 等数据. - */ -spinlock_t mali_dvfs_spinlock; -struct mutex mali_set_clock_lock; -struct mutex mali_enable_clock_lock; - -#ifdef CONFIG_MALI_MIDGARD_DEBUG_SYS -static void update_time_in_state(int level); -#endif -/* .DP : current_mali_dvfs_status. */ -static mali_dvfs_status mali_dvfs_status_current; - -#define LIMIT_FPS 60 -#define LIMIT_FPS_POWER_SAVE 50 - -/*---------------------------------------------------------------------------*/ -#ifdef CONFIG_MALI_MIDGARD_DVFS -static void gpufreq_input_event(struct input_handle *handle, unsigned int type, - unsigned int code, int value) -{ - mali_dvfs_status *dvfs_status; - struct rk_context *platform; - unsigned long flags; - - if (type != EV_ABS) - return; - - dvfs_status = &mali_dvfs_status_current; - platform = (struct rk_context *)dvfs_status->kbdev->platform_context; - - spin_lock_irqsave(&platform->gpu_in_touch_lock, flags); - /* 有 input_event 到来, 设置对应标识. */ - platform->gpu_in_touch = true; - spin_unlock_irqrestore(&platform->gpu_in_touch_lock, flags); -} - -static int gpufreq_input_connect(struct input_handler *handler, - struct input_dev *dev, const struct input_device_id *id) -{ - struct input_handle *handle; // 用于关联 'dev' 和 'handler'. - int error; - - handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); - if (!handle) - return -ENOMEM; - - handle->dev = dev; // 'handle' 关联的 input_dev. - handle->handler = handler; - handle->name = "gpufreq"; - - error = input_register_handle(handle); - if (error) - goto err2; - - error = input_open_device(handle); - if (error) - goto err1; - pr_info("%s\n",__func__); - return 0; - -err1: - input_unregister_handle(handle); -err2: - kfree(handle); - return error; -} - -static void gpufreq_input_disconnect(struct input_handle *handle) -{ - input_close_device(handle); - input_unregister_handle(handle); - kfree(handle); - pr_info("%s\n",__func__); -} - -/** - * 待处理(关联) 的 input_device_ids_table. - */ -static const struct input_device_id gpufreq_ids[] = { - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | - INPUT_DEVICE_ID_MATCH_ABSBIT, - .evbit = { BIT_MASK(EV_ABS) }, - .absbit = { [BIT_WORD(ABS_MT_POSITION_X)] = - BIT_MASK(ABS_MT_POSITION_X) | - BIT_MASK(ABS_MT_POSITION_Y) }, - }, - { - .flags = INPUT_DEVICE_ID_MATCH_KEYBIT | - INPUT_DEVICE_ID_MATCH_ABSBIT, - .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, - .absbit = { [BIT_WORD(ABS_X)] = - BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) }, - }, - { }, -}; - -static struct input_handler gpufreq_input_handler = { - .event = gpufreq_input_event, - .connect = gpufreq_input_connect, - .disconnect = gpufreq_input_disconnect, - .name = "gpufreq", - .id_table = gpufreq_ids, -}; -#endif -/*---------------------------------------------------------------------------*/ - -/** - * mali_dvfs_work 的实现主体, 即对 dvfs_event 的处理流程的主体函数. - */ -static void mali_dvfs_event_proc(struct work_struct *w) -{ - unsigned long flags; - mali_dvfs_status *dvfs_status; - - static int level_down_time = 0; // counter_of_requests_to_jump_down_in_dvfs_level_table : - // 对 mali_dvfs_level 下跳 请求 发生的次数的静态计数. - static int level_up_time = 0; // counter_of_requests_to_jump_up_in_dvfs_level_table : - // 对 mali_dvfs_level 上跳 请求发生的次数的静态计数. - static u32 temp_tmp; - struct rk_context *platform; - u32 fps = 0; // real_fps. - u32 fps_limit; - u32 policy; - mutex_lock(&mali_enable_clock_lock); - dvfs_status = &mali_dvfs_status_current; - - if (!kbase_platform_dvfs_get_enable_status()) { - mutex_unlock(&mali_enable_clock_lock); - return; - } - platform = (struct rk_context *)dvfs_status->kbdev->platform_context; - - fps = rk_get_real_fps(0); - - dvfs_status->temperature_time++; - - temp_tmp += rockchip_tsadc_get_temp(1); // .Q : 获取当前温度? "1" : 意义? 指定特定的测试通道? - - if(dvfs_status->temperature_time >= gpu_temp_statis_time) { - dvfs_status->temperature_time = 0; - dvfs_status->temperature = temp_tmp / gpu_temp_statis_time; - temp_tmp = 0; - } - - spin_lock_irqsave(&mali_dvfs_spinlock, flags); - /* - policy = rockchip_pm_get_policy(); - */ - policy = ROCKCHIP_PM_POLICY_NORMAL; - - if (ROCKCHIP_PM_POLICY_PERFORMANCE == policy) { - dvfs_status->step = MALI_DVFS_STEP - 1; - } else { - fps_limit = (ROCKCHIP_PM_POLICY_NORMAL == policy)?LIMIT_FPS : LIMIT_FPS_POWER_SAVE; - V("policy : %d , fps_limit = %d", policy, fps_limit); - - /*give priority to temperature unless in performance mode */ - if (dvfs_status->temperature > gpu_temp_limit) // 若记录的 gpu 温度 超过了 上限, 则 ... - { - if(dvfs_status->step > 0) - dvfs_status->step--; - - if(gpu_temp_statis_time > 1) - dvfs_status->temperature = 0; - /* - pr_info("decrease step for temperature over %d,next clock = %d\n", - gpu_temp_limit, mali_dvfs_infotbl[dvfs_status->step].clock); - */ - V("jump down in dvfs_level_table to level '%d', for temperature over %d, next clock = %d", - dvfs_status->step, - gpu_temp_limit, - mali_dvfs_infotbl[dvfs_status->step].clock); - } - // 若 current_calculated_utilisation 要求 上调 mali_dvfs_level, - // 且 current_dvfs_level 还可能被上调, - // 且 real_fps "小于" fps_limit, - // 则 .... - else if ( (dvfs_status->utilisation > mali_dvfs_infotbl[dvfs_status->step].max_threshold) - && (dvfs_status->step < MALI_DVFS_STEP - 1) - && fps < fps_limit ) - { - // 至此, 可认为一次请求 mali_dvfs_level 上跳 发生. - - level_up_time++; - - /* 若 上跳请求的次数 达到 执行具体上跳 要求, 则... */ - if (level_up_time == MALI_DVFS_UP_TIME_INTERVAL) - { - V("to jump up in dvfs_level_table, utilisation=%d, current clock=%d, fps = %d, temperature = %d", - dvfs_status->utilisation, - mali_dvfs_infotbl[dvfs_status->step].clock, - fps, - dvfs_status->temperature); - /* 预置 current_dvfs_level 上跳. */ // 具体生效将在最后. - dvfs_status->step++; - /* 清 上跳请求计数. */ - level_up_time = 0; - - V(" next clock=%d.", mali_dvfs_infotbl[dvfs_status->step].clock); - BUG_ON(dvfs_status->step >= MALI_DVFS_STEP); // 数组中元素的 index 总是比 size 小. - } - - /* 清 下跳请求计数. */ - level_down_time = 0; - } - /* 否则, 若 current_calculated_utilisation 要求 current_dvfs_level 下跳, 且 还可以下跳, 则... */ - else if ((dvfs_status->step > 0) - && (dvfs_status->utilisation < mali_dvfs_infotbl[dvfs_status->step].min_threshold)) - { - level_down_time++; - - if (level_down_time==MALI_DVFS_DOWN_TIME_INTERVAL) - { - V("to jump down in dvfs_level_table ,utilisation=%d, current clock=%d, fps = %d, temperature = %d", - dvfs_status->utilisation, - mali_dvfs_infotbl[dvfs_status->step].clock, - fps, - dvfs_status->temperature); - - BUG_ON(dvfs_status->step <= 0); - dvfs_status->step--; - level_down_time = 0; - - V(" next clock=%d",mali_dvfs_infotbl[dvfs_status->step].clock); - } - - level_up_time = 0; - } - /* 否则, ... */ - else - { - level_down_time = 0; - level_up_time = 0; - - V("keep current_dvfs_level, utilisation=%d,current clock=%d,fps = %d,temperature = %d\n", - dvfs_status->utilisation, - mali_dvfs_infotbl[dvfs_status->step].clock, - fps, - dvfs_status->temperature); - } - } -#ifdef CONFIG_MALI_MIDGARD_FREQ_LOCK - // #error // 目前配置下, 本段代码有效. - - // 若 指定了 dvfs_level_upper_limit, - // 且 预置的 current_dvfs_level "大于" dvfs_level_upper_limit, - // 则... - if ((dvfs_status->upper_lock >= 0) - && (dvfs_status->step > dvfs_status->upper_lock)) - { - /* 将 预置的 current_dvfs_level 调整到 dvfs_level_upper_limit. */ - dvfs_status->step = dvfs_status->upper_lock; - } - - if (dvfs_status->under_lock > 0) { - if (dvfs_status->step < dvfs_status->under_lock) - dvfs_status->step = dvfs_status->under_lock; - } -#endif - spin_unlock_irqrestore(&mali_dvfs_spinlock, flags); - /* 将命令 dvfs_module 让 current_dvfs_level 具体生效. */ - kbase_platform_dvfs_set_level(dvfs_status->kbdev, dvfs_status->step); - - mutex_unlock(&mali_enable_clock_lock); -} - -/** - * mali_dvfs_work : 处理来自 kbase_platform_dvfs_event 的 dvfs_event 的 work. - */ -static DECLARE_WORK(mali_dvfs_work, mali_dvfs_event_proc); - - -/* ############################################################################################# */ -// callback_interface_to_common_parts_in_mdd - -/** - * 由 common_parts_in_mdd 调用的, 将 dvfs_event (utilisation_report_event) 通知回调到 platform_dependent_part_in_mdd. - */ -int kbase_platform_dvfs_event(struct kbase_device *kbdev, - u32 utilisation, // current_calculated_utilisation - u32 util_gl_share_no_use, - u32 util_cl_share_no_use[2] ) -{ - unsigned long flags; - struct rk_context *platform; - - BUG_ON(!kbdev); - platform = (struct rk_context *)kbdev->platform_context; - - spin_lock_irqsave(&mali_dvfs_spinlock, flags); - if (platform->time_tick < MALI_DVFS_UP_TIME_INTERVAL) { - platform->time_tick++; - platform->time_busy += kbdev->pm.backend.metrics.time_busy; - - platform->time_idle += kbdev->pm.backend.metrics.time_idle; - } else { - platform->time_busy = kbdev->pm.backend.metrics.time_busy; - platform->time_idle = kbdev->pm.backend.metrics.time_idle; - platform->time_tick = 0; - } - - if ((platform->time_tick == MALI_DVFS_UP_TIME_INTERVAL) && - (platform->time_idle + platform->time_busy > 0)) - platform->utilisation = (100 * platform->time_busy) / - (platform->time_idle + platform->time_busy); - - /* 记录 current_calculated_utilisation. */ - mali_dvfs_status_current.utilisation = utilisation; - spin_unlock_irqrestore(&mali_dvfs_spinlock, flags); - - /* 要求在 cpu_0 上, 使用 workqueue mali_dvfs_wq, 执行 mali_dvfs_work. */ - queue_work_on(0, mali_dvfs_wq, &mali_dvfs_work); - /*add error handle here */ - return MALI_TRUE; -} -/* ############################################################################################# */ - -int kbase_platform_dvfs_get_utilisation(void) -{ - unsigned long flags; - int utilisation = 0; - - spin_lock_irqsave(&mali_dvfs_spinlock, flags); - utilisation = mali_dvfs_status_current.utilisation; - spin_unlock_irqrestore(&mali_dvfs_spinlock, flags); - - return utilisation; -} - -int kbase_platform_dvfs_get_enable_status(void) -{ - struct kbase_device *kbdev; - unsigned long flags; - int enable; - - kbdev = mali_dvfs_status_current.kbdev; - spin_lock_irqsave(&kbdev->pm.backend.metrics.lock, flags); - enable = kbdev->pm.backend.metrics.timer_active; - spin_unlock_irqrestore(&kbdev->pm.backend.metrics.lock, flags); - - return enable; -} - -int kbase_platform_dvfs_enable(bool enable, int freq) -{ - mali_dvfs_status *dvfs_status; - struct kbase_device *kbdev; - unsigned long flags; - struct rk_context *platform; - - dvfs_status = &mali_dvfs_status_current; - kbdev = mali_dvfs_status_current.kbdev; - - BUG_ON(kbdev == NULL); - platform = (struct rk_context *)kbdev->platform_context; - - mutex_lock(&mali_enable_clock_lock); - - if (enable != kbdev->pm.backend.metrics.timer_active) { - /* 若要 使能 dvfs, 则... */ - if (enable) { - spin_lock_irqsave(&kbdev->pm.backend.metrics.lock, flags); - kbdev->pm.backend.metrics.timer_active = MALI_TRUE; - spin_unlock_irqrestore(&kbdev->pm.backend.metrics.lock, flags); - hrtimer_start(&kbdev->pm.backend.metrics.timer, - HR_TIMER_DELAY_MSEC(KBASE_PM_DVFS_FREQUENCY), - HRTIMER_MODE_REL); - } - /* 否则, 即要 disable dvfs, 则 ... */ - else { - spin_lock_irqsave(&kbdev->pm.backend.metrics.lock, flags); - kbdev->pm.backend.metrics.timer_active = MALI_FALSE; - spin_unlock_irqrestore(&kbdev->pm.backend.metrics.lock, flags); - hrtimer_cancel(&kbdev->pm.backend.metrics.timer); - } - } - - if (freq != MALI_DVFS_CURRENT_FREQ) { - spin_lock_irqsave(&mali_dvfs_spinlock, flags); - platform->time_tick = 0; - platform->time_busy = 0; - platform->time_idle = 0; - platform->utilisation = 0; - dvfs_status->step = kbase_platform_dvfs_get_level(freq); - spin_unlock_irqrestore(&mali_dvfs_spinlock, flags); - kbase_platform_dvfs_set_level(dvfs_status->kbdev, dvfs_status->step); - } - - mutex_unlock(&mali_enable_clock_lock); - - return MALI_TRUE; -} - -#define dividend 7 -#define fix_float(a) ((((a)*dividend)%10)?((((a)*dividend)/10)+1):(((a)*dividend)/10)) -/** - * 为 'mali_dvfs_info' 中 index 是 'level' 的 level_item, 计算 min_threshold 和 max_threshold. - */ -static bool calculate_dvfs_max_min_threshold(u32 level) -{ - u32 pre_level; - u32 tmp ; - if (0 == level) { - if ((MALI_DVFS_STEP-1) == level) { - mali_dvfs_infotbl[level].min_threshold = level0_min; - mali_dvfs_infotbl[level].max_threshold = levelf_max; - } else { - mali_dvfs_infotbl[level].min_threshold = level0_min; - mali_dvfs_infotbl[level].max_threshold = level0_max; - } - } else { - pre_level = level - 1; - if ((MALI_DVFS_STEP-1) == level) { - mali_dvfs_infotbl[level].max_threshold = levelf_max; - } else { - mali_dvfs_infotbl[level].max_threshold = mali_dvfs_infotbl[pre_level].max_threshold + - div_dvfs; - } - mali_dvfs_infotbl[level].min_threshold = (mali_dvfs_infotbl[pre_level].max_threshold * - (mali_dvfs_infotbl[pre_level].clock/1000)) / - (mali_dvfs_infotbl[level].clock/1000); - - tmp = mali_dvfs_infotbl[level].max_threshold - mali_dvfs_infotbl[level].min_threshold; - - mali_dvfs_infotbl[level].min_threshold += fix_float(tmp); - } - - pr_info("mali_dvfs_infotbl[%d].clock=%d,min_threshold=%d,max_threshold=%d\n", - level,mali_dvfs_infotbl[level].clock, mali_dvfs_infotbl[level].min_threshold, - mali_dvfs_infotbl[level].max_threshold); - - return MALI_TRUE; -} - -int kbase_platform_dvfs_init(struct kbase_device *kbdev) -{ - unsigned long flags; - /*default status - add here with the right function to get initilization value. - */ - struct rk_context *platform; - int i; - int rc; - - platform = (struct rk_context *)kbdev->platform_context; - if (NULL == platform) - panic("oops"); - - D("to get gpu_clk_freq_table from system_dvfs_module."); - mali_freq_table = dvfs_get_freq_volt_table(platform->mali_clk_node); - if (mali_freq_table == NULL) { - printk("mali freq table not assigned yet,use default\n"); - goto not_assigned ; - } else { - D("we got valid gpu_clk_freq_table, to init mali_dvfs_level_table with it."); - - /*recalculte step*/ - MALI_DVFS_STEP = 0; - - for ( i = 0; - mali_freq_table[i].frequency != CPUFREQ_TABLE_END - && i < MAX_NUM_OF_MALI_DVFS_LEVELS; - i++ ) - { - mali_dvfs_infotbl[i].clock = mali_freq_table[i].frequency; - MALI_DVFS_STEP++; - } - - if(MALI_DVFS_STEP > 1) - div_dvfs = round_up( ( (levelf_max - level0_max) / (MALI_DVFS_STEP - 1) ), 1); - - printk("MALI_DVFS_STEP = %d, div_dvfs = %d \n",MALI_DVFS_STEP, div_dvfs); - - for(i=0;igpu_in_touch_lock); - rc = input_register_handler(&gpufreq_input_handler); - if ( 0 != rc ) - { - E("fail to register gpufreq_input_handler."); - } - - return MALI_TRUE; -} - -void kbase_platform_dvfs_term(void) -{ - if (mali_dvfs_wq) - destroy_workqueue(mali_dvfs_wq); - - mali_dvfs_wq = NULL; - - input_unregister_handler(&gpufreq_input_handler); -} -#endif /*CONFIG_MALI_MIDGARD_DVFS*/ - -int mali_get_dvfs_upper_locked_freq(void) -{ - unsigned long flags; - int gpu_clk_freq = -1; // gpu_clk_freq_of_upper_limit - -#ifdef CONFIG_MALI_MIDGARD_FREQ_LOCK - spin_lock_irqsave(&mali_dvfs_spinlock, flags); - if (mali_dvfs_status_current.upper_lock >= 0) - { - gpu_clk_freq = mali_dvfs_infotbl[mali_dvfs_status_current.upper_lock].clock; - } - spin_unlock_irqrestore(&mali_dvfs_spinlock, flags); -#endif - return gpu_clk_freq; -} - -int mali_get_dvfs_under_locked_freq(void) -{ - unsigned long flags; - int gpu_clk_freq = -1; // gpu_clk_freq_of_upper_limit - -#ifdef CONFIG_MALI_MIDGARD_FREQ_LOCK - spin_lock_irqsave(&mali_dvfs_spinlock, flags); - if (mali_dvfs_status_current.under_lock >= 0) - { - gpu_clk_freq = mali_dvfs_infotbl[mali_dvfs_status_current.under_lock].clock; - } - spin_unlock_irqrestore(&mali_dvfs_spinlock, flags); -#endif - return gpu_clk_freq; -} - -int mali_get_dvfs_current_level(void) -{ - unsigned long flags; - int current_level = -1; - -#ifdef CONFIG_MALI_MIDGARD_FREQ_LOCK - spin_lock_irqsave(&mali_dvfs_spinlock, flags); - current_level = mali_dvfs_status_current.step; - spin_unlock_irqrestore(&mali_dvfs_spinlock, flags); -#endif - return current_level; -} - -int mali_dvfs_freq_lock(int level) -{ - unsigned long flags; -#ifdef CONFIG_MALI_MIDGARD_FREQ_LOCK - /*-----------------------------------*/ - spin_lock_irqsave(&mali_dvfs_spinlock, flags); - - if (mali_dvfs_status_current.under_lock >= 0 - && mali_dvfs_status_current.under_lock > level) - { - printk(KERN_ERR " Upper lock Error : Attempting to set upper lock to below under lock\n"); - spin_unlock_irqrestore(&mali_dvfs_spinlock, flags); - return -1; - } - - V("to set current dvfs_upper_lock to level '%d'.", level); - mali_dvfs_status_current.upper_lock = level; - - spin_unlock_irqrestore(&mali_dvfs_spinlock, flags); - /*-----------------------------------*/ - - printk(KERN_DEBUG " Upper Lock Set : %d\n", level); -#endif - return 0; -} - -void mali_dvfs_freq_unlock(void) -{ - unsigned long flags; -#ifdef CONFIG_MALI_MIDGARD_FREQ_LOCK - spin_lock_irqsave(&mali_dvfs_spinlock, flags); - mali_dvfs_status_current.upper_lock = -1; - spin_unlock_irqrestore(&mali_dvfs_spinlock, flags); -#endif - printk(KERN_DEBUG "mali Upper Lock Unset\n"); -} - -int mali_dvfs_freq_under_lock(int level) -{ - unsigned long flags; -#ifdef CONFIG_MALI_MIDGARD_FREQ_LOCK - spin_lock_irqsave(&mali_dvfs_spinlock, flags); - if (mali_dvfs_status_current.upper_lock >= 0 && - mali_dvfs_status_current.upper_lock < level) { - printk(KERN_ERR "mali Under lock Error : Attempting to set under lock to above upper lock\n"); - spin_unlock_irqrestore(&mali_dvfs_spinlock, flags); - return -1; - } - mali_dvfs_status_current.under_lock = level; - spin_unlock_irqrestore(&mali_dvfs_spinlock, flags); - - printk(KERN_DEBUG "mali Under Lock Set : %d\n", level); -#endif - return 0; -} - -void mali_dvfs_freq_under_unlock(void) -{ - unsigned long flags; -#ifdef CONFIG_MALI_MIDGARD_FREQ_LOCK - spin_lock_irqsave(&mali_dvfs_spinlock, flags); - mali_dvfs_status_current.under_lock = -1; - spin_unlock_irqrestore(&mali_dvfs_spinlock, flags); -#endif - printk(KERN_DEBUG " mali clock Under Lock Unset\n"); -} - -void kbase_platform_dvfs_set_clock(struct kbase_device *kbdev, int freq) -{ - struct rk_context *platform; - - if (!kbdev) - panic("oops"); - - platform = (struct rk_context *)kbdev->platform_context; - if (NULL == platform) - panic("oops"); - - if (!platform->mali_clk_node) { - printk("mali_clk_node not init\n"); - return; - } - /* .KP : 将调用平台特定接口, 设置 gpu_clk. */ - mali_dvfs_clk_set(platform->mali_clk_node,freq); - - return; -} - -int kbase_platform_dvfs_get_level(int freq) -{ - int i; - for (i = 0; i < MALI_DVFS_STEP; i++) { - if (mali_dvfs_infotbl[i].clock == freq) - return i; - } - return -1; -} - -void kbase_platform_dvfs_set_level(struct kbase_device *kbdev, int level) -{ - static int prev_level = -1; - - if (level == prev_level) - return; - - if (WARN_ON((level >= MALI_DVFS_STEP) || (level < 0))) { - printk("unkown mali dvfs level:level = %d,set clock not done \n",level); - return ; - } - /*panic("invalid level");*/ -#ifdef CONFIG_MALI_MIDGARD_FREQ_LOCK - if (mali_dvfs_status_current.upper_lock >= 0 && - level > mali_dvfs_status_current.upper_lock) - level = mali_dvfs_status_current.upper_lock; - if (mali_dvfs_status_current.under_lock >= 0 && - level < mali_dvfs_status_current.under_lock) - level = mali_dvfs_status_current.under_lock; -#endif -#ifdef CONFIG_MALI_MIDGARD_DVFS - mutex_lock(&mali_set_clock_lock); -#endif - - /* 令 mali_dvfs_status_current 的 current_dvfs_level 的具体时钟配置生效. */ - kbase_platform_dvfs_set_clock(kbdev, mali_dvfs_infotbl[level].clock); -#if defined(CONFIG_MALI_MIDGARD_DEBUG_SYS) && defined(CONFIG_MALI_MIDGARD_DVFS) - // 将实际退出 prev_level, update mali_dvfs_level_table 中 prev_level 的 total_time_in_this_level. - update_time_in_state(prev_level); -#endif - prev_level = level; -#ifdef CONFIG_MALI_MIDGARD_DVFS - mutex_unlock(&mali_set_clock_lock); -#endif -} - -#ifdef CONFIG_MALI_MIDGARD_DEBUG_SYS -#ifdef CONFIG_MALI_MIDGARD_DVFS -static u64 prev_time = 0; -/** - * update mali_dvfs_level_table 中当前 dvfs_level 'level' 的 total_time_in_this_level. - */ -static void update_time_in_state(int level) -{ - u64 current_time; - - if (level < 0) - return; - -#if 0 - /* 若当前 mali_dvfs "未开启", 则... */ - if (!kbase_platform_dvfs_get_enable_status()) - { - return; - } -#endif - - if (prev_time ==0) - prev_time=get_jiffies_64(); - - current_time = get_jiffies_64(); - mali_dvfs_infotbl[level].time += current_time - prev_time; - - prev_time = current_time; -} -#endif - -ssize_t show_time_in_state(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct kbase_device *kbdev; - ssize_t ret = 0; - int i; - - kbdev = dev_get_drvdata(dev); - -#ifdef CONFIG_MALI_MIDGARD_DVFS - update_time_in_state(mali_dvfs_status_current.step); -#endif - if (!kbdev) - { - return -ENODEV; - } - - ret += snprintf(buf + ret, - PAGE_SIZE - ret, - "------------------------------------------------------------------------------"); - ret += snprintf(buf + ret, - PAGE_SIZE - ret, - "\n%-16s\t%-24s\t%-24s", - "index_of_level", - "gpu_clk_freq (KHz)", - "time_in_this_level (s)"); - ret += snprintf(buf + ret, - PAGE_SIZE - ret, - "\n------------------------------------------------------------------------------"); - - for ( i = 0; i < MALI_DVFS_STEP; i++ ) - { - ret += snprintf(buf + ret, - PAGE_SIZE - ret, - "\n%-16d\t%-24u\t%-24u", - i, - mali_dvfs_infotbl[i].clock / 1000, - jiffies_to_msecs(mali_dvfs_infotbl[i].time) / 1000); - } - ret += snprintf(buf + ret, - PAGE_SIZE - ret, - "\n------------------------------------------------------------------------------"); - - if (ret < PAGE_SIZE - 1) - ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); - else { - buf[PAGE_SIZE - 2] = '\n'; - buf[PAGE_SIZE - 1] = '\0'; - ret = PAGE_SIZE - 1; - } - - return ret; -} - -ssize_t set_time_in_state(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - int i; - - /* reset 所有 level 的 total_time_in_this_level. */ - for (i = 0; i < MALI_DVFS_STEP; i++) - { - mali_dvfs_infotbl[i].time = 0; - } - - prev_time = 0; - - printk(KERN_DEBUG "time_in_state value is reset complete.\n"); - return count; -} -#endif diff --git a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_dvfs.h b/drivers/gpu/arm/midgard/platform/rk/mali_kbase_dvfs.h deleted file mode 100755 index 8d885c8e83f2..000000000000 --- a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_dvfs.h +++ /dev/null @@ -1,173 +0,0 @@ -/* drivers/gpu/midgard/platform/rk/mali_kbase_dvfs.h - * - * Rockchip SoC Mali-T764 DVFS driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software FoundatIon. - */ - -/** - * @file mali_kbase_dvfs.h - * DVFS - * 声明 平台相关的 mali_dvfs_facility 对外提供的接口, 比如初始化, 设置 gpu_clk_freq, ... - * 但这里 并没有 实现良好封装. - * - * .DP : mali_dvfs_facility : platform_dependent_part 中对 mali(gpu) DVFS 功能的具体实现. - */ - -#ifndef _KBASE_DVFS_H_ -#define _KBASE_DVFS_H_ - -/* Frequency that DVFS clock frequency decisions should be made */ -#define KBASE_PM_DVFS_FREQUENCY 100 - -#define MALI_DVFS_KEEP_STAY_CNT 10 - -/** - * 一个门限, 当 counter_of_requests_to_jump_up_in_dvfs_level_table 到达该 value 的时候, - * 才执行具体的将 current_dvfs_level 上跳的操作. - */ -#define MALI_DVFS_UP_TIME_INTERVAL 1 - -/** - * 一个门限, 当 counter_of_requests_to_jump_down_in_dvfs_level_table 到达该 value 的时候, - * 才执行具体的将 current_dvfs_level 下跳的操作. - */ -#define MALI_DVFS_DOWN_TIME_INTERVAL 2 - -/** - * @see kbase_platform_dvfs_enable. - */ -#define MALI_DVFS_CURRENT_FREQ 0 - -#if 0 -#define MALI_DVFS_BL_CONFIG_FREQ 500 -#define MALI_DVFS_START_FREQ 400 -#endif - -/** - * mali_dvfs_level_t, 某 mali_dvfs_level (功耗层级) 的具体配置信息. - */ -typedef struct _mali_dvfs_info { - /** 使用的电压. .Q : 目前实际不起作用? */ - unsigned int voltage; - /** - * gpu_clock_freq. 当前 level 使用的 GPU 时钟频率. 以 KHz 为单位. - */ - unsigned int clock; - /** - * 若 current_calculated_utilisation 低于本成员, 将可能下跳到 mali_dvfs_level_table 中, 临近的低功耗 mali_dvfs_level. - */ - int min_threshold; - /** - * 若 current_calculated_utilisation 高于本成员, 将可能上跳到 mali_dvfs_level_table 中, 临近的高功耗 mali_dvfs_level. - */ - int max_threshold; - /** - * total_time_in_this_level : gpu 停留在当前 level 上的 累计时间. 以 jiffy 为单位. - */ - unsigned long long time; -} mali_dvfs_info; - -#define MALI_KHZ 1000 -extern mali_dvfs_info *p_mali_dvfs_infotbl; -extern unsigned int MALI_DVFS_STEP; -#ifdef CONFIG_MALI_MIDGARD_DVFS -#define CONFIG_MALI_MIDGARD_FREQ_LOCK -#endif - -/** - * 将 gpu_clk 设置为 'freq', 'freq' 以 KHz 为单位. - */ -void kbase_platform_dvfs_set_clock(struct kbase_device *kbdev, int freq); - -/** - * 命令 dvfs_module 为 gpu 配置 'level' 指定的 dvfs_level, 并具体生效. - * @param level - * 待使用的 mali_dvfs_level 在 mali_dvfs_level_table 中的 index. - */ -void kbase_platform_dvfs_set_level(struct kbase_device *kbdev, int level); - -/** - * 检索 mali_dvfs_level_table, 返回其中 gpu_clock_freq 精确是 'freq' 的 level_item 的 index. - * 若没有找到, 返回 -1. - * 'freq' 以 KHz 为单位. - */ -int kbase_platform_dvfs_get_level(int freq); - -#ifdef CONFIG_MALI_MIDGARD_DVFS -/** - * 初始化 mali_dvfs_facility. - */ -int kbase_platform_dvfs_init(struct kbase_device *dev); - -/** - * 中止化 mali_dvfs_facility. - */ -void kbase_platform_dvfs_term(void); -/*int kbase_platform_dvfs_event(struct kbase_device *kbdev, u32 utilisation);*/ -/*int kbase_platform_dvfs_event(struct kbase_device *kbdev, u32 utilisation,u32 util_gl_share, u32 util_cl_share[2]);*/ - -/** - * 返回当前 mali_dvfs 是否是开启, 即 common_parts 是否会回调通知 dvfs_event. - */ -int kbase_platform_dvfs_get_enable_status(void); - -/** - * 使能或者禁用 dvfs, 并将 gpu_clk 设置为 'freq'(最接近的 允许的 clk). - * 若 'freq' 是 MALI_DVFS_CURRENT_FREQ, 则 "不" 改变当前的 gpu_clk_freq. - */ -int kbase_platform_dvfs_enable(bool enable, int freq); - -/** - * 返回 mali(gpu) 当前(最近的) utilisation. - */ -int kbase_platform_dvfs_get_utilisation(void); -#endif - -/** - * 返回 current_dvfs_level 在 mali_dvfs_level_table 中的 index. - */ -int mali_get_dvfs_current_level(void); - -/** - * 返回当前 dvfs_level_upper_limit 的 gpu_clk_freq, 以 KHz 为单位. - * 若没有设置, 返回 -1. - */ -int mali_get_dvfs_upper_locked_freq(void); -/** - * 返回当前 dvfs_level_lower_limit 的 gpu_clk_freq, 以 KHz 为单位. - * 若没有设置, 返回 -1. - */ -int mali_get_dvfs_under_locked_freq(void); - -/** - * 将 'level' 设置为当前的 dvfs_level_upper_limit.. - * 这里用 "freq_lock" 不贴切. - * @return - * 若成功, 返回 0. - * 否则, 返回其他 value. - */ -int mali_dvfs_freq_lock(int level); -/** - * 清除当前的 dvfs_level_upper_limit 设置. - */ -void mali_dvfs_freq_unlock(void); -/** - * 将 'level' 设置为当前的 dvfs_level_lower_limit. - * @return - * 若成功, 返回 0. - * 否则, 返回其他 value. - */ -int mali_dvfs_freq_under_lock(int level); -/** - * 清除当前的 dvfs_level_lower_limit 设置. - */ -void mali_dvfs_freq_under_unlock(void); - -// @see 'time_in_state' in mali_kbase_platform.c. -ssize_t show_time_in_state(struct device *dev, struct device_attribute *attr, char *buf); -ssize_t set_time_in_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); - -#endif /* _KBASE_DVFS_H_ */ diff --git a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_platform.c b/drivers/gpu/arm/midgard/platform/rk/mali_kbase_platform.c deleted file mode 100755 index 85fa87a3ec77..000000000000 --- a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_platform.c +++ /dev/null @@ -1,1176 +0,0 @@ -/* drivers/gpu/t6xx/kbase/src/platform/rk/mali_kbase_platform.c - * - * Rockchip SoC Mali-T764 platform-dependent codes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software FoundatIon. - */ - -/** - * @file mali_kbase_platform.c - * - * 对 mali_kbase_platform.h 声明的 pm, clk 等接口的具体实现. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include - -// #define ENABLE_DEBUG_LOG -#include "custom_log.h" - -/* ############################################################################################# */ - -#define MALI_T7XX_DEFAULT_CLOCK 100000 - - -/** - * clk_of_gpu_dvfs_node 的状态. - * 1, clock 被使能. - * 0, 禁止. - */ -static int mali_clk_status = 0; - -/** - * gpu_power_domain 的状态. - * 1, 上电. - * 0, 掉电. - */ -static int mali_pd_status = 0; - -// u32 kbase_group_error = 0; -static struct kobject *rk_gpu; - -int mali_dvfs_clk_set(struct dvfs_node *node, unsigned long rate) -{ - int ret = 0; - if(!node) - { - printk("clk_get_dvfs_node error \r\n"); - ret = -1; - } - /* .KP : 调用 dvfs_module 设置 gpu_clk. */ - ret = dvfs_clk_set_rate(node,rate * MALI_KHZ); - if(ret) - { - printk("dvfs_clk_set_rate error \r\n"); - } - return ret; -} - -/** - * 初始化和 gpu_pm 和 gpu_clk. - */ -static int kbase_platform_power_clock_init(struct kbase_device *kbdev) -{ - /*struct device *dev = kbdev->dev;*/ - struct rk_context *platform; - - platform = (struct rk_context *)kbdev->platform_context; - if (NULL == platform) - panic("oops"); - - /* enable mali t760 powerdomain*/ - platform->mali_pd = clk_get(NULL,"pd_gpu"); - if(IS_ERR_OR_NULL(platform->mali_pd)) - { - platform->mali_pd = NULL; - printk(KERN_ERR "%s, %s(): failed to get [platform->mali_pd]\n", __FILE__, __func__); - goto out; - } - else - { - clk_prepare_enable(platform->mali_pd); - printk("mali pd enabled\n"); - } - mali_pd_status = 1; - - /* enable mali t760 clock */ - platform->mali_clk_node = clk_get_dvfs_node("clk_gpu"); - if (IS_ERR_OR_NULL(platform->mali_clk_node)) - { - platform->mali_clk_node = NULL; - printk(KERN_ERR "%s, %s(): failed to get [platform->mali_clk_node]\n", __FILE__, __func__); - goto out; - } - else - { - dvfs_clk_prepare_enable(platform->mali_clk_node); - printk("clk enabled\n"); - } - mali_dvfs_clk_set(platform->mali_clk_node, MALI_T7XX_DEFAULT_CLOCK); - mali_clk_status = 1; - - return 0; - -out: - if(platform->mali_pd) - clk_put(platform->mali_pd); - - return -EPERM; - -} - -int kbase_platform_clock_off(struct kbase_device *kbdev) -{ - struct rk_context *platform; - if (!kbdev) - return -ENODEV; - - platform = (struct rk_context *)kbdev->platform_context; - if (!platform) - return -ENODEV; - - if (mali_clk_status == 0) - return 0; - - if((platform->mali_clk_node)) - dvfs_clk_disable_unprepare(platform->mali_clk_node); - - mali_clk_status = 0; - - return 0; -} - -int kbase_platform_clock_on(struct kbase_device *kbdev) -{ - struct rk_context *platform; - if (!kbdev) - return -ENODEV; - - platform = (struct rk_context *)kbdev->platform_context; - if (!platform) - return -ENODEV; - - if (mali_clk_status == 1) - return 0; - - if(platform->mali_clk_node) - dvfs_clk_prepare_enable(platform->mali_clk_node); - - mali_clk_status = 1; - - return 0; -} - -int kbase_platform_is_power_on(void) -{ - return mali_pd_status; -} - -/*turn on power domain*/ -int kbase_platform_power_on(struct kbase_device *kbdev) -{ - struct rk_context *platform; - if (!kbdev) - return -ENODEV; - - platform = (struct rk_context *)kbdev->platform_context; - if (!platform) - return -ENODEV; - - if (mali_pd_status == 1) - return 0; -#if 1 - if(platform->mali_pd) - clk_prepare_enable(platform->mali_pd); -#endif - mali_pd_status = 1; - KBASE_TIMELINE_GPU_POWER(kbdev, 1); - - return 0; -} - -/*turn off power domain*/ -int kbase_platform_power_off(struct kbase_device *kbdev) -{ - struct rk_context *platform; - if (!kbdev) - return -ENODEV; - - platform = (struct rk_context *)kbdev->platform_context; - if (!platform) - return -ENODEV; - - if (mali_pd_status== 0) - return 0; -#if 1 - if(platform->mali_pd) - clk_disable_unprepare(platform->mali_pd); -#endif - mali_pd_status = 0; - KBASE_TIMELINE_GPU_POWER(kbdev, 0); - - return 0; -} - - -int kbase_platform_cmu_pmu_control(struct kbase_device *kbdev, int control) -{ - unsigned long flags; - struct rk_context *platform; - if (!kbdev) - return -ENODEV; - - platform = (struct rk_context *)kbdev->platform_context; - if (!platform) - return -ENODEV; - - spin_lock_irqsave(&platform->cmu_pmu_lock, flags); - - /* off */ - if (control == 0) - { - /* 若已经关闭, 则... */ - if (platform->cmu_pmu_status == 0) - { - spin_unlock_irqrestore(&platform->cmu_pmu_lock, flags); - return 0; - } - - /* 关闭 gpu_power_domain. */ - if (kbase_platform_power_off(kbdev)) - { - panic("failed to turn off mali power domain\n"); - } - /* 关闭 gpu_dvfs_node 的 clock. */ - if (kbase_platform_clock_off(kbdev)) - { - panic("failed to turn off mali clock\n"); - } - - platform->cmu_pmu_status = 0; - printk("turn off mali power \n"); - } - else /* on */ - { - if (platform->cmu_pmu_status == 1) - { - spin_unlock_irqrestore(&platform->cmu_pmu_lock, flags); - return 0; - } - - /* 开启 gpu_power_domain. */ - if (kbase_platform_power_on(kbdev)) - { - panic("failed to turn on mali power domain\n"); - } - /* 使能 gpu_dvfs_node 的 clock. */ - if (kbase_platform_clock_on(kbdev)) - { - panic("failed to turn on mali clock\n"); - } - - platform->cmu_pmu_status = 1; - printk(KERN_ERR "turn on mali power\n"); - } - - spin_unlock_irqrestore(&platform->cmu_pmu_lock, flags); - - return 0; -} - -/*---------------------------------------------------------------------------*/ - -static ssize_t error_count_show(struct device *dev,struct device_attribute *attr, char *buf) -{ - struct kbase_device *kbdev = dev_get_drvdata(dev); - ssize_t ret; - - D_PTR(dev); - if ( NULL == kbdev ) - { - E("fail to get kbase_device instance."); - return 0; - } - - D_DEC(kbdev->kbase_group_error); - ret = scnprintf(buf, PAGE_SIZE, "%u\n", kbdev->kbase_group_error); - return ret; -} -static DEVICE_ATTR(error_count, S_IRUGO, error_count_show, NULL); - - -/*---------------------------------------------------------------------------*/ -/* < 对在 sysfs_dir_of_mali_device 下的 rk_ext_file_nodes 的具体实现, >*/ -// .DP : impl_of_rk_ext_file_nodes. - -/** - * .doc : 对 sysfs_dir_of_mali_device 下 rk_ext_file_nodes 提供的接口的定义 - * - * sysfs_dir_of_mali_device 通常是 sys/devices/ffa30000.gpu - * - * 其下有如下的 rk_ext_file_nodes : - * clock, - * 对该文件的 cat 操作, 将输出当前 gpu_clk_freq 和可能的 freq 的列表, 形如 : - * current_gpu_clk_freq : 99000 KHz - * possible_freqs : 99000, 179000, 297000, 417000, 480000 (KHz) - * 出现在 "possible_freqs" 中的有效频点, 依赖在 .dts 文件中的配置. - * 可以使用 echo 命令向本文件写入待设置的 gpu_clk_freq_in_khz, 比如 : - * echo 417000 > clock - * 注意, 这里写入的 gpu_clk_freq_in_khz "必须" 是出现在 possible_freqs 中的. - * 另外, mali_module 默认使能 dvfs, - * 所以若希望将 gpu_clk 固定在上面的特定 freq, 要关闭 dvfs 先 : - * echo off > dvfs - * fbdev, - * 只支持 cat. - * .R : 目前不确定该提供接口的用意. - * // dtlb, - * dvfs, - * cat 该节点, 将返回当前 mali_dvfs 的状态, 包括 mali_dvfs 是否开启, gpu 使用率, 当前 gpu_clk 频率. - * 若当前 mali_dvfs 被开启, 可能返回如下信息 : - * mali_dvfs is ON - * gpu_utilisation : 100 - * current_gpu_clk_freq : 480 MHz - * 若当前 mali_dvfs 被关闭, 可能返回 : - * mali_dvfs is OFF - * current_gpu_clk_freq : 99 MHz - * 若一段时间没有 job 下发到 gpu, common_parts 也会自动关闭 mali_dvfs. - * - * 将字串 off 写入该节点, 将关闭 mali_dvfs, - * 且会将 gpu_clk_freq 固定到可能的最高的频率 或者 gpu_clk_freq_of_upper_limit(若有指定). - * 之后, 若将字串 on 写入该节点, 将重新开启 mali_dvfs. - * - * dvfs_upper_lock, - * cat 该节点, 返回当前 dvfs_level_upper_limit 的信息, 诸如 - * upper_lock_freq : 417000 KHz - * possible upper_lock_freqs : 99000, 179000, 297000, 417000, 480000 (KHz) - * if you want to unset upper_lock_freq, to echo 'off' to this file. - * - * 对该节点写入上面 possible upper_lock_freqs 中的某个 频率, 可以将该频率设置为 gpu_clk_freq_of_upper_limit, 比如. - * echo 417000 > dvfs_upper_lock - * 若要清除之前设置的 dvfs_level_upper_limit, 写入 off 即可. - * - * dvfs_under_lock, - * cat 该节点, 返回当前 dvfs_level_lower_limit 的信息, 诸如 - * under_lock_freq : 179000 KHz - * possible under_lock_freqs : 99000, 179000, 297000, 417000, 480000 (KHz) - * if you want to unset under_lock_freq, to echo 'off' to this file. - * 对该节点写入上面 possible under_lock_freq 中的某个 频率, 可以将该频率设置为 gpu_clk_freq_of_lower_limit, 比如. - * echo 179000 > dvfs_under_lock - * 若要清除之前设置的 dvfs_level_lower_limit, 写入 off 即可. - * - * time_in_state - * cat 该节点, 返回 mali_dvfs 停留在不同 level 中的时间统计, 譬如 - * ------------------------------------------------------------------------------ - * index_of_level gpu_clk_freq (KHz) time_in_this_level (s) - * ------------------------------------------------------------------------------ - * 0 99 206 - * 1 179 9 - * 2 297 0 - * 3 417 0 - * 4 480 47 - * ------------------------------------------------------------------------------ - * 若通过 dvfs 节点, 开启/关闭 mali_dvfs, 则本节点输出的信息可能不准确. - * - * 若要复位上述时间统计, 可以向该节点写入任意字串, 比如 : - * echo dummy > time_in_state - */ - -#ifdef CONFIG_MALI_MIDGARD_DEBUG_SYS -static ssize_t show_clock(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct kbase_device *kbdev; - struct rk_context *platform; - ssize_t ret = 0; - unsigned int clkrate = 0; // 从 dvfs_module 获取的 gpu_clk_freq, Hz 为单位. - int i ; - kbdev = dev_get_drvdata(dev); - - if (!kbdev) - return -ENODEV; - - platform = (struct rk_context *)kbdev->platform_context; - if (!platform) - return -ENODEV; - - if (!platform->mali_clk_node) - { - printk("mali_clk_node not init\n"); - return -ENODEV; - } - clkrate = dvfs_clk_get_rate(platform->mali_clk_node); - ret += snprintf(buf + ret, PAGE_SIZE - ret, "current_gpu_clk_freq : %d KHz", clkrate / 1000); - - /* To be revised */ - ret += snprintf(buf + ret, PAGE_SIZE - ret, "\npossible_freqs : "); - for ( i = 0; i < MALI_DVFS_STEP; i++ ) - { - if ( i < (MALI_DVFS_STEP - 1) ) - { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d, ", p_mali_dvfs_infotbl[i].clock); - } - else - { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d ", p_mali_dvfs_infotbl[i].clock); - } - } - ret += snprintf(buf + ret, PAGE_SIZE - ret, "(KHz)"); - - if (ret < PAGE_SIZE - 1) - { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); - } - else { - buf[PAGE_SIZE - 2] = '\n'; - buf[PAGE_SIZE - 1] = '\0'; - ret = PAGE_SIZE - 1; - } - - return ret; -} - -static ssize_t set_clock(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - struct kbase_device *kbdev; - struct rk_context *platform; - unsigned int tmp = 0, freq = 0; - kbdev = dev_get_drvdata(dev); - tmp = 0; - if (!kbdev) - return -ENODEV; - - platform = (struct rk_context *)kbdev->platform_context; - if (!platform) - return -ENODEV; - - if (!platform->mali_clk_node) - return -ENODEV; -#if 0 - if (sysfs_streq("500", buf)) { - freq = 500; - } else if (sysfs_streq("400", buf)) { - freq = 400; - } else if (sysfs_streq("350", buf)) { - freq = 350; - } else if (sysfs_streq("266", buf)) { - freq = 266; - } else if (sysfs_streq("160", buf)) { - freq = 160; - } else if (sysfs_streq("100", buf)) { - freq = 100; - } else { - dev_err(dev, "set_clock: invalid value\n"); - return -ENOENT; - } -#endif - freq = simple_strtoul(buf, NULL, 10); - D("freq : %u.", freq); - - kbase_platform_dvfs_set_level(kbdev, kbase_platform_dvfs_get_level(freq)); - return count; -} - -static ssize_t show_fbdev(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct kbase_device *kbdev; - ssize_t ret = 0; - int i; - - kbdev = dev_get_drvdata(dev); - - if (!kbdev) - return -ENODEV; - - for (i = 0; i < num_registered_fb; i++) - { - ret += snprintf(buf + ret, - PAGE_SIZE - ret, - "fb[%d] xres=%d, yres=%d, addr=0x%lx\n", - i, - registered_fb[i]->var.xres, - registered_fb[i]->var.yres, - registered_fb[i]->fix.smem_start); - } - - if (ret < PAGE_SIZE - 1) - ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); - else { - buf[PAGE_SIZE - 2] = '\n'; - buf[PAGE_SIZE - 1] = '\0'; - ret = PAGE_SIZE - 1; - } - - return ret; -} - -typedef enum { - L1_I_tag_RAM = 0x00, - L1_I_data_RAM = 0x01, - L1_I_BTB_RAM = 0x02, - L1_I_GHB_RAM = 0x03, - L1_I_TLB_RAM = 0x04, - L1_I_indirect_predictor_RAM = 0x05, - L1_D_tag_RAM = 0x08, - L1_D_data_RAM = 0x09, - L1_D_load_TLB_array = 0x0A, - L1_D_store_TLB_array = 0x0B, - L2_tag_RAM = 0x10, - L2_data_RAM = 0x11, - L2_snoop_tag_RAM = 0x12, - L2_data_ECC_RAM = 0x13, - L2_dirty_RAM = 0x14, - L2_TLB_RAM = 0x18 -} RAMID_type; - -static inline void asm_ramindex_mrc(u32 *DL1Data0, u32 *DL1Data1, u32 *DL1Data2, u32 *DL1Data3) -{ - u32 val; - - if (DL1Data0) { - asm volatile ("mrc p15, 0, %0, c15, c1, 0" : "=r" (val)); - *DL1Data0 = val; - } - if (DL1Data1) { - asm volatile ("mrc p15, 0, %0, c15, c1, 1" : "=r" (val)); - *DL1Data1 = val; - } - if (DL1Data2) { - asm volatile ("mrc p15, 0, %0, c15, c1, 2" : "=r" (val)); - *DL1Data2 = val; - } - if (DL1Data3) { - asm volatile ("mrc p15, 0, %0, c15, c1, 3" : "=r" (val)); - *DL1Data3 = val; - } -} - -static inline void asm_ramindex_mcr(u32 val) -{ - asm volatile ("mcr p15, 0, %0, c15, c4, 0" : : "r" (val)); - asm volatile ("dsb"); - asm volatile ("isb"); -} - -static void get_tlb_array(u32 val, u32 *DL1Data0, u32 *DL1Data1, u32 *DL1Data2, u32 *DL1Data3) -{ - asm_ramindex_mcr(val); - asm_ramindex_mrc(DL1Data0, DL1Data1, DL1Data2, DL1Data3); -} - -static RAMID_type ramindex = L1_D_load_TLB_array; -static ssize_t show_dtlb(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct kbase_device *kbdev; - ssize_t ret = 0; - int entries, ways; - u32 DL1Data0 = 0, DL1Data1 = 0, DL1Data2 = 0, DL1Data3 = 0; - - kbdev = dev_get_drvdata(dev); - - if (!kbdev) - return -ENODEV; - - /* L1-I tag RAM */ - if (ramindex == L1_I_tag_RAM) - printk(KERN_DEBUG "Not implemented yet\n"); - /* L1-I data RAM */ - else if (ramindex == L1_I_data_RAM) - printk(KERN_DEBUG "Not implemented yet\n"); - /* L1-I BTB RAM */ - else if (ramindex == L1_I_BTB_RAM) - printk(KERN_DEBUG "Not implemented yet\n"); - /* L1-I GHB RAM */ - else if (ramindex == L1_I_GHB_RAM) - printk(KERN_DEBUG "Not implemented yet\n"); - /* L1-I TLB RAM */ - else if (ramindex == L1_I_TLB_RAM) { - printk(KERN_DEBUG "L1-I TLB RAM\n"); - for (entries = 0; entries < 32; entries++) { - get_tlb_array((((u8) ramindex) << 24) + entries, &DL1Data0, &DL1Data1, &DL1Data2, NULL); - printk(KERN_DEBUG "entries[%d], DL1Data0=%08x, DL1Data1=%08x DL1Data2=%08x\n", entries, DL1Data0, DL1Data1 & 0xffff, 0x0); - } - } - /* L1-I indirect predictor RAM */ - else if (ramindex == L1_I_indirect_predictor_RAM) - printk(KERN_DEBUG "Not implemented yet\n"); - /* L1-D tag RAM */ - else if (ramindex == L1_D_tag_RAM) - printk(KERN_DEBUG "Not implemented yet\n"); - /* L1-D data RAM */ - else if (ramindex == L1_D_data_RAM) - printk(KERN_DEBUG "Not implemented yet\n"); - /* L1-D load TLB array */ - else if (ramindex == L1_D_load_TLB_array) { - printk(KERN_DEBUG "L1-D load TLB array\n"); - for (entries = 0; entries < 32; entries++) { - get_tlb_array((((u8) ramindex) << 24) + entries, &DL1Data0, &DL1Data1, &DL1Data2, &DL1Data3); - printk(KERN_DEBUG "entries[%d], DL1Data0=%08x, DL1Data1=%08x, DL1Data2=%08x, DL1Data3=%08x\n", entries, DL1Data0, DL1Data1, DL1Data2, DL1Data3 & 0x3f); - } - } - /* L1-D store TLB array */ - else if (ramindex == L1_D_store_TLB_array) { - printk(KERN_DEBUG "\nL1-D store TLB array\n"); - for (entries = 0; entries < 32; entries++) { - get_tlb_array((((u8) ramindex) << 24) + entries, &DL1Data0, &DL1Data1, &DL1Data2, &DL1Data3); - printk(KERN_DEBUG "entries[%d], DL1Data0=%08x, DL1Data1=%08x, DL1Data2=%08x, DL1Data3=%08x\n", entries, DL1Data0, DL1Data1, DL1Data2, DL1Data3 & 0x3f); - } - } - /* L2 tag RAM */ - else if (ramindex == L2_tag_RAM) - printk(KERN_DEBUG "Not implemented yet\n"); - /* L2 data RAM */ - else if (ramindex == L2_data_RAM) - printk(KERN_DEBUG "Not implemented yet\n"); - /* L2 snoop tag RAM */ - else if (ramindex == L2_snoop_tag_RAM) - printk(KERN_DEBUG "Not implemented yet\n"); - /* L2 data ECC RAM */ - else if (ramindex == L2_data_ECC_RAM) - printk(KERN_DEBUG "Not implemented yet\n"); - /* L2 dirty RAM */ - else if (ramindex == L2_dirty_RAM) - printk(KERN_DEBUG "Not implemented yet\n"); - - /* L2 TLB array */ - else if (ramindex == L2_TLB_RAM) { - printk(KERN_DEBUG "\nL2 TLB array\n"); - for (ways = 0; ways < 4; ways++) { - for (entries = 0; entries < 512; entries++) { - get_tlb_array((ramindex << 24) + (ways << 18) + entries, &DL1Data0, &DL1Data1, &DL1Data2, &DL1Data3); - printk(KERN_DEBUG "ways[%d]:entries[%d], DL1Data0=%08x, DL1Data1=%08x, DL1Data2=%08x, DL1Data3=%08x\n", ways, entries, DL1Data0, DL1Data1, DL1Data2, DL1Data3); - } - } - } else { - } - - ret += snprintf(buf + ret, PAGE_SIZE - ret, "Succeeded...\n"); - - if (ret < PAGE_SIZE - 1) - ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); - else { - buf[PAGE_SIZE - 2] = '\n'; - buf[PAGE_SIZE - 1] = '\0'; - ret = PAGE_SIZE - 1; - } - return ret; -} - -static ssize_t set_dtlb(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - struct kbase_device *kbdev; - kbdev = dev_get_drvdata(dev); - - if (!kbdev) - return -ENODEV; - - if (sysfs_streq("L1_I_tag_RAM", buf)) { - ramindex = L1_I_tag_RAM; - } else if (sysfs_streq("L1_I_data_RAM", buf)) { - ramindex = L1_I_data_RAM; - } else if (sysfs_streq("L1_I_BTB_RAM", buf)) { - ramindex = L1_I_BTB_RAM; - } else if (sysfs_streq("L1_I_GHB_RAM", buf)) { - ramindex = L1_I_GHB_RAM; - } else if (sysfs_streq("L1_I_TLB_RAM", buf)) { - ramindex = L1_I_TLB_RAM; - } else if (sysfs_streq("L1_I_indirect_predictor_RAM", buf)) { - ramindex = L1_I_indirect_predictor_RAM; - } else if (sysfs_streq("L1_D_tag_RAM", buf)) { - ramindex = L1_D_tag_RAM; - } else if (sysfs_streq("L1_D_data_RAM", buf)) { - ramindex = L1_D_data_RAM; - } else if (sysfs_streq("L1_D_load_TLB_array", buf)) { - ramindex = L1_D_load_TLB_array; - } else if (sysfs_streq("L1_D_store_TLB_array", buf)) { - ramindex = L1_D_store_TLB_array; - } else if (sysfs_streq("L2_tag_RAM", buf)) { - ramindex = L2_tag_RAM; - } else if (sysfs_streq("L2_data_RAM", buf)) { - ramindex = L2_data_RAM; - } else if (sysfs_streq("L2_snoop_tag_RAM", buf)) { - ramindex = L2_snoop_tag_RAM; - } else if (sysfs_streq("L2_data_ECC_RAM", buf)) { - ramindex = L2_data_ECC_RAM; - } else if (sysfs_streq("L2_dirty_RAM", buf)) { - ramindex = L2_dirty_RAM; - } else if (sysfs_streq("L2_TLB_RAM", buf)) { - ramindex = L2_TLB_RAM; - } else { - printk(KERN_DEBUG "Invalid value....\n\n"); - printk(KERN_DEBUG "Available options are one of below\n"); - printk(KERN_DEBUG "L1_I_tag_RAM, L1_I_data_RAM, L1_I_BTB_RAM\n"); - printk(KERN_DEBUG "L1_I_GHB_RAM, L1_I_TLB_RAM, L1_I_indirect_predictor_RAM\n"); - printk(KERN_DEBUG "L1_D_tag_RAM, L1_D_data_RAM, L1_D_load_TLB_array, L1_D_store_TLB_array\n"); - printk(KERN_DEBUG "L2_tag_RAM, L2_data_RAM, L2_snoop_tag_RAM, L2_data_ECC_RAM\n"); - printk(KERN_DEBUG "L2_dirty_RAM, L2_TLB_RAM\n"); - } - - return count; -} - -static ssize_t show_dvfs(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct kbase_device *kbdev; - struct rk_context *platform; - ssize_t ret = 0; - unsigned int clkrate; - - kbdev = dev_get_drvdata(dev); - - if (!kbdev) - return -ENODEV; - - platform = (struct rk_context *)kbdev->platform_context; - if (!platform) - return -ENODEV; - - /* 获取当前 gpu_dvfs_node 的 clk_freq, Hz 为单位. */ - clkrate = dvfs_clk_get_rate(platform->mali_clk_node); - -#ifdef CONFIG_MALI_MIDGARD_DVFS - /* 若 mali_dvfs 是 开启的, 则... */ - if (kbase_platform_dvfs_get_enable_status()) - { - ret += snprintf(buf + ret, - PAGE_SIZE - ret, - "mali_dvfs is ON \ngpu_utilisation : %d \ncurrent_gpu_clk_freq : %u MHz", - kbase_platform_dvfs_get_utilisation(), - clkrate / 1000000); - } - /* 否则, ... */ - else - { - ret += snprintf(buf + ret, - PAGE_SIZE - ret, - "mali_dvfs is OFF \ncurrent_gpu_clk_freq : %u MHz", - clkrate / 1000000); - } -#else - ret += snprintf(buf + ret, PAGE_SIZE - ret, "mali_dvfs is DISABLED"); -#endif - - if (ret < PAGE_SIZE - 1) - ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); - else { - buf[PAGE_SIZE - 2] = '\n'; - buf[PAGE_SIZE - 1] = '\0'; - ret = PAGE_SIZE - 1; - } - - return ret; -} - -static ssize_t set_dvfs(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - struct kbase_device *kbdev = dev_get_drvdata(dev); -#ifdef CONFIG_MALI_MIDGARD_DVFS - struct rk_context *platform; -#endif - - if (!kbdev) - return -ENODEV; - -#ifdef CONFIG_MALI_MIDGARD_DVFS - platform = (struct rk_context *)kbdev->platform_context; - if (sysfs_streq("off", buf)) { - /*kbase_platform_dvfs_enable(false, MALI_DVFS_BL_CONFIG_FREQ);*/ - D("to disable mali_dvfs, and set current_dvfs_level to the highest one."); - kbase_platform_dvfs_enable(false, p_mali_dvfs_infotbl[MALI_DVFS_STEP-1].clock); - platform->dvfs_enabled = false; - } else if (sysfs_streq("on", buf)) { - /*kbase_platform_dvfs_enable(true, MALI_DVFS_START_FREQ);*/ - D("to disable mali_dvfs, and set current_dvfs_level to the lowest one."); - kbase_platform_dvfs_enable(true, p_mali_dvfs_infotbl[0].clock); - platform->dvfs_enabled = true; - } else { - printk(KERN_DEBUG "invalid val -only [on, off] is accepted\n"); - } -#else - printk(KERN_DEBUG "mali DVFS is disabled\n"); -#endif - return count; -} - -static ssize_t show_upper_lock_dvfs(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct kbase_device *kbdev; - ssize_t ret = 0; - int i; -#ifdef CONFIG_MALI_MIDGARD_DVFS - int gpu_clk_freq = 0; -#endif - - kbdev = dev_get_drvdata(dev); - - if (!kbdev) - { - E("err."); - return -ENODEV; - } - -#ifdef CONFIG_MALI_MIDGARD_DVFS - gpu_clk_freq = mali_get_dvfs_upper_locked_freq(); - if (gpu_clk_freq > 0) - { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "upper_lock_freq : %d KHz", gpu_clk_freq); - } - else - { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "upper_lock_freq is NOT set"); - } - /*ret += snprintf(buf + ret, PAGE_SIZE - ret, "\nPossible settings : 400, 350,266, 160, 100, If you want to unlock : 600 or off");*/ - - ret += snprintf(buf + ret, PAGE_SIZE - ret, "\npossible upper_lock_freqs : "); - for ( i = 0; i < MALI_DVFS_STEP; i++ ) - { - if ( i < (MALI_DVFS_STEP - 1) ) - { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d, ", p_mali_dvfs_infotbl[i].clock); - } - else - { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d ", p_mali_dvfs_infotbl[i].clock); - } - } - ret += snprintf(buf + ret, PAGE_SIZE - ret, "(KHz)"); - - if ( gpu_clk_freq > 0 ) - { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "\nif you want to unset upper_lock_freq, to echo 'off' to this file."); - } -#else - ret += snprintf(buf + ret, PAGE_SIZE - ret, "mali DVFS is disabled. You can not set"); -#endif - - if (ret < PAGE_SIZE - 1) - ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); - else { - buf[PAGE_SIZE - 2] = '\n'; - buf[PAGE_SIZE - 1] = '\0'; - ret = PAGE_SIZE - 1; - } - - return ret; -} - -static ssize_t set_upper_lock_dvfs(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - struct kbase_device *kbdev = NULL; - int i; - unsigned int freq = 0; // 可能由 caller 传入的, 待设置的 gpu_freq_upper_limit. - int ret = 0; - - kbdev = dev_get_drvdata(dev); - - if ( NULL == kbdev) - { - E("'kbdev' is NULL."); - return -ENODEV; - } - -#ifdef CONFIG_MALI_MIDGARD_DVFS - if (sysfs_streq("off", buf)) - { - mali_dvfs_freq_unlock(); - } - else - { - freq = simple_strtoul(buf, NULL, 10); - D_DEC(freq); - - D("to search the level that matches target_freq; num_of_mali_dvfs_levels : %d.", MALI_DVFS_STEP); - for(i=0;i 0) - { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "under_lock_freq : %d KHz",gpu_clk_freq); - } - else - { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "under_lock_freq is NOT set."); - } - /*ret += snprintf(buf + ret, PAGE_SIZE - ret, "\nPossible settings : 600, 400, 350,266, 160, If you want to unlock : 100 or off");*/ - ret += snprintf(buf + ret, PAGE_SIZE - ret, "\npossible under_lock_freqs : "); - for ( i = 0; i < MALI_DVFS_STEP; i++ ) - { - if ( i < (MALI_DVFS_STEP - 1) ) - { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d, ", p_mali_dvfs_infotbl[i].clock); - } - else - { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d ", p_mali_dvfs_infotbl[i].clock); - } - } - ret += snprintf(buf + ret, PAGE_SIZE - ret, "(KHz)"); - - if ( gpu_clk_freq > 0 ) - { - ret += snprintf(buf + ret, PAGE_SIZE - ret, "\nif you want to unset under_lock_freq, to echo 'off' to this file."); - } -#else - ret += snprintf(buf + ret, PAGE_SIZE - ret, "mali DVFS is disabled. You can not set"); -#endif - - if (ret < PAGE_SIZE - 1) - ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); - else { - buf[PAGE_SIZE - 2] = '\n'; - buf[PAGE_SIZE - 1] = '\0'; - ret = PAGE_SIZE - 1; - } - - return ret; -} - -static ssize_t set_under_lock_dvfs(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - int i; - unsigned int freq = 0; - struct kbase_device *kbdev = NULL; - int ret = 0; - - kbdev = dev_get_drvdata(dev); - if ( NULL == kbdev) - { - E("err.") - return -ENODEV; - } - -#ifdef CONFIG_MALI_MIDGARD_DVFS - if (sysfs_streq("off", buf)) - { - mali_dvfs_freq_under_unlock(); - } - else - { - freq = simple_strtoul(buf, NULL, 10); - D_DEC(freq); - - for(i=0;iplatform_context = (void *)platform; - - platform->cmu_pmu_status = 0; -#ifdef CONFIG_MALI_MIDGARD_DVFS - platform->utilisation = 0; - platform->time_busy = 0; - platform->time_idle = 0; - platform->time_tick = 0; - platform->dvfs_enabled = true; -#endif - - rk_gpu = kobject_create_and_add("rk_gpu", NULL); - if (!rk_gpu) - return MALI_ERROR_FUNCTION_FAILED; - - ret = sysfs_create_file(rk_gpu, &dev_attr_error_count.attr); - if(ret) - return MALI_ERROR_FUNCTION_FAILED; - - spin_lock_init(&platform->cmu_pmu_lock); - - if (kbase_platform_power_clock_init(kbdev)) - goto clock_init_fail; - -#ifdef CONFIG_MALI_MIDGARD_DVFS - kbase_platform_dvfs_init(kbdev); -#endif /* CONFIG_MALI_MIDGARD_DVFS */ - - /* Enable power */ - kbase_platform_cmu_pmu_control(kbdev, 1); - return MALI_ERROR_NONE; - - clock_init_fail: - kfree(platform); - - return MALI_ERROR_FUNCTION_FAILED; -} - -void kbase_platform_term(struct kbase_device *kbdev) -{ - struct rk_context *platform; - - platform = (struct rk_context *)kbdev->platform_context; - -#ifdef CONFIG_MALI_MIDGARD_DVFS - kbase_platform_dvfs_term(); -#endif /* CONFIG_MALI_MIDGARD_DVFS */ - - /* Disable power */ - kbase_platform_cmu_pmu_control(kbdev, 0); - kfree(kbdev->platform_context); - kbdev->platform_context = 0; - return; -} diff --git a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_platform.h b/drivers/gpu/arm/midgard/platform/rk/mali_kbase_platform.h deleted file mode 100755 index 8df43236a950..000000000000 --- a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_platform.h +++ /dev/null @@ -1,224 +0,0 @@ -/* drivers/gpu/t6xx/kbase/src/platform/rk/mali_kbase_platform.h - * Rockchip SoC Mali-T764 platform-dependent codes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software FoundatIon. - */ - -/** - * @file mali_kbase_platform.h - * // Platform-dependent init - * - * 声明 platform_dependent_part 的 work_context 类型, pm, clk 等操作的接口. - */ - -#ifndef _KBASE_PLATFORM_H_ -#define _KBASE_PLATFORM_H_ - -/** - * work_context_of_platform_dependent_part_of_rk. - */ -struct rk_context { - /** Indicator if system clock to mail-t604 is active */ - int cmu_pmu_status; - /** cmd & pmu lock */ - spinlock_t cmu_pmu_lock; - /** gpu_power_domain. */ - struct clk *mali_pd; - /** gpu_dvfs_node. */ - struct dvfs_node * mali_clk_node; -#ifdef CONFIG_MALI_MIDGARD_DVFS - /*To calculate utilization for x sec */ - int time_tick; - int utilisation; - u32 time_busy; - u32 time_idle; - /** mali_dvfs 是否被使能. */ - bool dvfs_enabled; - /** 标识当前有 touch_input_event 到来. */ - bool gpu_in_touch; - spinlock_t gpu_in_touch_lock; -#endif -}; - -/*-------------------------------------------------------*/ - -typedef unsigned long mali_bool; - -#ifndef MALI_TRUE -#define MALI_TRUE (1) -#endif - -#ifndef MALI_FALSE -#define MALI_FALSE (0) -#endif - -/*-------------------------------------------------------*/ - -/** - * @name Mali error types - * @brief The common error type for the mali drivers - * The mali_error type, all driver error handling should be of this type unless - * it must deal with a specific APIs error type. - * @{ - * - * .R : r6p0-02rel0 已经不再 头文件中提供对 mali_error 的定义. - */ -typedef enum -{ - /** - * @brief Common Mali errors for the entire driver - * MALI_ERROR_NONE is guaranteed to be 0. - * @{ - */ - MALI_ERROR_NONE = 0, - MALI_ERROR_OUT_OF_GPU_MEMORY, - MALI_ERROR_OUT_OF_MEMORY, - MALI_ERROR_FUNCTION_FAILED, - /* @} */ - /** - * @brief Mali errors for Client APIs to pass to EGL when creating EGLImages - * These errors must only be returned to EGL from one of the Client APIs as part of the - * (clientapi)_egl_image_interface.h - * @{ - */ - MALI_ERROR_EGLP_BAD_ACCESS, - MALI_ERROR_EGLP_BAD_PARAMETER, - /* @} */ - /** - * @brief Mali errors for the MCL module. - * These errors must only be used within the private components of the OpenCL implementation that report - * directly to API functions for cases where errors cannot be detected in the entrypoints file. They must - * not be passed between driver components. - * These are errors in the mali error space specifically for the MCL module, hence the MCLP prefix. - * @{ - */ - MALI_ERROR_MCLP_DEVICE_NOT_FOUND, - MALI_ERROR_MCLP_DEVICE_NOT_AVAILABLE, - MALI_ERROR_MCLP_COMPILER_NOT_AVAILABLE, - MALI_ERROR_MCLP_MEM_OBJECT_ALLOCATION_FAILURE, - MALI_ERROR_MCLP_PROFILING_INFO_NOT_AVAILABLE, - MALI_ERROR_MCLP_MEM_COPY_OVERLAP, - MALI_ERROR_MCLP_IMAGE_FORMAT_MISMATCH, - MALI_ERROR_MCLP_IMAGE_FORMAT_NOT_SUPPORTED, - MALI_ERROR_MCLP_BUILD_PROGRAM_FAILURE, - MALI_ERROR_MCLP_MAP_FAILURE, - MALI_ERROR_MCLP_MISALIGNED_SUB_BUFFER_OFFSET, - MALI_ERROR_MCLP_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST, - MALI_ERROR_MCLP_INVALID_VALUE, - MALI_ERROR_MCLP_INVALID_DEVICE_TYPE, - MALI_ERROR_MCLP_INVALID_PLATFORM, - MALI_ERROR_MCLP_INVALID_DEVICE, - MALI_ERROR_MCLP_INVALID_CONTEXT, - MALI_ERROR_MCLP_INVALID_QUEUE_PROPERTIES, - MALI_ERROR_MCLP_INVALID_COMMAND_QUEUE, - MALI_ERROR_MCLP_INVALID_HOST_PTR, - MALI_ERROR_MCLP_INVALID_MEM_OBJECT, - MALI_ERROR_MCLP_INVALID_IMAGE_FORMAT_DESCRIPTOR, - MALI_ERROR_MCLP_INVALID_IMAGE_SIZE, - MALI_ERROR_MCLP_INVALID_SAMPLER, - MALI_ERROR_MCLP_INVALID_BINARY, - MALI_ERROR_MCLP_INVALID_BUILD_OPTIONS, - MALI_ERROR_MCLP_INVALID_PROGRAM, - MALI_ERROR_MCLP_INVALID_PROGRAM_EXECUTABLE, - MALI_ERROR_MCLP_INVALID_KERNEL_NAME, - MALI_ERROR_MCLP_INVALID_KERNEL_DEFINITION, - MALI_ERROR_MCLP_INVALID_KERNEL, - MALI_ERROR_MCLP_INVALID_ARG_INDEX, - MALI_ERROR_MCLP_INVALID_ARG_VALUE, - MALI_ERROR_MCLP_INVALID_ARG_SIZE, - MALI_ERROR_MCLP_INVALID_KERNEL_ARGS, - MALI_ERROR_MCLP_INVALID_WORK_DIMENSION, - MALI_ERROR_MCLP_INVALID_WORK_GROUP_SIZE, - MALI_ERROR_MCLP_INVALID_WORK_ITEM_SIZE, - MALI_ERROR_MCLP_INVALID_GLOBAL_OFFSET, - MALI_ERROR_MCLP_INVALID_EVENT_WAIT_LIST, - MALI_ERROR_MCLP_INVALID_EVENT, - MALI_ERROR_MCLP_INVALID_OPERATION, - MALI_ERROR_MCLP_INVALID_GL_OBJECT, - MALI_ERROR_MCLP_INVALID_BUFFER_SIZE, - MALI_ERROR_MCLP_INVALID_MIP_LEVEL, - MALI_ERROR_MCLP_INVALID_GLOBAL_WORK_SIZE, - MALI_ERROR_MCLP_INVALID_GL_SHAREGROUP_REFERENCE_KHR, - MALI_ERROR_MCLP_INVALID_EGL_OBJECT, - /* @} */ - /** - * @brief Mali errors for the BASE module - * These errors must only be used within the private components of the Base implementation. They will not - * passed to other modules by the base driver. - * These are errors in the mali error space specifically for the BASE module, hence the BASEP prefix. - * @{ - */ - MALI_ERROR_BASEP_INVALID_FUNCTION, - /* @} */ - /** A dependency exists upon a resource that the client application wants to modify, so the driver must either - * create a copy of the resource (if possible) or block until the dependency has been satisfied. - */ - MALI_ERROR_RESOURCE_IN_USE, - - /** - * @brief A stride value was too big. - * - * A surface descriptor can store strides of up to 231-1 bytes but strides greater than - * 228-1 bytes cannot be expressed in bits without overflow. - */ - MALI_ERROR_STRIDE_TOO_BIG - -} mali_error; - -/** - * 将 gpu_clk 设置为 'rate', 'rate' 以 KHz 为单位. - * @param node: - * 指向 gpu_dvfs_node - * @param rate - * 预期设置的 gpu_clk 的 value, KHz 为单位. - */ -int mali_dvfs_clk_set(struct dvfs_node * node,unsigned long rate); // 'rate' 以 KHz 为单位. - -/* All things that are needed for the Linux port. */ -/** - * 关闭/开启 gpu 的 power 和 clock. - * @param kbdev - * 指向 mali_device. - * @param control - * 若是 1, 表征要开启. - * 若是 0, 表征要关闭. - */ -int kbase_platform_cmu_pmu_control(struct kbase_device *kbdev, int control); -/** - * 在 sysfs_dir_of_mali_device 下创建 rk_ext_file_nodes. - */ -int kbase_platform_create_sysfs_file(struct device *dev); -/** - * 删除 sysfs_dir_of_mali_device 下的 rk_ext_file_nodes. - */ -void kbase_platform_remove_sysfs_file(struct device *dev); - -/** - * 返回 gpu_power_domain 是否开启. - */ -int kbase_platform_is_power_on(void); - -mali_error kbase_platform_init(struct kbase_device *kbdev); -void kbase_platform_term(struct kbase_device *kbdev); - -/** - * 使能 clk_of_gpu_dvfs_node. - */ -int kbase_platform_clock_on(struct kbase_device *kbdev); -/** - * 禁止(关闭) clk_of_gpu_dvfs_node. - */ -int kbase_platform_clock_off(struct kbase_device *kbdev); - -/** - * 开启 gpu_power_domain. - */ -int kbase_platform_power_off(struct kbase_device *kbdev); -/** - * 关闭 gpu_power_domain. - */ -int kbase_platform_power_on(struct kbase_device *kbdev); - -#endif /* _KBASE_PLATFORM_H_ */