xref: /OK3568_Linux_fs/kernel/drivers/gpu/arm/mali400/mali/common/mali_gp_job.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (C) 2011-2017 ARM Limited. All rights reserved.
3  *
4  * This program is free software and is provided to you under the terms of the GNU General Public License version 2
5  * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
6  *
7  * A copy of the licence is included with the program, and can also be obtained from Free Software
8  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
9  */
10 
11 #ifndef __MALI_GP_JOB_H__
12 #define __MALI_GP_JOB_H__
13 
14 #include "mali_osk.h"
15 #include "mali_osk_list.h"
16 #include "mali_uk_types.h"
17 #include "mali_session.h"
18 #include "mali_timeline.h"
19 #include "mali_scheduler_types.h"
20 #include "mali_scheduler.h"
21 #include "mali_executor.h"
22 #include "mali_timeline.h"
23 
24 struct mali_defer_mem;
25 /**
26  * This structure represents a GP job
27  *
28  * The GP job object itself is not protected by any single lock,
29  * but relies on other locks instead (scheduler, executor and timeline lock).
30  * Think of the job object as moving between these sub systems through-out
31  * its lifetime. Different part of the GP job struct is used by different
32  * subsystems. Accessor functions ensure that correct lock is taken.
33  * Do NOT access any data members directly from outside this module!
34  */
35 struct mali_gp_job {
36 	/*
37 	 * These members are typically only set at creation,
38 	 * and only read later on.
39 	 * They do not require any lock protection.
40 	 */
41 	_mali_uk_gp_start_job_s uargs;                     /**< Arguments from user space */
42 	struct mali_session_data *session;                 /**< Session which submitted this job */
43 	u32 pid;                                           /**< Process ID of submitting process */
44 	u32 tid;                                           /**< Thread ID of submitting thread */
45 	u32 id;                                            /**< Identifier for this job in kernel space (sequential numbering) */
46 	u32 cache_order;                                   /**< Cache order used for L2 cache flushing (sequential numbering) */
47 	struct mali_timeline_tracker tracker;              /**< Timeline tracker for this job */
48 	struct mali_timeline_tracker *pp_tracker;          /**< Pointer to Timeline tracker for PP job that depends on this job. */
49 	_mali_osk_notification_t *finished_notification;   /**< Notification sent back to userspace on job complete */
50 
51 	/*
52 	 * These members are used by the scheduler,
53 	 * protected by scheduler lock
54 	 */
55 	_mali_osk_list_t list;                             /**< Used to link jobs together in the scheduler queue */
56 
57 	/*
58 	 * These members are used by the executor and/or group,
59 	 * protected by executor lock
60 	 */
61 	_mali_osk_notification_t *oom_notification;        /**< Notification sent back to userspace on OOM */
62 
63 	/*
64 	 * Set by executor/group on job completion, read by scheduler when
65 	 * returning job to user. Hold executor lock when setting,
66 	 * no lock needed when reading
67 	 */
68 	u32 heap_current_addr;                             /**< Holds the current HEAP address when the job has completed */
69 	u32 perf_counter_value0;                           /**< Value of performance counter 0 (to be returned to user space) */
70 	u32 perf_counter_value1;                           /**< Value of performance counter 1 (to be returned to user space) */
71 	struct mali_defer_mem *dmem;                                          /** < used for defer bind to store dmem info */
72 	struct list_head varying_alloc;                    /**< hold the list of varying allocations */
73 	u32 bind_flag;                                     /** < flag for deferbind*/
74 	u32 *varying_list;                                 /**< varying memory list need to to defer bind*/
75 	struct list_head vary_todo;                        /**< list of backend list need to do defer bind*/
76 	u32 required_varying_memsize;                      /** < size of varying memory to reallocate*/
77 	u32 big_job;                                       /** < if the gp job have large varying output and may take long time*/
78 };
79 
80 #define MALI_DEFER_BIND_MEMORY_PREPARED (0x1 << 0)
81 #define MALI_DEFER_BIND_MEMORY_BINDED (0x1 << 2)
82 
83 struct mali_gp_allocation_node {
84 	struct list_head node;
85 	mali_mem_allocation *alloc;
86 };
87 
88 struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *uargs, u32 id, struct mali_timeline_tracker *pp_tracker);
89 void mali_gp_job_delete(struct mali_gp_job *job);
90 
91 u32 mali_gp_job_get_gp_counter_src0(void);
92 void mali_gp_job_set_gp_counter_src0(u32 counter);
93 u32 mali_gp_job_get_gp_counter_src1(void);
94 void mali_gp_job_set_gp_counter_src1(u32 counter);
95 
mali_gp_job_get_id(struct mali_gp_job * job)96 MALI_STATIC_INLINE u32 mali_gp_job_get_id(struct mali_gp_job *job)
97 {
98 	MALI_DEBUG_ASSERT_POINTER(job);
99 	return (NULL == job) ? 0 : job->id;
100 }
101 
mali_gp_job_set_cache_order(struct mali_gp_job * job,u32 cache_order)102 MALI_STATIC_INLINE void mali_gp_job_set_cache_order(struct mali_gp_job *job,
103 		u32 cache_order)
104 {
105 	MALI_DEBUG_ASSERT_POINTER(job);
106 	MALI_DEBUG_ASSERT_SCHEDULER_LOCK_HELD();
107 	job->cache_order = cache_order;
108 }
109 
mali_gp_job_get_cache_order(struct mali_gp_job * job)110 MALI_STATIC_INLINE u32 mali_gp_job_get_cache_order(struct mali_gp_job *job)
111 {
112 	MALI_DEBUG_ASSERT_POINTER(job);
113 	return (NULL == job) ? 0 : job->cache_order;
114 }
115 
mali_gp_job_get_user_id(struct mali_gp_job * job)116 MALI_STATIC_INLINE u64 mali_gp_job_get_user_id(struct mali_gp_job *job)
117 {
118 	MALI_DEBUG_ASSERT_POINTER(job);
119 	return job->uargs.user_job_ptr;
120 }
121 
mali_gp_job_get_frame_builder_id(struct mali_gp_job * job)122 MALI_STATIC_INLINE u32 mali_gp_job_get_frame_builder_id(struct mali_gp_job *job)
123 {
124 	MALI_DEBUG_ASSERT_POINTER(job);
125 	return job->uargs.frame_builder_id;
126 }
127 
mali_gp_job_get_flush_id(struct mali_gp_job * job)128 MALI_STATIC_INLINE u32 mali_gp_job_get_flush_id(struct mali_gp_job *job)
129 {
130 	MALI_DEBUG_ASSERT_POINTER(job);
131 	return job->uargs.flush_id;
132 }
133 
mali_gp_job_get_pid(struct mali_gp_job * job)134 MALI_STATIC_INLINE u32 mali_gp_job_get_pid(struct mali_gp_job *job)
135 {
136 	MALI_DEBUG_ASSERT_POINTER(job);
137 	return job->pid;
138 }
139 
mali_gp_job_get_tid(struct mali_gp_job * job)140 MALI_STATIC_INLINE u32 mali_gp_job_get_tid(struct mali_gp_job *job)
141 {
142 	MALI_DEBUG_ASSERT_POINTER(job);
143 	return job->tid;
144 }
145 
mali_gp_job_get_frame_registers(struct mali_gp_job * job)146 MALI_STATIC_INLINE u32 *mali_gp_job_get_frame_registers(struct mali_gp_job *job)
147 {
148 	MALI_DEBUG_ASSERT_POINTER(job);
149 	return job->uargs.frame_registers;
150 }
151 
mali_gp_job_get_session(struct mali_gp_job * job)152 MALI_STATIC_INLINE struct mali_session_data *mali_gp_job_get_session(struct mali_gp_job *job)
153 {
154 	MALI_DEBUG_ASSERT_POINTER(job);
155 	return job->session;
156 }
157 
mali_gp_job_has_vs_job(struct mali_gp_job * job)158 MALI_STATIC_INLINE mali_bool mali_gp_job_has_vs_job(struct mali_gp_job *job)
159 {
160 	MALI_DEBUG_ASSERT_POINTER(job);
161 	return (job->uargs.frame_registers[0] != job->uargs.frame_registers[1]) ? MALI_TRUE : MALI_FALSE;
162 }
163 
mali_gp_job_has_plbu_job(struct mali_gp_job * job)164 MALI_STATIC_INLINE mali_bool mali_gp_job_has_plbu_job(struct mali_gp_job *job)
165 {
166 	MALI_DEBUG_ASSERT_POINTER(job);
167 	return (job->uargs.frame_registers[2] != job->uargs.frame_registers[3]) ? MALI_TRUE : MALI_FALSE;
168 }
169 
mali_gp_job_get_current_heap_addr(struct mali_gp_job * job)170 MALI_STATIC_INLINE u32 mali_gp_job_get_current_heap_addr(struct mali_gp_job *job)
171 {
172 	MALI_DEBUG_ASSERT_POINTER(job);
173 	return job->heap_current_addr;
174 }
175 
mali_gp_job_set_current_heap_addr(struct mali_gp_job * job,u32 heap_addr)176 MALI_STATIC_INLINE void mali_gp_job_set_current_heap_addr(struct mali_gp_job *job, u32 heap_addr)
177 {
178 	MALI_DEBUG_ASSERT_POINTER(job);
179 	MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
180 	job->heap_current_addr = heap_addr;
181 }
182 
mali_gp_job_get_perf_counter_flag(struct mali_gp_job * job)183 MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_flag(struct mali_gp_job *job)
184 {
185 	MALI_DEBUG_ASSERT_POINTER(job);
186 	return job->uargs.perf_counter_flag;
187 }
188 
mali_gp_job_get_perf_counter_src0(struct mali_gp_job * job)189 MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src0(struct mali_gp_job *job)
190 {
191 	MALI_DEBUG_ASSERT_POINTER(job);
192 	return job->uargs.perf_counter_src0;
193 }
194 
mali_gp_job_get_perf_counter_src1(struct mali_gp_job * job)195 MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src1(struct mali_gp_job *job)
196 {
197 	MALI_DEBUG_ASSERT_POINTER(job);
198 	return job->uargs.perf_counter_src1;
199 }
200 
mali_gp_job_get_perf_counter_value0(struct mali_gp_job * job)201 MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_value0(struct mali_gp_job *job)
202 {
203 	MALI_DEBUG_ASSERT_POINTER(job);
204 	return job->perf_counter_value0;
205 }
206 
mali_gp_job_get_perf_counter_value1(struct mali_gp_job * job)207 MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_value1(struct mali_gp_job *job)
208 {
209 	MALI_DEBUG_ASSERT_POINTER(job);
210 	return job->perf_counter_value1;
211 }
212 
mali_gp_job_set_perf_counter_src0(struct mali_gp_job * job,u32 src)213 MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_src0(struct mali_gp_job *job, u32 src)
214 {
215 	MALI_DEBUG_ASSERT_POINTER(job);
216 	job->uargs.perf_counter_src0 = src;
217 }
218 
mali_gp_job_set_perf_counter_src1(struct mali_gp_job * job,u32 src)219 MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_src1(struct mali_gp_job *job, u32 src)
220 {
221 	MALI_DEBUG_ASSERT_POINTER(job);
222 	job->uargs.perf_counter_src1 = src;
223 }
224 
mali_gp_job_set_perf_counter_value0(struct mali_gp_job * job,u32 value)225 MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_value0(struct mali_gp_job *job, u32 value)
226 {
227 	MALI_DEBUG_ASSERT_POINTER(job);
228 	MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
229 	job->perf_counter_value0 = value;
230 }
231 
mali_gp_job_set_perf_counter_value1(struct mali_gp_job * job,u32 value)232 MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_value1(struct mali_gp_job *job, u32 value)
233 {
234 	MALI_DEBUG_ASSERT_POINTER(job);
235 	MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
236 	job->perf_counter_value1 = value;
237 }
238 
239 void mali_gp_job_list_add(struct mali_gp_job *job, _mali_osk_list_t *list);
240 
mali_gp_job_list_move(struct mali_gp_job * job,_mali_osk_list_t * list)241 MALI_STATIC_INLINE void mali_gp_job_list_move(struct mali_gp_job *job,
242 		_mali_osk_list_t *list)
243 {
244 	MALI_DEBUG_ASSERT_POINTER(job);
245 	MALI_DEBUG_ASSERT_SCHEDULER_LOCK_HELD();
246 	MALI_DEBUG_ASSERT(!_mali_osk_list_empty(&job->list));
247 	_mali_osk_list_move(&job->list, list);
248 }
249 
mali_gp_job_list_remove(struct mali_gp_job * job)250 MALI_STATIC_INLINE void mali_gp_job_list_remove(struct mali_gp_job *job)
251 {
252 	MALI_DEBUG_ASSERT_POINTER(job);
253 	MALI_DEBUG_ASSERT_SCHEDULER_LOCK_HELD();
254 	_mali_osk_list_delinit(&job->list);
255 }
256 
257 MALI_STATIC_INLINE _mali_osk_notification_t *
mali_gp_job_get_finished_notification(struct mali_gp_job * job)258 mali_gp_job_get_finished_notification(struct mali_gp_job *job)
259 {
260 	_mali_osk_notification_t *notification;
261 
262 	MALI_DEBUG_ASSERT_POINTER(job);
263 	MALI_DEBUG_ASSERT_POINTER(job->finished_notification);
264 
265 	notification = job->finished_notification;
266 	job->finished_notification = NULL;
267 
268 	return notification;
269 }
270 
mali_gp_job_get_oom_notification(struct mali_gp_job * job)271 MALI_STATIC_INLINE _mali_osk_notification_t *mali_gp_job_get_oom_notification(
272 	struct mali_gp_job *job)
273 {
274 	_mali_osk_notification_t *notification;
275 
276 	MALI_DEBUG_ASSERT_POINTER(job);
277 	MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
278 	MALI_DEBUG_ASSERT_POINTER(job->oom_notification);
279 
280 	notification = job->oom_notification;
281 	job->oom_notification = NULL;
282 
283 	return notification;
284 }
285 
mali_gp_job_set_oom_notification(struct mali_gp_job * job,_mali_osk_notification_t * notification)286 MALI_STATIC_INLINE void mali_gp_job_set_oom_notification(
287 	struct mali_gp_job *job,
288 	_mali_osk_notification_t *notification)
289 {
290 	MALI_DEBUG_ASSERT_POINTER(job);
291 	MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
292 	MALI_DEBUG_ASSERT(NULL == job->oom_notification);
293 	job->oom_notification = notification;
294 }
295 
mali_gp_job_get_tracker(struct mali_gp_job * job)296 MALI_STATIC_INLINE struct mali_timeline_tracker *mali_gp_job_get_tracker(
297 	struct mali_gp_job *job)
298 {
299 	MALI_DEBUG_ASSERT_POINTER(job);
300 	return &(job->tracker);
301 }
302 
303 
mali_gp_job_get_timeline_point_ptr(struct mali_gp_job * job)304 MALI_STATIC_INLINE u32 *mali_gp_job_get_timeline_point_ptr(
305 	struct mali_gp_job *job)
306 {
307 	MALI_DEBUG_ASSERT_POINTER(job);
308 	return (u32 __user *)(uintptr_t)job->uargs.timeline_point_ptr;
309 }
310 
311 
312 /**
313  * Release reference on tracker for PP job that depends on this GP job.
314  *
315  * @note If GP job has a reference on tracker, this function MUST be called before the GP job is
316  * deleted.
317  *
318  * @param job GP job that is done.
319  * @param success MALI_TRUE if job completed successfully, MALI_FALSE if not.
320  * @return A scheduling bitmask indicating whether scheduling needs to be done.
321  */
322 mali_scheduler_mask mali_gp_job_signal_pp_tracker(struct mali_gp_job *job, mali_bool success);
323 
324 #endif /* __MALI_GP_JOB_H__ */
325