Merge tag lsk-v3.10-15.03-android
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / arm / mali400 / mali / common / mali_pp_job.h
1 /*
2  * Copyright (C) 2011-2014 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_PP_JOB_H__
12 #define __MALI_PP_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_kernel_common.h"
19 #include "regs/mali_200_regs.h"
20 #include "mali_kernel_core.h"
21 #include "mali_dlbu.h"
22 #include "mali_timeline.h"
23 #include "mali_scheduler.h"
24 #include "mali_executor.h"
25 #if defined(CONFIG_DMA_SHARED_BUFFER) && !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
26 #include "linux/mali_memory_dma_buf.h"
27 #endif
28
29 /**
30  * This structure represents a PP job, including all sub jobs.
31  *
32  * The PP job object itself is not protected by any single lock,
33  * but relies on other locks instead (scheduler, executor and timeline lock).
34  * Think of the job object as moving between these sub systems through-out
35  * its lifetime. Different part of the PP job struct is used by different
36  * subsystems. Accessor functions ensure that correct lock is taken.
37  * Do NOT access any data members directly from outside this module!
38  */
39 struct mali_pp_job {
40         /*
41          * These members are typically only set at creation,
42          * and only read later on.
43          * They do not require any lock protection.
44          */
45         _mali_uk_pp_start_job_s uargs;                     /**< Arguments from user space */
46         struct mali_session_data *session;                 /**< Session which submitted this job */
47         u32 pid;                                           /**< Process ID of submitting process */
48         u32 tid;                                           /**< Thread ID of submitting thread */
49         u32 id;                                            /**< Identifier for this job in kernel space (sequential numbering) */
50         u32 cache_order;                                   /**< Cache order used for L2 cache flushing (sequential numbering) */
51         struct mali_timeline_tracker tracker;              /**< Timeline tracker for this job */
52         _mali_osk_notification_t *finished_notification;   /**< Notification sent back to userspace on job complete */
53         u32 perf_counter_per_sub_job_count;                /**< Number of values in the two arrays which is != MALI_HW_CORE_NO_COUNTER */
54         u32 perf_counter_per_sub_job_src0[_MALI_PP_MAX_SUB_JOBS]; /**< Per sub job counters src0 */
55         u32 perf_counter_per_sub_job_src1[_MALI_PP_MAX_SUB_JOBS]; /**< Per sub job counters src1 */
56         u32 sub_jobs_num;                                  /**< Number of subjobs; set to 1 for Mali-450 if DLBU is used, otherwise equals number of PP cores */
57
58         /*
59          * These members are used by both scheduler and executor.
60          * They are "protected" by atomic operations.
61          */
62         _mali_osk_atomic_t sub_jobs_completed;                            /**< Number of completed sub-jobs in this superjob */
63         _mali_osk_atomic_t sub_job_errors;                                /**< Bitfield with errors (errors for each single sub-job is or'ed together) */
64
65         /*
66          * These members are used by scheduler, but only when no one else
67          * knows about this job object but the working function.
68          * No lock is thus needed for these.
69          */
70         u32 *memory_cookies;                               /**< Memory cookies attached to job */
71 #if defined(CONFIG_DMA_SHARED_BUFFER) && !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
72         struct mali_dma_buf_attachment **dma_bufs;         /**< Array of DMA-bufs used by job */
73 #endif
74
75         /*
76          * These members are used by the scheduler,
77          * protected by scheduler lock
78          */
79         _mali_osk_list_t list;                             /**< Used to link jobs together in the scheduler queue */
80         _mali_osk_list_t session_fb_lookup_list;           /**< Used to link jobs together from the same frame builder in the session */
81         u32 sub_jobs_started;                              /**< Total number of sub-jobs started (always started in ascending order) */
82
83         /*
84          * Set by executor/group on job completion, read by scheduler when
85          * returning job to user. Hold executor lock when setting,
86          * no lock needed when reading
87          */
88         u32 perf_counter_value0[_MALI_PP_MAX_SUB_JOBS];    /**< Value of performance counter 0 (to be returned to user space), one for each sub job */
89         u32 perf_counter_value1[_MALI_PP_MAX_SUB_JOBS];    /**< Value of performance counter 1 (to be returned to user space), one for each sub job */
90 };
91
92 void mali_pp_job_initialize(void);
93 void mali_pp_job_terminate(void);
94
95 struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *uargs, u32 id);
96 void mali_pp_job_delete(struct mali_pp_job *job);
97
98 u32 mali_pp_job_get_perf_counter_src0(struct mali_pp_job *job, u32 sub_job);
99 u32 mali_pp_job_get_perf_counter_src1(struct mali_pp_job *job, u32 sub_job);
100
101 void mali_pp_job_set_pp_counter_global_src0(u32 counter);
102 void mali_pp_job_set_pp_counter_global_src1(u32 counter);
103 void mali_pp_job_set_pp_counter_sub_job_src0(u32 sub_job, u32 counter);
104 void mali_pp_job_set_pp_counter_sub_job_src1(u32 sub_job, u32 counter);
105
106 u32 mali_pp_job_get_pp_counter_global_src0(void);
107 u32 mali_pp_job_get_pp_counter_global_src1(void);
108 u32 mali_pp_job_get_pp_counter_sub_job_src0(u32 sub_job);
109 u32 mali_pp_job_get_pp_counter_sub_job_src1(u32 sub_job);
110
111 MALI_STATIC_INLINE u32 mali_pp_job_get_id(struct mali_pp_job *job)
112 {
113         MALI_DEBUG_ASSERT_POINTER(job);
114         return (NULL == job) ? 0 : job->id;
115 }
116
117 MALI_STATIC_INLINE void mali_pp_job_set_cache_order(struct mali_pp_job *job,
118                 u32 cache_order)
119 {
120         MALI_DEBUG_ASSERT_POINTER(job);
121         MALI_DEBUG_ASSERT_SCHEDULER_LOCK_HELD();
122         job->cache_order = cache_order;
123 }
124
125 MALI_STATIC_INLINE u32 mali_pp_job_get_cache_order(struct mali_pp_job *job)
126 {
127         MALI_DEBUG_ASSERT_POINTER(job);
128         return (NULL == job) ? 0 : job->cache_order;
129 }
130
131 MALI_STATIC_INLINE u64 mali_pp_job_get_user_id(struct mali_pp_job *job)
132 {
133         MALI_DEBUG_ASSERT_POINTER(job);
134         return job->uargs.user_job_ptr;
135 }
136
137 MALI_STATIC_INLINE u32 mali_pp_job_get_frame_builder_id(struct mali_pp_job *job)
138 {
139         MALI_DEBUG_ASSERT_POINTER(job);
140         return job->uargs.frame_builder_id;
141 }
142
143 MALI_STATIC_INLINE u32 mali_pp_job_get_flush_id(struct mali_pp_job *job)
144 {
145         MALI_DEBUG_ASSERT_POINTER(job);
146         return job->uargs.flush_id;
147 }
148
149 MALI_STATIC_INLINE u32 mali_pp_job_get_pid(struct mali_pp_job *job)
150 {
151         MALI_DEBUG_ASSERT_POINTER(job);
152         return job->pid;
153 }
154
155 MALI_STATIC_INLINE u32 mali_pp_job_get_tid(struct mali_pp_job *job)
156 {
157         MALI_DEBUG_ASSERT_POINTER(job);
158         return job->tid;
159 }
160
161 MALI_STATIC_INLINE u32 *mali_pp_job_get_frame_registers(struct mali_pp_job *job)
162 {
163         MALI_DEBUG_ASSERT_POINTER(job);
164         return job->uargs.frame_registers;
165 }
166
167 MALI_STATIC_INLINE u32 *mali_pp_job_get_dlbu_registers(struct mali_pp_job *job)
168 {
169         MALI_DEBUG_ASSERT_POINTER(job);
170         return job->uargs.dlbu_registers;
171 }
172
173 MALI_STATIC_INLINE mali_bool mali_pp_job_is_virtual(struct mali_pp_job *job)
174 {
175 #if defined(CONFIG_MALI450)
176         MALI_DEBUG_ASSERT_POINTER(job);
177         return (0 == job->uargs.num_cores) ? MALI_TRUE : MALI_FALSE;
178 #else
179         return MALI_FALSE;
180 #endif
181 }
182
183 MALI_STATIC_INLINE u32 mali_pp_job_get_addr_frame(struct mali_pp_job *job, u32 sub_job)
184 {
185         MALI_DEBUG_ASSERT_POINTER(job);
186
187         if (mali_pp_job_is_virtual(job)) {
188                 return MALI_DLBU_VIRT_ADDR;
189         } else if (0 == sub_job) {
190                 return job->uargs.frame_registers[MALI200_REG_ADDR_FRAME / sizeof(u32)];
191         } else if (sub_job < _MALI_PP_MAX_SUB_JOBS) {
192                 return job->uargs.frame_registers_addr_frame[sub_job - 1];
193         }
194
195         return 0;
196 }
197
198 MALI_STATIC_INLINE u32 mali_pp_job_get_addr_stack(struct mali_pp_job *job, u32 sub_job)
199 {
200         MALI_DEBUG_ASSERT_POINTER(job);
201
202         if (0 == sub_job) {
203                 return job->uargs.frame_registers[MALI200_REG_ADDR_STACK / sizeof(u32)];
204         } else if (sub_job < _MALI_PP_MAX_SUB_JOBS) {
205                 return job->uargs.frame_registers_addr_stack[sub_job - 1];
206         }
207
208         return 0;
209 }
210
211 void mali_pp_job_list_add(struct mali_pp_job *job, _mali_osk_list_t *list);
212
213 MALI_STATIC_INLINE void mali_pp_job_list_addtail(struct mali_pp_job *job,
214                 _mali_osk_list_t *list)
215 {
216         _mali_osk_list_addtail(&job->list, list);
217 }
218
219 MALI_STATIC_INLINE void mali_pp_job_list_move(struct mali_pp_job *job,
220                 _mali_osk_list_t *list)
221 {
222         MALI_DEBUG_ASSERT_POINTER(job);
223         MALI_DEBUG_ASSERT_SCHEDULER_LOCK_HELD();
224         MALI_DEBUG_ASSERT(!_mali_osk_list_empty(&job->list));
225         _mali_osk_list_move(&job->list, list);
226 }
227
228 MALI_STATIC_INLINE void mali_pp_job_list_remove(struct mali_pp_job *job)
229 {
230         MALI_DEBUG_ASSERT_POINTER(job);
231         MALI_DEBUG_ASSERT_SCHEDULER_LOCK_HELD();
232         _mali_osk_list_delinit(&job->list);
233 }
234
235 MALI_STATIC_INLINE u32 *mali_pp_job_get_wb0_registers(struct mali_pp_job *job)
236 {
237         MALI_DEBUG_ASSERT_POINTER(job);
238         return job->uargs.wb0_registers;
239 }
240
241 MALI_STATIC_INLINE u32 *mali_pp_job_get_wb1_registers(struct mali_pp_job *job)
242 {
243         MALI_DEBUG_ASSERT_POINTER(job);
244         return job->uargs.wb1_registers;
245 }
246
247 MALI_STATIC_INLINE u32 *mali_pp_job_get_wb2_registers(struct mali_pp_job *job)
248 {
249         MALI_DEBUG_ASSERT_POINTER(job);
250         return job->uargs.wb2_registers;
251 }
252
253 MALI_STATIC_INLINE u32 mali_pp_job_get_wb0_source_addr(struct mali_pp_job *job)
254 {
255         MALI_DEBUG_ASSERT_POINTER(job);
256         return job->uargs.wb0_registers[MALI200_REG_ADDR_WB_SOURCE_ADDR / sizeof(u32)];
257 }
258
259 MALI_STATIC_INLINE u32 mali_pp_job_get_wb1_source_addr(struct mali_pp_job *job)
260 {
261         MALI_DEBUG_ASSERT_POINTER(job);
262         return job->uargs.wb1_registers[MALI200_REG_ADDR_WB_SOURCE_ADDR / sizeof(u32)];
263 }
264
265 MALI_STATIC_INLINE u32 mali_pp_job_get_wb2_source_addr(struct mali_pp_job *job)
266 {
267         MALI_DEBUG_ASSERT_POINTER(job);
268         return job->uargs.wb2_registers[MALI200_REG_ADDR_WB_SOURCE_ADDR / sizeof(u32)];
269 }
270
271 MALI_STATIC_INLINE void mali_pp_job_disable_wb0(struct mali_pp_job *job)
272 {
273         MALI_DEBUG_ASSERT_POINTER(job);
274         job->uargs.wb0_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
275 }
276
277 MALI_STATIC_INLINE void mali_pp_job_disable_wb1(struct mali_pp_job *job)
278 {
279         MALI_DEBUG_ASSERT_POINTER(job);
280         job->uargs.wb1_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
281 }
282
283 MALI_STATIC_INLINE void mali_pp_job_disable_wb2(struct mali_pp_job *job)
284 {
285         MALI_DEBUG_ASSERT_POINTER(job);
286         job->uargs.wb2_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
287 }
288
289 MALI_STATIC_INLINE mali_bool mali_pp_job_all_writeback_unit_disabled(struct mali_pp_job *job)
290 {
291         MALI_DEBUG_ASSERT_POINTER(job);
292
293         if (job->uargs.wb0_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] ||
294             job->uargs.wb1_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] ||
295             job->uargs.wb2_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT]
296            ) {
297                 /* At least one output unit active */
298                 return MALI_FALSE;
299         }
300
301         /* All outputs are disabled - we can abort the job */
302         return MALI_TRUE;
303 }
304
305 MALI_STATIC_INLINE void mali_pp_job_fb_lookup_add(struct mali_pp_job *job)
306 {
307         u32 fb_lookup_id;
308
309         MALI_DEBUG_ASSERT_POINTER(job);
310         MALI_DEBUG_ASSERT_SCHEDULER_LOCK_HELD();
311
312         fb_lookup_id = MALI_PP_JOB_FB_LOOKUP_LIST_MASK & job->uargs.frame_builder_id;
313
314         MALI_DEBUG_ASSERT(MALI_PP_JOB_FB_LOOKUP_LIST_SIZE > fb_lookup_id);
315
316         _mali_osk_list_addtail(&job->session_fb_lookup_list,
317                                &job->session->pp_job_fb_lookup_list[fb_lookup_id]);
318 }
319
320 MALI_STATIC_INLINE void mali_pp_job_fb_lookup_remove(struct mali_pp_job *job)
321 {
322         MALI_DEBUG_ASSERT_POINTER(job);
323         MALI_DEBUG_ASSERT_SCHEDULER_LOCK_HELD();
324         _mali_osk_list_delinit(&job->session_fb_lookup_list);
325 }
326
327 MALI_STATIC_INLINE struct mali_session_data *mali_pp_job_get_session(struct mali_pp_job *job)
328 {
329         MALI_DEBUG_ASSERT_POINTER(job);
330         return job->session;
331 }
332
333 MALI_STATIC_INLINE mali_bool mali_pp_job_has_started_sub_jobs(struct mali_pp_job *job)
334 {
335         MALI_DEBUG_ASSERT_POINTER(job);
336         MALI_DEBUG_ASSERT_SCHEDULER_LOCK_HELD();
337         return (0 < job->sub_jobs_started) ? MALI_TRUE : MALI_FALSE;
338 }
339
340 MALI_STATIC_INLINE mali_bool mali_pp_job_has_unstarted_sub_jobs(struct mali_pp_job *job)
341 {
342         MALI_DEBUG_ASSERT_POINTER(job);
343         MALI_DEBUG_ASSERT_SCHEDULER_LOCK_HELD();
344         return (job->sub_jobs_started < job->sub_jobs_num) ? MALI_TRUE : MALI_FALSE;
345 }
346
347 /* Function used when we are terminating a session with jobs. Return TRUE if it has a rendering job.
348    Makes sure that no new subjobs are started. */
349 MALI_STATIC_INLINE void mali_pp_job_mark_unstarted_failed(struct mali_pp_job *job)
350 {
351         u32 jobs_remaining;
352         u32 i;
353
354         MALI_DEBUG_ASSERT_POINTER(job);
355         MALI_DEBUG_ASSERT_SCHEDULER_LOCK_HELD();
356
357         jobs_remaining = job->sub_jobs_num - job->sub_jobs_started;
358         job->sub_jobs_started += jobs_remaining;
359
360         /* Not the most optimal way, but this is only used in error cases */
361         for (i = 0; i < jobs_remaining; i++) {
362                 _mali_osk_atomic_inc(&job->sub_jobs_completed);
363                 _mali_osk_atomic_inc(&job->sub_job_errors);
364         }
365 }
366
367 MALI_STATIC_INLINE mali_bool mali_pp_job_is_complete(struct mali_pp_job *job)
368 {
369         MALI_DEBUG_ASSERT_POINTER(job);
370         return (job->sub_jobs_num ==
371                 _mali_osk_atomic_read(&job->sub_jobs_completed)) ?
372                MALI_TRUE : MALI_FALSE;
373 }
374
375 MALI_STATIC_INLINE u32 mali_pp_job_get_first_unstarted_sub_job(struct mali_pp_job *job)
376 {
377         MALI_DEBUG_ASSERT_POINTER(job);
378         MALI_DEBUG_ASSERT_SCHEDULER_LOCK_HELD();
379         return job->sub_jobs_started;
380 }
381
382 MALI_STATIC_INLINE u32 mali_pp_job_get_sub_job_count(struct mali_pp_job *job)
383 {
384         MALI_DEBUG_ASSERT_POINTER(job);
385         return job->sub_jobs_num;
386 }
387
388 MALI_STATIC_INLINE u32 mali_pp_job_unstarted_sub_job_count(struct mali_pp_job *job)
389 {
390         MALI_DEBUG_ASSERT_POINTER(job);
391         MALI_DEBUG_ASSERT_SCHEDULER_LOCK_HELD();
392         MALI_DEBUG_ASSERT(job->sub_jobs_num >= job->sub_jobs_started);
393         return (job->sub_jobs_num - job->sub_jobs_started);
394 }
395
396 MALI_STATIC_INLINE u32 mali_pp_job_num_memory_cookies(struct mali_pp_job *job)
397 {
398         MALI_DEBUG_ASSERT_POINTER(job);
399         return job->uargs.num_memory_cookies;
400 }
401
402 MALI_STATIC_INLINE u32 mali_pp_job_get_memory_cookie(
403         struct mali_pp_job *job, u32 index)
404 {
405         MALI_DEBUG_ASSERT_POINTER(job);
406         MALI_DEBUG_ASSERT(index < job->uargs.num_memory_cookies);
407         MALI_DEBUG_ASSERT_POINTER(job->memory_cookies);
408         return job->memory_cookies[index];
409 }
410
411 MALI_STATIC_INLINE mali_bool mali_pp_job_needs_dma_buf_mapping(struct mali_pp_job *job)
412 {
413         MALI_DEBUG_ASSERT_POINTER(job);
414
415         if (0 < job->uargs.num_memory_cookies) {
416                 return MALI_TRUE;
417         }
418
419         return MALI_FALSE;
420 }
421
422 #if defined(CONFIG_DMA_SHARED_BUFFER) && !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
423 MALI_STATIC_INLINE u32 mali_pp_job_num_dma_bufs(struct mali_pp_job *job)
424 {
425         MALI_DEBUG_ASSERT_POINTER(job);
426         return job->uargs.num_memory_cookies;
427 }
428
429 MALI_STATIC_INLINE struct mali_dma_buf_attachment *mali_pp_job_get_dma_buf(
430         struct mali_pp_job *job, u32 index)
431 {
432         MALI_DEBUG_ASSERT_POINTER(job);
433         MALI_DEBUG_ASSERT(index < job->uargs.num_memory_cookies);
434         MALI_DEBUG_ASSERT_POINTER(job->dma_bufs);
435         return job->dma_bufs[index];
436 }
437
438 MALI_STATIC_INLINE void mali_pp_job_set_dma_buf(struct mali_pp_job *job,
439                 u32 index, struct mali_dma_buf_attachment *mem)
440 {
441         MALI_DEBUG_ASSERT_POINTER(job);
442         MALI_DEBUG_ASSERT(index < job->uargs.num_memory_cookies);
443         MALI_DEBUG_ASSERT_POINTER(job->dma_bufs);
444         job->dma_bufs[index] = mem;
445 }
446 #endif
447
448 MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_started(struct mali_pp_job *job, u32 sub_job)
449 {
450         MALI_DEBUG_ASSERT_POINTER(job);
451         MALI_DEBUG_ASSERT_SCHEDULER_LOCK_HELD();
452
453         /* Assert that we are marking the "first unstarted sub job" as started */
454         MALI_DEBUG_ASSERT(job->sub_jobs_started == sub_job);
455
456         job->sub_jobs_started++;
457 }
458
459 MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_completed(struct mali_pp_job *job, mali_bool success)
460 {
461         MALI_DEBUG_ASSERT_POINTER(job);
462
463         _mali_osk_atomic_inc(&job->sub_jobs_completed);
464         if (MALI_FALSE == success) {
465                 _mali_osk_atomic_inc(&job->sub_job_errors);
466         }
467 }
468
469 MALI_STATIC_INLINE mali_bool mali_pp_job_was_success(struct mali_pp_job *job)
470 {
471         MALI_DEBUG_ASSERT_POINTER(job);
472         if (0 == _mali_osk_atomic_read(&job->sub_job_errors)) {
473                 return MALI_TRUE;
474         }
475         return MALI_FALSE;
476 }
477
478 MALI_STATIC_INLINE mali_bool mali_pp_job_use_no_notification(
479         struct mali_pp_job *job)
480 {
481         MALI_DEBUG_ASSERT_POINTER(job);
482         return (job->uargs.flags & _MALI_PP_JOB_FLAG_NO_NOTIFICATION) ?
483                MALI_TRUE : MALI_FALSE;
484 }
485
486 MALI_STATIC_INLINE mali_bool mali_pp_job_is_pilot_job(struct mali_pp_job *job)
487 {
488         /*
489          * A pilot job is currently identified as jobs which
490          * require no callback notification.
491          */
492         return mali_pp_job_use_no_notification(job);
493 }
494
495 MALI_STATIC_INLINE _mali_osk_notification_t *
496 mali_pp_job_get_finished_notification(struct mali_pp_job *job)
497 {
498         _mali_osk_notification_t *notification;
499
500         MALI_DEBUG_ASSERT_POINTER(job);
501         MALI_DEBUG_ASSERT_POINTER(job->finished_notification);
502
503         notification = job->finished_notification;
504         job->finished_notification = NULL;
505
506         return notification;
507 }
508
509 MALI_STATIC_INLINE mali_bool mali_pp_job_is_window_surface(
510         struct mali_pp_job *job)
511 {
512         MALI_DEBUG_ASSERT_POINTER(job);
513         return (job->uargs.flags & _MALI_PP_JOB_FLAG_IS_WINDOW_SURFACE)
514                ? MALI_TRUE : MALI_FALSE;
515 }
516
517 MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_flag(struct mali_pp_job *job)
518 {
519         MALI_DEBUG_ASSERT_POINTER(job);
520         return job->uargs.perf_counter_flag;
521 }
522
523 MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_value0(struct mali_pp_job *job, u32 sub_job)
524 {
525         MALI_DEBUG_ASSERT_POINTER(job);
526         return job->perf_counter_value0[sub_job];
527 }
528
529 MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_value1(struct mali_pp_job *job, u32 sub_job)
530 {
531         MALI_DEBUG_ASSERT_POINTER(job);
532         return job->perf_counter_value1[sub_job];
533 }
534
535 MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_value0(struct mali_pp_job *job, u32 sub_job, u32 value)
536 {
537         MALI_DEBUG_ASSERT_POINTER(job);
538         MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
539         job->perf_counter_value0[sub_job] = value;
540 }
541
542 MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_value1(struct mali_pp_job *job, u32 sub_job, u32 value)
543 {
544         MALI_DEBUG_ASSERT_POINTER(job);
545         MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
546         job->perf_counter_value1[sub_job] = value;
547 }
548
549 MALI_STATIC_INLINE _mali_osk_errcode_t mali_pp_job_check(struct mali_pp_job *job)
550 {
551         MALI_DEBUG_ASSERT_POINTER(job);
552         if (mali_pp_job_is_virtual(job) && job->sub_jobs_num != 1) {
553                 return _MALI_OSK_ERR_FAULT;
554         }
555         return _MALI_OSK_ERR_OK;
556 }
557
558 /**
559  * Returns MALI_TRUE if this job has more than two sub jobs and all sub jobs are unstarted.
560  *
561  * @param job Job to check.
562  * @return MALI_TRUE if job has more than two sub jobs and all sub jobs are unstarted, MALI_FALSE if not.
563  */
564 MALI_STATIC_INLINE mali_bool mali_pp_job_is_large_and_unstarted(struct mali_pp_job *job)
565 {
566         MALI_DEBUG_ASSERT_POINTER(job);
567         MALI_DEBUG_ASSERT_SCHEDULER_LOCK_HELD();
568         MALI_DEBUG_ASSERT(!mali_pp_job_is_virtual(job));
569
570         return (0 == job->sub_jobs_started && 2 < job->sub_jobs_num);
571 }
572
573 /**
574  * Get PP job's Timeline tracker.
575  *
576  * @param job PP job.
577  * @return Pointer to Timeline tracker for the job.
578  */
579 MALI_STATIC_INLINE struct mali_timeline_tracker *mali_pp_job_get_tracker(struct mali_pp_job *job)
580 {
581         MALI_DEBUG_ASSERT_POINTER(job);
582         return &(job->tracker);
583 }
584
585 MALI_STATIC_INLINE u32 *mali_pp_job_get_timeline_point_ptr(
586         struct mali_pp_job *job)
587 {
588         MALI_DEBUG_ASSERT_POINTER(job);
589         return (u32 __user *)(uintptr_t)job->uargs.timeline_point_ptr;
590 }
591
592
593 #endif /* __MALI_PP_JOB_H__ */