#include #define max(x, y) \ (((x) > (y)) ? (x) : (y)) #define min(x, y) \ (((x) < (y)) ? (x) : (y)) #define clamp(val, lo, hi) \ ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val))) #define PROC_NAME "proc" #define SRAM_NAME "sram" #define PROC_ID 0 #define SRAM_ID 1 #define proc_reg PROC_ID #define sram_reg SRAM_ID #define LIST_CSIZE 8 const char *reg_name_list[] = { PROC_NAME, SRAM_NAME }; const int proc_volt_list[LIST_CSIZE] = { 1310000, 1250000, 1200000, 1150000, 1100000, 1050000, 1000000, 950000 }; const int sram_volt_list[LIST_CSIZE] = { 1400000, 1350000, 1300000, 1250000, 1200000, 1150000, 1100000, 1050000 }; int proc_volt = -1; int sram_volt = -1; struct mtk_cpufreq_platform_data { int min_volt_shift; int max_volt_shift; int proc_max_volt; int sram_min_volt; int sram_max_volt; }; struct mtk_cpu_dvfs_info { const struct mtk_cpufreq_platform_data *soc_data; }; static int regulator_get_voltage(int reg_id) { if (reg_id == PROC_ID) return proc_volt; else if (reg_id == SRAM_ID) return sram_volt; printf("### [%s] reg_id: %d not available\n", __func__, reg_id); return -1; } static int check_sram_valid(int volt) { int found = 0; for (int i = 0; i < LIST_CSIZE; ++i) if (volt == sram_volt_list[i]) { found = 1; break; } return found; } static int regulator_set_voltage(int reg_id, int min_uv, int max_uv) { int ret = 0; if (reg_id == PROC_ID) { proc_volt = min_uv; printf("### [%s] set %s volt %d/%d uV\n", __func__, reg_name_list[reg_id], min_uv, max_uv); } else if (reg_id == SRAM_ID) { if (check_sram_valid(min_uv)) { sram_volt = min_uv; printf("### [%s] set %s volt %d/%d uV\n", __func__, reg_name_list[reg_id], min_uv, max_uv); } else { ret = -1; printf("!!! [%s] set %s volt %d uV is not valid\n", __func__, reg_name_list[reg_id], min_uv); } } else ret = -1; return ret; } static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info, int new_vproc) { const struct mtk_cpufreq_platform_data *soc_data = info->soc_data; // struct regulator *proc_reg = info->proc_reg; // struct regulator *sram_reg = info->sram_reg; int pre_vproc, pre_vsram, new_vsram, vsram, vproc, ret; // int retry = info->vtrack_max; pre_vproc = regulator_get_voltage(proc_reg); // if (pre_vproc < 0) { // dev_err(info->cpu_dev, // "invalid Vproc value: %d\n", pre_vproc); // return pre_vproc; // } pre_vsram = regulator_get_voltage(sram_reg); // if (pre_vsram < 0) { // dev_err(info->cpu_dev, "invalid Vsram value: %d\n", pre_vsram); // return pre_vsram; // } new_vsram = clamp(new_vproc + soc_data->min_volt_shift, soc_data->sram_min_volt, soc_data->sram_max_volt); printf("## [%s] target vproc: %d; vsram: %d\n", __func__, new_vproc, new_vsram); do { if (pre_vproc <= new_vproc) { vsram = clamp(pre_vproc + soc_data->max_volt_shift, soc_data->sram_min_volt, new_vsram); ret = regulator_set_voltage(sram_reg, vsram, soc_data->sram_max_volt); if (ret) return ret; if (vsram == soc_data->sram_max_volt || new_vsram == soc_data->sram_min_volt) vproc = new_vproc; else vproc = vsram - soc_data->min_volt_shift; ret = regulator_set_voltage(proc_reg, vproc, soc_data->proc_max_volt); if (ret) { regulator_set_voltage(sram_reg, pre_vsram, soc_data->sram_max_volt); return ret; } } else if (pre_vproc > new_vproc) { vproc = max(new_vproc, pre_vsram - soc_data->max_volt_shift); ret = regulator_set_voltage(proc_reg, vproc, soc_data->proc_max_volt); if (ret) return ret; if (vproc == new_vproc) vsram = new_vsram; else vsram = max(new_vsram, vproc + soc_data->min_volt_shift); ret = regulator_set_voltage(sram_reg, vsram, soc_data->sram_max_volt); if (ret) { regulator_set_voltage(proc_reg, pre_vproc, soc_data->proc_max_volt); return ret; } } pre_vproc = vproc; pre_vsram = vsram; // if (--retry < 0) { // dev_err(info->cpu_dev, // "over loop count, failed to set voltage\n"); // return -EINVAL; // } } while (vproc != new_vproc || vsram != new_vsram); return 0; } int main(void) { struct mtk_cpufreq_platform_data soc_data = { .min_volt_shift = 100000, .max_volt_shift = 200000, .proc_max_volt = 1310000, .sram_min_volt = 0, .sram_max_volt = 1350000, }; struct mtk_cpu_dvfs_info info = { .soc_data = &soc_data, }; proc_volt = 950000; sram_volt = 1050000; printf("[%s] init setting: \n", __func__); printf("init proc_volt: %d\n", proc_volt); printf("init sram_volt: %d\n", sram_volt); printf("min_volt_shift: %d\n", soc_data.min_volt_shift); printf("max_volt_shift: %d\n", soc_data.max_volt_shift); printf("proc_max_volt : %d\n", soc_data.proc_max_volt ); printf("sram_min_volt : %d\n", soc_data.sram_min_volt ); printf("sram_max_volt : %d\n", soc_data.sram_max_volt ); printf("\n"); printf("##### Test Start #####\n"); int fail_count = 0; for (int i = 0; i < LIST_CSIZE; ++i) { for (int j = 0; j < LIST_CSIZE; ++j) { if (i == j) continue; printf("opp[%d]->[%d]\n", i, j); fail_count += mtk_cpufreq_voltage_tracking(&info, proc_volt_list[i]); fail_count += mtk_cpufreq_voltage_tracking(&info, proc_volt_list[j]); printf("\n"); } } printf("##### Test Result: %s. #####\n", fail_count ? "Failed" : "PASS"); return 0; }