rk3288_mali_t760_driver_r6p0-02rel0_13_x@0
authorchenzhen <chenzhen@rock-chips.com>
Wed, 12 Aug 2015 09:54:35 +0000 (17:54 +0800)
committerchenzhen <chenzhen@rock-chips.com>
Wed, 12 Aug 2015 09:56:34 +0000 (17:56 +0800)
drivers/gpu/arm/midgard/mali_kbase_config_defaults.h
drivers/gpu/arm/midgard/mali_kbase_core_linux.c
drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_platform.h
drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_rk.c
drivers/gpu/arm/midgard/platform/rk/mali_kbase_dvfs.c
drivers/gpu/arm/midgard/platform/rk/mali_kbase_dvfs.h
drivers/gpu/arm/midgard/platform/rk/mali_kbase_platform.c
drivers/gpu/arm/midgard/platform/rk/mali_kbase_platform.h

index ce5d0703911c2b2ffd6baa33f8fdbf72ad9df39f..bd48ed96e962f9f41c282bbfec5664a034b1f448 100644 (file)
@@ -162,7 +162,8 @@ enum {
 /*
  * Default period for DVFS sampling
  */
-#define DEFAULT_PM_DVFS_PERIOD 100 /* 100ms */
+// #define DEFAULT_PM_DVFS_PERIOD 100 /* 100ms */
+#define DEFAULT_PM_DVFS_PERIOD 20 /* 20 ms */
 
 /*
  * Power Management poweroff tick granuality. This is in nanoseconds to
index e0ad7f7872b6d52b87a0bb9a600265b617e51df7..1285ec7970a0f0017d8460a592e49a8f4c2822e4 100644 (file)
@@ -104,7 +104,7 @@ EXPORT_SYMBOL(shared_kernel_test_data);
 
 #define KBASE_DRV_NAME "mali"
 /** rk_ext : version of rk_ext on mali_ko, aka. rk_ko_ver. */
-#define ROCKCHIP_VERSION    (12)
+#define ROCKCHIP_VERSION    (13)
 
 static const char kbase_drv_name[] = KBASE_DRV_NAME;
 
index 992434bec2ff94f8cc6a14eb8e3ab7e7361af571..7def683e74fa5a3039615ed54adbaf784104382e 100644 (file)
  *
  */
 
-
+/**
+ * @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 
index 1a342bc9e454668d95e5389abd6a69c7c0ae9b9a..68125f97e37c5ca6e6256c46b7a3359fe2953ed7 100755 (executable)
 #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);
 
@@ -155,6 +165,7 @@ int kbase_platform_rk_init(struct kbase_device *kbdev)
                         E("fail to register pm_notifier.");
                        return -1;
                }
+               
                pr_info("%s,register_reboot_notifier\n",__func__);
                register_reboot_notifier(&mali_reboot_notifier);
                return 0;
@@ -191,19 +202,30 @@ static int pm_callback_power_on(struct kbase_device *kbdev)
        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 (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);
@@ -220,6 +242,7 @@ static void pm_callback_power_off(struct kbase_device *kbdev)
 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))
index c2f0522c7c88b4c984546b2622a61a5655559e8a..13cd2dd7ea5fb8f2c23b7fa8afbca97d691f23ac 100755 (executable)
@@ -1,6 +1,6 @@
 /* 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
@@ -13,6 +13,9 @@
  * DVFS
  */
 
+// #define ENABLE_DEBUG_LOG
+#include "custom_log.h"
+
 #include <mali_kbase.h>
 #include <mali_kbase_uku.h>
 #include <mali_kbase_mem.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},
+       {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;
@@ -93,12 +146,13 @@ struct mutex mali_enable_clock_lock;
 #ifdef CONFIG_MALI_MIDGARD_DEBUG_SYS
 static void update_time_in_state(int level);
 #endif
-/*dvfs status*/
+/* .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)
@@ -114,6 +168,7 @@ static void gpufreq_input_event(struct input_handle *handle, unsigned int type,
        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);
 }
@@ -121,14 +176,14 @@ static void gpufreq_input_event(struct input_handle *handle, unsigned int type,
 static int gpufreq_input_connect(struct input_handler *handler,
                struct input_dev *dev, const struct input_device_id *id)
 {
-       struct input_handle *handle;
+       struct input_handle *handle;    // 用于关联 'dev' 和 'handler'.
        int error;
 
        handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
        if (!handle)
                return -ENOMEM;
 
-       handle->dev = dev;
+       handle->dev = dev;              // 'handle' 关联的 input_dev.
        handle->handler = handler;
        handle->name = "gpufreq";
 
@@ -141,6 +196,7 @@ static int gpufreq_input_connect(struct input_handler *handler,
                goto err1;
        pr_info("%s\n",__func__);
        return 0;
+
 err1:
        input_unregister_handle(handle);
 err2:
@@ -156,6 +212,9 @@ static void gpufreq_input_disconnect(struct input_handle *handle)
        pr_info("%s\n",__func__);
 }
 
+/**
+ * 待处理(关联) 的 input_device_ids_table.
+ */
 static const struct input_device_id gpufreq_ids[] = {
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
@@ -183,16 +242,23 @@ static struct input_handler gpufreq_input_handler = {
        .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;
-       static int level_up_time = 0;
+
+       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;
+       u32 fps = 0;            // real_fps.
        u32 fps_limit;
        u32 policy;
        mutex_lock(&mali_enable_clock_lock);
@@ -207,9 +273,9 @@ static void mali_dvfs_event_proc(struct work_struct *w)
        fps = rk_get_real_fps(0);
 
        dvfs_status->temperature_time++;
-       
-       temp_tmp += rockchip_tsadc_get_temp(1);
-       
+
+       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;
@@ -226,68 +292,105 @@ static void mali_dvfs_event_proc(struct work_struct *w)
                dvfs_status->step = MALI_DVFS_STEP - 1;
        } else {
                fps_limit = (ROCKCHIP_PM_POLICY_NORMAL == policy)?LIMIT_FPS : LIMIT_FPS_POWER_SAVE;
-               /*
-               printk("policy : %d , fps_limit = %d\n",policy,fps_limit);
-               */
-               
+               V("policy : %d , fps_limit = %d", policy, fps_limit);
+
                /*give priority to temperature unless in performance mode */
-               if (dvfs_status->temperature > gpu_temp_limit) {
+               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);
-                       */
-               } else if ((dvfs_status->utilisation > mali_dvfs_infotbl[dvfs_status->step].max_threshold) &&
-                                  (dvfs_status->step < MALI_DVFS_STEP-1) && fps < fps_limit) {
+                          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) {
-                               /*
-                               printk("up,utilisation=%d,current clock=%d,fps = %d,temperature = %d",
-                                               dvfs_status->utilisation, mali_dvfs_infotbl[dvfs_status->step].clock,
-                                               fps,dvfs_status->temperature);
-                               */
+
+                       /* 若 上跳请求的次数 达到 执行具体上跳 要求, 则... */
+                       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;
-                               /*
-                               printk(" next clock=%d\n",mali_dvfs_infotbl[dvfs_status->step].clock);
-                               */
-                               BUG_ON(dvfs_status->step >= MALI_DVFS_STEP);
+
+                               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;
-               } else if ((dvfs_status->step > 0) &&
-                                       (dvfs_status->utilisation < mali_dvfs_infotbl[dvfs_status->step].min_threshold)) {
+               } 
+               /* 否则, 若 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) {
-                               /*
-                               printk("down,utilisation=%d,current clock=%d,fps = %d,temperature = %d",
+
+                       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);
-                               */
+                                               mali_dvfs_infotbl[dvfs_status->step].clock,
+                                               fps,
+                                               dvfs_status->temperature);
+
                                BUG_ON(dvfs_status->step <= 0);
                                dvfs_status->step--;
                                level_down_time = 0;
-                               /*
-                               printk(" next clock=%d\n",mali_dvfs_infotbl[dvfs_status->step].clock);
-                               */
+
+                               V(" next clock=%d",mali_dvfs_infotbl[dvfs_status->step].clock);
                        }
+
                        level_up_time = 0;
-               } else {
+               } 
+               /* 否则, ... */
+               else 
+               {
                        level_down_time = 0;
                        level_up_time = 0;
-                       /*
-                       printk("keep,utilisation=%d,current clock=%d,fps = %d,temperature = %d\n",
+
+                       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);                       
-                       */
+                                       mali_dvfs_infotbl[dvfs_status->step].clock,
+                                       fps,
+                                       dvfs_status->temperature);                      
                }
        }
 #ifdef CONFIG_MALI_MIDGARD_FREQ_LOCK
