static void set_num_cores(struct work_struct *work)
{
int err = mali_perf_set_num_pp_cores(num_cores_enabled);
+
MALI_DEBUG_ASSERT(0 == err);
MALI_IGNORE(err);
}
if (num_cores_enabled < num_cores_total) {
num_cores_enabled = num_cores_total;
schedule_work(&wq_work);
- MALI_DEBUG_PRINT(3, ("Core scaling: Enabling maximum number of cores\n"));
+ MALI_DEBUG_PRINT(3,
+ ("Core scaling: Enabling max num of cores\n"));
}
MALI_DEBUG_ASSERT(num_cores_total == num_cores_enabled);
* in order to make a good core scaling algorithm.
*/
- MALI_DEBUG_PRINT(3, ("Utilization: (%3d, %3d, %3d), cores enabled: %d/%d\n", data->utilization_gpu, data->utilization_gp, data->utilization_pp, num_cores_enabled, num_cores_total));
+ MALI_DEBUG_PRINT(3,
+ ("Utilization:(%3d, %3d, %3d), cores enabled: %d/%d\n",
+ data->utilization_gpu,
+ data->utilization_gp,
+ data->utilization_pp,
+ num_cores_enabled,
+ num_cores_total));
- /* NOTE: this function is normally called directly from the utilization callback which is in
- * timer context. */
+ /* NOTE:
+ * this function is normally called directly
+ * from the utilization callback which is in timer context. */
- if (PERCENT_OF(90, 256) < data->utilization_pp) {
+ if (PERCENT_OF(90, 256) < data->utilization_pp)
enable_max_num_cores();
- } else if (PERCENT_OF(50, 256) < data->utilization_pp) {
+ else if (PERCENT_OF(50, 256) < data->utilization_pp)
enable_one_core();
- } else if (PERCENT_OF(40, 256) < data->utilization_pp) {
- /* do nothing */
- } else if (PERCENT_OF(0, 256) < data->utilization_pp) {
+ else if (PERCENT_OF(40, 256) < data->utilization_pp)
+ MALI_DEBUG_PRINT(6, ("do nothing"));
+ else if (PERCENT_OF(0, 256) < data->utilization_pp)
disable_one_core();
- } else {
- /* do nothing */
- }
+ else
+ MALI_DEBUG_PRINT(6, ("do nothing"));
}
-/* --------------------------------------------------------------------------------------------------------\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
- * ÕâÀï, ±»µ÷Óú¯Êý "±ØÐë" ÊDZ»¶¨ÒåΪ "·µ»Ø 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 */
+
+/** .! : 若需要全局地关闭 D log, 可以使能下面的代码. */
+/*
+#undef ENABLE_DEBUG_LOG
+#warning "custom debug log is disabled globally!"
+*/
+
+/*----------------------------------------------------------------------------*/
+
+#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 (NULL == p_str) { \
+ D(#p_str" = NULL."); \
+ else \
+ D(#p_str" = '%s'.", p_str); \
+} while (0)
+
+#define E_STR(p_str) \
+do { \
+ if (NULL == 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
+
+/*-------------------------------------------------------*/
+
+#define EXIT_FOR_DEBUG \
+do { \
+ E("To exit for debug."); \
+ return 1; \
+} while (0)
+
+/*-------------------------------------------------------*/
+
+/**
+ * 调用函数, 并检查返回值, 根据返回值决定是否跳转到指定的错误处理代码.
+ * @param func_call
+ * 对特定函数的调用,
+ * 该函数的返回值必须是 表征 成功 or err 的 整型数.
+ * 且被 "必须" 被定义为 "返回 0 表示操作成功".
+ * @param result
+ * 用于记录函数返回的 error code 的 整型变量,
+ * 通常是 "ret" or "result" 等.
+ * @param label
+ * 若函数返回错误,
+ * 程序将要跳转到的 错误处理处的 标号,
+ * 通常就是 "EXIT".
+ */
+#define CHECK_FUNC_CALL(func_call, result, label) \
+do { \
+ (result) = (func_call) \
+ if (0 != (result)) { \
+ E("Function call returned error : " #result " = %d.", result); \
+ goto label;\
+ } \
+} while (0)
+
+/**
+ * 在特定条件下, 判定 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__ */
-/*\r
- * Rockchip SoC Mali-450 DVFS driver\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License version 2 as\r
- * published by the Free Software FoundatIon.\r
- */\r
-\r
-#include "mali_platform.h"\r
-#include "mali_dvfs.h"\r
-\r
-#define level0_min 0\r
-#define level0_max 70\r
-#define levelf_max 100\r
-\r
-#define mali_dividend 7\r
-#define mali_fix_float(a) ((((a)*mali_dividend)%10)?((((a)*mali_dividend)/10)+1):(((a)*mali_dividend)/10))\r
-\r
-#define work_to_dvfs(w) container_of(w, struct mali_dvfs, work)\r
-#define dvfs_to_drv_data(dvfs) container_of(dvfs, struct mali_platform_drv_data, dvfs)\r
-\r
-static void mali_dvfs_event_proc(struct work_struct *w)\r
-{\r
- struct mali_dvfs *dvfs = work_to_dvfs(w);\r
- struct mali_platform_drv_data *drv_data = dvfs_to_drv_data(dvfs);\r
- unsigned int utilisation = dvfs->utilisation;\r
- unsigned int level = dvfs->current_level;\r
- const struct mali_fv_info *threshold = &drv_data->fv_info[level];\r
- int ret;\r
-\r
- utilisation = utilisation * 100 / 256;\r
-\r
- // dev_dbg(drv_data->dev, "utilisation percent = %d\n", utilisation);\r
-\r
- if (utilisation > threshold->max &&\r
- level < drv_data->fv_info_length - 1 )\r
- level += 1;\r
- else if (level > 0 && utilisation < threshold->min)\r
- level -= 1;\r
- else\r
- return;\r
-\r
- dev_dbg(drv_data->dev, "Setting dvfs level %u: freq = %lu Hz\n",\r
- level, drv_data->fv_info[level].freq);\r
-\r
- ret = mali_set_level(drv_data->dev, level);\r
- if (ret) {\r
- dev_err(drv_data->dev, "set freq error, %d", ret);\r
- return;\r
- }\r
-}\r
-\r
-bool mali_dvfs_is_enabled(struct device *dev)\r
-{\r
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);\r
- struct mali_dvfs *dvfs = &drv_data->dvfs;\r
-\r
- return dvfs->enabled;\r
-}\r
-\r
-void mali_dvfs_enable(struct device *dev)\r
-{\r
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);\r
- struct mali_dvfs *dvfs = &drv_data->dvfs;\r
-\r
- dvfs->enabled = true;\r
-}\r
-\r
-void mali_dvfs_disable(struct device *dev)\r
-{\r
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);\r
- struct mali_dvfs *dvfs = &drv_data->dvfs;\r
-\r
- dvfs->enabled = false;\r
- cancel_work_sync(&dvfs->work);\r
-}\r
-\r
-unsigned int mali_dvfs_utilisation(struct device *dev)\r
-{\r
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);\r
- struct mali_dvfs *dvfs = &drv_data->dvfs;\r
-\r
- return dvfs->utilisation;\r
-}\r
-\r
-int mali_dvfs_event(struct device *dev, u32 utilisation)\r
-{\r
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);\r
- struct mali_dvfs *dvfs = &drv_data->dvfs;\r
-\r
- dvfs->utilisation = utilisation;\r
-\r
- if (dvfs->enabled)\r
- schedule_work(&dvfs->work);\r
-\r
- return MALI_TRUE;\r
-}\r
-static void mali_dvfs_threshold(u32 div, struct mali_platform_drv_data *drv_data)\r
-{\r
- int length = drv_data->fv_info_length;\r
- u32 pre_level;\r
- u32 tmp;\r
- int level;\r
-\r
- for (level = 0; level < length; level++) {\r
- if (level == 0) {\r
- drv_data->fv_info[level].min = level0_min;\r
- if (length == 1)\r
- drv_data->fv_info[level].max = levelf_max;\r
- else\r
- drv_data->fv_info[level].max = level0_max;\r
- } else {\r
- pre_level = level - 1;\r
- if (level == length - 1)\r
- drv_data->fv_info[level].max = levelf_max;\r
- else\r
- drv_data->fv_info[level].max = drv_data->fv_info[pre_level].max + div;\r
-\r
- drv_data->fv_info[level].min = drv_data->fv_info[pre_level].max *\r
- drv_data->fv_info[pre_level].freq / drv_data->fv_info[level].freq;\r
-\r
- tmp = drv_data->fv_info[level].max - drv_data->fv_info[level].min;\r
- drv_data->fv_info[level].min += mali_fix_float(tmp);\r
- }\r
-\r
- dev_info(drv_data->dev, "freq: %lu, min_threshold: %d, max_threshold: %d\n",\r
- drv_data->fv_info[level].freq,\r
- drv_data->fv_info[level].min,\r
- drv_data->fv_info[level].max);\r
- }\r
-}\r
-\r
-int mali_dvfs_init(struct device *dev)\r
-{\r
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);\r
- struct mali_dvfs *dvfs = &drv_data->dvfs;\r
- struct cpufreq_frequency_table *freq_table;\r
- int i = 0;\r
- int div_dvfs;\r
- int ret;\r
-\r
- freq_table = dvfs_get_freq_volt_table(drv_data->clk);\r
- if (!freq_table) {\r
- dev_err(dev, "Can't find dvfs table in dts\n");\r
- return -1;\r
- }\r
-\r
- while (freq_table[i].frequency != CPUFREQ_TABLE_END) {\r
- drv_data->fv_info_length++;\r
- i++;\r
- }\r
-\r
- drv_data->fv_info = devm_kcalloc(dev, drv_data->fv_info_length,\r
- sizeof(*drv_data->fv_info),\r
- GFP_KERNEL);\r
- if (!drv_data->fv_info)\r
- return -ENOMEM;\r
-\r
- for (i = 0; i < drv_data->fv_info_length; i++)\r
- drv_data->fv_info[i].freq = freq_table[i].frequency * 1000;\r
-\r
- if(drv_data->fv_info_length > 1)\r
- div_dvfs = round_up(((levelf_max - level0_max) /\r
- (drv_data->fv_info_length-1)), 1);\r
-\r
- mali_dvfs_threshold(div_dvfs, drv_data);\r
-\r
- ret = dvfs_clk_set_rate(drv_data->clk, drv_data->fv_info[0].freq);\r
- if (ret)\r
- return ret;\r
-\r
- drv_data->dvfs.current_level = 0;\r
-\r
- dev_info(dev, "initial freq = %lu\n",\r
- dvfs_clk_get_rate(drv_data->clk));\r
-\r
- INIT_WORK(&dvfs->work, mali_dvfs_event_proc);\r
- dvfs->enabled = true;\r
-\r
- return 0;\r
-}\r
-\r
-void mali_dvfs_term(struct device *dev)\r
-{\r
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);\r
- struct mali_dvfs *dvfs = &drv_data->dvfs;\r
-\r
- dvfs->enabled = false;\r
- cancel_work_sync(&dvfs->work);\r
-}\r
+/*
+ * Rockchip SoC Mali-450 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.
+ */
+
+#include "mali_platform.h"
+#include "mali_dvfs.h"
+
+#define level0_min 0
+#define level0_max 70
+#define levelf_max 100
+
+#define mali_dividend 7
+#define mali_fix_float(a) \
+ ((((a) * mali_dividend) % 10) \
+ ? ((((a) * mali_dividend) / 10) + 1) \
+ : (((a) * mali_dividend) / 10))
+
+#define work_to_dvfs(w) container_of(w, struct mali_dvfs, work)
+#define dvfs_to_drv_data(dvfs) \
+ container_of(dvfs, struct mali_platform_drv_data, dvfs)
+
+static void mali_dvfs_event_proc(struct work_struct *w)
+{
+ struct mali_dvfs *dvfs = work_to_dvfs(w);
+ struct mali_platform_drv_data *drv_data = dvfs_to_drv_data(dvfs);
+ unsigned int utilisation = dvfs->utilisation;
+ unsigned int level = dvfs->current_level;
+ const struct mali_fv_info *threshold = &drv_data->fv_info[level];
+ int ret;
+
+ utilisation = utilisation * 100 / 256;
+
+ /* dev_dbg(drv_data->dev, "utilisation percent = %d\n", utilisation); */
+
+ if (utilisation > threshold->max &&
+ level < drv_data->fv_info_length - 1)
+ level += 1;
+ else if (level > 0 && utilisation < threshold->min)
+ level -= 1;
+ else
+ return;
+
+ dev_dbg(drv_data->dev, "Setting dvfs level %u: freq = %lu Hz\n",
+ level, drv_data->fv_info[level].freq);
+
+ ret = mali_set_level(drv_data->dev, level);
+ if (ret) {
+ dev_err(drv_data->dev, "set freq error, %d", ret);
+ return;
+ }
+}
+
+bool mali_dvfs_is_enabled(struct device *dev)
+{
+ struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
+ struct mali_dvfs *dvfs = &drv_data->dvfs;
+
+ return dvfs->enabled;
+}
+
+void mali_dvfs_enable(struct device *dev)
+{
+ struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
+ struct mali_dvfs *dvfs = &drv_data->dvfs;
+
+ dvfs->enabled = true;
+}
+
+void mali_dvfs_disable(struct device *dev)
+{
+ struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
+ struct mali_dvfs *dvfs = &drv_data->dvfs;
+
+ dvfs->enabled = false;
+ cancel_work_sync(&dvfs->work);
+}
+
+unsigned int mali_dvfs_utilisation(struct device *dev)
+{
+ struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
+ struct mali_dvfs *dvfs = &drv_data->dvfs;
+
+ return dvfs->utilisation;
+}
+
+int mali_dvfs_event(struct device *dev, u32 utilisation)
+{
+ struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
+ struct mali_dvfs *dvfs = &drv_data->dvfs;
+
+ dvfs->utilisation = utilisation;
+
+ if (dvfs->enabled)
+ schedule_work(&dvfs->work);
+
+ return MALI_TRUE;
+}
+static void mali_dvfs_threshold(u32 div,
+ struct mali_platform_drv_data *drv_data)
+{
+ int length = drv_data->fv_info_length;
+ u32 pre_level;
+ u32 tmp;
+ int level;
+
+ for (level = 0; level < length; level++) {
+ if (level == 0) {
+ drv_data->fv_info[level].min = level0_min;
+ if (length == 1)
+ drv_data->fv_info[level].max = levelf_max;
+ else
+ drv_data->fv_info[level].max = level0_max;
+ } else {
+ pre_level = level - 1;
+ if (level == length - 1)
+ drv_data->fv_info[level].max = levelf_max;
+ else
+ drv_data->fv_info[level].max =
+ drv_data->fv_info[pre_level].max
+ + div;
+
+ drv_data->fv_info[level].min =
+ drv_data->fv_info[pre_level].max
+ * drv_data->fv_info[pre_level].freq
+ / drv_data->fv_info[level].freq;
+
+ tmp =
+ drv_data->fv_info[level].max
+ - drv_data->fv_info[level].min;
+ drv_data->fv_info[level].min += mali_fix_float(tmp);
+ }
+
+ dev_info(drv_data->dev,
+ "freq: %lu, min_threshold: %d, max_threshold: %d\n",
+ drv_data->fv_info[level].freq,
+ drv_data->fv_info[level].min,
+ drv_data->fv_info[level].max);
+ }
+}
+
+int mali_dvfs_init(struct device *dev)
+{
+ struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
+ struct mali_dvfs *dvfs = &drv_data->dvfs;
+ struct cpufreq_frequency_table *freq_table;
+ int i = 0;
+ int div_dvfs;
+ int ret;
+
+ freq_table = dvfs_get_freq_volt_table(drv_data->clk);
+ if (!freq_table) {
+ dev_err(dev, "Can't find dvfs table in dts\n");
+ return -1;
+ }
+
+ while (freq_table[i].frequency != CPUFREQ_TABLE_END) {
+ drv_data->fv_info_length++;
+ i++;
+ }
+
+ drv_data->fv_info = devm_kcalloc(dev, drv_data->fv_info_length,
+ sizeof(*drv_data->fv_info),
+ GFP_KERNEL);
+ if (!drv_data->fv_info)
+ return -ENOMEM;
+
+ for (i = 0; i < drv_data->fv_info_length; i++)
+ drv_data->fv_info[i].freq = freq_table[i].frequency * 1000;
+
+ if (drv_data->fv_info_length > 1)
+ div_dvfs = round_up(((levelf_max - level0_max) /
+ (drv_data->fv_info_length-1)), 1);
+
+ mali_dvfs_threshold(div_dvfs, drv_data);
+
+ ret = dvfs_clk_set_rate(drv_data->clk, drv_data->fv_info[0].freq);
+ if (ret)
+ return ret;
+
+ drv_data->dvfs.current_level = 0;
+
+ dev_info(dev, "initial freq = %lu\n", dvfs_clk_get_rate(drv_data->clk));
+
+ INIT_WORK(&dvfs->work, mali_dvfs_event_proc);
+ dvfs->enabled = true;
+
+ return 0;
+}
+
+void mali_dvfs_term(struct device *dev)
+{
+ struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
+ struct mali_dvfs *dvfs = &drv_data->dvfs;
+
+ dvfs->enabled = false;
+ cancel_work_sync(&dvfs->work);
+}
-/*\r
- * Rockchip SoC Mali-450 DVFS driver\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License version 2 as\r
- * published by the Free Software FoundatIon.\r
- */\r
-#include <linux/workqueue.h>\r
-#include <linux/types.h>\r
-#include <linux/device.h>\r
-\r
-#ifndef _MALI_DVFS_H_\r
-#define _MALI_DVFS_H_\r
-\r
-struct mali_dvfs {\r
- struct work_struct work;\r
- unsigned int utilisation;\r
- unsigned int current_level;\r
- bool enabled;\r
-};\r
-\r
-int mali_dvfs_init(struct device *dev);\r
-void mali_dvfs_term(struct device *dev);\r
-void mali_set_dvfs(struct device *dev, bool enable);\r
-bool mali_dvfs_is_enabled(struct device *dev);\r
-void mali_dvfs_enable(struct device *dev);\r
-void mali_dvfs_disable(struct device *dev);\r
-unsigned int mali_dvfs_utilisation(struct device *dev);\r
-int mali_dvfs_event(struct device *dev, u32 utilisation);\r
-#endif /*_MALI_DVFS_H_*/\r
+/*
+ * Rockchip SoC Mali-450 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.
+ */
+#include <linux/workqueue.h>
+#include <linux/types.h>
+#include <linux/device.h>
+
+#ifndef _MALI_DVFS_H_
+#define _MALI_DVFS_H_
+
+struct mali_dvfs {
+ struct work_struct work;
+ unsigned int utilisation;
+ unsigned int current_level;
+ bool enabled;
+};
+
+int mali_dvfs_init(struct device *dev);
+void mali_dvfs_term(struct device *dev);
+void mali_set_dvfs(struct device *dev, bool enable);
+bool mali_dvfs_is_enabled(struct device *dev);
+void mali_dvfs_enable(struct device *dev);
+void mali_dvfs_disable(struct device *dev);
+unsigned int mali_dvfs_utilisation(struct device *dev);
+int mali_dvfs_event(struct device *dev, u32 utilisation);
+#endif /*_MALI_DVFS_H_*/
#include <linux/device.h>
#include <linux/regulator/driver.h>
#include <linux/miscdevice.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/cpufreq.h>
#include <linux/of.h>
int ret;
unsigned int current_level;
- _mali_osk_mutex_wait(drv_data->clockSetlock);
+ _mali_osk_mutex_wait(drv_data->clock_set_lock);
current_level = drv_data->dvfs.current_level;
freq = drv_data->fv_info[level].freq;
if (level == current_level) {
- _mali_osk_mutex_signal(drv_data->clockSetlock);
+ _mali_osk_mutex_signal(drv_data->clock_set_lock);
return 0;
}
ret = dvfs_clk_set_rate(drv_data->clk, freq);
if (ret) {
- _mali_osk_mutex_signal(drv_data->clockSetlock);
+ _mali_osk_mutex_signal(drv_data->clock_set_lock);
return ret;
}
drv_data->dvfs.current_level = level;
- _mali_osk_mutex_signal(drv_data->clockSetlock);
+ _mali_osk_mutex_signal(drv_data->clock_set_lock);
return 0;
}
{
struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
- return scnprintf(buf, PAGE_SIZE, "%lu\n", dvfs_clk_get_rate(drv_data->clk));
+ return scnprintf(buf,
+ PAGE_SIZE,
+ "%lu\n",
+ dvfs_clk_get_rate(drv_data->clk));
}
static ssize_t set_clock(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
-{
+{
struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
unsigned long freq;
ssize_t ret;
for (level = drv_data->fv_info_length - 1; level > 0; level--) {
unsigned long tmp = drv_data->fv_info[level].freq;
+
if (tmp <= freq)
break;
}
}
static ssize_t show_dvfs_enable(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
return scnprintf(buf, PAGE_SIZE, "%u\n", mali_dvfs_is_enabled(dev));
}
static ssize_t set_dvfs_enable(struct device *dev,
- struct device_attribute *attr, const char *buf,
- size_t count)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
{
unsigned long enable;
ssize_t ret;
}
static ssize_t show_utilisation(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
return scnprintf(buf, PAGE_SIZE, "%u\n", mali_dvfs_utilisation(dev));
}
-static int error_count_show(struct device *dev,struct device_attribute *attr, char *buf)
+static int error_count_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
return sprintf(buf, "%d\n", mali_group_error);
}
if (ret)
goto term_clk;
- mali_drv_data->clockSetlock = _mali_osk_mutex_init(_MALI_OSK_LOCKFLAG_ORDERED,
- _MALI_OSK_LOCK_ORDER_UTILIZATION);
+ mali_drv_data->clock_set_lock =
+ _mali_osk_mutex_init(_MALI_OSK_LOCKFLAG_ORDERED,
+ _MALI_OSK_LOCK_ORDER_UTILIZATION);
mali_core_scaling_enable = 1;
- return 0;
+ return 0;
term_clk:
mali_clock_term(dev);
err_init:
- return _MALI_OSK_ERR_FAULT;
+ return _MALI_OSK_ERR_FAULT;
}
_mali_osk_errcode_t mali_platform_deinit(struct platform_device *pdev)
mali_core_scaling_term();
mali_clock_term(dev);
- _mali_osk_mutex_term(drv_data->clockSetlock);
+ _mali_osk_mutex_term(drv_data->clock_set_lock);
return 0;
}
return 0;
}
-_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode)
+_mali_osk_errcode_t mali_platform_power_mode_change(
+ enum mali_power_mode power_mode)
{
- switch(power_mode) {
- case MALI_POWER_MODE_ON:
- MALI_DEBUG_PRINT(2, ("MALI_POWER_MODE_ON\r\n"));
- mali_power_domain_control(MALI_POWER_MODE_ON);
- break;
- case MALI_POWER_MODE_LIGHT_SLEEP:
- MALI_DEBUG_PRINT(2, ("MALI_POWER_MODE_LIGHT_SLEEP\r\n"));
- mali_power_domain_control(MALI_POWER_MODE_LIGHT_SLEEP);
- break;
- case MALI_POWER_MODE_DEEP_SLEEP:
- MALI_DEBUG_PRINT(2, ("MALI_POWER_MODE_DEEP_SLEEP\r\n"));
- mali_power_domain_control(MALI_POWER_MODE_DEEP_SLEEP);
- break;
- default:
- MALI_DEBUG_PRINT(2, ("mali_platform_power_mode_change:power_mode(%d) not support \r\n",
- power_mode));
+ switch (power_mode) {
+ case MALI_POWER_MODE_ON:
+ MALI_DEBUG_PRINT(2, ("MALI_POWER_MODE_ON\r\n"));
+ mali_power_domain_control(MALI_POWER_MODE_ON);
+ break;
+ case MALI_POWER_MODE_LIGHT_SLEEP:
+ MALI_DEBUG_PRINT(2, ("MALI_POWER_MODE_LIGHT_SLEEP\r\n"));
+ mali_power_domain_control(MALI_POWER_MODE_LIGHT_SLEEP);
+ break;
+ case MALI_POWER_MODE_DEEP_SLEEP:
+ MALI_DEBUG_PRINT(2, ("MALI_POWER_MODE_DEEP_SLEEP\r\n"));
+ mali_power_domain_control(MALI_POWER_MODE_DEEP_SLEEP);
+ break;
+ default:
+ MALI_DEBUG_PRINT(2,
+ (":power_mode(%d) not support \r\n",
+ power_mode));
}
-
- return 0;
+
+ return 0;
}
void mali_gpu_utilization_handler(struct mali_gpu_utilization_data *data)
{
- if(data->utilization_pp > 256)
+ if (data->utilization_pp > 256)
return;
if (mali_core_scaling_enable)
mali_core_scaling_update(data);
- // dev_dbg(mali_dev, "utilization:%d\r\n", data->utilization_pp);
+ /* dev_dbg(mali_dev, "utilization:%d\r\n", data->utilization_pp); */
mali_dvfs_event(mali_dev, data->utilization_pp);
}
/** @brief description of power change reasons
*/
-typedef enum mali_power_mode_tag
-{
+enum mali_power_mode {
MALI_POWER_MODE_ON, /**< Power Mali on */
MALI_POWER_MODE_LIGHT_SLEEP, /**< Mali has been idle for a short time, or runtime PM suspend */
MALI_POWER_MODE_DEEP_SLEEP, /**< Mali has been idle for a long time, or OS suspend */
-} mali_power_mode;
+};
struct mali_fv_info {
unsigned long freq;
unsigned int fv_info_length;
struct mali_dvfs dvfs;
struct device *dev;
- bool power_state;
- _mali_osk_mutex_t *clockSetlock;
+ bool power_state;
+ _mali_osk_mutex_t *clock_set_lock;
};
/** @brief Platform specific setup and initialisation of MALI
* @param power_mode defines the power modes
* @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
*/
-_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode);
+_mali_osk_errcode_t mali_platform_power_mode_change(
+ enum mali_power_mode power_mode);
/** @brief Platform specific handling of GPU utilization data
* copies and copies may only be made to the extent permitted
* by a licensing agreement from ARM Limited.
*/
-
+
#include <linux/platform_device.h>
#include <linux/version.h>
#include <linux/pm.h>
static int mali_runtime_suspend(struct device *device)
{
int ret = 0;
+
MALI_DEBUG_PRINT(4, ("mali_runtime_suspend() called\n"));
if (NULL != device->driver &&
static int mali_runtime_resume(struct device *device)
{
int ret = 0;
+
MALI_DEBUG_PRINT(4, ("mali_runtime_resume() called\n"));
mali_platform_power_mode_change(MALI_POWER_MODE_ON);
static int mali_runtime_idle(struct device *device)
{
int ret = 0;
+
MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n"));
if (NULL != device->driver &&
int ret = 0;
MALI_DEBUG_PRINT(4, ("mali_os_suspend() called\n"));
-
+
if (NULL != device->driver &&
NULL != device->driver->pm &&
NULL != device->driver->pm->suspend) {
return ret;
}
-static struct dev_pm_ops mali_gpu_device_type_pm_ops =
-{
+static const struct dev_pm_ops mali_gpu_device_type_pm_ops = {
.suspend = mali_os_suspend,
.resume = mali_os_resume,
.freeze = mali_os_freeze,
#endif
};
-static struct device_type mali_gpu_device_device_type =
-{
+static const struct device_type mali_gpu_device_device_type = {
.pm = &mali_gpu_device_type_pm_ops,
};
-static struct mali_gpu_device_data mali_gpu_data =
-{
- .shared_mem_size = 1024* 1024 * 1024, /* 1GB */
+static const struct mali_gpu_device_data mali_gpu_data = {
+ .shared_mem_size = 1024 * 1024 * 1024, /* 1GB */
.fb_start = 0x40000000,
.fb_size = 0xb1000000,
.max_job_runtime = 60000, /* 60 seconds */
- //.utilization_interval = 0, /* 0ms */
+ /* .utilization_interval = 0, */ /* 0ms */
.utilization_callback = mali_gpu_utilization_handler,
};
{
int err = 0;
int num_pp_cores = 0;
- MALI_DEBUG_PRINT(2,("mali_platform_device_register() called\n"));
+
+ MALI_DEBUG_PRINT(2, ("mali_platform_device_register() called\n"));
if (cpu_is_rk312x())
num_pp_cores = 2;
if (err == 0) {
err = mali_platform_init(pdev);
if (err == 0) {
-
#ifdef CONFIG_PM_RUNTIME
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
pm_runtime_set_autosuspend_delay(&(pdev->dev), 1000);
pm_runtime_use_autosuspend(&(pdev->dev));
-#endif
pm_runtime_enable(&(pdev->dev));
#endif
MALI_DEBUG_ASSERT(0 < num_pp_cores);
-/* --------------------------------------------------------------------------------------------------------\r
- * File: rk_ext.h \r
- *\r
- * Desc: rk_ext_on_mali_ko 中的 通行定义等. \r
- *\r
- * Usage: \r
- *\r
- * Note:\r
- *\r
- * Author: ChenZhen\r
- * \r
- * Log:\r
- * \r
- * --------------------------------------------------------------------------------------------------------\r
- */\r
-\r
-\r
-#ifndef __RK_EXT_H__\r
-#define __RK_EXT_H__\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-/* ---------------------------------------------------------------------------------------------------------\r
- * Include Files\r
- * ---------------------------------------------------------------------------------------------------------\r
- */\r
-\r
-\r
-/* ---------------------------------------------------------------------------------------------------------\r
- * Macros Definition \r
- * ---------------------------------------------------------------------------------------------------------\r
- */\r
-\r
-/** version of rk_ext on mali_ko, aka. rk_ko_ver. */\r
-#define RK_KO_VER (4)\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 /* __RK_EXT_H__ */\r
-\r
+/* ----------------------------------------------------------------------------
+ * File: rk_ext.h
+ *
+ * Desc: rk_ext_on_mali_ko 中的 通行定义等.
+ *
+ * Usage:
+ *
+ * Note:
+ *
+ * Author: ChenZhen
+ *
+ * Log:
+ *
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef __RK_EXT_H__
+#define __RK_EXT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+/** version of rk_ext on mali_ko, aka. rk_ko_ver. */
+#define RK_KO_VER (4)
+
+/*---------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RK_EXT_H__ */
+