static int gpu_dvfs_on_off(struct kbase_device *kbdev, bool enable) { unsigned long flags; struct exynos_context *platform = (struct exynos_context *)kbdev->platform_context; if (!platform) return -ENODEV; if (enable && !platform->dvfs_status) { platform->dvfs_status = true; gpu_control_state_set(kbdev, GPU_CONTROL_CHANGE_CLK_VOL, platform->cur_clock); gpu_dvfs_handler_init(kbdev); if (!kbdev->pm.metrics.timer_active) { spin_lock_irqsave(&kbdev->pm.metrics.lock, flags); kbdev->pm.metrics.timer_active = true; spin_unlock_irqrestore(&kbdev->pm.metrics.lock, flags); hrtimer_start(&kbdev->pm.metrics.timer, HR_TIMER_DELAY_MSEC(platform->polling_speed), HRTIMER_MODE_REL); } } else if (!enable && platform->dvfs_status) { platform->dvfs_status = false; gpu_dvfs_handler_deinit(kbdev); gpu_control_state_set(kbdev, GPU_CONTROL_CHANGE_CLK_VOL, MALI_DVFS_BL_CONFIG_FREQ); if (kbdev->pm.metrics.timer_active) { spin_lock_irqsave(&kbdev->pm.metrics.lock, flags); kbdev->pm.metrics.timer_active = false; spin_unlock_irqrestore(&kbdev->pm.metrics.lock, flags); hrtimer_cancel(&kbdev->pm.metrics.timer); } } else { GPU_LOG(DVFS_WARNING, "impossible state to change dvfs status (current: %d, request: %d)\n", platform->dvfs_status, enable); return -1; } return 0; }
int gpu_dvfs_on_off(bool enable) { struct kbase_device *kbdev = pkbdev; struct exynos_context *platform = (struct exynos_context *)kbdev->platform_context; DVFS_ASSERT(platform); if (enable && !platform->dvfs_status) { mutex_lock(&platform->gpu_dvfs_handler_lock); gpu_set_target_clk_vol(platform->cur_clock, false); gpu_dvfs_handler_init(kbdev); mutex_unlock(&platform->gpu_dvfs_handler_lock); gpu_dvfs_timer_control(true); } else if (!enable && platform->dvfs_status) { gpu_dvfs_timer_control(false); mutex_lock(&platform->gpu_dvfs_handler_lock); gpu_dvfs_handler_deinit(kbdev); gpu_set_target_clk_vol(platform->gpu_dvfs_config_clock, false); mutex_unlock(&platform->gpu_dvfs_handler_lock); } else { GPU_LOG(DVFS_WARNING, DUMMY, 0u, 0u, "%s: impossible state to change dvfs status (current: %d, request: %d)\n", __func__, platform->dvfs_status, enable); return -1; } return 0; }
/** ** Exynos5 hardware specific termination **/ static void kbase_platform_exynos5_term(struct kbase_device *kbdev) { struct exynos_context *platform; platform = (struct exynos_context *) kbdev->platform_context; gpu_notifier_term(); #ifdef CONFIG_MALI_DVFS gpu_dvfs_handler_deinit(kbdev); #endif /* CONFIG_MALI_DVFS */ gpu_dvfs_utilization_deinit(kbdev); gpu_control_module_term(kbdev); kfree(kbdev->platform_context); kbdev->platform_context = 0; #ifdef CONFIG_MALI_DEBUG_SYS gpu_remove_sysfs_file(kbdev->dev); #endif /* CONFIG_MALI_DEBUG_SYS */ }