[MTK] Boost CPU/DDR/GPU in android code

文摘 Kernel MediaTek 2020-05-29 阅读:1971

[DESCRIPTION]

    为了追求性能,客户有时候想在特定场景中拉满CPU/DDR/GPU,比如亮屏/解锁等场景。以下提供一种在代码中boost CPU/DDR/GPU的方法。

[SOLUTION]

 1. Kernel 代码里拉CPU频率
     可以参考 kernel-4.*/drivers/misc/mediatek/usb_boost/v1/usb_boost_plat.c
     1). 包含头文件

           #include "mtk_ppm_api.h"
           #include "cpu_ctrl.h"
           #define BSP_CERVINO_CLUSTER_NUMBERS 2

      2). 在您的 driver 问中添加

            struct ppm_limit_data fingerprint_freq_to_set[BSP_CERVINO_CLUSTER_NUMBERS];
            struct ppm_limit_data fingerprint_freq_to_release[BSP_CERVINO_CLUSTER_NUMBERS];

            static int fingerprint_freq_set(void)
            {
                  int i, cluster_num;

                  cluster_num = arch_get_nr_clusters();
                  if(cluster_num > BSP_CERVINO_CLUSTER_NUMBERS)
                        cluster_num = BSP_CERVINO_CLUSTER_NUMBERS;

                  for (i = 0; i < BSP_CERVINO_CLUSTER_NUMBERS; i++) {
                        fingerprint_freq_to_set[i].min = 2001000;
                        fingerprint_freq_to_set[i].max = -1;
                  }

                   if(cluster_num > 0){
                        update_userlimit_cpu_freq(CPU_KIR_FINGERPRINT, cluster_num, fingerprint_freq_to_set);
                        return 0;
                   }
                   return -1;
            }

            static int fingerprint_freq_release(void)
            {
                 int i,cluster_num;

                 cluster_num = arch_get_nr_clusters();
                 if(cluster_num > BSP_CERVINO_CLUSTER_NUMBERS)
                       cluster_num = BSP_CERVINO_CLUSTER_NUMBERS;

                 for (i = 0; i < BSP_CERVINO_CLUSTER_NUMBERS; i++) {
                       fingerprint_freq_to_release[i].min = -1;
                       fingerprint_freq_to_release[i].max = -1;
                 }

                 if(cluster_num > 0){
                      update_userlimit_cpu_freq(CPU_KIR_FINGERPRINT, cluster_num, fingerprint_freq_to_release);
                      return 0;
                 }
                 return -1;
            }

            在您需要的地方 调 fingerprint_freq_set() 去拉 CPU频率;
            不需要拉的时候,必须恢复默认配置,释放拉的动作:调 fingerprint_freq_release() 去释放 CPU频率。

             set 和 release 必须要对比,否则会引起功耗问题。

     3). 在 kernel-4.×/drivers/misc/mediatek/include/mt-plat/cpu_ctrl.h 中添加

            enum {
                        CPU_KIR_PERF = 0,
                        CPU_KIR_FPSGO,
                        CPU_KIR_WIFI,
                        CPU_KIR_BOOT,
                        CPU_KIR_TOUCH,
                        CPU_KIR_PERFTOUCH,
                        CPU_KIR_USB,
                        + CPU_KIR_FINGERPRINT,
                        CPU_MAX_KIR
            };

 2. 拉DDR频率也可以参考刚刚这个文件 kernel-4.14/drivers/misc/mediatek/usb_boost/v1/usb_boost_plat.c

     1) Makefile:
          ccflags-y += -I$(srctree)/drivers/devfreq/

     2) kernel usage:
          #include <linux/pm_qos.h>
          #include "helio-dvfsrc-opp.h"

          static struct pm_qos_request xxx_ddr_req;

          pm_qos_add_request(&xxx_ddr_req, PM_QOS_DDR_OPP_DEFAULT_VALUE);

          pm_qos_update_request(&xxx_ddr_req, DDR_OPP_0); //LP4-3200, LP3-1866, 最高檔
          pm_qos_update_request(&xxx_ddr_req, DDR_OPP_1); //LP4-2400, LP3-1600 or above
          pm_qos_update_request(&xxx_ddr_req, DDR_OPP_3); //LP4-1600, LP3-1200 or above

          pm_qos_update_request(&xxx_ddr_req, DDR_OPP_UNREQ); //un-request, or PM_QOS_DDR_OPP_DEFAULT_VALUE

          可以参考:
          static int vcorefs_hold(struct act_arg_obj *arg)
          {
                    pm_qos_update_request(&pm_qos_ddr_req, DDR_OPP_0);
                    return 0;
          }

          static int vcorefs_release(struct act_arg_obj *arg)
          {
                    pm_qos_update_request(&pm_qos_ddr_req, DDR_OPP_UNREQ);
                    return 0;
          }

          vcorefs_hold 和 vcorefs_release要对应起来,否则会有power问题。

 3. kernel中暂时不提供拉GPU的接口,但在HAL/JNI/Java等上层代码可以boost GPU,见第4条。

 4. 如果要在HAL/JNI/Java等上层代码boost CPU/GPU/DDR,请自行在MTK-online上搜Power Hal文档参考修改,里面有完整的 .cpp/.java修改说明。
          android Q:  MTK_PowerHal_Q0_Porting_Guide
          android P:  MTK_P0_BSP+_PowerHalService_Programming_Guide
          android O:  MTK_O1_BSP+_PowerHalService_Programming_Guide
         每个android版本对应的API接口是一样,请下载对应版本的文档来参考。

     1) 以android Q0为例,如何在 HAL/JNI/等上层代码上boost CPU/GPU/DDR

         you can refer to "MTK_PowerHal_Q0_Porting_Guide" about powerHAl customization, you can search this document on MTK-ON-LINE

         a. int perf_lock_acq(int handle, int duration, int list[], int numArgs)
             handle:
             user handle
             If handle is 0 or invalid value => register a new handle. Please always check return value.

             duration:
             boost duration: unit: ms
             Set duration to 0 for infinite time

             list[]:
             opcode value list
             Please refer to vendor/mediatek/proprietary/hardware/power/include/mtkperf_resource.h

             numArgs:
             Length of list[]
             It should be (resource size * 2)

         b. int perf_lock_rel(int handle)
             Handle:
             handle to release

         c. Please refer to vendor/mediatek/proprietary/hardware/power/test/test_v_1_0
             int perf_lock_rsc1[] = {PERF_RES_CPUFREQ_MIN_CLUSTER_0, 1000000, PERF_RES_CPUFREQ_MIN_CLUSTER_1, 3000000, PERF_RES_DRAM_OPP_MIN, 0};
             int perf_lock_rsc2[] = {PERF_RES_CPUFREQ_MIN_CLUSTER_0, 3000000, PERF_RES_CPUFREQ_MIN_CLUSTER_1, 1000000, PERF_RES_DRAM_OPP_MIN, 0};

             /* such as sample 1*/
             int perf_lock_opts[4] = {PERF_RES_CPUFREQ_PERF_MODE, 1, PERF_RES_DRAM_OPP_MIN, 0}; // force all cpu run at the highest freq and DRAM max
             perf_lock_hdl = 0; // perf_lock_hdl should be 0 when allocate a new lock

             perf_lock_hdl = perf_lock_acq(perf_lock_hdl, 3000, perf_lock_opts, 4); // boost time 3000ms
             //............

             perf_lock_rel(perf_lock_hdl);

             /* sample 2*/
             android::hardware::hidl_vec<int32_t> perf_lock_rsc[6] = {PERF_RES_CPUFREQ_MIN_CLUSTER_0, 4, PERF_RES_CPUFREQ_MIN_CLUSTER_1, 4, PERF_RES_DRAM_VCORE_MIN, 0}; // CPU freq index 4, Dram index 0, 0 is the max feq

             perf_lock_hdl = gMtkPerf->perfLockAcquire (perf_lock_hdl, 3000, perf_lock_opts, debug_info); // duration: 3000ms
             //...........
             gMtkPerf->perfLockRelease (perf_lock_hdl);

     2) 默认代码你可以参考:
         vendor/mediatek/proprietary/hardware/power/test/test_v_1_0/power_native_test.cpp

         PERF_RES_GPU_FREQ_MIN                  //GPU最低档位
         PERF_RES_CPUCORE_MIN_CLUSTER_0 //CPU online数

         // 设置4个CPU online + GPU频率最高
         int perf_lock_opts[4] = {PERF_RES_CPUFREQ_MIN_CLUSTER_0, 4, PERF_RES_GPU_FREQ_MIN, 0};
         // GPU频率配置为0,表示最高档位,即配置GPU频率最高。 你需要看GPU的频率500500对应的是什么档,如果是最高档位,设置为0即可
         ................
         perf_lock_hdl = perf_lock_acq(perf_lock_hdl, 3000, perf_lock_opts, 4); // duration timeout: 3000ms
         //...................
         perf_lock_rel(perf_lock_hdl);

         // 如果你要设置 CPU频率也是最高,可以这样配置:
         int perf_lock_opts[4] = {PERF_RES_CPUFREQ_MIN_CLUSTER_0, 4, PERF_RES_CPUFREQ_MIN_CLUSTER_0, 3000000, PERF_RES_GPU_FREQ_MIN, 0};
         ................
         perf_lock_hdl = perf_lock_acq(perf_lock_hdl, 3000, perf_lock_opts, 6);
         ...................
         perf_lock_rel(perf_lock_hdl);


0条评论

© 2020 芯缘异码. Powered by Typecho