summaryrefslogtreecommitdiff
path: root/mali_kbase/csf/mali_kbase_csf_kcpu.h
blob: 85d76444201525a04d29146a7f6448913f06bac3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
 *
 * (C) COPYRIGHT 2018-2023 ARM Limited. All rights reserved.
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU license.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 */

#ifndef _KBASE_CSF_KCPU_H_
#define _KBASE_CSF_KCPU_H_

#include <mali_kbase_fence.h>
#include <mali_kbase_sync.h>

#include <linux/version_compat_defs.h>

/* The maximum number of KCPU commands in flight, enqueueing more commands
 * than this value shall block.
 */
#define KBASEP_KCPU_QUEUE_SIZE ((size_t)256)

/**
 * struct kbase_kcpu_command_import_info - Structure which holds information
 *				about the buffer to be imported
 *
 * @gpu_va:	Address of the buffer to be imported.
 */
struct kbase_kcpu_command_import_info {
	u64 gpu_va;
};

/**
 * struct kbase_kcpu_command_fence_info - Structure which holds information about the
 *                                        fence object enqueued in the kcpu command queue
 *
 * @fence_cb:      Fence callback
 * @fence:         Fence
 * @kcpu_queue:    kcpu command queue
 * @fence_has_force_signaled:	fence has forced signaled after fence timeouted
 */
struct kbase_kcpu_command_fence_info {
	struct dma_fence_cb fence_cb;
	struct dma_fence *fence;
	struct kbase_kcpu_command_queue *kcpu_queue;
	bool fence_has_force_signaled;
};

/**
 * struct kbase_kcpu_command_cqs_set_info - Structure which holds information
 *				about CQS objects for the kcpu CQS set command
 *
 * @objs:	Array of structures which define CQS objects to be used by
 *		the kcpu command.
 * @nr_objs:	Number of CQS objects in the array.
 */
struct kbase_kcpu_command_cqs_set_info {
	struct base_cqs_set *objs;
	unsigned int nr_objs;
};

/**
 * struct kbase_kcpu_command_cqs_wait_info - Structure which holds information
 *				about CQS objects for the kcpu CQS wait command
 *
 * @objs:	Array of structures which define CQS objects to be used by
 *		the kcpu command.
 * @signaled:	Bit array used to report the status of the CQS wait objects.
 *              1 is signaled, 0 otherwise.
 * @nr_objs:	Number of CQS objects in the array.
 * @inherit_err_flags:	Bit-pattern for the CQSs in the array who's error field
 *			to be served as the source for importing into the
 *			queue's error-state.
 */
struct kbase_kcpu_command_cqs_wait_info {
	struct base_cqs_wait_info *objs;
	unsigned long *signaled;
	unsigned int nr_objs;
	u32 inherit_err_flags;
};

/**
 * struct kbase_kcpu_command_cqs_set_operation_info - Structure which holds information
 *				about CQS objects for the kcpu CQS timeline set command
 *
 * @objs:	Array of structures which define CQS timeline objects to be used by
 *		the kcpu command.
 * @nr_objs:	Number of CQS objects in the array.
 */
struct kbase_kcpu_command_cqs_set_operation_info {
	struct base_cqs_set_operation_info *objs;
	unsigned int nr_objs;
};

/**
 * struct kbase_kcpu_command_cqs_wait_operation_info - Structure which holds information
 *				about CQS objects for the kcpu CQS timeline wait command
 *
 * @objs:	Array of structures which define CQS timeline objects to be used by
 *		the kcpu command.
 * @signaled:	Bit array used to report the status of the CQS wait objects.
 *              1 is signaled, 0 otherwise.
 * @nr_objs:	Number of CQS objects in the array.
 * @inherit_err_flags: Bit-pattern for CQSs in the array who's error field is to
 *                     be used as the source to import into the queue's error-state
 */
struct kbase_kcpu_command_cqs_wait_operation_info {
	struct base_cqs_wait_operation_info *objs;
	unsigned long *signaled;
	unsigned int nr_objs;
	u32 inherit_err_flags;
};

