void kbase_platform_dvfs_set_level(kbase_device *kbdev, int level) { static int prev_level = -1; int f; if (level == prev_level) return; if (WARN_ON((level >= MALI_DVFS_STEP)||(level < 0))) panic("invalid level"); #ifdef CONFIG_MALI_T6XX_DVFS mutex_lock(&mali_set_clock_lock); #endif f = mali_dvfs_infotbl[level].mem_freq; if (level > prev_level) { exynos5_bus_mif_update(mem_freq_req, f); kbase_platform_dvfs_set_vol(mali_dvfs_infotbl[level].voltage); kbase_platform_dvfs_set_clock(kbdev, mali_dvfs_infotbl[level].clock); } else { kbase_platform_dvfs_set_clock(kbdev, mali_dvfs_infotbl[level].clock); kbase_platform_dvfs_set_vol(mali_dvfs_infotbl[level].voltage); exynos5_bus_mif_update(mem_freq_req, f); } #if defined(CONFIG_MALI_T6XX_DEBUG_SYS) && defined(CONFIG_MALI_T6XX_DVFS) update_time_in_state(prev_level); #endif prev_level = level; #ifdef CONFIG_MALI_T6XX_DVFS mutex_unlock(&mali_set_clock_lock); #endif }
int kbase_platform_dvfs_enable(bool enable, int freq) { mali_dvfs_status *dvfs_status; struct kbase_device *kbdev; unsigned long flags; struct exynos_context *platform; int f; dvfs_status = &mali_dvfs_status_current; kbdev = mali_dvfs_status_current.kbdev; BUG_ON(kbdev == NULL); platform = (struct exynos_context *)kbdev->platform_context; mutex_lock(&mali_enable_clock_lock); if (enable != kbdev->pm.metrics.timer_active) { if (enable) { spin_lock_irqsave(&kbdev->pm.metrics.lock, flags); kbdev->pm.metrics.timer_active = MALI_TRUE; spin_unlock_irqrestore(&kbdev->pm.metrics.lock, flags); hrtimer_start(&kbdev->pm.metrics.timer, HR_TIMER_DELAY_MSEC(KBASE_PM_DVFS_FREQUENCY), HRTIMER_MODE_REL); f = mali_dvfs_infotbl[dvfs_status->step].mem_freq; exynos5_bus_mif_update(mem_freq_req, f); } else { spin_lock_irqsave(&kbdev->pm.metrics.lock, flags); kbdev->pm.metrics.timer_active = MALI_FALSE; spin_unlock_irqrestore(&kbdev->pm.metrics.lock, flags); hrtimer_cancel(&kbdev->pm.metrics.timer); exynos5_bus_mif_update(mem_freq_req, 0); } } if (freq != MALI_DVFS_CURRENT_FREQ) { spin_lock_irqsave(&mali_dvfs_spinlock, flags); platform->time_tick = 0; platform->time_busy = 0; platform->time_idle = 0; platform->utilisation = 0; dvfs_status->step = kbase_platform_dvfs_get_level(freq); spin_unlock_irqrestore(&mali_dvfs_spinlock, flags); kbase_platform_dvfs_set_level(dvfs_status->kbdev, dvfs_status->step); } mutex_unlock(&mali_enable_clock_lock); return MALI_TRUE; }
static void exynos5250_set_frequency(unsigned int old_index, unsigned int new_index) { /* MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */ clk_set_parent(moutcore, mout_mpll); if (old_index >= new_index) exynos5_bus_mif_update(mif_bus_freq, exynos5250_bus_table[new_index]); clk_set_rate(fout_apll, exynos5250_freq_table[new_index].frequency * 1000); if (old_index < new_index) exynos5_bus_mif_update(mif_bus_freq, exynos5250_bus_table[new_index]); /* MUX_CORE_SEL = APLL */ clk_set_parent(moutcore, mout_apll); }