123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- /*
- *
- * (C) COPYRIGHT 2013-2015 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation, and any use by you of this program is subject to the terms
- * of such GNU licence.
- *
- * A copy of the licence is included with the program, and can also be obtained
- * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
- /*
- * Base kernel core availability APIs
- */
- #include <mali_kbase.h>
- #include <mali_kbase_pm.h>
- #include <backend/gpu/mali_kbase_pm_internal.h>
- static const struct kbase_pm_ca_policy *const policy_list[] = {
- &kbase_pm_ca_fixed_policy_ops,
- };
- /**
- * POLICY_COUNT - The number of policies available in the system.
- *
- * This is derived from the number of functions listed in policy_list.
- */
- #define POLICY_COUNT (sizeof(policy_list)/sizeof(*policy_list))
- int kbase_pm_ca_init(struct kbase_device *kbdev)
- {
- KBASE_DEBUG_ASSERT(kbdev != NULL);
- kbdev->pm.backend.ca_current_policy = policy_list[0];
- kbdev->pm.backend.ca_current_policy->init(kbdev);
- return 0;
- }
- void kbase_pm_ca_term(struct kbase_device *kbdev)
- {
- kbdev->pm.backend.ca_current_policy->term(kbdev);
- }
- int kbase_pm_ca_list_policies(const struct kbase_pm_ca_policy * const **list)
- {
- if (!list)
- return POLICY_COUNT;
- *list = policy_list;
- return POLICY_COUNT;
- }
- const struct kbase_pm_ca_policy
- *kbase_pm_ca_get_policy(struct kbase_device *kbdev)
- {
- KBASE_DEBUG_ASSERT(kbdev != NULL);
- return kbdev->pm.backend.ca_current_policy;
- }
- void kbase_pm_ca_set_policy(struct kbase_device *kbdev,
- const struct kbase_pm_ca_policy *new_policy)
- {
- const struct kbase_pm_ca_policy *old_policy;
- unsigned long flags;
- KBASE_DEBUG_ASSERT(kbdev != NULL);
- KBASE_DEBUG_ASSERT(new_policy != NULL);
- KBASE_TRACE_ADD(kbdev, PM_CA_SET_POLICY, NULL, NULL, 0u,
- new_policy->id);
- /* During a policy change we pretend the GPU is active */
- /* A suspend won't happen here, because we're in a syscall from a
- * userspace thread */
- kbase_pm_context_active(kbdev);
- mutex_lock(&kbdev->pm.lock);
- /* Remove the policy to prevent IRQ handlers from working on it */
- spin_lock_irqsave(&kbdev->pm.power_change_lock, flags);
- old_policy = kbdev->pm.backend.ca_current_policy;
- kbdev->pm.backend.ca_current_policy = NULL;
- spin_unlock_irqrestore(&kbdev->pm.power_change_lock, flags);
- if (old_policy->term)
- old_policy->term(kbdev);
- if (new_policy->init)
- new_policy->init(kbdev);
- spin_lock_irqsave(&kbdev->pm.power_change_lock, flags);
- kbdev->pm.backend.ca_current_policy = new_policy;
- /* If any core power state changes were previously attempted, but
- * couldn't be made because the policy was changing (current_policy was
- * NULL), then re-try them here. */
- kbase_pm_update_cores_state_nolock(kbdev);
- kbdev->pm.backend.ca_current_policy->update_core_status(kbdev,
- kbdev->shader_ready_bitmap,
- kbdev->shader_transitioning_bitmap);
- spin_unlock_irqrestore(&kbdev->pm.power_change_lock, flags);
- mutex_unlock(&kbdev->pm.lock);
- /* Now the policy change is finished, we release our fake context active
- * reference */
- kbase_pm_context_idle(kbdev);
- }
- u64 kbase_pm_ca_get_core_mask(struct kbase_device *kbdev)
- {
- lockdep_assert_held(&kbdev->pm.power_change_lock);
- /* All cores must be enabled when instrumentation is in use */
- if (kbdev->pm.backend.instr_enabled)
- return kbdev->gpu_props.props.raw_props.shader_present &
- kbdev->pm.debug_core_mask_all;
- if (kbdev->pm.backend.ca_current_policy == NULL)
- return kbdev->gpu_props.props.raw_props.shader_present &
- kbdev->pm.debug_core_mask_all;
- return kbdev->pm.backend.ca_current_policy->get_core_mask(kbdev) &
- kbdev->pm.debug_core_mask_all;
- }
- void kbase_pm_ca_update_core_status(struct kbase_device *kbdev, u64 cores_ready,
- u64 cores_transitioning)
- {
- lockdep_assert_held(&kbdev->pm.power_change_lock);
- if (kbdev->pm.backend.ca_current_policy != NULL)
- kbdev->pm.backend.ca_current_policy->update_core_status(kbdev,
- cores_ready,
- cores_transitioning);
- }
- void kbase_pm_ca_instr_enable(struct kbase_device *kbdev)
- {
- unsigned long flags;
- spin_lock_irqsave(&kbdev->pm.power_change_lock, flags);
- kbdev->pm.backend.instr_enabled = true;
- kbase_pm_update_cores_state_nolock(kbdev);
- spin_unlock_irqrestore(&kbdev->pm.power_change_lock, flags);
- }
- void kbase_pm_ca_instr_disable(struct kbase_device *kbdev)
- {
- unsigned long flags;
- spin_lock_irqsave(&kbdev->pm.power_change_lock, flags);
- kbdev->pm.backend.instr_enabled = false;
- kbase_pm_update_cores_state_nolock(kbdev);
- spin_unlock_irqrestore(&kbdev->pm.power_change_lock, flags);
- }
|