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  */
kbase_jm_next_job(struct kbase_device *kbdev, int js, int nr_jobs_to_submit)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 
kbase_jm_kick(struct kbase_device *kbdev, u32 js_mask)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 
kbase_jm_try_kick(struct kbase_device *kbdev, u32 js_mask)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 
kbase_jm_try_kick_all(struct kbase_device *kbdev)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 
kbase_jm_idle_ctx(struct kbase_device *kbdev, struct kbase_context *kctx)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 
kbase_jm_return_atom_to_js(struct kbase_device *kbdev, struct kbase_jd_atom *katom)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 
kbase_jm_complete(struct kbase_device *kbdev, struct kbase_jd_atom *katom, ktime_t *end_timestamp)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 
132