blob: 8e0c32108f96bae4ab4bdadca3cf182e01927b2d [file] [log] [blame]
Jordan Crousef5ad1992019-09-09 10:41:36 -06001/* Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved.
Shrenuj Bansala419c792016-10-20 14:05:11 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13#ifndef __ADRENO_RINGBUFFER_H
14#define __ADRENO_RINGBUFFER_H
15
16#include "kgsl_iommu.h"
17#include "adreno_iommu.h"
18#include "adreno_dispatch.h"
19
20/* Given a ringbuffer, return the adreno device that owns it */
21
22#define _RB_OFFSET(_id) (offsetof(struct adreno_device, ringbuffers) + \
23 ((_id) * sizeof(struct adreno_ringbuffer)))
24
25#define ADRENO_RB_DEVICE(_rb) \
26 ((struct adreno_device *) (((void *) (_rb)) - _RB_OFFSET((_rb)->id)))
27
28/* Adreno ringbuffer size in bytes */
29#define KGSL_RB_SIZE (32 * 1024)
30
31/*
32 * A handy macro to convert the RB size to dwords since most ringbuffer
33 * operations happen in dword increments
34 */
35#define KGSL_RB_DWORDS (KGSL_RB_SIZE >> 2)
36
37struct kgsl_device;
38struct kgsl_device_private;
39
40/**
41 * struct adreno_submit_time - utility structure to store the wall clock / GPU
42 * ticks at command submit time
43 * @ticks: GPU ticks at submit time (from the 19.2Mhz timer)
44 * @ktime: local clock time (in nanoseconds)
45 * @utime: Wall clock time
Harshdeep Dhatt358ad222018-02-02 11:48:39 -070046 * @drawobj: the object that we want to profile
Shrenuj Bansala419c792016-10-20 14:05:11 -070047 */
48struct adreno_submit_time {
49 uint64_t ticks;
50 u64 ktime;
51 struct timespec utime;
Harshdeep Dhatt358ad222018-02-02 11:48:39 -070052 struct kgsl_drawobj *drawobj;
Shrenuj Bansala419c792016-10-20 14:05:11 -070053};
54
55/**
56 * struct adreno_ringbuffer_pagetable_info - Contains fields used during a
57 * pagetable switch.
58 * @current_global_ptname: The current pagetable id being used by the GPU.
59 * Only the ringbuffers[0] current_global_ptname is used to keep track of
60 * the current pagetable id
61 * @current_rb_ptname: The current pagetable active on the given RB
62 * @incoming_ptname: Contains the incoming pagetable we are switching to. After
63 * switching of pagetable this value equals current_rb_ptname.
64 * @switch_pt_enable: Flag used during pagetable switch to check if pt
65 * switch can be skipped
66 * @ttbr0: value to program into TTBR0 during pagetable switch.
67 * @contextidr: value to program into CONTEXTIDR during pagetable switch.
68 */
69struct adreno_ringbuffer_pagetable_info {
70 int current_global_ptname;
71 int current_rb_ptname;
72 int incoming_ptname;
73 int switch_pt_enable;
74 uint64_t ttbr0;
75 unsigned int contextidr;
76};
77
78#define PT_INFO_OFFSET(_field) \
79 offsetof(struct adreno_ringbuffer_pagetable_info, _field)
80
81/**
82 * struct adreno_ringbuffer - Definition for an adreno ringbuffer object
83 * @flags: Internal control flags for the ringbuffer
84 * @buffer_desc: Pointer to the ringbuffer memory descripto
85 * @_wptr: The next value of wptr to be written to the hardware on submit
86 * @wptr: Local copy of the wptr offset last written to hardware
87 * @last_wptr: offset of the last wptr that was written to CFF
88 * @rb_ctx: The context that represents a ringbuffer
89 * @id: Priority level of the ringbuffer, also used as an ID
90 * @fault_detect_ts: The last retired global timestamp read during fault detect
91 * @timestamp: The RB's global timestamp
92 * @events: A kgsl_event_group for this context - contains the list of GPU
93 * events
94 * @drawctxt_active: The last pagetable that this ringbuffer is set to
95 * @preemption_desc: The memory descriptor containing
96 * preemption info written/read by CP
Harshdeep Dhatt58b70eb2017-03-28 09:21:40 -060097 * @secure_preemption_desc: The memory descriptor containing
98 * preemption info written/read by CP for secure contexts
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -060099 * @perfcounter_save_restore_desc: Used by CP to save/restore the perfcounter
100 * values across preemption
Shrenuj Bansala419c792016-10-20 14:05:11 -0700101 * @pagetable_desc: Memory to hold information about the pagetables being used
102 * and the commands to switch pagetable on the RB
103 * @dispatch_q: The dispatcher side queue for this ringbuffer
104 * @ts_expire_waitq: Wait queue to wait for rb timestamp to expire
105 * @ts_expire_waitq: Wait q to wait for rb timestamp to expire
106 * @wptr_preempt_end: Used during preemption to check that preemption occurred
107 * at the right rptr
108 * @gpr11: The gpr11 value of this RB
109 * @preempted_midway: Indicates that the RB was preempted before rptr = wptr
110 * @sched_timer: Timer that tracks how long RB has been waiting to be scheduled
111 * or how long it has been scheduled for after preempting in
112 * @starve_timer_state: Indicates the state of the wait.
113 * @preempt_lock: Lock to protect the wptr pointer while it is being updated
114 */
115struct adreno_ringbuffer {
116 uint32_t flags;
117 struct kgsl_memdesc buffer_desc;
118 unsigned int _wptr;
119 unsigned int wptr;
120 unsigned int last_wptr;
121 int id;
122 unsigned int fault_detect_ts;
123 unsigned int timestamp;
124 struct kgsl_event_group events;
125 struct adreno_context *drawctxt_active;
126 struct kgsl_memdesc preemption_desc;
Harshdeep Dhatt58b70eb2017-03-28 09:21:40 -0600127 struct kgsl_memdesc secure_preemption_desc;
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600128 struct kgsl_memdesc perfcounter_save_restore_desc;
Shrenuj Bansala419c792016-10-20 14:05:11 -0700129 struct kgsl_memdesc pagetable_desc;
130 struct adreno_dispatcher_drawqueue dispatch_q;
131 wait_queue_head_t ts_expire_waitq;
132 unsigned int wptr_preempt_end;
133 unsigned int gpr11;
134 int preempted_midway;
135 unsigned long sched_timer;
136 enum adreno_dispatcher_starve_timer_states starve_timer_state;
137 spinlock_t preempt_lock;
Jordan Crousef5ad1992019-09-09 10:41:36 -0600138 /**
139 * @profile_desc: global memory to construct IB1s to do user side
140 * profiling
141 */
142 struct kgsl_memdesc profile_desc;
143 /**
144 * @profile_index: Pointer to the next "slot" in profile_desc for a user
145 * profiling IB1. This allows for PAGE_SIZE / 16 = 256 simultaneous
146 * commands per ringbuffer with user profiling enabled
147 * enough.
148 */
149 u32 profile_index;
Shrenuj Bansala419c792016-10-20 14:05:11 -0700150};
151
152/* Returns the current ringbuffer */
153#define ADRENO_CURRENT_RINGBUFFER(a) ((a)->cur_rb)
154
155int cp_secure_mode(struct adreno_device *adreno_dev, uint *cmds, int set);
156
157int adreno_ringbuffer_issueibcmds(struct kgsl_device_private *dev_priv,
158 struct kgsl_context *context,
159 struct kgsl_drawobj *drawobj,
160 uint32_t *timestamp);
161
162int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev,
163 struct kgsl_drawobj_cmd *cmdobj,
164 struct adreno_submit_time *time);
165
166int adreno_ringbuffer_probe(struct adreno_device *adreno_dev, bool nopreempt);
167
168int adreno_ringbuffer_start(struct adreno_device *adreno_dev,
169 unsigned int start_type);
170
171void adreno_ringbuffer_stop(struct adreno_device *adreno_dev);
172
173void adreno_ringbuffer_close(struct adreno_device *adreno_dev);
174
Harshdeep Dhattd91388b2017-12-08 15:51:49 -0700175int adreno_ringbuffer_issue_internal_cmds(struct adreno_ringbuffer *rb,
Shrenuj Bansala419c792016-10-20 14:05:11 -0700176 unsigned int flags,
177 unsigned int *cmdaddr,
178 int sizedwords);
179
180void adreno_ringbuffer_submit(struct adreno_ringbuffer *rb,
181 struct adreno_submit_time *time);
182
183int adreno_ringbuffer_submit_spin(struct adreno_ringbuffer *rb,
184 struct adreno_submit_time *time, unsigned int timeout);
185
186void kgsl_cp_intrcallback(struct kgsl_device *device);
187
188unsigned int *adreno_ringbuffer_allocspace(struct adreno_ringbuffer *rb,
189 unsigned int numcmds);
190
191void adreno_ringbuffer_read_pfp_ucode(struct kgsl_device *device);
192
193void adreno_ringbuffer_read_pm4_ucode(struct kgsl_device *device);
194
195int adreno_ringbuffer_waittimestamp(struct adreno_ringbuffer *rb,
196 unsigned int timestamp,
197 unsigned int msecs);
198
199int adreno_rb_readtimestamp(struct adreno_device *adreno_dev,
200 void *priv, enum kgsl_timestamp_type type,
201 unsigned int *timestamp);
202
203static inline int adreno_ringbuffer_count(struct adreno_ringbuffer *rb,
204 unsigned int rptr)
205{
206 if (rb->wptr >= rptr)
207 return rb->wptr - rptr;
208 return rb->wptr + KGSL_RB_DWORDS - rptr;
209}
210
211/* Increment a value by 4 bytes with wrap-around based on size */
212static inline unsigned int adreno_ringbuffer_inc_wrapped(unsigned int val,
213 unsigned int size)
214{
215 return (val + sizeof(unsigned int)) % size;
216}
217
218/* Decrement a value by 4 bytes with wrap-around based on size */
219static inline unsigned int adreno_ringbuffer_dec_wrapped(unsigned int val,
220 unsigned int size)
221{
222 return (val + size - sizeof(unsigned int)) % size;
223}
224
225static inline int adreno_ringbuffer_set_pt_ctx(struct adreno_ringbuffer *rb,
226 struct kgsl_pagetable *pt, struct adreno_context *context,
227 unsigned long flags)
228{
229 return adreno_iommu_set_pt_ctx(rb, pt, context, flags);
230}
231
232#endif /* __ADRENO_RINGBUFFER_H */