-       if ((dvfs_status->upper_lock >= 0) && (dvfs_status->step > dvfs_status->upper_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)
@@ -295,15 +398,26 @@ static void mali_dvfs_event_proc(struct work_struct *w)
        }
 #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,
+                               u32 utilisation,          // current_calculated_utilisation 
                                u32 util_gl_share_no_use,
                                u32 util_cl_share_no_use[2] )
 {
@@ -330,13 +444,16 @@ int kbase_platform_dvfs_event(struct kbase_device *kbdev,
                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)
 {
@@ -380,6 +497,7 @@ int kbase_platform_dvfs_enable(bool enable, int freq)
        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;
@@ -387,7 +505,9 @@ int kbase_platform_dvfs_enable(bool enable, int freq)
                        hrtimer_start(&kbdev->pm.backend.metrics.timer,
                                        HR_TIMER_DELAY_MSEC(KBASE_PM_DVFS_FREQUENCY),
                                        HRTIMER_MODE_REL);
-               } else {
+               }
+               /* 否则, 即要 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);
@@ -404,14 +524,18 @@ int kbase_platform_dvfs_enable(bool enable, int freq)
                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;
@@ -440,9 +564,11 @@ static bool calculate_dvfs_max_min_threshold(u32 level)
                
                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;
 }
 
@@ -460,26 +586,37 @@ int kbase_platform_dvfs_init(struct kbase_device *kbdev)
        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++) {
+
+               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);
+                       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");
@@ -488,21 +625,24 @@ not_assigned :
        mutex_init(&mali_set_clock_lock);
        mutex_init(&mali_enable_clock_lock);
 
-       spin_lock_init(&platform->gpu_in_touch_lock);
-       rc = input_register_handler(&gpufreq_input_handler);
-
        /*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.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;
 }
 
@@ -520,29 +660,33 @@ void kbase_platform_dvfs_term(void)
 int mali_get_dvfs_upper_locked_freq(void)
 {
        unsigned long flags;
-       int locked_level = -1;
+       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)
-               locked_level = mali_dvfs_infotbl[mali_dvfs_status_current.upper_lock].clock;
+       {
+               gpu_clk_freq = mali_dvfs_infotbl[mali_dvfs_status_current.upper_lock].clock;
+       }
        spin_unlock_irqrestore(&mali_dvfs_spinlock, flags);
 #endif
-       return locked_level;
+       return gpu_clk_freq;
 }
 
 int mali_get_dvfs_under_locked_freq(void)
 {
        unsigned long flags;
-       int locked_level = -1;
+       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)
-               locked_level = mali_dvfs_infotbl[mali_dvfs_status_current.under_lock].clock;
+       {
+               gpu_clk_freq = mali_dvfs_infotbl[mali_dvfs_status_current.under_lock].clock;
+       }
        spin_unlock_irqrestore(&mali_dvfs_spinlock, flags);
 #endif
-       return locked_level;
+       return gpu_clk_freq;
 }
 
 int mali_get_dvfs_current_level(void)
@@ -562,15 +706,22 @@ 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) {
+
+       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
@@ -633,12 +784,12 @@ void kbase_platform_dvfs_set_clock(struct kbase_device *kbdev, int freq)
                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;
@@ -648,6 +799,7 @@ int kbase_platform_dvfs_get_level(int freq)
        }
        return -1;
 }
+
 void kbase_platform_dvfs_set_level(struct kbase_device *kbdev, int level)
 {
        static int prev_level = -1;
@@ -672,8 +824,10 @@ void kbase_platform_dvfs_set_level(struct kbase_device *kbdev, int level)
        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;
@@ -684,29 +838,38 @@ void kbase_platform_dvfs_set_level(struct kbase_device *kbdev, int level)
 
 #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;
-       static u64 prev_time=0;
 
        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;
+       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)
+ssize_t show_time_in_state(struct device *dev,
+                          struct device_attribute *attr,
+                          char *buf)
 {
        struct kbase_device *kbdev;
        ssize_t ret = 0;
@@ -718,12 +881,35 @@ ssize_t show_time_in_state(struct device *dev, struct device_attribute *attr,
        update_time_in_state(mali_dvfs_status_current.step);
 #endif
        if (!kbdev)
+       {
                return -ENODEV;
+       }
 
-       for (i = 0; i < MALI_DVFS_STEP; i++)
-               ret += snprintf(buf + ret, PAGE_SIZE - ret,
-                                               "%d %llu\n",
-                                               mali_dvfs_infotbl[i].clock, mali_dvfs_infotbl[i].time);
+       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");
@@ -741,8 +927,13 @@ ssize_t set_time_in_state(struct device *dev, struct device_attribute *attr,
 {
        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;
index 52167d362cc59d91ded5a990057a5ea5c911792d..8d885c8e83f2ee94e8914a6795caf110cf8c28fc 100755 (executable)
 /**
  * @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_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;
 
@@ -41,28 +77,96 @@ extern unsigned int MALI_DVFS_STEP;
 #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);
 
index 340f376332c416302089b2b2e5baf76bd84435a6..226bddd927c37bb16c07351f25cae31a14f439aa 100755 (executable)
@@ -9,8 +9,10 @@
 
 /**
  * @file mali_kbase_platform.c
- * Platform-dependent init.
+ * 
+ * 对 mali_kbase_platform.h 声明的 pm, clk 等接口的具体实现. 
  */
+
 #include <mali_kbase.h>
 #include <mali_kbase_pm.h>
 #include <mali_kbase_uku.h>
@@ -43,6 +45,7 @@
 
 #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;
+// u32 kbase_group_error = 0;
 static struct kobject *rk_gpu;
 
-int mali_dvfs_clk_set(struct dvfs_node *node,unsigned long rate)
+int mali_dvfs_clk_set(struct dvfs_node *node, unsigned long rate)
 {
        int ret = 0;
        if(!node)
@@ -64,6 +78,7 @@ int mali_dvfs_clk_set(struct dvfs_node *node,unsigned long rate)
                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)
        {
@@ -71,6 +86,10 @@ int mali_dvfs_clk_set(struct dvfs_node *node,unsigned long rate)
        }
        return ret;
 }
