void kbase_pm_term(kbase_device *kbdev) { unsigned long flags; OSK_ASSERT(kbdev != NULL); OSK_ASSERT(kbdev->pm.active_count == 0); OSK_ASSERT(kbdev->pm.gpu_cycle_counter_requests == 0); /* Destroy the workqueue - this ensures that all messages have been processed */ destroy_workqueue(kbdev->pm.workqueue); if (kbdev->pm.current_policy != NULL) { /* Free any resources the policy allocated */ KBASE_TRACE_ADD( kbdev, PM_CURRENT_POLICY_TERM, NULL, NULL, 0u, kbdev->pm.current_policy->id ); kbdev->pm.current_policy->term(kbdev); } /* Synchronise with other threads */ spin_lock_irqsave(&kbdev->pm.power_change_lock, flags); spin_unlock_irqrestore(&kbdev->pm.power_change_lock, flags); /* Shut down the metrics subsystem */ kbasep_pm_metrics_term(kbdev); }
mali_error kbase_pm_init(kbase_device *kbdev) { mali_error ret = MALI_ERROR_NONE; kbase_pm_callback_conf *callbacks; OSK_ASSERT(kbdev != NULL); kbdev->pm.gpu_powered = MALI_FALSE; atomic_set(&kbdev->pm.gpu_in_desired_state, MALI_TRUE); callbacks = (kbase_pm_callback_conf*) kbasep_get_config_value(kbdev, kbdev->config_attributes, KBASE_CONFIG_ATTR_POWER_MANAGEMENT_CALLBACKS); if (callbacks) { kbdev->pm.callback_power_on = callbacks->power_on_callback; kbdev->pm.callback_power_off = callbacks->power_off_callback; kbdev->pm.callback_power_runtime_init = callbacks->power_runtime_init_callback; kbdev->pm.callback_power_runtime_term = callbacks->power_runtime_term_callback; kbdev->pm.callback_power_runtime_on = callbacks->power_runtime_on_callback; kbdev->pm.callback_power_runtime_off = callbacks->power_runtime_off_callback; } else { kbdev->pm.callback_power_on = NULL; kbdev->pm.callback_power_off = NULL; kbdev->pm.callback_power_runtime_init = NULL; kbdev->pm.callback_power_runtime_term = NULL; kbdev->pm.callback_power_runtime_on = NULL; kbdev->pm.callback_power_runtime_off = NULL; } /* Initialise the metrics subsystem */ ret = kbasep_pm_metrics_init(kbdev); if (MALI_ERROR_NONE != ret) { return ret; } init_waitqueue_head(&kbdev->pm.l2_powered_wait); kbdev->pm.l2_powered = 0; init_waitqueue_head(&kbdev->pm.power_state_wait); kbdev->pm.power_state = PM_POWER_STATE_TRANS; init_waitqueue_head(&kbdev->pm.no_outstanding_event_wait); kbdev->pm.no_outstanding_event = 1; /* Simulate failure to create the workqueue */ if(OSK_SIMULATE_FAILURE(OSK_BASE_PM)) { kbdev->pm.workqueue = NULL; goto workq_fail; } kbdev->pm.workqueue = alloc_workqueue("kbase_pm", WQ_NON_REENTRANT | WQ_HIGHPRI | WQ_MEM_RECLAIM, 1); if (NULL == kbdev->pm.workqueue) { goto workq_fail; } spin_lock_init(&kbdev->pm.power_change_lock); spin_lock_init(&kbdev->pm.active_count_lock); spin_lock_init(&kbdev->pm.gpu_cycle_counter_requests_lock); spin_lock_init(&kbdev->pm.gpu_powered_lock); return MALI_ERROR_NONE; workq_fail: kbasep_pm_metrics_term(kbdev); return MALI_ERROR_FUNCTION_FAILED; }
mali_error kbase_pm_init(kbase_device *kbdev) { mali_error ret = MALI_ERROR_NONE; kbase_pm_callback_conf *callbacks; KBASE_DEBUG_ASSERT(kbdev != NULL); mutex_init(&kbdev->pm.lock); kbdev->pm.gpu_powered = MALI_FALSE; kbdev->pm.suspending = MALI_FALSE; #ifdef CONFIG_MALI_DEBUG kbdev->pm.driver_ready_for_irqs = MALI_FALSE; #endif /* CONFIG_MALI_DEBUG */ kbdev->pm.gpu_in_desired_state = MALI_TRUE; init_waitqueue_head(&kbdev->pm.gpu_in_desired_state_wait); callbacks = (kbase_pm_callback_conf *) kbasep_get_config_value(kbdev, kbdev->config_attributes, KBASE_CONFIG_ATTR_POWER_MANAGEMENT_CALLBACKS); if (callbacks) { kbdev->pm.callback_power_on = callbacks->power_on_callback; kbdev->pm.callback_power_off = callbacks->power_off_callback; kbdev->pm.callback_power_runtime_init = callbacks->power_runtime_init_callback; kbdev->pm.callback_power_runtime_term = callbacks->power_runtime_term_callback; kbdev->pm.callback_power_runtime_on = callbacks->power_runtime_on_callback; kbdev->pm.callback_power_runtime_off = callbacks->power_runtime_off_callback; } else { kbdev->pm.callback_power_on = NULL; kbdev->pm.callback_power_off = NULL; kbdev->pm.callback_power_runtime_init = NULL; kbdev->pm.callback_power_runtime_term = NULL; kbdev->pm.callback_power_runtime_on = NULL; kbdev->pm.callback_power_runtime_off = NULL; } kbdev->pm.platform_dvfs_frequency = (u32) kbasep_get_config_value(kbdev, kbdev->config_attributes, KBASE_CONFIG_ATTR_POWER_MANAGEMENT_DVFS_FREQ); /* Initialise the metrics subsystem */ ret = kbasep_pm_metrics_init(kbdev); if (MALI_ERROR_NONE != ret) return ret; init_waitqueue_head(&kbdev->pm.l2_powered_wait); kbdev->pm.l2_powered = 0; init_waitqueue_head(&kbdev->pm.reset_done_wait); kbdev->pm.reset_done = MALI_FALSE; init_waitqueue_head(&kbdev->pm.zero_active_count_wait); kbdev->pm.active_count = 0; spin_lock_init(&kbdev->pm.power_change_lock); spin_lock_init(&kbdev->pm.gpu_cycle_counter_requests_lock); spin_lock_init(&kbdev->pm.gpu_powered_lock); if (MALI_ERROR_NONE != kbase_pm_ca_init(kbdev)) goto workq_fail; if (MALI_ERROR_NONE != kbase_pm_policy_init(kbdev)) goto pm_policy_fail; return MALI_ERROR_NONE; pm_policy_fail: kbase_pm_ca_term(kbdev); workq_fail: kbasep_pm_metrics_term(kbdev); return MALI_ERROR_FUNCTION_FAILED; }
mali_error kbase_pm_init(struct kbase_device *kbdev) { mali_error ret = MALI_ERROR_NONE; struct kbase_pm_callback_conf *callbacks; KBASE_DEBUG_ASSERT(kbdev != NULL); mutex_init(&kbdev->pm.lock); kbdev->pm.gpu_powered = MALI_FALSE; kbdev->pm.suspending = MALI_FALSE; #ifdef CONFIG_MALI_DEBUG kbdev->pm.driver_ready_for_irqs = MALI_FALSE; #endif /* CONFIG_MALI_DEBUG */ kbdev->pm.gpu_in_desired_state = MALI_TRUE; init_waitqueue_head(&kbdev->pm.gpu_in_desired_state_wait); callbacks = (struct kbase_pm_callback_conf *)kbasep_get_config_value(kbdev, kbdev->config_attributes, KBASE_CONFIG_ATTR_POWER_MANAGEMENT_CALLBACKS); if (callbacks) { kbdev->pm.callback_power_on = callbacks->power_on_callback; kbdev->pm.callback_power_off = callbacks->power_off_callback; kbdev->pm.callback_power_suspend = callbacks->power_suspend_callback; kbdev->pm.callback_power_resume = callbacks->power_resume_callback; kbdev->pm.callback_power_runtime_init = callbacks->power_runtime_init_callback; kbdev->pm.callback_power_runtime_term = callbacks->power_runtime_term_callback; kbdev->pm.callback_power_runtime_on = callbacks->power_runtime_on_callback; kbdev->pm.callback_power_runtime_off = callbacks->power_runtime_off_callback; } else { kbdev->pm.callback_power_on = NULL; kbdev->pm.callback_power_off = NULL; kbdev->pm.callback_power_suspend = NULL; kbdev->pm.callback_power_resume = NULL; kbdev->pm.callback_power_runtime_init = NULL; kbdev->pm.callback_power_runtime_term = NULL; kbdev->pm.callback_power_runtime_on = NULL; kbdev->pm.callback_power_runtime_off = NULL; } /* MTK GPU DVFS init */ _mtk_gpu_dvfs_init(); /* MTK Register input boost and power limit call back function */ mt_gpufreq_input_boost_notify_registerCB(mtk_gpu_input_boost_CB); mt_gpufreq_power_limit_notify_registerCB(mtk_gpu_power_limit_CB); /* Register gpu boost function to MTK HAL */ mtk_boost_gpu_freq_fp = mtk_kbase_boost_gpu_freq; mtk_custom_boost_gpu_freq_fp = mtk_kbase_custom_boost_gpu_freq; /* used for for performance service boost */ mtk_set_bottom_gpu_freq_fp = mtk_kbase_ged_bottom_gpu_freq; /* used for GED boost */ mtk_custom_get_gpu_freq_level_count_fp = mtk_kbase_custom_get_gpu_freq_level_count; /* MTK MET use */ mtk_get_gpu_loading_fp = kbasep_get_gl_utilization; kbdev->pm.platform_dvfs_frequency = (u32) kbasep_get_config_value(kbdev, kbdev->config_attributes, KBASE_CONFIG_ATTR_POWER_MANAGEMENT_DVFS_FREQ); /* Initialise the metrics subsystem */ ret = kbasep_pm_metrics_init(kbdev); if (MALI_ERROR_NONE != ret) return ret; init_waitqueue_head(&kbdev->pm.l2_powered_wait); kbdev->pm.l2_powered = 0; init_waitqueue_head(&kbdev->pm.reset_done_wait); kbdev->pm.reset_done = MALI_FALSE; init_waitqueue_head(&kbdev->pm.zero_active_count_wait); kbdev->pm.active_count = 0; spin_lock_init(&kbdev->pm.power_change_lock); spin_lock_init(&kbdev->pm.gpu_cycle_counter_requests_lock); spin_lock_init(&kbdev->pm.gpu_powered_lock); if (MALI_ERROR_NONE != kbase_pm_ca_init(kbdev)) goto workq_fail; if (MALI_ERROR_NONE != kbase_pm_policy_init(kbdev)) goto pm_policy_fail; return MALI_ERROR_NONE; pm_policy_fail: kbase_pm_ca_term(kbdev); workq_fail: kbasep_pm_metrics_term(kbdev); return MALI_ERROR_FUNCTION_FAILED; }