/**
 * struct kbase_kcpu_command_jit_alloc_info - Structure which holds information
 *				needed for the kcpu command for jit allocations
 *
 * @node:	Used to keep track of all JIT free/alloc commands in submission
 *		order. This must be located in the front of this struct to
 *		match that of kbase_kcpu_command_jit_free_info.
 * @info:	Array of objects of the struct base_jit_alloc_info type which
 *		specify jit allocations to be made by the kcpu command.
 * @count:	Number of jit alloc objects in the array.
 * @blocked:	Whether this allocation has been put into the pending list to
 *		be retried later.
 */
struct kbase_kcpu_command_jit_alloc_info {
	struct list_head node;
	struct base_jit_alloc_info *info;
	u8 count;
	bool blocked;
};

/**
 * struct kbase_kcpu_command_jit_free_info - Structure which holds information
 *				needed for the kcpu jit free command
 *
 * @node:	Used to keep track of all JIT free/alloc commands in submission
 *		order. This must be located in the front of this struct to
 *		match that of kbase_kcpu_command_jit_alloc_info.
 * @ids:	Array of identifiers of jit allocations which are to be freed
 *		by the kcpu command.
 * @count:	Number of elements in the array.
 */
struct kbase_kcpu_command_jit_free_info {
	struct list_head node;
	u8 *ids;
	u8 count;
};

/**
 * struct kbase_suspend_copy_buffer - information about the suspend buffer
 *		to be copied.
 *
 * @size:	size of the suspend buffer in bytes.
 * @pages:	pointer to an array of pointers to the pages which contain
 *		the user buffer.
 * @nr_pages:	number of pages.
 * @offset:	offset into the pages
 * @cpu_alloc:	Reference to physical pages of suspend buffer allocation.
 */
struct kbase_suspend_copy_buffer {
	size_t size;
	struct page **pages;
	unsigned int nr_pages;
	size_t offset;
	struct kbase_mem_phy_alloc *cpu_alloc;
};

#if IS_ENABLED(CONFIG_MALI_VECTOR_DUMP) || MALI_UNIT_TEST
/**
 * struct kbase_kcpu_command_group_suspend_info - structure which contains
 *		suspend buffer data captured for a suspended queue group.
 *
 * @sus_buf:		Pointer to the structure which contains details of the
 *			user buffer and its kernel pinned pages.
 * @group_handle:	Handle to the mapping of CSG.
 */
struct kbase_kcpu_command_group_suspend_info {
	struct kbase_suspend_copy_buffer *sus_buf;
	u8 group_handle;
};
#endif


/**
 * struct kbase_kcpu_command - Command which is to be part of the kernel
 *                            command queue
 *
 * @type:	Type of the command.
 * @enqueue_ts:	Denotes the relative time of enqueueing, a smaller value
 *		indicates that it has been enqueued earlier.
 * @info:	Structure which holds information about the command
 *		dependent on the command type.
 * @info.fence:              Fence
 * @info.cqs_wait:           CQS wait
 * @info.cqs_set:            CQS set
 * @info.cqs_wait_operation: CQS wait operation
 * @info.cqs_set_operation:  CQS set operation
 * @info.import:             import
 * @info.jit_alloc:          JIT allocation
 * @info.jit_free:           JIT deallocation
 * @info.suspend_buf_copy:   suspend buffer copy
 * @info.sample_time:        sample time
 */
struct kbase_kcpu_command {
	enum base_kcpu_command_type type;
	u64 enqueue_ts;
	union {
		struct kbase_kcpu_command_fence_info fence;
		struct kbase_kcpu_command_cqs_wait_info cqs_wait;
		struct kbase_kcpu_command_cqs_set_info cqs_set;
		struct kbase_kcpu_command_cqs_wait_operation_info cqs_wait_operation;
		struct kbase_kcpu_command_cqs_set_operation_info cqs_set_operation;
		struct kbase_kcpu_command_import_info import;
		struct kbase_kcpu_command_jit_alloc_info jit_alloc;
		struct kbase_kcpu_command_jit_free_info jit_free;
#if IS_ENABLED(CONFIG_MALI_VECTOR_DUMP) || MALI_UNIT_TEST
		struct kbase_kcpu_command_group_suspend_info suspend_buf_copy;
#endif
	} info;
};