+
+/**
+ * 初始化和 gpu_pm 和 gpu_clk.
+ */
 static int kbase_platform_power_clock_init(struct kbase_device *kbdev)
 {
        /*struct device *dev = kbdev->dev;*/
@@ -108,9 +127,9 @@ static int kbase_platform_power_clock_init(struct kbase_device *kbdev)
                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_dvfs_clk_set(platform->mali_clk_node, MALI_T7XX_DEFAULT_CLOCK);
        mali_clk_status = 1;
+
        return 0;
        
 out:
@@ -120,6 +139,7 @@ out:
        return -EPERM;
 
 }
+
 int kbase_platform_clock_off(struct kbase_device *kbdev)
 {
        struct rk_context *platform;
@@ -161,6 +181,7 @@ int kbase_platform_clock_on(struct kbase_device *kbdev)
 
        return 0;
 }
+
 int kbase_platform_is_power_on(void)
 {
        return mali_pd_status;
@@ -212,6 +233,7 @@ int kbase_platform_power_off(struct kbase_device *kbdev)
        return 0;
 }
 
+
 int kbase_platform_cmu_pmu_control(struct kbase_device *kbdev, int control)
 {
        unsigned long flags;
@@ -228,33 +250,45 @@ int kbase_platform_cmu_pmu_control(struct kbase_device *kbdev, int control)
        /* 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 
+       else /* on */
        {
-               /* 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");
@@ -265,31 +299,110 @@ int kbase_platform_cmu_pmu_control(struct kbase_device *kbdev, int control)
        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_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, "%d\n", kbdev->kbase_group_error);
+       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;
+       unsigned int clkrate = 0;       // 从 dvfs_module 获取的 gpu_clk_freq, Hz 为单位.
        int i ;
        kbdev = dev_get_drvdata(dev);
 
@@ -306,16 +419,27 @@ static ssize_t show_clock(struct device *dev, struct device_attribute *attr, cha
                return -ENODEV;
        }
        clkrate = dvfs_clk_get_rate(platform->mali_clk_node);
-       ret += snprintf(buf + ret, PAGE_SIZE - ret, "Current clk mali = %dMhz", clkrate / 1000000);
-
+       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 settings:");
-       for(i=0;i<MALI_DVFS_STEP;i++)
-               ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d ",p_mali_dvfs_infotbl[i].clock/1000);
-               ret += snprintf(buf + ret, PAGE_SIZE - ret, "Mhz");
+       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';
@@ -360,6 +484,7 @@ static ssize_t set_clock(struct device *dev, struct device_attribute *attr, cons
        }
 #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;
@@ -377,7 +502,15 @@ static ssize_t show_fbdev(struct device *dev, struct device_attribute *attr, cha
                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);
+       {
+               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");
@@ -611,15 +744,29 @@ static ssize_t show_dvfs(struct device *dev, struct device_attribute *attr, char
        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\nutilisation:%d\ncurrent clock:%dMhz", kbase_platform_dvfs_get_utilisation(),clkrate/1000000);
+       {
+               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,clock:%dMhz",clkrate/1000000);
+       {
+               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");
+       ret += snprintf(buf + ret, PAGE_SIZE - ret, "mali_dvfs is DISABLED");
 #endif
 
        if (ret < PAGE_SIZE - 1)
@@ -647,10 +794,12 @@ static ssize_t set_dvfs(struct device *dev, struct device_attribute *attr, const
        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 {
@@ -668,27 +817,47 @@ static ssize_t show_upper_lock_dvfs(struct device *dev, struct device_attribute
        ssize_t ret = 0;
        int i;
 #ifdef CONFIG_MALI_MIDGARD_DVFS
-       int locked_level = -1;
+       int gpu_clk_freq = 0;
 #endif
 
        kbdev = dev_get_drvdata(dev);
 
        if (!kbdev)
+       {
+               E("err.");
                return -ENODEV;
+       }
 
 #ifdef CONFIG_MALI_MIDGARD_DVFS
-       locked_level = mali_get_dvfs_upper_locked_freq();
-       if (locked_level > 0)
-               ret += snprintf(buf + ret, PAGE_SIZE - ret, "Current Upper Lock Level = %dMhz", locked_level);
+       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, "Unset the Upper Lock Level");
+       {
+               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 settings :");
-       for(i=0;i<MALI_DVFS_STEP;i++)
-               ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d ",p_mali_dvfs_infotbl[i].clock/1000);
-       ret += snprintf(buf + ret, PAGE_SIZE - ret, "Mhz");
-       ret += snprintf(buf + ret, PAGE_SIZE - ret, ", If you want to unlock : 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
@@ -706,16 +875,18 @@ static ssize_t show_upper_lock_dvfs(struct device *dev, struct device_attribute
 
 static ssize_t set_upper_lock_dvfs(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
-       struct kbase_device *kbdev;
+       struct kbase_device *kbdev = NULL;
        int i;
-       unsigned int freq;
-       kbdev = dev_get_drvdata(dev);
-       freq = 0;
+       unsigned int freq = 0;              // 可能由 caller 传入的, 待设置的 gpu_freq_upper_limit.
+        int ret = 0;
 
-       if (!kbdev)
-               return -ENODEV;
+       kbdev = dev_get_drvdata(dev);
 
-freq = simple_strtoul(buf, NULL, 10);
+       if ( NULL == kbdev)
+        {
+                E("'kbdev' is NULL.");
+               return -ENODEV;
+        }
 
 #ifdef CONFIG_MALI_MIDGARD_DVFS
        if (sysfs_streq("off", buf)) 
@@ -724,20 +895,34 @@ freq = simple_strtoul(buf, NULL, 10);
        } 
        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) 
                        {
-                               mali_dvfs_freq_lock(i);
+                                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;
                        }
-                       if(i==MALI_DVFS_STEP)
-                       {
-                               dev_err(dev, "set_clock: invalid value\n");
-                               return -ENOENT;
-                       }
+               }
+               /* 若 "没有" 找到和 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
@@ -751,7 +936,7 @@ static ssize_t show_under_lock_dvfs(struct device *dev, struct device_attribute
        ssize_t ret = 0;
        int i;
 #ifdef CONFIG_MALI_MIDGARD_DVFS
-       int locked_level = -1;
+       int gpu_clk_freq = 0;
 #endif
 
        kbdev = dev_get_drvdata(dev);
@@ -760,18 +945,34 @@ static ssize_t show_under_lock_dvfs(struct device *dev, struct device_attribute
                return -ENODEV;
 
 #ifdef CONFIG_MALI_MIDGARD_DVFS
-       locked_level = mali_get_dvfs_under_locked_freq();
-       if (locked_level > 0)
-               ret += snprintf(buf + ret, PAGE_SIZE - ret, "Current Under Lock Level = %dMhz", locked_level);
+       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, "Unset the Under Lock Level");
+       {
+               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 settings :");
-       for(i=0;i<MALI_DVFS_STEP;i++)
-               ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d ",p_mali_dvfs_infotbl[i].clock/1000);
-       ret += snprintf(buf + ret, PAGE_SIZE - ret, "Mhz");
-       ret += snprintf(buf + ret, PAGE_SIZE - ret, ", If you want to unlock : 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
@@ -790,35 +991,49 @@ static ssize_t show_under_lock_dvfs(struct device *dev, struct device_attribute
 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;
-       struct kbase_device *kbdev;
-       kbdev = dev_get_drvdata(dev);
-       freq = 0;
+       unsigned int freq = 0;
+       struct kbase_device *kbdev = NULL;
+        int ret = 0;
 
-       if (!kbdev)
+       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_unlock();
+               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) 
                        {
-                               mali_dvfs_freq_lock(i);
+                                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;
                        }
-                       if(i==MALI_DVFS_STEP)
-                       {
-                               dev_err(dev, "set_clock: invalid value\n");
-                               return -ENOENT;
-                       }
+               }
+               /* 若 "没有" 找到和 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
@@ -836,6 +1051,7 @@ DEVICE_ATTR(dvfs, S_IRUGO | S_IWUSR, show_dvfs, set_dvfs);
 DEVICE_ATTR(dvfs_upper_lock, S_IRUGO | S_IWUSR, show_upper_lock_dvfs, set_upper_lock_dvfs);
 DEVICE_ATTR(dvfs_under_lock, S_IRUGO | S_IWUSR, show_under_lock_dvfs, set_under_lock_dvfs);
 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)
 {
@@ -849,12 +1065,12 @@ int kbase_platform_create_sysfs_file(struct device *dev)
                goto out;
        }
 
-    /*  rk_ext : device will crash after "cat /sys/devices/ffa30000.gpu/dtlb".
+       /*  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");
@@ -876,6 +1092,7 @@ int kbase_platform_create_sysfs_file(struct device *dev)
                goto out;
        }
        return 0;
+
  out:
        return -ENOENT;
 }
@@ -902,6 +1119,7 @@ mali_error kbase_platform_init(struct kbase_device *kbdev)
        if (NULL == platform)
                return MALI_ERROR_OUT_OF_MEMORY;
 
+       /* .KP : 将 'rk_context' 关联到 mali_device. */
        kbdev->platform_context = (void *)platform;
 
        platform->cmu_pmu_status = 0;
index e9c4e2ec9a15e901b1b5e90079cd4822e0b90186..8df43236a95013863d505ef4d3a55f6d1dc43e67 100755 (executable)
@@ -8,18 +8,25 @@
 
 /**
  * @file mali_kbase_platform.h
- * Platform-dependent init
+ * // 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 */
@@ -27,7 +34,9 @@ struct rk_context {
        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
@@ -158,20 +167,58 @@ typedef enum
 
 } mali_error;
 
-
-int mali_dvfs_clk_set(struct dvfs_node * node,unsigned long rate);
+/**
+ * 将 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_ */