3 * (C) COPYRIGHT 2013-2017 ARM Limited. All rights reserved.
5 * This program is free software and is provided to you under the terms of the
6 * GNU General Public License version 2 as published by the Free Software
7 * Foundation, and any use by you of this program is subject to the terms
10 * A copy of the licence is included with the program, and can also be obtained
11 * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
12 * Boston, MA 02110-1301, USA.
19 * Base kernel core availability APIs
22 #include <mali_kbase.h>
23 #include <mali_kbase_pm.h>
24 #include <backend/gpu/mali_kbase_pm_internal.h>
26 static const struct kbase_pm_ca_policy
*const policy_list
[] = {
27 &kbase_pm_ca_fixed_policy_ops
,
28 #ifdef CONFIG_MALI_DEVFREQ
29 &kbase_pm_ca_devfreq_policy_ops
,
31 #if !MALI_CUSTOMER_RELEASE
32 &kbase_pm_ca_demand_policy_ops
,
33 &kbase_pm_ca_random_policy_ops
,
38 * POLICY_COUNT - The number of policies available in the system.
40 * This is derived from the number of functions listed in policy_list.
42 #define POLICY_COUNT (sizeof(policy_list)/sizeof(*policy_list))
44 int kbase_pm_ca_init(struct kbase_device
*kbdev
)
46 KBASE_DEBUG_ASSERT(kbdev
!= NULL
);
48 kbdev
->pm
.backend
.ca_current_policy
= policy_list
[0];
50 kbdev
->pm
.backend
.ca_current_policy
->init(kbdev
);
55 void kbase_pm_ca_term(struct kbase_device
*kbdev
)
57 kbdev
->pm
.backend
.ca_current_policy
->term(kbdev
);
60 int kbase_pm_ca_list_policies(const struct kbase_pm_ca_policy
* const **list
)
70 KBASE_EXPORT_TEST_API(kbase_pm_ca_list_policies
);
72 const struct kbase_pm_ca_policy
73 *kbase_pm_ca_get_policy(struct kbase_device
*kbdev
)
75 KBASE_DEBUG_ASSERT(kbdev
!= NULL
);
77 return kbdev
->pm
.backend
.ca_current_policy
;
80 KBASE_EXPORT_TEST_API(kbase_pm_ca_get_policy
);
82 void kbase_pm_ca_set_policy(struct kbase_device
*kbdev
,
83 const struct kbase_pm_ca_policy
*new_policy
)
85 const struct kbase_pm_ca_policy
*old_policy
;
88 KBASE_DEBUG_ASSERT(kbdev
!= NULL
);
89 KBASE_DEBUG_ASSERT(new_policy
!= NULL
);
91 KBASE_TRACE_ADD(kbdev
, PM_CA_SET_POLICY
, NULL
, NULL
, 0u,
94 /* During a policy change we pretend the GPU is active */
95 /* A suspend won't happen here, because we're in a syscall from a
97 kbase_pm_context_active(kbdev
);
99 mutex_lock(&kbdev
->pm
.lock
);
101 /* Remove the policy to prevent IRQ handlers from working on it */
102 spin_lock_irqsave(&kbdev
->hwaccess_lock
, flags
);
103 old_policy
= kbdev
->pm
.backend
.ca_current_policy
;
104 kbdev
->pm
.backend
.ca_current_policy
= NULL
;
105 spin_unlock_irqrestore(&kbdev
->hwaccess_lock
, flags
);
107 if (old_policy
->term
)
108 old_policy
->term(kbdev
);
110 if (new_policy
->init
)
111 new_policy
->init(kbdev
);
113 spin_lock_irqsave(&kbdev
->hwaccess_lock
, flags
);
114 kbdev
->pm
.backend
.ca_current_policy
= new_policy
;
116 /* If any core power state changes were previously attempted, but
117 * couldn't be made because the policy was changing (current_policy was
118 * NULL), then re-try them here. */
119 kbase_pm_update_cores_state_nolock(kbdev
);
121 kbdev
->pm
.backend
.ca_current_policy
->update_core_status(kbdev
,
122 kbdev
->shader_ready_bitmap
,
123 kbdev
->shader_transitioning_bitmap
);
125 spin_unlock_irqrestore(&kbdev
->hwaccess_lock
, flags
);
127 mutex_unlock(&kbdev
->pm
.lock
);
129 /* Now the policy change is finished, we release our fake context active
131 kbase_pm_context_idle(kbdev
);
134 KBASE_EXPORT_TEST_API(kbase_pm_ca_set_policy
);
136 u64
kbase_pm_ca_get_core_mask(struct kbase_device
*kbdev
)
138 lockdep_assert_held(&kbdev
->hwaccess_lock
);
140 /* All cores must be enabled when instrumentation is in use */
141 if (kbdev
->pm
.backend
.instr_enabled
)
142 return kbdev
->gpu_props
.props
.raw_props
.shader_present
&
143 kbdev
->pm
.debug_core_mask_all
;
145 if (kbdev
->pm
.backend
.ca_current_policy
== NULL
)
146 return kbdev
->gpu_props
.props
.raw_props
.shader_present
&
147 kbdev
->pm
.debug_core_mask_all
;
149 return kbdev
->pm
.backend
.ca_current_policy
->get_core_mask(kbdev
) &
150 kbdev
->pm
.debug_core_mask_all
;
153 KBASE_EXPORT_TEST_API(kbase_pm_ca_get_core_mask
);
155 void kbase_pm_ca_update_core_status(struct kbase_device
*kbdev
, u64 cores_ready
,
156 u64 cores_transitioning
)
158 lockdep_assert_held(&kbdev
->hwaccess_lock
);
160 if (kbdev
->pm
.backend
.ca_current_policy
!= NULL
)
161 kbdev
->pm
.backend
.ca_current_policy
->update_core_status(kbdev
,
163 cores_transitioning
);
166 void kbase_pm_ca_instr_enable(struct kbase_device
*kbdev
)
170 spin_lock_irqsave(&kbdev
->hwaccess_lock
, flags
);
171 kbdev
->pm
.backend
.instr_enabled
= true;
173 kbase_pm_update_cores_state_nolock(kbdev
);
174 spin_unlock_irqrestore(&kbdev
->hwaccess_lock
, flags
);
177 void kbase_pm_ca_instr_disable(struct kbase_device
*kbdev
)
179 lockdep_assert_held(&kbdev
->hwaccess_lock
);
180 kbdev
->pm
.backend
.instr_enabled
= false;
182 kbase_pm_update_cores_state_nolock(kbdev
);