static int exynos8890_devfreq_int_get_volt_table(struct device *dev, u32 *volt_table, struct exynos_devfreq_data *data) { struct dvfs_rate_volt int_rate_volt[data->max_state]; int table_size; int i; table_size = cal_dfs_get_rate_asv_table(dvfs_int, int_rate_volt); if (!table_size) { dev_err(dev, "failed get ASV table\n"); return -ENODEV; } if (table_size != data->max_state) { dev_err(dev, "ASV table size is not matched\n"); return -ENODEV; } for (i = 0; i < data->max_state; i++) { if (data->opp_list[i].freq != (u32)(int_rate_volt[i].rate)) { dev_err(dev, "Freq tablle is not matched(%u:%u)\n", data->opp_list[i].freq, (u32)int_rate_volt[i].rate); return -EINVAL; } volt_table[i] = (u32)int_rate_volt[i].volt; } return 0; }
static int gpu_dvfs_update_asv_table(struct exynos_context *platform) { int i, voltage, dvfs_table_size; gpu_dvfs_info *dvfs_table; #ifdef CONFIG_PWRCAL struct dvfs_rate_volt g3d_rate_volt[48]; int cal_table_size; int j; dvfs_table = platform->table; dvfs_table_size = platform->table_size; cal_table_size = cal_dfs_get_rate_asv_table(dvfs_g3d, g3d_rate_volt); if (!cal_table_size) GPU_LOG(DVFS_WARNING, DUMMY, 0u, 0u, "Failed get G3D ASV table\n"); for (i = 0; i < dvfs_table_size; i++) { for (j = 0; j < cal_table_size; j++) { if (dvfs_table[i].clock * 1000 == g3d_rate_volt[j].rate) { voltage = g3d_rate_volt[j].volt; if (voltage > 0) { dvfs_table[i].voltage = g3d_rate_volt[j].volt; GPU_LOG(DVFS_WARNING, DUMMY, 0u, 0u, "G3D %dKhz ASV is %duV\n", dvfs_table[i].clock*1000, dvfs_table[i].voltage); } } } } #else DVFS_ASSERT(platform); dvfs_table = platform->table; dvfs_table_size = platform->table_size; for (i = 0; i < dvfs_table_size; i++) { if (platform->dynamic_abb_status) { dvfs_table[i].asv_abb = get_match_abb(ID_G3D, dvfs_table[i].clock*1000); GPU_LOG(DVFS_WARNING, DUMMY, 0u, 0u, "DEVFREQ: %uKhz, ABB %u\n", dvfs_table[i].clock*1000, dvfs_table[i].asv_abb); } voltage = get_match_volt(ID_G3D, dvfs_table[i].clock*1000); if (voltage > 0) dvfs_table[i].voltage = voltage; GPU_LOG(DVFS_WARNING, DUMMY, 0u, 0u, "G3D %dKhz ASV is %duV\n", dvfs_table[i].clock*1000, dvfs_table[i].voltage); } #endif return 0; }
static int exynos_mp_cpufreq_init_cal_table(cluster_type cluster) { int table_size, cl_id, i; struct dvfs_rate_volt *ptr_temp_table; struct exynos_dvfs_info *ptr = exynos_info[cluster]; unsigned int cal_max_freq; unsigned int cal_max_support_idx = ptr->max_support_idx; if (!ptr->freq_table || !ptr->volt_table) { pr_err("%s: freq of volt table is NULL\n", __func__); return -EINVAL; } if (!cluster) cl_id = dvfs_little; else cl_id = dvfs_big; /* allocate to temporary memory for getting table from cal */ ptr_temp_table = kzalloc(sizeof(struct dvfs_rate_volt) * ptr->max_idx_num, GFP_KERNEL); /* check freq_table with cal */ table_size = cal_dfs_get_rate_asv_table(cl_id, ptr_temp_table); if (ptr->max_idx_num != table_size) { pr_err("%s: DT is not matched cal table size\n", __func__); kfree(ptr_temp_table); return -EINVAL; } cal_max_freq = cal_dfs_get_max_freq(cl_id); if (!cal_max_freq) { pr_err("%s: failed get max frequency from PWRCAL\n", __func__); kfree(ptr_temp_table); return -EINVAL; } for (i = 0; i< ptr->max_idx_num; i++) { if (ptr->freq_table[i].frequency != (unsigned int)ptr_temp_table[i].rate) { pr_err("%s: DT is not matched cal frequency_table(dt : %d, cal : %d\n", __func__, ptr->freq_table[i].frequency, (unsigned int)ptr_temp_table[i].rate); kfree(ptr_temp_table); return -EINVAL; } else { /* copy cal voltage to cpufreq driver voltage table */ ptr->volt_table[i] = ptr_temp_table[i].volt; } if (ptr_temp_table[i].rate == cal_max_freq) cal_max_support_idx = i; } pr_info("CPUFREQ of %s CAL max_freq %lu KHz, DT max_freq %lu\n", cluster ? "CL1" : "CL0", ptr_temp_table[cal_max_support_idx].rate, ptr_temp_table[ptr->max_support_idx].rate); /* if (ptr->max_support_idx < cal_max_support_idx) ptr->max_support_idx = cal_max_support_idx; */ pr_info("CPUFREQ of %s Current max freq %lu KHz\n", cluster ? "CL1" : "CL0", ptr_temp_table[ptr->max_support_idx].rate); /* free temporary memory */ kfree(ptr_temp_table); return 0; }