f2167887229bc25c272a3070131a1520ac1c4bee
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / arm / midgard / backend / gpu / mali_kbase_jm_as.c
1 /*
2  *
3  * (C) COPYRIGHT 2014-2015 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 /*
20  * Register backend context / address space management
21  */
22
23 #include <mali_kbase.h>
24 #include <mali_kbase_hwaccess_jm.h>
25
26 /**
27  * assign_and_activate_kctx_addr_space - Assign an AS to a context
28  * @kbdev: Kbase device
29  * @kctx: Kbase context
30  * @current_as: Address Space to assign
31  *
32  * Assign an Address Space (AS) to a context, and add the context to the Policy.
33  *
34  * This includes
35  *   setting up the global runpool_irq structure and the context on the AS,
36  *   Activating the MMU on the AS,
37  *   Allowing jobs to be submitted on the AS.
38  *
39  * Context:
40  *   kbasep_js_kctx_info.jsctx_mutex held,
41  *   kbasep_js_device_data.runpool_mutex held,
42  *   AS transaction mutex held,
43  *   Runpool IRQ lock held
44  */
45 static void assign_and_activate_kctx_addr_space(struct kbase_device *kbdev,
46                                                 struct kbase_context *kctx,
47                                                 struct kbase_as *current_as)
48 {
49         struct kbasep_js_device_data *js_devdata = &kbdev->js_data;
50         struct kbasep_js_per_as_data *js_per_as_data;
51         int as_nr = current_as->number;
52
53         lockdep_assert_held(&kctx->jctx.sched_info.ctx.jsctx_mutex);
54         lockdep_assert_held(&js_devdata->runpool_mutex);
55         lockdep_assert_held(&current_as->transaction_mutex);
56         lockdep_assert_held(&js_devdata->runpool_irq.lock);
57
58         js_per_as_data = &js_devdata->runpool_irq.per_as_data[as_nr];
59
60         /* Attribute handling */
61         kbasep_js_ctx_attr_runpool_retain_ctx(kbdev, kctx);
62
63         /* Assign addr space */
64         kctx->as_nr = as_nr;
65
66         /* If the GPU is currently powered, activate this address space on the
67          * MMU */
68         if (kbdev->pm.backend.gpu_powered)
69                 kbase_mmu_update(kctx);
70         /* If the GPU was not powered then the MMU will be reprogrammed on the
71          * next pm_context_active() */
72
73         /* Allow it to run jobs */
74         kbasep_js_set_submit_allowed(js_devdata, kctx);
75
76         /* Book-keeping */
77         js_per_as_data->kctx = kctx;
78         js_per_as_data->as_busy_refcount = 0;
79
80         kbase_js_runpool_inc_context_count(kbdev, kctx);
81 }
82
83 /**
84  * release_addr_space - Release an address space
85  * @kbdev: Kbase device
86  * @kctx_as_nr: Address space of context to release
87  * @kctx: Context being released
88  *
89  * Context: kbasep_js_device_data.runpool_mutex must be held
90  *
91  * Release an address space, making it available for being picked again.
92  */
93 static void release_addr_space(struct kbase_device *kbdev, int kctx_as_nr,
94                                                 struct kbase_context *kctx)
95 {
96         struct kbasep_js_device_data *js_devdata;
97         u16 as_bit = (1u << kctx_as_nr);
98
99         js_devdata = &kbdev->js_data;
100         lockdep_assert_held(&js_devdata->runpool_mutex);
101
102         /* The address space must not already be free */
103         KBASE_DEBUG_ASSERT(!(js_devdata->as_free & as_bit));
104
105         js_devdata->as_free |= as_bit;
106
107         kbase_js_runpool_dec_context_count(kbdev, kctx);
108 }
109
110 bool kbase_backend_use_ctx_sched(struct kbase_device *kbdev,
111                                                 struct kbase_context *kctx)
112 {
113         int i;
114
115         if (kbdev->hwaccess.active_kctx == kctx) {
116                 /* Context is already active */
117                 return true;
118         }
119
120         for (i = 0; i < kbdev->nr_hw_address_spaces; i++) {
121                 struct kbasep_js_per_as_data *js_per_as_data =
122                                 &kbdev->js_data.runpool_irq.per_as_data[i];
123
124                 if (js_per_as_data->kctx == kctx) {
125                         /* Context already has ASID - mark as active */
126                         return true;
127                 }
128         }
129
130         /* Context does not have address space assigned */
131         return false;
132 }
133
134 void kbase_backend_release_ctx_irq(struct kbase_device *kbdev,
135                                                 struct kbase_context *kctx)
136 {
137         struct kbasep_js_per_as_data *js_per_as_data;
138         int as_nr = kctx->as_nr;
139
140         if (as_nr == KBASEP_AS_NR_INVALID) {
141                 WARN(1, "Attempting to release context without ASID\n");
142                 return;
143         }
144
145         lockdep_assert_held(&kbdev->as[as_nr].transaction_mutex);
146         lockdep_assert_held(&kbdev->js_data.runpool_irq.lock);
147
148         js_per_as_data = &kbdev->js_data.runpool_irq.per_as_data[kctx->as_nr];
149         if (js_per_as_data->as_busy_refcount != 0) {
150                 WARN(1, "Attempting to release active ASID\n");
151                 return;
152         }
153
154         /* Release context from address space */
155         js_per_as_data->kctx = NULL;
156
157         kbasep_js_clear_submit_allowed(&kbdev->js_data, kctx);
158         /* If the GPU is currently powered, de-activate this address space on
159          * the MMU */
160         if (kbdev->pm.backend.gpu_powered)
161                 kbase_mmu_disable(kctx);
162         /* If the GPU was not powered then the MMU will be reprogrammed on the
163          * next pm_context_active() */
164
165         release_addr_space(kbdev, as_nr, kctx);
166         kctx->as_nr = KBASEP_AS_NR_INVALID;
167 }
168
169 void kbase_backend_release_ctx_noirq(struct kbase_device *kbdev,
170                                                 struct kbase_context *kctx)
171 {
172 }
173
174 void kbase_backend_release_free_address_space(struct kbase_device *kbdev,
175                                                                 int as_nr)
176 {
177         struct kbasep_js_device_data *js_devdata;
178
179         js_devdata = &kbdev->js_data;
180
181         lockdep_assert_held(&js_devdata->runpool_mutex);
182
183         js_devdata->as_free |= (1 << as_nr);
184 }
185
186 /**
187  * check_is_runpool_full - check whether the runpool is full for a specified
188  * context
189  * @kbdev: Kbase device
190  * @kctx:  Kbase context
191  *
192  * If kctx == NULL, then this makes the least restrictive check on the
193  * runpool. A specific context that is supplied immediately after could fail
194  * the check, even under the same conditions.
195  *
196  * Therefore, once a context is obtained you \b must re-check it with this
197  * function, since the return value could change to false.
198  *
199  * Context:
200  *   In all cases, the caller must hold kbasep_js_device_data.runpool_mutex.
201  *   When kctx != NULL the caller must hold the
202  *   kbasep_js_kctx_info.ctx.jsctx_mutex.
203  *   When kctx == NULL, then the caller need not hold any jsctx_mutex locks (but
204  *   it doesn't do any harm to do so).
205  *
206  * Return: true if the runpool is full
207  */
208 static bool check_is_runpool_full(struct kbase_device *kbdev,
209                                                 struct kbase_context *kctx)
210 {
211         struct kbasep_js_device_data *js_devdata;
212         bool is_runpool_full;
213
214         js_devdata = &kbdev->js_data;
215         lockdep_assert_held(&js_devdata->runpool_mutex);
216
217         /* Regardless of whether a context is submitting or not, can't have more
218          * than there are HW address spaces */
219         is_runpool_full = (bool) (js_devdata->nr_all_contexts_running >=
220                                                 kbdev->nr_hw_address_spaces);
221
222         if (kctx != NULL && (kctx->jctx.sched_info.ctx.flags &
223                                         KBASE_CTX_FLAG_SUBMIT_DISABLED) == 0) {
224                 lockdep_assert_held(&kctx->jctx.sched_info.ctx.jsctx_mutex);
225                 /* Contexts that submit might use less of the address spaces
226                  * available, due to HW workarounds.  In which case, the runpool
227                  * is also full when the number of submitting contexts exceeds
228                  * the number of submittable address spaces.
229                  *
230                  * Both checks must be made: can have nr_user_address_spaces ==
231                  * nr_hw_address spaces, and at the same time can have
232                  * nr_user_contexts_running < nr_all_contexts_running. */
233                 is_runpool_full |= (bool)
234                                         (js_devdata->nr_user_contexts_running >=
235                                                 kbdev->nr_user_address_spaces);
236         }
237
238         return is_runpool_full;
239 }
240
241 int kbase_backend_find_free_address_space(struct kbase_device *kbdev,
242                                                 struct kbase_context *kctx)
243 {
244         struct kbasep_js_device_data *js_devdata;
245         struct kbasep_js_kctx_info *js_kctx_info;
246         unsigned long flags;
247         int i;
248
249         js_devdata = &kbdev->js_data;
250         js_kctx_info = &kctx->jctx.sched_info;
251
252         mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
253         mutex_lock(&js_devdata->runpool_mutex);
254
255         /* First try to find a free address space */
256         if (check_is_runpool_full(kbdev, kctx))
257                 i = -1;
258         else
259                 i = ffs(js_devdata->as_free) - 1;
260
261         if (i >= 0 && i < kbdev->nr_hw_address_spaces) {
262                 js_devdata->as_free &= ~(1 << i);
263
264                 mutex_unlock(&js_devdata->runpool_mutex);
265                 mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
266
267                 return i;
268         }
269
270         spin_lock_irqsave(&js_devdata->runpool_irq.lock, flags);
271
272         /* No address space currently free, see if we can release one */
273         for (i = 0; i < kbdev->nr_hw_address_spaces; i++) {
274                 struct kbasep_js_per_as_data *js_per_as_data;
275                 struct kbasep_js_kctx_info *as_js_kctx_info;
276                 struct kbase_context *as_kctx;
277
278                 js_per_as_data = &kbdev->js_data.runpool_irq.per_as_data[i];
279                 as_kctx = js_per_as_data->kctx;
280                 as_js_kctx_info = &as_kctx->jctx.sched_info;
281
282                 /* Don't release privileged or active contexts, or contexts with
283                  * jobs running */
284                 if (as_kctx && !(as_kctx->jctx.sched_info.ctx.flags &
285                                                 KBASE_CTX_FLAG_PRIVILEGED) &&
286                         js_per_as_data->as_busy_refcount == 0) {
287                         if (!kbasep_js_runpool_retain_ctx_nolock(kbdev,
288                                                                 as_kctx)) {
289                                 WARN(1, "Failed to retain active context\n");
290
291                                 spin_unlock_irqrestore(
292                                                 &js_devdata->runpool_irq.lock,
293                                                                         flags);
294                                 mutex_unlock(&js_devdata->runpool_mutex);
295                                 mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
296
297                                 return KBASEP_AS_NR_INVALID;
298                         }
299
300                         kbasep_js_clear_submit_allowed(js_devdata, as_kctx);
301
302                         /* Drop and retake locks to take the jsctx_mutex on the
303                          * context we're about to release without violating lock
304                          * ordering
305                          */
306                         spin_unlock_irqrestore(&js_devdata->runpool_irq.lock,
307                                                                         flags);
308                         mutex_unlock(&js_devdata->runpool_mutex);
309                         mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
310
311
312                         /* Release context from address space */
313                         mutex_lock(&as_js_kctx_info->ctx.jsctx_mutex);
314                         mutex_lock(&js_devdata->runpool_mutex);
315
316                         kbasep_js_runpool_release_ctx_nolock(kbdev, as_kctx);
317
318                         if (!as_js_kctx_info->ctx.is_scheduled) {
319                                 kbasep_js_runpool_requeue_or_kill_ctx(kbdev,
320                                                                 as_kctx,
321                                                                 true);
322
323                                 js_devdata->as_free &= ~(1 << i);
324
325                                 mutex_unlock(&js_devdata->runpool_mutex);
326                                 mutex_unlock(&as_js_kctx_info->ctx.jsctx_mutex);
327
328                                 return i;
329                         }
330
331                         /* Context was retained while locks were dropped,
332                          * continue looking for free AS */
333
334                         mutex_unlock(&js_devdata->runpool_mutex);
335                         mutex_unlock(&as_js_kctx_info->ctx.jsctx_mutex);
336
337                         mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
338                         mutex_lock(&js_devdata->runpool_mutex);
339                         spin_lock_irqsave(&js_devdata->runpool_irq.lock, flags);
340                 }
341         }
342
343         spin_unlock_irqrestore(&js_devdata->runpool_irq.lock, flags);
344
345         mutex_unlock(&js_devdata->runpool_mutex);
346         mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
347
348         return KBASEP_AS_NR_INVALID;
349 }
350
351 bool kbase_backend_use_ctx(struct kbase_device *kbdev,
352                                 struct kbase_context *kctx,
353                                 int as_nr)
354 {
355         struct kbasep_js_device_data *js_devdata;
356         struct kbasep_js_kctx_info *js_kctx_info;
357         struct kbase_as *new_address_space = NULL;
358
359         js_devdata = &kbdev->js_data;
360         js_kctx_info = &kctx->jctx.sched_info;
361
362         if (kbdev->hwaccess.active_kctx == kctx ||
363             kctx->as_nr != KBASEP_AS_NR_INVALID ||
364             as_nr == KBASEP_AS_NR_INVALID) {
365                 WARN(1, "Invalid parameters to use_ctx()\n");
366                 return false;
367         }
368
369         new_address_space = &kbdev->as[as_nr];
370
371         lockdep_assert_held(&js_devdata->runpool_mutex);
372         lockdep_assert_held(&new_address_space->transaction_mutex);
373         lockdep_assert_held(&js_devdata->runpool_irq.lock);
374
375         assign_and_activate_kctx_addr_space(kbdev, kctx, new_address_space);
376
377         if ((js_kctx_info->ctx.flags & KBASE_CTX_FLAG_PRIVILEGED) != 0) {
378                 /* We need to retain it to keep the corresponding address space
379                  */
380                 kbasep_js_runpool_retain_ctx_nolock(kbdev, kctx);
381         }
382
383         return true;
384 }
385