/**
 * struct kbase_kcpu_command_queue - a command queue executed by the kernel
 *
 * @lock:			Lock to protect accesses to this queue.
 * @kctx:			The context to which this command queue belongs.
 * @commands:			Array of commands which have been successfully
 *				enqueued to this command queue.
 * @work:			struct kthread_work which contains a pointer to
 *				the function which handles processing of kcpu
 *				commands enqueued into a kcpu command queue;
 *				part of kernel API for processing workqueues
 *				This would be used if the context is not
 *				prioritised, otherwise it would be handled by
 *				kbase_csf_scheduler_kthread().
 * @timeout_work:		struct kthread_work which contains a pointer to the
 *				function which handles post-timeout actions
 *				queue when a fence signal timeout occurs.
 * @high_prio_work:		A counterpart to @work, this queue would be
 *				added to a list to be processed by
 *				kbase_csf_scheduler_kthread() if it is
 *				prioritised.
 * @pending_kick:		Indicates that kbase_csf_scheduler_kthread()
 *				should re-evaluate pending commands for this
 *				queue. This would be set to false when the work
 *				is done. This is used mainly for
 *				synchronisation with queue termination.
 * @start_offset:		Index of the command to be executed next
 * @id:				KCPU command queue ID.
 * @num_pending_cmds:		The number of commands enqueued but not yet
 *				executed or pending
 * @cqs_wait_count:		Tracks the number of CQS wait commands enqueued
 * @fence_context:		The dma-buf fence context number for this kcpu
 *				queue. A unique context number is allocated for
 *				each kcpu queue.
 * @fence_seqno:		The dma-buf fence sequence number for the fence
 *				that is returned on the enqueue of fence signal
 *				command. This is increased every time the
 *				fence signal command is queued.
 * @fence_wait_processed:	Used to avoid reprocessing of the fence wait
 *				command which has blocked the processing of
 *				commands that follow it.
 * @enqueue_failed:		Indicates that no space has become available in
 *				the buffer since an enqueue operation failed
 *				because of insufficient free space.
 * @command_started:		Indicates that the command at the front of the
 *				queue has been started in a previous queue
 *				process, but was not completed due to some
 *				unmet dependencies. Ensures that instrumentation
 *				of the execution start of these commands is only
 *				fired exactly once.
 * @has_error:			Indicates that the kcpu queue is in error mode
 *				or without errors since last cleaned.
 * @jit_blocked:		Used to keep track of command queues blocked
 *				by a pending JIT allocation command.
 * @fence_timeout:		Timer used to detect the fence wait timeout.
 * @metadata:                   Metadata structure containing basic information about
 *                              this queue for any fence objects associated with this queue.
 * @fence_signal_timeout:	Timer used for detect a fence signal command has
 *				been blocked for too long.
 * @fence_signal_pending_cnt:	Enqueued fence signal commands in the queue.
 */
struct kbase_kcpu_command_queue {
	struct mutex lock;
	struct kbase_context *kctx;
	struct kbase_kcpu_command commands[KBASEP_KCPU_QUEUE_SIZE];
	struct kthread_work work;
	struct kthread_work timeout_work;
	struct list_head high_prio_work;
	atomic_t pending_kick;
	u8 start_offset;
	u8 id;
	u16 num_pending_cmds;
	u32 cqs_wait_count;
	u64 fence_context;
	unsigned int fence_seqno;
	bool fence_wait_processed;
	bool enqueue_failed;
	bool command_started;
	struct list_head jit_blocked;
	bool has_error;
	struct timer_list fence_timeout;
#if IS_ENABLED(CONFIG_SYNC_FILE)
	struct kbase_kcpu_dma_fence_meta *metadata;
#endif /* CONFIG_SYNC_FILE */
	struct timer_list fence_signal_timeout;
	atomic_t fence_signal_pending_cnt;
};

/**
 * kbase_csf_kcpu_queue_new - Create new KCPU command queue.
 *
 * @kctx:	Pointer to the kbase context within which the KCPU command
 *		queue will be created.
 * @newq:	Pointer to the structure which contains information about
 *		the new KCPU command queue to be created.
 *
 * Return: 0 if successful or a negative error code on failure.
 */
int kbase_csf_kcpu_queue_new(struct kbase_context *kctx, struct kbase_ioctl_kcpu_queue_new *newq);

