xref: /OK3568_Linux_fs/kernel/drivers/gpu/arm/bifrost/mali_kbase_jm.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * (C) COPYRIGHT 2013-2022 ARM Limited. All rights reserved.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * This program is free software and is provided to you under the terms of the
7*4882a593Smuzhiyun  * GNU General Public License version 2 as published by the Free Software
8*4882a593Smuzhiyun  * Foundation, and any use by you of this program is subject to the terms
9*4882a593Smuzhiyun  * of such GNU license.
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  * This program is distributed in the hope that it will be useful,
12*4882a593Smuzhiyun  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*4882a593Smuzhiyun  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*4882a593Smuzhiyun  * GNU General Public License for more details.
15*4882a593Smuzhiyun  *
16*4882a593Smuzhiyun  * You should have received a copy of the GNU General Public License
17*4882a593Smuzhiyun  * along with this program; if not, you can access it online at
18*4882a593Smuzhiyun  * http://www.gnu.org/licenses/gpl-2.0.html.
19*4882a593Smuzhiyun  *
20*4882a593Smuzhiyun  */
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun /*
23*4882a593Smuzhiyun  * HW access job manager common APIs
24*4882a593Smuzhiyun  */
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #include <mali_kbase.h>
27*4882a593Smuzhiyun #include "mali_kbase_hwaccess_jm.h"
28*4882a593Smuzhiyun #include "mali_kbase_jm.h"
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #if !MALI_USE_CSF
31*4882a593Smuzhiyun /**
32*4882a593Smuzhiyun  * kbase_jm_next_job() - Attempt to run the next @nr_jobs_to_submit jobs on slot
33*4882a593Smuzhiyun  *			 @js on the active context.
34*4882a593Smuzhiyun  * @kbdev:		Device pointer
35*4882a593Smuzhiyun  * @js:			Job slot to run on
36*4882a593Smuzhiyun  * @nr_jobs_to_submit:	Number of jobs to attempt to submit
37*4882a593Smuzhiyun  *
38*4882a593Smuzhiyun  * Return: true if slot can still be submitted on, false if slot is now full.
39*4882a593Smuzhiyun  */
kbase_jm_next_job(struct kbase_device * kbdev,unsigned int js,int nr_jobs_to_submit)40*4882a593Smuzhiyun static bool kbase_jm_next_job(struct kbase_device *kbdev, unsigned int js, int nr_jobs_to_submit)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun 	struct kbase_context *kctx;
43*4882a593Smuzhiyun 	int i;
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun 	kctx = kbdev->hwaccess.active_kctx[js];
46*4882a593Smuzhiyun 	dev_dbg(kbdev->dev, "Trying to run the next %d jobs in kctx %pK (s:%u)\n",
47*4882a593Smuzhiyun 		nr_jobs_to_submit, (void *)kctx, js);
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	if (!kctx)
50*4882a593Smuzhiyun 		return true;
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun 	for (i = 0; i < nr_jobs_to_submit; i++) {
53*4882a593Smuzhiyun 		struct kbase_jd_atom *katom = kbase_js_pull(kctx, js);
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 		if (!katom)
56*4882a593Smuzhiyun 			return true; /* Context has no jobs on this slot */
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun 		kbase_backend_run_atom(kbdev, katom);
59*4882a593Smuzhiyun 	}
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	dev_dbg(kbdev->dev, "Slot ringbuffer should now be full (s:%u)\n", js);
62*4882a593Smuzhiyun 	return false;
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun 
kbase_jm_kick(struct kbase_device * kbdev,u32 js_mask)65*4882a593Smuzhiyun u32 kbase_jm_kick(struct kbase_device *kbdev, u32 js_mask)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun 	u32 ret_mask = 0;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	lockdep_assert_held(&kbdev->hwaccess_lock);
70*4882a593Smuzhiyun 	dev_dbg(kbdev->dev, "JM kick slot mask 0x%x\n", js_mask);
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	while (js_mask) {
73*4882a593Smuzhiyun 		unsigned int js = ffs(js_mask) - 1;
74*4882a593Smuzhiyun 		int nr_jobs_to_submit = kbase_backend_slot_free(kbdev, js);
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 		if (kbase_jm_next_job(kbdev, js, nr_jobs_to_submit))
77*4882a593Smuzhiyun 			ret_mask |= (1 << js);
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 		js_mask &= ~(1 << js);
80*4882a593Smuzhiyun 	}
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	dev_dbg(kbdev->dev, "Can still submit to mask 0x%x\n", ret_mask);
83*4882a593Smuzhiyun 	return ret_mask;
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun 
kbase_jm_try_kick(struct kbase_device * kbdev,u32 js_mask)86*4882a593Smuzhiyun void kbase_jm_try_kick(struct kbase_device *kbdev, u32 js_mask)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun 	struct kbasep_js_device_data *js_devdata = &kbdev->js_data;
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	lockdep_assert_held(&kbdev->hwaccess_lock);
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 	if (!down_trylock(&js_devdata->schedule_sem)) {
93*4882a593Smuzhiyun 		kbase_jm_kick(kbdev, js_mask);
94*4882a593Smuzhiyun 		up(&js_devdata->schedule_sem);
95*4882a593Smuzhiyun 	}
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun 
kbase_jm_try_kick_all(struct kbase_device * kbdev)98*4882a593Smuzhiyun void kbase_jm_try_kick_all(struct kbase_device *kbdev)
99*4882a593Smuzhiyun {
100*4882a593Smuzhiyun 	struct kbasep_js_device_data *js_devdata = &kbdev->js_data;
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	lockdep_assert_held(&kbdev->hwaccess_lock);
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	if (!down_trylock(&js_devdata->schedule_sem)) {
105*4882a593Smuzhiyun 		kbase_jm_kick_all(kbdev);
106*4882a593Smuzhiyun 		up(&js_devdata->schedule_sem);
107*4882a593Smuzhiyun 	}
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun 
kbase_jm_idle_ctx(struct kbase_device * kbdev,struct kbase_context * kctx)110*4882a593Smuzhiyun void kbase_jm_idle_ctx(struct kbase_device *kbdev, struct kbase_context *kctx)
111*4882a593Smuzhiyun {
112*4882a593Smuzhiyun 	unsigned int js;
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	lockdep_assert_held(&kbdev->hwaccess_lock);
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	for (js = 0; js < BASE_JM_MAX_NR_SLOTS; js++) {
117*4882a593Smuzhiyun 		if (kbdev->hwaccess.active_kctx[js] == kctx) {
118*4882a593Smuzhiyun 			dev_dbg(kbdev->dev, "Marking kctx %pK as inactive (s:%u)\n", (void *)kctx,
119*4882a593Smuzhiyun 				js);
120*4882a593Smuzhiyun 			kbdev->hwaccess.active_kctx[js] = NULL;
121*4882a593Smuzhiyun 		}
122*4882a593Smuzhiyun 	}
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun 
kbase_jm_return_atom_to_js(struct kbase_device * kbdev,struct kbase_jd_atom * katom)125*4882a593Smuzhiyun struct kbase_jd_atom *kbase_jm_return_atom_to_js(struct kbase_device *kbdev,
126*4882a593Smuzhiyun 				struct kbase_jd_atom *katom)
127*4882a593Smuzhiyun {
128*4882a593Smuzhiyun 	lockdep_assert_held(&kbdev->hwaccess_lock);
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	dev_dbg(kbdev->dev, "Atom %pK is returning with event code 0x%x\n",
131*4882a593Smuzhiyun 		(void *)katom, katom->event_code);
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	KBASE_KTRACE_ADD_JM(kbdev, JM_RETURN_ATOM_TO_JS, katom->kctx, katom,
134*4882a593Smuzhiyun 			    katom->jc, katom->event_code);
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun 	if (katom->event_code != BASE_JD_EVENT_STOPPED &&
137*4882a593Smuzhiyun 			katom->event_code != BASE_JD_EVENT_REMOVED_FROM_NEXT) {
138*4882a593Smuzhiyun 		return kbase_js_complete_atom(katom, NULL);
139*4882a593Smuzhiyun 	}
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	kbase_js_unpull(katom->kctx, katom);
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	return NULL;
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun 
kbase_jm_complete(struct kbase_device * kbdev,struct kbase_jd_atom * katom,ktime_t * end_timestamp)146*4882a593Smuzhiyun struct kbase_jd_atom *kbase_jm_complete(struct kbase_device *kbdev,
147*4882a593Smuzhiyun 		struct kbase_jd_atom *katom, ktime_t *end_timestamp)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun 	lockdep_assert_held(&kbdev->hwaccess_lock);
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	return kbase_js_complete_atom(katom, end_timestamp);
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun #endif /* !MALI_USE_CSF */
154