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
|
/* Copyright (c) 2002,2007-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* 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.
*
*/
#ifndef __ADRENO_DRAWCTXT_H
#define __ADRENO_DRAWCTXT_H
struct adreno_context_type {
unsigned int type;
const char *str;
};
#define ADRENO_CONTEXT_DRAWQUEUE_SIZE 128
#define SUBMIT_RETIRE_TICKS_SIZE 7
struct kgsl_device;
struct adreno_device;
struct kgsl_device_private;
struct kgsl_context;
/**
* struct adreno_context - Adreno GPU draw context
* @timestamp: Last issued context-specific timestamp
* @internal_timestamp: Global timestamp of the last issued command
* NOTE: guarded by device->mutex, not drawctxt->mutex!
* @type: Context type (GL, CL, RS)
* @mutex: Mutex to protect the drawqueue
* @drawqueue: Queue of drawobjs waiting to be dispatched for this
* context
* @drawqueue_head: Head of the drawqueue queue
* @drawqueue_tail: Tail of the drawqueue queue
* @pending: Priority list node for the dispatcher list of pending contexts
* @wq: Workqueue structure for contexts to sleep pending room in the queue
* @waiting: Workqueue structure for contexts waiting for a timestamp or event
* @timeout: Workqueue structure for contexts waiting to invalidate
* @queued: Number of commands queued in the drawqueue
* @fault_policy: GFT fault policy set in _skip_cmd();
* @debug_root: debugfs entry for this context.
* @queued_timestamp: The last timestamp that was queued on this context
* @rb: The ringbuffer in which this context submits commands.
* @submitted_timestamp: The last timestamp that was submitted for this context
* @submit_retire_ticks: Array to hold command obj execution times from submit
* to retire
* @ticks_index: The index into submit_retire_ticks[] where the new delta will
* be written.
* @active_node: Linkage for nodes in active_list
* @active_time: Time when this context last seen
*/
struct adreno_context {
struct kgsl_context base;
unsigned int timestamp;
unsigned int internal_timestamp;
unsigned int type;
spinlock_t lock;
/* Dispatcher */
struct kgsl_drawobj *drawqueue[ADRENO_CONTEXT_DRAWQUEUE_SIZE];
unsigned int drawqueue_head;
unsigned int drawqueue_tail;
struct plist_node pending;
wait_queue_head_t wq;
wait_queue_head_t waiting;
wait_queue_head_t timeout;
int queued;
unsigned int fault_policy;
struct dentry *debug_root;
unsigned int queued_timestamp;
struct adreno_ringbuffer *rb;
unsigned int submitted_timestamp;
uint64_t submit_retire_ticks[SUBMIT_RETIRE_TICKS_SIZE];
int ticks_index;
struct list_head active_node;
unsigned long active_time;
};
/* Flag definitions for flag field in adreno_context */
/**
* enum adreno_context_priv - Private flags for an adreno draw context
* @ADRENO_CONTEXT_FAULT - set if the context has faulted (and recovered)
* @ADRENO_CONTEXT_GPU_HANG - Context has caused a GPU hang
* @ADRENO_CONTEXT_GPU_HANG_FT - Context has caused a GPU hang
* and fault tolerance was successful
* @ADRENO_CONTEXT_SKIP_EOF - Context skip IBs until the next end of frame
* marker.
* @ADRENO_CONTEXT_FORCE_PREAMBLE - Force the preamble for the next submission.
* @ADRENO_CONTEXT_SKIP_CMD - Context's drawobj's skipped during
fault tolerance.
* @ADRENO_CONTEXT_FENCE_LOG - Dump fences on this context.
*/
enum adreno_context_priv {
ADRENO_CONTEXT_FAULT = KGSL_CONTEXT_PRIV_DEVICE_SPECIFIC,
ADRENO_CONTEXT_GPU_HANG,
ADRENO_CONTEXT_GPU_HANG_FT,
ADRENO_CONTEXT_SKIP_EOF,
ADRENO_CONTEXT_FORCE_PREAMBLE,
ADRENO_CONTEXT_SKIP_CMD,
ADRENO_CONTEXT_FENCE_LOG,
};
/* Flags for adreno_drawctxt_switch() */
#define ADRENO_CONTEXT_SWITCH_FORCE_GPU BIT(0)
struct kgsl_context *adreno_drawctxt_create(struct kgsl_device_private *,
uint32_t *flags);
void adreno_drawctxt_detach(struct kgsl_context *context);
void adreno_drawctxt_destroy(struct kgsl_context *context);
void adreno_drawctxt_sched(struct kgsl_device *device,
struct kgsl_context *context);
struct adreno_ringbuffer;
int adreno_drawctxt_switch(struct adreno_device *adreno_dev,
struct adreno_ringbuffer *rb,
struct adreno_context *drawctxt,
unsigned int flags);
int adreno_drawctxt_wait(struct adreno_device *adreno_dev,
struct kgsl_context *context,
uint32_t timestamp, unsigned int timeout);
void adreno_drawctxt_invalidate(struct kgsl_device *device,
struct kgsl_context *context);
void adreno_drawctxt_dump(struct kgsl_device *device,
struct kgsl_context *context);
static struct adreno_context_type ctxt_type_table[] = {KGSL_CONTEXT_TYPES};
static inline const char *get_api_type_str(unsigned int type)
{
int i;
for (i = 0; i < ARRAY_SIZE(ctxt_type_table); i++) {
if (ctxt_type_table[i].type == type)
return ctxt_type_table[i].str;
}
return "UNKNOWN";
}
#endif /* __ADRENO_DRAWCTXT_H */
|