/**
 * kbase_csf_kcpu_queue_delete - Delete KCPU command queue.
 *
 * @kctx:	Pointer to the kbase context from which the KCPU command
 *		queue is to be deleted.
 * @del:	Pointer to the structure which specifies the KCPU command
 *		queue to be deleted.
 *
 * Return: 0 if successful or a negative error code on failure.
 */
int kbase_csf_kcpu_queue_delete(struct kbase_context *kctx,
				struct kbase_ioctl_kcpu_queue_delete *del);

/**
 * kbase_csf_kcpu_queue_process - Proces pending KCPU queue commands
 *
 * @queue:		The queue to process pending commands for
 * @drain_queue:	Whether to skip all blocking commands in the queue.
 *			This is expected to be set to true on queue
 *			termination.
 *
 * Return: 0 if successful or a negative error code on failure.
 */
void kbase_csf_kcpu_queue_process(struct kbase_kcpu_command_queue *queue, bool drain_queue);

/**
 * kbase_csf_kcpu_queue_enqueue - Enqueue a KCPU command into a KCPU command
 *				  queue.
 *
 * @kctx:	Pointer to the kbase context within which the KCPU command
 *		is to be enqueued into the KCPU command queue.
 * @enq:	Pointer to the structure which specifies the KCPU command
 *		as well as the KCPU command queue into which the command
 *		is to be enqueued.
 *
 * Return: 0 if successful or a negative error code on failure.
 */
int kbase_csf_kcpu_queue_enqueue(struct kbase_context *kctx,
				 struct kbase_ioctl_kcpu_queue_enqueue *enq);

/**
 * kbase_csf_kcpu_queue_context_init - Initialize the kernel CPU queues context
 *                                     for a GPU address space
 *
 * @kctx: Pointer to the kbase context being initialized.
 *
 * This function must be called only when a kbase context is instantiated.
 *
 * Return: 0 if successful or a negative error code on failure.
 */
int kbase_csf_kcpu_queue_context_init(struct kbase_context *kctx);

/**
 * kbase_csf_kcpu_queue_context_term - Terminate the kernel CPU queues context
 *                                     for a GPU address space
 * @kctx: Pointer to the kbase context being terminated.
 *
 * This function deletes any kernel CPU queues that weren't deleted before
 * context termination.
 *
 */
void kbase_csf_kcpu_queue_context_term(struct kbase_context *kctx);

#if IS_ENABLED(CONFIG_SYNC_FILE)
/* Test wrappers for dma fence operations. */
int kbase_kcpu_fence_signal_process(struct kbase_kcpu_command_queue *kcpu_queue,
				    struct kbase_kcpu_command_fence_info *fence_info);

int kbase_kcpu_fence_signal_init(struct kbase_kcpu_command_queue *kcpu_queue,
				 struct kbase_kcpu_command *current_command,
				 struct base_fence *fence, struct sync_file **sync_file, int *fd);
#endif /* CONFIG_SYNC_FILE */

/*
 * kbase_csf_kcpu_queue_halt_timers - Halt the KCPU fence timers associated with
 *                                    the kbase device.
 *
 * @kbdev: Kbase device
 *
 * Note that this function assumes that the caller has ensured that the
 * kbase_device::kctx_list does not get updated during this function's runtime.
 * At the moment, the function is only safe to call during system suspend, when
 * the device PM active count has reached zero.
 *
 * Return: 0 on success, negative value otherwise.
 */
int kbase_csf_kcpu_queue_halt_timers(struct kbase_device *kbdev);

/*
 * kbase_csf_kcpu_queue_resume_timers - Resume the KCPU fence timers associated
 *                                      with the kbase device.
 *
 * @kbdev: Kbase device
 *
 * Note that this function assumes that the caller has ensured that the
 * kbase_device::kctx_list does not get updated during this function's runtime.
 * At the moment, the function is only safe to call during system resume.
 */
void kbase_csf_kcpu_queue_resume_timers(struct kbase_device *kbdev);

bool kbase_kcpu_command_fence_has_force_signaled(struct kbase_kcpu_command_fence_info *fence_info);
#endif /* _KBASE_CSF_KCPU_H_ */