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;
}
Ejemplo n.º 2
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;
}