static s32 cpufreq_governor_dbs(struct cpufreq_policy *policy, u32 event) { s32 cpu = (s32)policy->cpu; struct cpu_dbs_info_s *dbs_info = NULL; u32 retValue = 0; ST_PWC_SWITCH_STRU cpufreq_control_nv = {0} ; /*cpu 信息*/ dbs_info = &per_cpu(g_acpu_dbs_info, (u32)cpu); /*lint --e{744 } */ switch (event) { case CPUFREQ_GOV_START: cpufreq_debug("CPUFREQ_GOV_START\n"); mutex_lock(&dbs_mutex); dbs_enable++; /*cpu 信息初始化 函数??idle_time*/ dbs_info->prev_cpu_idle = get_cpu_idle_time(0, &dbs_info->prev_cpu_wall); dbs_info->cur_policy = policy; dbs_info->cpu = cpu; dbs_info->freq_table = cpufreq_frequency_get_table((u32)cpu); dbs_info->cpu_down_time = 0; dbs_info->cpu_up_time = 0; retValue = bsp_nvm_read(NV_ID_DRV_NV_PWC_SWITCH,(u8*)&cpufreq_control_nv,sizeof(ST_PWC_SWITCH_STRU)); if (NV_OK == retValue) { g_cpufreq_lock_status_flag = cpufreq_control_nv.dfs; } else { cpufreq_err("read nv failed %d\n", retValue); } if (1 == dbs_enable) { retValue = bsp_nvm_read(NV_ID_DRV_NV_DFS_SWITCH,(u8*)&g_stDfsSwitch,sizeof(ST_PWC_DFS_STRU)); if (NV_OK != retValue) { cpufreq_err("read nv failed use default value\n"); g_stDfsSwitch.AcpuDownLimit = 20; g_stDfsSwitch.AcpuDownNum = 3; g_stDfsSwitch.AcpuUpLimit = 80; g_stDfsSwitch.AcpuUpNum = 1; g_stDfsSwitch.DFSTimerLen = 400; } dbs_tuners_ins.up_threshold = g_stDfsSwitch.AcpuUpLimit; dbs_tuners_ins.down_threshold = g_stDfsSwitch.AcpuDownLimit; dbs_tuners_ins.down_threshold_times = g_stDfsSwitch.AcpuDownNum; dbs_tuners_ins.up_threshold_times = g_stDfsSwitch.AcpuUpNum; dbs_tuners_ins.sampling_rate = g_stDfsSwitch.DFSTimerLen * 10000; /*unit:us*/ /* * Start the timerschedule work, when this governor * is used for first time */ register_icc_for_cpufreq(); dbs_timer_init(dbs_info); } mutex_unlock(&dbs_mutex); break; case CPUFREQ_GOV_STOP: dbs_timer_exit(dbs_info); mutex_lock(&dbs_mutex); dbs_enable--; mutex_unlock(&dbs_mutex); break; case CPUFREQ_GOV_LIMITS: mutex_lock(&info_mutex); dbs_info->cpu_down_time = 0; dbs_info->cpu_up_time = 0; mutex_unlock(&info_mutex); if (policy->max < dbs_info->cur_policy->cur) __cpufreq_driver_target(dbs_info->cur_policy, policy->max, CPUFREQ_RELATION_H); else if (policy->min > dbs_info->cur_policy->cur) __cpufreq_driver_target(dbs_info->cur_policy, policy->min, CPUFREQ_RELATION_L); break; } return 0; }
void cpufreq_init(void) { /*lint --e{516}*/ u32 i = 0; u32 retValue = 0; ST_PWC_SWITCH_STRU cpufreq_control_nv = {0} ; retValue = bsp_nvm_read(NV_ID_DRV_NV_DFS_SWITCH,(u8*)&g_stDfsSwitch,sizeof(ST_PWC_DFS_STRU)); if (NV_OK != retValue) { cpufreq_err("read nv failed use default value\n"); g_stDfsSwitch.CcpuDownLimit = 60; g_stDfsSwitch.CcpuDownNum = 3; g_stDfsSwitch.CcpuUpLimit = 85; g_stDfsSwitch.CcpuUpNum = 1; g_stDfsSwitch.DFSTimerLen = 400; g_stDfsSwitch.Strategy = 0;/*使用4s检测一次的策略*/ g_stDfsSwitch.DFSDdrUpLimit = 85; g_stDfsSwitch.DFSDdrDownLimit = 60; g_stDfsSwitch.DFSDdrprofile = 5; g_stDfsSwitch.reserved = 0; } retValue = bsp_nvm_read(NV_ID_DRV_NV_PWC_SWITCH,(u8*)&cpufreq_control_nv,sizeof(ST_PWC_SWITCH_STRU)); if (NV_OK == retValue) { g_cpufreq_lock_status_flag = cpufreq_control_nv.dfs; } else { cpufreq_err("read nv failed %d\n", retValue); } memset(&g_stDfsCpuConfigInfo, 0, sizeof(g_stDfsCpuConfigInfo)); memset(&g_stDfsCpuControl, 0, sizeof(g_stDfsCpuControl)); g_stDfsCpuControl.enCurProfile = BALONG_FREQ_MAX; register_icc_for_cpufreq(); cpufreq_table_init(); #ifdef CONFIG_CCORE_PM if (bsp_device_pm_add(&g_cpufreq_dpm_device)) { cpufreq_err("register dpm failed,check it\n"); } #endif /*bit1 使用MS级调频策略*/ if (g_stDfsSwitch.Strategy & 0x1) { g_sem_calccpu_flag = semBCreate(SEM_Q_PRIORITY, SEM_FULL); /*lint !e64 */ if (NULL == g_sem_calccpu_flag) { cpufreq_err("Create g_sem_k3get_volt Failed %d\n", g_sem_calccpu_flag); } } g_stDfsCpuConfigInfo.ulDFSFunEnableFlag = DFS_TRUE; g_stDfsCpuConfigInfo.usProfileDownTime = g_stDfsSwitch.CcpuDownNum; g_stDfsCpuConfigInfo.usProfileUpTime = g_stDfsSwitch.CcpuUpNum; g_stDfsCpuConfigInfo.ulProfileNum = DC_RESV; g_stDfsCpuConfigInfo.ulTimerLen = g_stDfsSwitch.DFSTimerLen; g_test_in_interr_times = g_stDfsSwitch.DFSTimerLen; for (i = 0; i < g_stDfsCpuConfigInfo.ulProfileNum; i++) { g_stDfsCpuConfigInfo.astThresHold[i].usProfileUpLimit = g_stDfsSwitch.CcpuUpLimit; g_stDfsCpuConfigInfo.astThresHold[i].usProfileDownLimit = g_stDfsSwitch.CcpuDownLimit; } INIT_LIST_HEAD(&(g_v9_qos_list.entry)); /*添加DDR调频请求*/ (void)PWRCTRL_DfsQosRequest(DFS_QOS_ID_DDR_MINFREQ, BALONG_DDRFREQUENCY_MIN, &g_ddr_request_id); taskSpawn("dfs_task", 1, 0, 4096, (FUNCPTR)pwrctrl_dfs_mgrmsg_task, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);/*lint !e64 !e119 */ g_cpufreq_start_time = bsp_get_slice_value(); cpufreq_err("cpufreq init ok\n"); return; }