Ejemplo n.º 1
0
static void mali_dvfs_decide_next_level(mali_dvfs_status *dvfs_status)
{
	unsigned long flags;
	struct exynos_context *platform;

	platform = (struct exynos_context *)dvfs_status->kbdev->platform_context;
#ifdef MALI_DVFS_ASV_ENABLE
	if (dvfs_status->asv_status == ASV_STATUS_DISABLE_REQ) {
		dvfs_status->asv_status = mali_dvfs_update_asv(ASV_CMD_DISABLE);
	} else if (dvfs_status->asv_status == ASV_STATUS_NOT_INIT) {
		dvfs_status->asv_status = mali_dvfs_update_asv(ASV_CMD_ENABLE);
	}
#endif
	spin_lock_irqsave(&mali_dvfs_spinlock, flags);

#ifdef CONFIG_EXYNOS_THERMAL
	if (dvfs_status->step == kbase_platform_dvfs_get_level(GPU_MAX_CLK)) {
		dvfs_status->step--;
		goto skip;
	}
#endif

	if (dvfs_status->utilisation > mali_dvfs_infotbl[dvfs_status->step].max_threshold) {
#ifdef PLATFORM_UTILIZATION
		if (dvfs_status->step == kbase_platform_dvfs_get_level(500)) {
			if (platform->utilisation > mali_dvfs_infotbl[dvfs_status->step].max_threshold) {
				dvfs_status->step++;
				DVFS_ASSERT(dvfs_status->step < MALI_DVFS_STEP);
			}
		} else {
#endif
			dvfs_status->step++;
			DVFS_ASSERT(dvfs_status->step < MALI_DVFS_STEP);
#ifdef PLATFORM_UTILIZATION
		}
#endif
	} else if ((dvfs_status->step > 0) &&
			(platform->time_tick == MALI_DVFS_TIME_INTERVAL) &&
			(platform->utilisation < mali_dvfs_infotbl[dvfs_status->step].min_threshold)) {
		DVFS_ASSERT(dvfs_status->step > 0);
		dvfs_status->step--;
	}
#ifdef CONFIG_EXYNOS_THERMAL
skip:
#endif
#ifdef CONFIG_MALI_T6XX_FREQ_LOCK
	if (dvfs_status->min_lock > 0) {
		if (dvfs_status->step < dvfs_status->min_lock)
			dvfs_status->step = dvfs_status->min_lock;
	}

	if ((dvfs_status->max_lock >= 0) && (dvfs_status->step > dvfs_status->max_lock)) {
		dvfs_status->step = dvfs_status->max_lock;
	}
#endif
	spin_unlock_irqrestore(&mali_dvfs_spinlock, flags);

}
static void mali_dvfs_event_proc(struct work_struct *w)
{
	unsigned long flags;
	mali_dvfs_status *dvfs_status;
	struct exynos_context *platform;

	mutex_lock(&mali_enable_clock_lock);
	dvfs_status = &mali_dvfs_status_current;

	if (!kbase_platform_dvfs_get_enable_status()) {
		mutex_unlock(&mali_enable_clock_lock);
		return;
	}

	platform = (struct exynos_context *)dvfs_status->kbdev->platform_context;
#ifdef MALI_DVFS_ASV_ENABLE
	if (dvfs_status->asv_status==ASV_STATUS_DISABLE_REQ) {
		dvfs_status->asv_status=mali_dvfs_update_asv(ASV_CMD_DISABLE);
	} else if (dvfs_status->asv_status==ASV_STATUS_NOT_INIT) {
		dvfs_status->asv_status=mali_dvfs_update_asv(ASV_CMD_ENABLE);
	}
#endif
	spin_lock_irqsave(&mali_dvfs_spinlock, flags);
	if (dvfs_status->utilisation > mali_dvfs_infotbl[dvfs_status->step].max_threshold) {
		if (dvfs_status->step==kbase_platform_dvfs_get_level(450)) {
			if (platform->utilisation > mali_dvfs_infotbl[dvfs_status->step].max_threshold)
				dvfs_status->step++;
			OSK_ASSERT(dvfs_status->step < MALI_DVFS_STEP);
		} else {
			dvfs_status->step++;
			OSK_ASSERT(dvfs_status->step < MALI_DVFS_STEP);
		}
	}else if ((dvfs_status->step>0) &&
			(platform->time_tick == MALI_DVFS_TIME_INTERVAL) &&
			(platform->utilisation < mali_dvfs_infotbl[dvfs_status->step].min_threshold)) {
		OSK_ASSERT(dvfs_status->step > 0);
		dvfs_status->step--;
	}
#ifdef CONFIG_MALI_T6XX_FREQ_LOCK
	if ((dvfs_status->upper_lock >= 0)&&(dvfs_status->step > dvfs_status->upper_lock)) {
		dvfs_status->step = dvfs_status->upper_lock;
	}
	if (dvfs_status->under_lock > 0) {
		if (dvfs_status->step < dvfs_status->under_lock)
			dvfs_status->step = dvfs_status->under_lock;
	}
#endif
	spin_unlock_irqrestore(&mali_dvfs_spinlock, flags);

	kbase_platform_dvfs_set_level(dvfs_status->kbdev, dvfs_status->step);

	mutex_unlock(&mali_enable_clock_lock);
}