static int gpu_set_clk_vol(struct kbase_device *kbdev, int clock, int voltage) { static int prev_clock = -1; struct exynos_context *platform = (struct exynos_context *) kbdev->platform_context; if (!platform) return -ENODEV; if ((clock > platform->table[platform->table_size-1].clock) || (clock < platform->table[0].clock)) { GPU_LOG(DVFS_ERROR, "Mismatch clock error (%d)\n", clock); return -1; } if (clock > prev_clock) { gpu_set_voltage(platform, voltage + platform->voltage_margin); #if SOC_NAME == 5260 set_match_abb(ID_G3D, platform->devfreq_g3d_asv_abb[platform->step]); #endif /* SOC_NAME */ gpu_set_clock(platform, clock); } else { gpu_set_clock(platform, clock); #if SOC_NAME == 5260 set_match_abb(ID_G3D, platform->devfreq_g3d_asv_abb[platform->step]); #endif /* SOC_NAME */ gpu_set_voltage(platform, voltage + platform->voltage_margin); } GPU_LOG(DVFS_INFO, "[G3D] clock changed [%d -> %d]\n", prev_clock, clock); gpu_dvfs_handler_control(kbdev, GPU_HANDLER_UPDATE_TIME_IN_STATE, prev_clock); prev_clock = clock; return 0; }
static int gpu_set_voltage_post(struct exynos_context *platform, bool is_up) { if (!platform) return -ENODEV; if (is_up && platform->dynamic_abb_status) set_match_abb(ID_G3D, gpu_dvfs_get_cur_asv_abb()); return 0; }
static int gpu_set_clk_vol(struct kbase_device *kbdev, int clock, int voltage) { static int prev_clock = -1; struct exynos_context *platform = (struct exynos_context *)kbdev->platform_context; if (!platform) return -ENODEV; if ((clock > platform->table[platform->table_size-1].clock) || (clock < platform->table[0].clock)) { GPU_LOG(DVFS_ERROR, "Mismatch clock error (%d)\n", clock); return -1; } if (platform->voltage_margin) voltage = MAX(voltage + platform->voltage_margin, COLD_MINIMUM_VOL); if (clock > prev_clock) { gpu_set_voltage(platform, voltage); #ifdef CONFIG_DYNIMIC_ABB set_match_abb(ID_G3D, platform->devfreq_g3d_asv_abb[platform->step]); #endif gpu_set_clock(platform, clock); #if defined(CONFIG_EXYNOS5422_BTS) bts_scen_update(TYPE_G3D_FREQ, clock); #endif /* CONFIG_EXYNOS5422_BTS */ } else { #if defined(CONFIG_EXYNOS5422_BTS) bts_scen_update(TYPE_G3D_FREQ, clock); #endif /* CONFIG_EXYNOS5422_BTS */ gpu_set_clock(platform, clock); #ifdef CONFIG_DYNIMIC_ABB set_match_abb(ID_G3D, platform->devfreq_g3d_asv_abb[platform->step]); #endif gpu_set_voltage(platform, voltage); } GPU_LOG(DVFS_INFO, "[G3D]clk[%d -> %d], vol[%d + %d]\n", prev_clock, clock, voltage, platform->voltage_margin); gpu_dvfs_handler_control(kbdev, GPU_HANDLER_UPDATE_TIME_IN_STATE, prev_clock); prev_clock = clock; return 0; }
int gpu_disable_dvs(struct exynos_context *platform) { if (!platform->dvs_status) return 0; if (!cal_get_fs_abb()) { if (set_match_abb(ID_G3D, gpu_dvfs_get_cur_asv_abb())) { GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to restore RBB setting\n", __func__); return -1; } } #if defined(CONFIG_REGULATOR_S2MPS13) if (s2m_set_dvs_pin(false) != 0) { GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to disable dvs\n", __func__); return -1; } #endif /* CONFIG_REGULATOR_S2MPS13 */ GPU_LOG(DVFS_INFO, DUMMY, 0u, 0u, "dvs is disabled (vol: %d)\n", gpu_get_cur_voltage(platform)); return 0; }
static int exynos5_devfreq_int_target(struct device *dev, unsigned long *target_freq, u32 flags) { int ret = 0; struct platform_device *pdev = container_of(dev, struct platform_device, dev); struct devfreq_data_int *data = platform_get_drvdata(pdev); struct devfreq *devfreq_int = data->devfreq; struct opp *target_opp; int target_idx, old_idx; unsigned long target_volt; unsigned long old_freq; mutex_lock(&data->lock); rcu_read_lock(); target_opp = devfreq_recommended_opp(dev, target_freq, flags); if (IS_ERR(target_opp)) { rcu_read_unlock(); mutex_unlock(&data->lock); dev_err(dev, "DEVFREQ(INT) : Invalid OPP to find\n"); ret = PTR_ERR(target_opp); goto out; } *target_freq = opp_get_freq(target_opp); target_volt = opp_get_voltage(target_opp); #ifdef CONFIG_EXYNOS_THERMAL target_volt = get_limit_voltage(target_volt, data->volt_offset); #endif /* just want to save voltage before apply constraint with isp */ data->target_volt = target_volt; if (target_volt < data->volt_constraint_isp) target_volt = data->volt_constraint_isp; rcu_read_unlock(); target_idx = exynos5_devfreq_get_idx(devfreq_int_opp_list, data->max_state, *target_freq); old_idx = exynos5_devfreq_get_idx(devfreq_int_opp_list, data->max_state, devfreq_int->previous_freq); old_freq = devfreq_int->previous_freq; if (target_idx < 0 || old_idx < 0) { ret = -EINVAL; goto out; } if (old_freq == *target_freq) goto out; pr_debug("INT %lu ===================> %lu\n", old_freq, *target_freq); if (old_freq < *target_freq) { if (data->int_set_volt) data->int_set_volt(data, target_volt, target_volt + VOLT_STEP); set_match_abb(ID_INT, data->int_asv_abb_table[target_idx]); if (data->int_set_freq) data->int_set_freq(data, target_idx, old_idx); } else { if (data->int_set_freq) data->int_set_freq(data, target_idx, old_idx); set_match_abb(ID_INT, data->int_asv_abb_table[target_idx]); if (data->int_set_volt) data->int_set_volt(data, target_volt, target_volt + VOLT_STEP); } out: mutex_unlock(&data->lock); return ret; }