Merge branch 'linux-linaro-lsk-v4.4-android' of git://git.linaro.org/kernel/linux...
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / arm / midgard / mali_kbase_jm.c
1 /*
2  *
3  * (C) COPYRIGHT 2014-2016 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  * HW access job manager common APIs
21  */
22
23 #include <mali_kbase.h>
24 #include "mali_kbase_hwaccess_jm.h"
25 #include "mali_kbase_jm.h"
26
27 /**
28  * kbase_jm_next_job() - Attempt to run the next @nr_jobs_to_submit jobs on slot
29  *                       @js on the active context.
30  * @kbdev:              Device pointer
31  * @js:                 Job slot to run on
32  * @nr_jobs_to_submit:  Number of jobs to attempt to submit
33  *
34  * Return: true if slot can still be submitted on, false if slot is now full.
35  */
36 static bool kbase_jm_next_job(struct kbase_device *kbdev, int js,
37                                 int nr_jobs_to_submit)
38 {
39         struct kbase_context *kctx;
40         int i;
41
42         kctx = kbdev->hwaccess.active_kctx;
43
44         if (!kctx)
45                 return true;
46
47         for (i = 0; i < nr_jobs_to_submit; i++) {
48                 struct kbase_jd_atom *katom = kbase_js_pull(kctx, js);
49
50                 if (!katom)
51                         return true; /* Context has no jobs on this slot */
52
53                 kbase_backend_run_atom(kbdev, katom);
54         }
55
56         return false; /* Slot ringbuffer should now be full */
57 }
58
59 u32 kbase_jm_kick(struct kbase_device *kbdev, u32 js_mask)
60 {
61         u32 ret_mask = 0;
62
63         lockdep_assert_held(&kbdev->hwaccess_lock);
64
65         while (js_mask) {
66                 int js = ffs(js_mask) - 1;
67                 int nr_jobs_to_submit = kbase_backend_slot_free(kbdev, js);
68
69                 if (kbase_jm_next_job(kbdev, js, nr_jobs_to_submit))
70                         ret_mask |= (1 << js);
71
72                 js_mask &= ~(1 << js);
73         }
74
75         return ret_mask;
76 }
77
78 void kbase_jm_try_kick(struct kbase_device *kbdev, u32 js_mask)
79 {
80         struct kbasep_js_device_data *js_devdata = &kbdev->js_data;
81
82         lockdep_assert_held(&kbdev->hwaccess_lock);
83
84         if (!down_trylock(&js_devdata->schedule_sem)) {
85                 kbase_jm_kick(kbdev, js_mask);
86                 up(&js_devdata->schedule_sem);
87         }
88 }
89
90 void kbase_jm_try_kick_all(struct kbase_device *kbdev)
91 {
92         struct kbasep_js_device_data *js_devdata = &kbdev->js_data;
93
94         lockdep_assert_held(&kbdev->hwaccess_lock);
95
96         if (!down_trylock(&js_devdata->schedule_sem)) {
97                 kbase_jm_kick_all(kbdev);
98                 up(&js_devdata->schedule_sem);
99         }
100 }
101
102 void kbase_jm_idle_ctx(struct kbase_device *kbdev, struct kbase_context *kctx)
103 {
104         lockdep_assert_held(&kbdev->hwaccess_lock);
105
106         if (kbdev->hwaccess.active_kctx == kctx)
107                 kbdev->hwaccess.active_kctx = NULL;
108 }
109
110 struct kbase_jd_atom *kbase_jm_return_atom_to_js(struct kbase_device *kbdev,
111                                 struct kbase_jd_atom *katom)
112 {
113         lockdep_assert_held(&kbdev->hwaccess_lock);
114
115         if (katom->event_code != BASE_JD_EVENT_STOPPED &&
116                         katom->event_code != BASE_JD_EVENT_REMOVED_FROM_NEXT) {
117                 return kbase_js_complete_atom(katom, NULL);
118         } else {
119                 kbase_js_unpull(katom->kctx, katom);
120                 return NULL;
121         }
122 }
123
124 struct kbase_jd_atom *kbase_jm_complete(struct kbase_device *kbdev,
125                 struct kbase_jd_atom *katom, ktime_t *end_timestamp)
126 {
127         lockdep_assert_held(&kbdev->hwaccess_lock);
128
129         return kbase_js_complete_atom(katom, end_timestamp);
130 }
131