We use devfreq to implement DVFS of GPU, instead of 'legacy_dvfs'.
Change-Id: If5c8ef05c8f37c88a5c22779468b21315d71eda0
Signed-off-by: chenzhen <chenzhen@rock-chips.com>
#
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
-/* --------------------------------------------------------------------------------------------------------\r
- * File: custom_log.h \r
- *\r
- * Desc: ChenZhen 偏好的 log 输出的定制实现. \r
- *\r
- * -----------------------------------------------------------------------------------\r
- * < 习语 和 缩略语 > : \r
- *\r
- * -----------------------------------------------------------------------------------\r
- * Usage: \r
- *\r
- * Note:\r
- *\r
- * Author: ChenZhen\r
- *\r
- * --------------------------------------------------------------------------------------------------------\r
- * Version:\r
- * v1.0\r
- * --------------------------------------------------------------------------------------------------------\r
- * Log:\r
- ----Fri Nov 19 15:20:28 2010 v1.0\r
- * \r
- * --------------------------------------------------------------------------------------------------------\r
- */\r
-\r
-\r
-#ifndef __CUSTOM_LOG_H__\r
-#define __CUSTOM_LOG_H__\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-/* ---------------------------------------------------------------------------------------------------------\r
- * Include Files\r
- * ---------------------------------------------------------------------------------------------------------\r
- */\r
-#include <linux/kernel.h>\r
-\r
-\r
-/* ---------------------------------------------------------------------------------------------------------\r
- * Macros Definition \r
- * ---------------------------------------------------------------------------------------------------------\r
- */\r
- \r
-/** 若下列 macro 有被定义, 才 使能 log 输出. */\r
-// #define ENABLE_DEBUG_LOG\r
-\r
-/** .! : 若需要全局地关闭 D log, 可以使能下面的代码. */\r
-/*\r
-#undef ENABLE_DEBUG_LOG\r
-#warning "custom debug log is disabled globally!"\r
-*/\r
-\r
-#define LOGD(fmt, args...) \\r
- printk(KERN_DEBUG fmt "\n", ## args)\r
-\r
-/*---------------------------------------------------------------------------*/\r
- \r
-#ifdef ENABLE_VERBOSE_LOG\r
-/** Verbose log. */\r
-#define V(fmt, args...) \\r
- { printk(KERN_DEBUG "V : [File] : %s; [Line] : %d; [Func] : %s(); " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ## args); }\r
-#else\r
-#define V(...) ((void)0)\r
-#endif\r
-\r
-\r
-#ifdef ENABLE_DEBUG_LOG\r
-/** Debug log. */\r
-#define D(fmt, args...) \\r
- { printk(KERN_DEBUG "D : [File] : %s; [Line] : %d; [Func] : %s(); " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ## args); }\r
-#else\r
-#define D(...) ((void)0)\r
-#endif\r
-\r
-#define I(fmt, args...) \\r
- { printk(KERN_INFO "I : [File] : %s; [Line] : %d; [Func] : %s(); " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ## args); }\r
-\r
-#define W(fmt, args...) \\r
- { printk(KERN_WARNING "W : [File] : %s; [Line] : %d; [Func] : %s(); " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ## args); }\r
-\r
-#define E(fmt, args...) \\r
- { printk(KERN_ERR "E : [File] : %s; [Line] : %d; [Func] : %s(); " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ## args); }\r
-\r
-/*-------------------------------------------------------*/\r
-\r
-/** 使用 D(), 以十进制的形式打印变量 'var' 的 value. */\r
-#define D_DEC(var) D(#var " = %d.", var);\r
-\r
-#define E_DEC(var) E(#var " = %d.", var);\r
-\r
-/** 使用 D(), 以十六进制的形式打印变量 'var' 的 value. */\r
-#define D_HEX(var) D(#var " = 0x%x.", var);\r
-\r
-#define E_HEX(var) E(#var " = 0x%x.", var);\r
-\r
-/** 使用 D(), 以十六进制的形式 打印指针类型变量 'ptr' 的 value. */\r
-#define D_PTR(ptr) D(#ptr " = %p.", ptr);\r
-\r
-#define E_PTR(ptr) E(#ptr " = %p.", ptr);\r
-\r
-/** 使用 D(), 打印 char 字串. */\r
-#define D_STR(pStr) \\r
-{\\r
- if ( NULL == pStr )\\r
- {\\r
- D(#pStr" = NULL.");\\r
- }\\r
- else\\r
- {\\r
- D(#pStr" = '%s'.", pStr);\\r
- }\\r
-}\r
-\r
-#define E_STR(pStr) \\r
-{\\r
- if ( NULL == pStr )\\r
- {\\r
- E(#pStr" = NULL.");\\r
- }\\r
- else\\r
- {\\r
- E(#pStr" = '%s'.", pStr);\\r
- }\\r
-}\r
-\r
-#ifdef ENABLE_DEBUG_LOG\r
-/**\r
- * log 从 'pStart' 地址开始的 'len' 个字节的数据. \r
- */\r
-#define D_MEM(pStart, len) \\r
- {\\r
- int i = 0;\\r
- char* p = (char*)pStart;\\r
- D("dump memory from addr of '" #pStart "', from %p, length %d' : ", pStart, len); \\r
- printk("\t\t");\\r
- for ( i = 0; i < len ; i++ )\\r
- {\\r
- printk("0x%02x, ", p[i] );\\r
- }\\r
- printk("\n");\\r
- }\r
-#else\r
-#define D_MEM(...) ((void)0)\r
-#endif\r
-\r
-/*-------------------------------------------------------*/\r
-\r
-#define EXIT_FOR_DEBUG \\r
-{\\r
- E("To exit for debug.");\\r
- return 1;\\r
-}\r
-\r
-/*-------------------------------------------------------*/\r
-\r
-/**\r
- * 调用函数, 并检查返回值, 根据返回值决定是否跳转到指定的错误处理代码. \r
- * @param functionCall\r
- * 对特定函数的调用, 该函数的返回值必须是 表征 成功 or err 的 整型数. \r
- * 这里, 被调用函数 "必须" 是被定义为 "返回 0 表示操作成功". \r
- * @param result\r
- * 用于记录函数返回的 error code 的 整型变量, 通常是 "ret" or "result" 等.\r
- * @param label\r
- * 若函数返回错误, 程序将要跳转到的 错误处理处的 标号, 通常就是 "EXIT". \r
- */\r
-#define CHECK_FUNC_CALL(functionCall, result, label) \\r
-{\\r
- if ( 0 != ( (result) = (functionCall) ) )\\r
- {\\r
- E("Function call returned error : " #result " = %d.", result);\\r
- goto label;\\r
- }\\r
-}\r
-\r
-/**\r
- * 在特定条件下, 判定 error 发生, 对变量 'retVar' 设置 'errCode', \r
- * Log 输出对应的 Error Caution, 然后跳转 'label' 指定的代码处执行. \r
- * @param msg\r
- * 纯字串形式的提示信息. \r
- * @param retVar\r
- * 标识函数执行状态或者结果的变量, 将被设置具体的 Error Code. \r
- * 通常是 'ret' or 'result'. \r
- * @param errCode\r
- * 表征特定 error 的常数标识, 通常是 宏的形态. \r
- * @param label\r
- * 程序将要跳转到的错误处理代码的标号, 通常就是 'EXIT'. \r
- * @param args...\r
- * 对应 'msgFmt' 实参中 '%s', '%d', ... 等 转换说明符 的具体可变长实参. \r
- */\r
-#define SET_ERROR_AND_JUMP(msgFmt, retVar, errCode, label, args...) \\r
-{\\r
- E("To set '" #retVar "' to %d('" #errCode "'), because : " msgFmt, (errCode), ## args);\\r
- (retVar) = (errCode);\\r
- goto label;\\r
-}\r
-\r
-\r
-/* ---------------------------------------------------------------------------------------------------------\r
- * Types and Structures Definition\r
- * ---------------------------------------------------------------------------------------------------------\r
- */\r
-\r
-\r
-/* ---------------------------------------------------------------------------------------------------------\r
- * Global Functions' Prototype\r
- * ---------------------------------------------------------------------------------------------------------\r
- */\r
-\r
-\r
-/* ---------------------------------------------------------------------------------------------------------\r
- * Inline Functions Implementation \r
- * ---------------------------------------------------------------------------------------------------------\r
- */\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif /* __CUSTOM_LOG_H__ */\r
-\r
+/* ----------------------------------------------------------------------------
+ * 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 <linux/kernel.h>
+#include <linux/printk.h>
+
+/* -----------------------------------------------------------------------------
+ * 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__ */
* 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
#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
#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
#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.
/**
* 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)
/**
* 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
*
* 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 <linux/ioport.h>
#include <mali_kbase.h>
#include <mali_kbase_defs.h>
#include <mali_kbase_config.h>
-#ifdef CONFIG_UMP
-#include <linux/ump-common.h>
-#endif /* CONFIG_UMP */
-#include <platform/rk/mali_kbase_platform.h>
-#include <platform/rk/mali_kbase_dvfs.h>
+
#include <linux/pm_runtime.h>
#include <linux/suspend.h>
-#include <linux/reboot.h>
+
/**
* @file mali_kbase_config_rk.c
* 对 platform_config_of_rk 的具体实现.
- *
- * mali_device_driver 包含两部分 :
- * .DP : platform_dependent_part_in_mdd : 依赖 platform 部分, 源码在 <mdd_src_dir>/platform/<platform_name> 目录下.
- * 在 mali_device_driver 内部, 记为 platform_dependent_part.
- * .DP : common_parts_in_mdd : arm 实现的通用的部分, 源码在 <mdd_src_dir> 目录下.
- * 在 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 部分,
+ * 源码在 <mdd_src_dir>/platform/<platform_name>/
+ * 在 mali_device_driver 内部,
+ * 记为 platform_dependent_part,
+ * 也被记为 platform_specific_code.
+ * .DP : common_parts_in_mdd :
+ * arm 实现的通用的部分,
+ * 源码在 <mdd_src_dir>/ 下.
+ * 在 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;
}
+
+++ /dev/null
-/* 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 <mali_kbase.h>
-#include <mali_kbase_uku.h>
-#include <mali_kbase_mem.h>
-#include <mali_midg_regmap.h>
-#include <mali_kbase_mem_linux.h>
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/platform_device.h>
-#include <linux/pci.h>
-#include <linux/miscdevice.h>
-#include <linux/list.h>
-#include <linux/semaphore.h>
-#include <linux/fs.h>
-#include <linux/uaccess.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/cpufreq.h>
-#include <linux/fb.h>
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/regulator/consumer.h>
-#include <linux/regulator/driver.h>
-#include <linux/rk_fb.h>
-#include <linux/input.h>
-#include <linux/rockchip/common.h>
-
-#include <platform/rk/mali_kbase_platform.h>
-#include <platform/rk/mali_kbase_dvfs.h>
-#include <mali_kbase_gator.h>
-#include <linux/rockchip/dvfs.h>
-/***********************************************************/
-/* 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;i<MALI_DVFS_STEP;i++)
- calculate_dvfs_max_min_threshold(i);
-
- p_mali_dvfs_infotbl = mali_dvfs_infotbl;
- }
-
-not_assigned :
- if (!mali_dvfs_wq)
- mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs");
-
- spin_lock_init(&mali_dvfs_spinlock);
- mutex_init(&mali_set_clock_lock);
- mutex_init(&mali_enable_clock_lock);
-
- /*add a error handling here */
- spin_lock_irqsave(&mali_dvfs_spinlock, flags);
- mali_dvfs_status_current.kbdev = kbdev;
- mali_dvfs_status_current.utilisation = 0;
- mali_dvfs_status_current.step = 0;
-#ifdef CONFIG_MALI_MIDGARD_FREQ_LOCK
- mali_dvfs_status_current.upper_lock = -1; // 初始时, 未设置.
- mali_dvfs_status_current.under_lock = -1;
-#endif
- spin_unlock_irqrestore(&mali_dvfs_spinlock, flags);
-
- spin_lock_init(&platform->gpu_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
+++ /dev/null
-/* 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_ */
+++ /dev/null
-/* 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 <mali_kbase.h>
-#include <mali_kbase_pm.h>
-#include <mali_kbase_uku.h>
-#include <mali_kbase_mem.h>
-#include <mali_midg_regmap.h>
-#include <mali_kbase_mem_linux.h>
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/platform_device.h>
-#include <linux/pci.h>
-#include <linux/miscdevice.h>
-#include <linux/list.h>
-#include <linux/semaphore.h>
-#include <linux/fs.h>
-#include <linux/uaccess.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-
-#include <linux/fb.h>
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <platform/rk/mali_kbase_platform.h>
-#include <platform/rk/mali_kbase_dvfs.h>
-
-#include <mali_kbase_gator.h>
-
-#include <linux/rockchip/dvfs.h>
-
-// #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<MALI_DVFS_STEP;i++)
- {
- D("p_mali_dvfs_infotbl[%d].clock : %d", i, p_mali_dvfs_infotbl[i].clock);
- if (p_mali_dvfs_infotbl[i].clock == freq)
- {
- D("target_freq is acceptable in level '%d', to set '%d' as index of dvfs_level_upper_limit.", i, i);
- ret = mali_dvfs_freq_lock(i);
- if ( 0 != ret )
- {
- E("fail to set dvfs_level_upper_limit, ret : %d.", ret);
- return -EINVAL;
- }
- break;
- }
- }
- /* 若 "没有" 找到和 target_freq match 的 level, 则... */
- if ( MALI_DVFS_STEP == i )
- {
- // dev_err(dev, "set_clock: invalid value\n");
- E("invalid target_freq : %d", freq);
- return -ENOENT;
- }
- }
-
-#else /* CONFIG_MALI_MIDGARD_DVFS */
- printk(KERN_DEBUG "mali DVFS is disabled. You can not set\n");
-#endif
-
- return count;
-}
-
-static ssize_t show_under_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)
- return -ENODEV;
-
-#ifdef CONFIG_MALI_MIDGARD_DVFS
- gpu_clk_freq = mali_get_dvfs_under_locked_freq();
- if (gpu_clk_freq > 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;i<MALI_DVFS_STEP;i++)
- {
- if (p_mali_dvfs_infotbl[i].clock == freq)
- {
- D("to set '%d' as the index of dvfs_level_lower_limit", i);
- ret = mali_dvfs_freq_under_lock(i);
- if ( 0 != ret )
- {
- E("fail to set dvfs_level_lower_limit, ret : %d.", ret);
- return -EINVAL;
- }
- break;
- }
- }
- /* 若 "没有" 找到和 target_freq match 的 level, 则... */
- if( i == MALI_DVFS_STEP )
- {
- dev_err(dev, "set_clock: invalid value\n");
- return -ENOENT;
- }
- }
-
-#else /* CONFIG_MALI_MIDGARD_DVFS */
- printk(KERN_DEBUG "mali DVFS is disabled. You can not set\n");
-#endif
- return count;
-}
-
-/** The sysfs file @c clock, fbdev.
- *
- * This is used for obtaining information about the mali t6xx operating clock & framebuffer address,
- */
-static DEVICE_ATTR(clock, S_IRUGO | S_IWUSR, show_clock, set_clock);
-static DEVICE_ATTR(fbdev, S_IRUGO, show_fbdev, NULL);
-static DEVICE_ATTR(dtlb, S_IRUGO | S_IWUSR, show_dtlb, set_dtlb);
-static DEVICE_ATTR(dvfs, S_IRUGO | S_IWUSR, show_dvfs, set_dvfs);
-static DEVICE_ATTR(dvfs_upper_lock, S_IRUGO | S_IWUSR, show_upper_lock_dvfs, set_upper_lock_dvfs);
-static DEVICE_ATTR(dvfs_under_lock, S_IRUGO | S_IWUSR, show_under_lock_dvfs, set_under_lock_dvfs);
-static DEVICE_ATTR(time_in_state, S_IRUGO | S_IWUSR, show_time_in_state, set_time_in_state);
-/*---------------------------------------------------------------------------*/
-
-int kbase_platform_create_sysfs_file(struct device *dev)
-{
- if (device_create_file(dev, &dev_attr_clock)) {
- dev_err(dev, "Couldn't create sysfs file [clock]\n");
- goto out;
- }
-
- if (device_create_file(dev, &dev_attr_fbdev)) {
- dev_err(dev, "Couldn't create sysfs file [fbdev]\n");
- goto out;
- }
-
- /* rk_ext : device will crash after "cat /sys/devices/ffa30000.gpu/dtlb".
- if (device_create_file(dev, &dev_attr_dtlb)) {
- dev_err(dev, "Couldn't create sysfs file [dtlb]\n");
- goto out;
- }
- */
-
- if (device_create_file(dev, &dev_attr_dvfs)) {
- dev_err(dev, "Couldn't create sysfs file [dvfs]\n");
- goto out;
- }
-
- if (device_create_file(dev, &dev_attr_dvfs_upper_lock)) {
- dev_err(dev, "Couldn't create sysfs file [dvfs_upper_lock]\n");
- goto out;
- }
-
- if (device_create_file(dev, &dev_attr_dvfs_under_lock)) {
- dev_err(dev, "Couldn't create sysfs file [dvfs_under_lock]\n");
- goto out;
- }
-
- if (device_create_file(dev, &dev_attr_time_in_state)) {
- dev_err(dev, "Couldn't create sysfs file [time_in_state]\n");
- goto out;
- }
- return 0;
-
- out:
- return -ENOENT;
-}
-
-void kbase_platform_remove_sysfs_file(struct device *dev)
-{
- device_remove_file(dev, &dev_attr_clock);
- device_remove_file(dev, &dev_attr_fbdev);
- device_remove_file(dev, &dev_attr_dtlb);
- device_remove_file(dev, &dev_attr_dvfs);
- device_remove_file(dev, &dev_attr_dvfs_upper_lock);
- device_remove_file(dev, &dev_attr_dvfs_under_lock);
- device_remove_file(dev, &dev_attr_time_in_state);
-}
-#endif /* CONFIG_MALI_MIDGARD_DEBUG_SYS */
-
-mali_error kbase_platform_init(struct kbase_device *kbdev)
-{
- struct rk_context *platform;
- int ret;
-
- platform = kmalloc(sizeof(struct rk_context), GFP_KERNEL);
-
- if (NULL == platform)
- return MALI_ERROR_OUT_OF_MEMORY;
-
- /* .KP : 将 'rk_context' 关联到 mali_device. */
- kbdev->platform_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;
-}
+++ /dev/null
-/* 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 2<sup>31</sup>-1 bytes but strides greater than
- * 2<sup>28</sup>-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_ */