gpu: update midgard r21p0 kernel driver
[GitHub/LineageOS/G12/android_hardware_amlogic_kernel-modules_mali-driver.git] / t83x / kernel / drivers / gpu / arm / midgard / backend / gpu / mali_kbase_pm_ca.c
1 /*
2 *
3 * (C) COPYRIGHT 2013-2017 ARM Limited. All rights reserved.
4 *
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
8 * of such GNU licence.
9 *
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.
13 *
14 */
15
16
17
18 /*
19 * Base kernel core availability APIs
20 */
21
22 #include <mali_kbase.h>
23 #include <mali_kbase_pm.h>
24 #include <backend/gpu/mali_kbase_pm_internal.h>
25
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,
30 #endif
31 #if !MALI_CUSTOMER_RELEASE
32 &kbase_pm_ca_demand_policy_ops,
33 &kbase_pm_ca_random_policy_ops,
34 #endif
35 };
36
37 /**
38 * POLICY_COUNT - The number of policies available in the system.
39 *
40 * This is derived from the number of functions listed in policy_list.
41 */
42 #define POLICY_COUNT (sizeof(policy_list)/sizeof(*policy_list))
43
44 int kbase_pm_ca_init(struct kbase_device *kbdev)
45 {
46 KBASE_DEBUG_ASSERT(kbdev != NULL);
47
48 kbdev->pm.backend.ca_current_policy = policy_list[0];
49
50 kbdev->pm.backend.ca_current_policy->init(kbdev);
51
52 return 0;
53 }
54
55 void kbase_pm_ca_term(struct kbase_device *kbdev)
56 {
57 kbdev->pm.backend.ca_current_policy->term(kbdev);
58 }
59
60 int kbase_pm_ca_list_policies(const struct kbase_pm_ca_policy * const **list)
61 {
62 if (!list)
63 return POLICY_COUNT;
64
65 *list = policy_list;
66
67 return POLICY_COUNT;
68 }
69
70 KBASE_EXPORT_TEST_API(kbase_pm_ca_list_policies);
71
72 const struct kbase_pm_ca_policy
73 *kbase_pm_ca_get_policy(struct kbase_device *kbdev)
74 {
75 KBASE_DEBUG_ASSERT(kbdev != NULL);
76
77 return kbdev->pm.backend.ca_current_policy;
78 }
79
80 KBASE_EXPORT_TEST_API(kbase_pm_ca_get_policy);
81
82 void kbase_pm_ca_set_policy(struct kbase_device *kbdev,
83 const struct kbase_pm_ca_policy *new_policy)
84 {
85 const struct kbase_pm_ca_policy *old_policy;
86 unsigned long flags;
87
88 KBASE_DEBUG_ASSERT(kbdev != NULL);
89 KBASE_DEBUG_ASSERT(new_policy != NULL);
90
91 KBASE_TRACE_ADD(kbdev, PM_CA_SET_POLICY, NULL, NULL, 0u,
92 new_policy->id);
93
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
96 * userspace thread */
97 kbase_pm_context_active(kbdev);
98
99 mutex_lock(&kbdev->pm.lock);
100
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);
106
107 if (old_policy->term)
108 old_policy->term(kbdev);
109
110 if (new_policy->init)
111 new_policy->init(kbdev);
112
113 spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
114 kbdev->pm.backend.ca_current_policy = new_policy;
115
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);
120
121 kbdev->pm.backend.ca_current_policy->update_core_status(kbdev,
122 kbdev->shader_ready_bitmap,
123 kbdev->shader_transitioning_bitmap);
124
125 spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
126
127 mutex_unlock(&kbdev->pm.lock);
128
129 /* Now the policy change is finished, we release our fake context active
130 * reference */
131 kbase_pm_context_idle(kbdev);
132 }
133
134 KBASE_EXPORT_TEST_API(kbase_pm_ca_set_policy);
135
136 u64 kbase_pm_ca_get_core_mask(struct kbase_device *kbdev)
137 {
138 lockdep_assert_held(&kbdev->hwaccess_lock);
139
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;
144
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;
148
149 return kbdev->pm.backend.ca_current_policy->get_core_mask(kbdev) &
150 kbdev->pm.debug_core_mask_all;
151 }
152
153 KBASE_EXPORT_TEST_API(kbase_pm_ca_get_core_mask);
154
155 void kbase_pm_ca_update_core_status(struct kbase_device *kbdev, u64 cores_ready,
156 u64 cores_transitioning)
157 {
158 lockdep_assert_held(&kbdev->hwaccess_lock);
159
160 if (kbdev->pm.backend.ca_current_policy != NULL)
161 kbdev->pm.backend.ca_current_policy->update_core_status(kbdev,
162 cores_ready,
163 cores_transitioning);
164 }
165
166 void kbase_pm_ca_instr_enable(struct kbase_device *kbdev)
167 {
168 unsigned long flags;
169
170 spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
171 kbdev->pm.backend.instr_enabled = true;
172
173 kbase_pm_update_cores_state_nolock(kbdev);
174 spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
175 }
176
177 void kbase_pm_ca_instr_disable(struct kbase_device *kbdev)
178 {
179 lockdep_assert_held(&kbdev->hwaccess_lock);
180 kbdev->pm.backend.instr_enabled = false;
181
182 kbase_pm_update_cores_state_nolock(kbdev);
183 }