blob: b9dd5f4564b55a2727c7a0f682bd74c90cd88dc6 [file] [log] [blame]
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -06001/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
2 *
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#include "adreno.h"
14#include "adreno_a6xx.h"
15#include "a6xx_reg.h"
16#include "adreno_trace.h"
17#include "adreno_pm4types.h"
18
19#define PREEMPT_RECORD(_field) \
20 offsetof(struct a6xx_cp_preemption_record, _field)
21
22#define PREEMPT_SMMU_RECORD(_field) \
23 offsetof(struct a6xx_cp_smmu_info, _field)
24
25enum {
26 SET_PSEUDO_REGISTER_SAVE_REGISTER_SMMU_INFO = 0,
27 SET_PSEUDO_REGISTER_SAVE_REGISTER_PRIV_NON_SECURE_SAVE_ADDR,
28 SET_PSEUDO_REGISTER_SAVE_REGISTER_PRIV_SECURE_SAVE_ADDR,
29 SET_PSEUDO_REGISTER_SAVE_REGISTER_NON_PRIV_SAVE_ADDR,
30 SET_PSEUDO_REGISTER_SAVE_REGISTER_COUNTER,
31};
32
33static void _update_wptr(struct adreno_device *adreno_dev, bool reset_timer)
34{
35 struct adreno_ringbuffer *rb = adreno_dev->cur_rb;
36 unsigned int wptr;
37 unsigned long flags;
Harshdeep Dhatt664ee632017-11-01 15:03:11 -060038 struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
39
40 /*
41 * Need to make sure GPU is up before we read the
42 * WPTR as fence doesn't wake GPU on read operation.
43 */
44 if (in_interrupt() == 0) {
45 int status;
46
47 if (gpudev->oob_set) {
48 status = gpudev->oob_set(adreno_dev,
49 OOB_PREEMPTION_SET_MASK,
50 OOB_PREEMPTION_CHECK_MASK,
51 OOB_PREEMPTION_CLEAR_MASK);
52 if (status)
53 return;
54 }
55 }
56
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -060057
58 spin_lock_irqsave(&rb->preempt_lock, flags);
59
60 adreno_readreg(adreno_dev, ADRENO_REG_CP_RB_WPTR, &wptr);
61
62 if (wptr != rb->wptr) {
63 adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_WPTR,
64 rb->wptr);
65 /*
66 * In case something got submitted while preemption was on
67 * going, reset the timer.
68 */
69 reset_timer = true;
70 }
71
72 if (reset_timer)
73 rb->dispatch_q.expires = jiffies +
74 msecs_to_jiffies(adreno_drawobj_timeout);
75
76 spin_unlock_irqrestore(&rb->preempt_lock, flags);
Harshdeep Dhatt664ee632017-11-01 15:03:11 -060077
78 if (in_interrupt() == 0) {
79 if (gpudev->oob_clear)
80 gpudev->oob_clear(adreno_dev,
81 OOB_PREEMPTION_CLEAR_MASK);
82 }
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -060083}
84
85static inline bool adreno_move_preempt_state(struct adreno_device *adreno_dev,
86 enum adreno_preempt_states old, enum adreno_preempt_states new)
87{
88 return (atomic_cmpxchg(&adreno_dev->preempt.state, old, new) == old);
89}
90
91static void _a6xx_preemption_done(struct adreno_device *adreno_dev)
92{
93 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
94 unsigned int status;
95
96 /*
97 * In the very unlikely case that the power is off, do nothing - the
98 * state will be reset on power up and everybody will be happy
99 */
100
101 if (!kgsl_state_is_awake(device))
102 return;
103
104 adreno_readreg(adreno_dev, ADRENO_REG_CP_PREEMPT, &status);
105
106 if (status & 0x1) {
107 KGSL_DRV_ERR(device,
108 "Preemption not complete: status=%X cur=%d R/W=%X/%X next=%d R/W=%X/%X\n",
109 status, adreno_dev->cur_rb->id,
110 adreno_get_rptr(adreno_dev->cur_rb),
111 adreno_dev->cur_rb->wptr, adreno_dev->next_rb->id,
112 adreno_get_rptr(adreno_dev->next_rb),
113 adreno_dev->next_rb->wptr);
114
115 /* Set a fault and restart */
116 adreno_set_gpu_fault(adreno_dev, ADRENO_PREEMPT_FAULT);
117 adreno_dispatcher_schedule(device);
118
119 return;
120 }
121
122 del_timer_sync(&adreno_dev->preempt.timer);
123
Harshdeep Dhatt003f6cf2017-12-14 11:00:22 -0700124 adreno_readreg(adreno_dev, ADRENO_REG_CP_PREEMPT_LEVEL_STATUS, &status);
125
126 trace_adreno_preempt_done(adreno_dev->cur_rb, adreno_dev->next_rb,
127 status);
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600128
129 /* Clean up all the bits */
130 adreno_dev->prev_rb = adreno_dev->cur_rb;
131 adreno_dev->cur_rb = adreno_dev->next_rb;
132 adreno_dev->next_rb = NULL;
133
134 /* Update the wptr for the new command queue */
135 _update_wptr(adreno_dev, true);
136
137 /* Update the dispatcher timer for the new command queue */
138 mod_timer(&adreno_dev->dispatcher.timer,
139 adreno_dev->cur_rb->dispatch_q.expires);
140
141 /* Clear the preempt state */
142 adreno_set_preempt_state(adreno_dev, ADRENO_PREEMPT_NONE);
143}
144
145static void _a6xx_preemption_fault(struct adreno_device *adreno_dev)
146{
147 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
148 unsigned int status;
149
150 /*
151 * If the power is on check the preemption status one more time - if it
152 * was successful then just transition to the complete state
153 */
154 if (kgsl_state_is_awake(device)) {
155 adreno_readreg(adreno_dev, ADRENO_REG_CP_PREEMPT, &status);
156
157 if (status == 0) {
158 adreno_set_preempt_state(adreno_dev,
159 ADRENO_PREEMPT_COMPLETE);
160
161 adreno_dispatcher_schedule(device);
162 return;
163 }
164 }
165
166 KGSL_DRV_ERR(device,
167 "Preemption timed out: cur=%d R/W=%X/%X, next=%d R/W=%X/%X\n",
168 adreno_dev->cur_rb->id,
169 adreno_get_rptr(adreno_dev->cur_rb), adreno_dev->cur_rb->wptr,
170 adreno_dev->next_rb->id,
171 adreno_get_rptr(adreno_dev->next_rb),
172 adreno_dev->next_rb->wptr);
173
174 adreno_set_gpu_fault(adreno_dev, ADRENO_PREEMPT_FAULT);
175 adreno_dispatcher_schedule(device);
176}
177
178static void _a6xx_preemption_worker(struct work_struct *work)
179{
180 struct adreno_preemption *preempt = container_of(work,
181 struct adreno_preemption, work);
182 struct adreno_device *adreno_dev = container_of(preempt,
183 struct adreno_device, preempt);
184 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
185
186 /* Need to take the mutex to make sure that the power stays on */
187 mutex_lock(&device->mutex);
188
189 if (adreno_in_preempt_state(adreno_dev, ADRENO_PREEMPT_FAULTED))
190 _a6xx_preemption_fault(adreno_dev);
191
192 mutex_unlock(&device->mutex);
193}
194
195static void _a6xx_preemption_timer(unsigned long data)
196{
197 struct adreno_device *adreno_dev = (struct adreno_device *) data;
198
199 /* We should only be here from a triggered state */
200 if (!adreno_move_preempt_state(adreno_dev,
201 ADRENO_PREEMPT_TRIGGERED, ADRENO_PREEMPT_FAULTED))
202 return;
203
204 /* Schedule the worker to take care of the details */
205 queue_work(system_unbound_wq, &adreno_dev->preempt.work);
206}
207
208/* Find the highest priority active ringbuffer */
209static struct adreno_ringbuffer *a6xx_next_ringbuffer(
210 struct adreno_device *adreno_dev)
211{
212 struct adreno_ringbuffer *rb;
213 unsigned long flags;
214 unsigned int i;
215
216 FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
217 bool empty;
218
219 spin_lock_irqsave(&rb->preempt_lock, flags);
220 empty = adreno_rb_empty(rb);
221 spin_unlock_irqrestore(&rb->preempt_lock, flags);
222
223 if (empty == false)
224 return rb;
225 }
226
227 return NULL;
228}
229
230void a6xx_preemption_trigger(struct adreno_device *adreno_dev)
231{
232 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
233 struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device);
234 struct adreno_ringbuffer *next;
Harshdeep Dhatt6d9eff92017-10-10 12:14:18 -0600235 uint64_t ttbr0, gpuaddr;
Harshdeep Dhatt003f6cf2017-12-14 11:00:22 -0700236 unsigned int contextidr, cntl;
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600237 unsigned long flags;
Harshdeep Dhatta8ec51c2017-09-21 17:24:08 -0600238 struct adreno_preemption *preempt = &adreno_dev->preempt;
Harshdeep Dhatt26c54f22017-08-30 17:37:39 -0600239
Harshdeep Dhatt003f6cf2017-12-14 11:00:22 -0700240 cntl = (((preempt->preempt_level << 6) & 0xC0) |
241 ((preempt->skipsaverestore << 9) & 0x200) |
242 ((preempt->usesgmem << 8) & 0x100) | 0x1);
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600243
244 /* Put ourselves into a possible trigger state */
245 if (!adreno_move_preempt_state(adreno_dev,
246 ADRENO_PREEMPT_NONE, ADRENO_PREEMPT_START))
247 return;
248
249 /* Get the next ringbuffer to preempt in */
250 next = a6xx_next_ringbuffer(adreno_dev);
251
252 /*
253 * Nothing to do if every ringbuffer is empty or if the current
254 * ringbuffer is the only active one
255 */
256 if (next == NULL || next == adreno_dev->cur_rb) {
257 /*
258 * Update any critical things that might have been skipped while
259 * we were looking for a new ringbuffer
260 */
261
262 if (next != NULL) {
263 _update_wptr(adreno_dev, false);
264
265 mod_timer(&adreno_dev->dispatcher.timer,
266 adreno_dev->cur_rb->dispatch_q.expires);
267 }
268
269 adreno_set_preempt_state(adreno_dev, ADRENO_PREEMPT_NONE);
270 return;
271 }
272
273 /* Turn off the dispatcher timer */
274 del_timer(&adreno_dev->dispatcher.timer);
275
276 /*
277 * This is the most critical section - we need to take care not to race
278 * until we have programmed the CP for the switch
279 */
280
281 spin_lock_irqsave(&next->preempt_lock, flags);
282
283 /*
284 * Get the pagetable from the pagetable info.
285 * The pagetable_desc is allocated and mapped at probe time, and
286 * preemption_desc at init time, so no need to check if
287 * sharedmem accesses to these memdescs succeed.
288 */
289 kgsl_sharedmem_readq(&next->pagetable_desc, &ttbr0,
290 PT_INFO_OFFSET(ttbr0));
291 kgsl_sharedmem_readl(&next->pagetable_desc, &contextidr,
292 PT_INFO_OFFSET(contextidr));
293
294 kgsl_sharedmem_writel(device, &next->preemption_desc,
295 PREEMPT_RECORD(wptr), next->wptr);
296
Harshdeep Dhatt4ab35b12017-11-16 08:34:39 -0700297 preempt->count++;
298
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600299 spin_unlock_irqrestore(&next->preempt_lock, flags);
300
301 /* And write it to the smmu info */
302 kgsl_sharedmem_writeq(device, &iommu->smmu_info,
303 PREEMPT_SMMU_RECORD(ttbr0), ttbr0);
304 kgsl_sharedmem_writel(device, &iommu->smmu_info,
305 PREEMPT_SMMU_RECORD(context_idr), contextidr);
306
Harshdeep Dhatt6d9eff92017-10-10 12:14:18 -0600307 kgsl_sharedmem_readq(&device->scratch, &gpuaddr,
308 SCRATCH_PREEMPTION_CTXT_RESTORE_ADDR_OFFSET(next->id));
Harshdeep Dhatt2e42f122017-05-31 17:27:19 -0600309
Harshdeep Dhatt59a69572017-11-01 14:46:13 -0600310 /*
Harshdeep Dhatt4a288a02017-11-09 14:39:51 -0700311 * Set a keepalive bit before the first preemption register write.
312 * This is required since while each individual write to the context
313 * switch registers will wake the GPU from collapse, it will not in
314 * itself cause GPU activity. Thus, the GPU could technically be
315 * re-collapsed between subsequent register writes leading to a
316 * prolonged preemption sequence. The keepalive bit prevents any
317 * further power collapse while it is set.
318 * It is more efficient to use a keepalive+wake-on-fence approach here
319 * rather than an OOB. Both keepalive and the fence are effectively
320 * free when the GPU is already powered on, whereas an OOB requires an
321 * unconditional handshake with the GMU.
322 */
323 kgsl_gmu_regrmw(device, A6XX_GMU_AO_SPARE_CNTL, 0x0, 0x2);
324
325 /*
Harshdeep Dhatt59a69572017-11-01 14:46:13 -0600326 * Fenced writes on this path will make sure the GPU is woken up
327 * in case it was power collapsed by the GMU.
328 */
329 adreno_gmu_fenced_write(adreno_dev,
330 ADRENO_REG_CP_CONTEXT_SWITCH_PRIV_NON_SECURE_RESTORE_ADDR_LO,
331 lower_32_bits(next->preemption_desc.gpuaddr),
332 FENCE_STATUS_WRITEDROPPED1_MASK);
333
334 adreno_gmu_fenced_write(adreno_dev,
335 ADRENO_REG_CP_CONTEXT_SWITCH_PRIV_NON_SECURE_RESTORE_ADDR_HI,
336 upper_32_bits(next->preemption_desc.gpuaddr),
337 FENCE_STATUS_WRITEDROPPED1_MASK);
338
339 adreno_gmu_fenced_write(adreno_dev,
Harshdeep Dhatt58b70eb2017-03-28 09:21:40 -0600340 ADRENO_REG_CP_CONTEXT_SWITCH_PRIV_SECURE_RESTORE_ADDR_LO,
341 lower_32_bits(next->secure_preemption_desc.gpuaddr),
342 FENCE_STATUS_WRITEDROPPED1_MASK);
343
344 adreno_gmu_fenced_write(adreno_dev,
345 ADRENO_REG_CP_CONTEXT_SWITCH_PRIV_SECURE_RESTORE_ADDR_HI,
346 upper_32_bits(next->secure_preemption_desc.gpuaddr),
347 FENCE_STATUS_WRITEDROPPED1_MASK);
348
349 adreno_gmu_fenced_write(adreno_dev,
Harshdeep Dhatt59a69572017-11-01 14:46:13 -0600350 ADRENO_REG_CP_CONTEXT_SWITCH_NON_PRIV_RESTORE_ADDR_LO,
351 lower_32_bits(gpuaddr),
352 FENCE_STATUS_WRITEDROPPED1_MASK);
353
354 adreno_gmu_fenced_write(adreno_dev,
355 ADRENO_REG_CP_CONTEXT_SWITCH_NON_PRIV_RESTORE_ADDR_HI,
356 upper_32_bits(gpuaddr),
357 FENCE_STATUS_WRITEDROPPED1_MASK);
Harshdeep Dhatt2e42f122017-05-31 17:27:19 -0600358
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600359 adreno_dev->next_rb = next;
360
361 /* Start the timer to detect a stuck preemption */
362 mod_timer(&adreno_dev->preempt.timer,
363 jiffies + msecs_to_jiffies(ADRENO_PREEMPT_TIMEOUT));
364
Harshdeep Dhatt003f6cf2017-12-14 11:00:22 -0700365 trace_adreno_preempt_trigger(adreno_dev->cur_rb, adreno_dev->next_rb,
366 cntl);
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600367
368 adreno_set_preempt_state(adreno_dev, ADRENO_PREEMPT_TRIGGERED);
369
370 /* Trigger the preemption */
Harshdeep Dhatt003f6cf2017-12-14 11:00:22 -0700371 adreno_gmu_fenced_write(adreno_dev, ADRENO_REG_CP_PREEMPT, cntl,
Harshdeep Dhatt59a69572017-11-01 14:46:13 -0600372 FENCE_STATUS_WRITEDROPPED1_MASK);
Harshdeep Dhatt4a288a02017-11-09 14:39:51 -0700373
374 /*
375 * Once preemption has been requested with the final register write,
376 * the preemption process starts and the GPU is considered busy.
377 * We can now safely clear the preemption keepalive bit, allowing
378 * power collapse to resume its regular activity.
379 */
380 kgsl_gmu_regrmw(device, A6XX_GMU_AO_SPARE_CNTL, 0x2, 0x0);
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600381}
382
383void a6xx_preemption_callback(struct adreno_device *adreno_dev, int bit)
384{
385 unsigned int status;
386
387 if (!adreno_move_preempt_state(adreno_dev,
388 ADRENO_PREEMPT_TRIGGERED, ADRENO_PREEMPT_PENDING))
389 return;
390
391 adreno_readreg(adreno_dev, ADRENO_REG_CP_PREEMPT, &status);
392
393 if (status & 0x1) {
394 KGSL_DRV_ERR(KGSL_DEVICE(adreno_dev),
395 "preempt interrupt with non-zero status: %X\n", status);
396
397 /*
398 * Under the assumption that this is a race between the
399 * interrupt and the register, schedule the worker to clean up.
400 * If the status still hasn't resolved itself by the time we get
401 * there then we have to assume something bad happened
402 */
403 adreno_set_preempt_state(adreno_dev, ADRENO_PREEMPT_COMPLETE);
404 adreno_dispatcher_schedule(KGSL_DEVICE(adreno_dev));
405 return;
406 }
407
408 del_timer(&adreno_dev->preempt.timer);
409
Harshdeep Dhatt003f6cf2017-12-14 11:00:22 -0700410 adreno_readreg(adreno_dev, ADRENO_REG_CP_PREEMPT_LEVEL_STATUS, &status);
411
412 trace_adreno_preempt_done(adreno_dev->cur_rb, adreno_dev->next_rb,
413 status);
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600414
415 adreno_dev->prev_rb = adreno_dev->cur_rb;
416 adreno_dev->cur_rb = adreno_dev->next_rb;
417 adreno_dev->next_rb = NULL;
418
419 /* Update the wptr if it changed while preemption was ongoing */
420 _update_wptr(adreno_dev, true);
421
422 /* Update the dispatcher timer for the new command queue */
423 mod_timer(&adreno_dev->dispatcher.timer,
424 adreno_dev->cur_rb->dispatch_q.expires);
425
426 adreno_set_preempt_state(adreno_dev, ADRENO_PREEMPT_NONE);
427
428 a6xx_preemption_trigger(adreno_dev);
429}
430
431void a6xx_preemption_schedule(struct adreno_device *adreno_dev)
432{
433 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
434
Harshdeep Dhatt7ee8a862017-11-20 17:51:54 -0700435 if (!adreno_is_preemption_enabled(adreno_dev))
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600436 return;
437
438 mutex_lock(&device->mutex);
439
440 if (adreno_in_preempt_state(adreno_dev, ADRENO_PREEMPT_COMPLETE))
441 _a6xx_preemption_done(adreno_dev);
442
443 a6xx_preemption_trigger(adreno_dev);
444
445 mutex_unlock(&device->mutex);
446}
447
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600448unsigned int a6xx_preemption_pre_ibsubmit(
449 struct adreno_device *adreno_dev,
450 struct adreno_ringbuffer *rb,
451 unsigned int *cmds, struct kgsl_context *context)
452{
453 unsigned int *cmds_orig = cmds;
Harshdeep Dhatt6d9eff92017-10-10 12:14:18 -0600454 uint64_t gpuaddr = 0;
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600455
Harshdeep Dhatt6d9eff92017-10-10 12:14:18 -0600456 if (context) {
457 gpuaddr = context->user_ctxt_record->memdesc.gpuaddr;
Harshdeep Dhatt2e42f122017-05-31 17:27:19 -0600458 *cmds++ = cp_type7_packet(CP_SET_PSEUDO_REGISTER, 15);
Harshdeep Dhatt6d9eff92017-10-10 12:14:18 -0600459 } else {
Harshdeep Dhatt2e42f122017-05-31 17:27:19 -0600460 *cmds++ = cp_type7_packet(CP_SET_PSEUDO_REGISTER, 12);
Harshdeep Dhatt6d9eff92017-10-10 12:14:18 -0600461 }
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600462
463 /* NULL SMMU_INFO buffer - we track in KMD */
464 *cmds++ = SET_PSEUDO_REGISTER_SAVE_REGISTER_SMMU_INFO;
465 cmds += cp_gpuaddr(adreno_dev, cmds, 0x0);
466
467 *cmds++ = SET_PSEUDO_REGISTER_SAVE_REGISTER_PRIV_NON_SECURE_SAVE_ADDR;
468 cmds += cp_gpuaddr(adreno_dev, cmds, rb->preemption_desc.gpuaddr);
469
470 *cmds++ = SET_PSEUDO_REGISTER_SAVE_REGISTER_PRIV_SECURE_SAVE_ADDR;
Harshdeep Dhatt58b70eb2017-03-28 09:21:40 -0600471 cmds += cp_gpuaddr(adreno_dev, cmds,
472 rb->secure_preemption_desc.gpuaddr);
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600473
Harshdeep Dhatt2e42f122017-05-31 17:27:19 -0600474 if (context) {
Harshdeep Dhatt2e42f122017-05-31 17:27:19 -0600475
476 *cmds++ = SET_PSEUDO_REGISTER_SAVE_REGISTER_NON_PRIV_SAVE_ADDR;
477 cmds += cp_gpuaddr(adreno_dev, cmds, gpuaddr);
478 }
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600479
480 /*
481 * There is no need to specify this address when we are about to
482 * trigger preemption. This is because CP internally stores this
483 * address specified here in the CP_SET_PSEUDO_REGISTER payload to
484 * the context record and thus knows from where to restore
485 * the saved perfcounters for the new ringbuffer.
486 */
487 *cmds++ = SET_PSEUDO_REGISTER_SAVE_REGISTER_COUNTER;
488 cmds += cp_gpuaddr(adreno_dev, cmds,
489 rb->perfcounter_save_restore_desc.gpuaddr);
490
Harshdeep Dhatt6d9eff92017-10-10 12:14:18 -0600491 if (context) {
492 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
493 struct adreno_context *drawctxt = ADRENO_CONTEXT(context);
494 struct adreno_ringbuffer *rb = drawctxt->rb;
495 uint64_t dest =
496 SCRATCH_PREEMPTION_CTXT_RESTORE_GPU_ADDR(device,
497 rb->id);
498
499 *cmds++ = cp_mem_packet(adreno_dev, CP_MEM_WRITE, 2, 2);
500 cmds += cp_gpuaddr(adreno_dev, cmds, dest);
501 *cmds++ = lower_32_bits(gpuaddr);
502 *cmds++ = upper_32_bits(gpuaddr);
503 }
504
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600505 return (unsigned int) (cmds - cmds_orig);
506}
507
508unsigned int a6xx_preemption_post_ibsubmit(struct adreno_device *adreno_dev,
509 unsigned int *cmds)
510{
511 unsigned int *cmds_orig = cmds;
Harshdeep Dhatt6d9eff92017-10-10 12:14:18 -0600512 struct adreno_ringbuffer *rb = adreno_dev->cur_rb;
513
514 if (rb) {
515 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
516 uint64_t dest = SCRATCH_PREEMPTION_CTXT_RESTORE_GPU_ADDR(device,
517 rb->id);
518
519 *cmds++ = cp_mem_packet(adreno_dev, CP_MEM_WRITE, 2, 2);
520 cmds += cp_gpuaddr(adreno_dev, cmds, dest);
521 *cmds++ = 0;
522 *cmds++ = 0;
523 }
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600524
525 *cmds++ = cp_type7_packet(CP_CONTEXT_SWITCH_YIELD, 4);
526 cmds += cp_gpuaddr(adreno_dev, cmds, 0x0);
527 *cmds++ = 1;
528 *cmds++ = 0;
529
530 return (unsigned int) (cmds - cmds_orig);
531}
532
533void a6xx_preemption_start(struct adreno_device *adreno_dev)
534{
535 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
536 struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device);
537 struct adreno_ringbuffer *rb;
538 unsigned int i;
539
Harshdeep Dhatt7ee8a862017-11-20 17:51:54 -0700540 if (!adreno_is_preemption_enabled(adreno_dev))
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600541 return;
542
543 /* Force the state to be clear */
544 adreno_set_preempt_state(adreno_dev, ADRENO_PREEMPT_NONE);
545
546 /* smmu_info is allocated and mapped in a6xx_preemption_iommu_init */
547 kgsl_sharedmem_writel(device, &iommu->smmu_info,
548 PREEMPT_SMMU_RECORD(magic), A6XX_CP_SMMU_INFO_MAGIC_REF);
549 kgsl_sharedmem_writeq(device, &iommu->smmu_info,
550 PREEMPT_SMMU_RECORD(ttbr0), MMU_DEFAULT_TTBR0(device));
551
552 /* The CP doesn't use the asid record, so poison it */
553 kgsl_sharedmem_writel(device, &iommu->smmu_info,
554 PREEMPT_SMMU_RECORD(asid), 0xDECAFBAD);
555 kgsl_sharedmem_writel(device, &iommu->smmu_info,
556 PREEMPT_SMMU_RECORD(context_idr),
557 MMU_DEFAULT_CONTEXTIDR(device));
558
559 adreno_writereg64(adreno_dev,
560 ADRENO_REG_CP_CONTEXT_SWITCH_SMMU_INFO_LO,
561 ADRENO_REG_CP_CONTEXT_SWITCH_SMMU_INFO_HI,
562 iommu->smmu_info.gpuaddr);
563
564 FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
565 /*
566 * preemption_desc is allocated and mapped at init time,
567 * so no need to check sharedmem_writel return value
568 */
569 kgsl_sharedmem_writel(device, &rb->preemption_desc,
570 PREEMPT_RECORD(rptr), 0);
571 kgsl_sharedmem_writel(device, &rb->preemption_desc,
572 PREEMPT_RECORD(wptr), 0);
573
574 adreno_ringbuffer_set_pagetable(rb,
575 device->mmu.defaultpagetable);
576 }
577}
578
579static int a6xx_preemption_ringbuffer_init(struct adreno_device *adreno_dev,
580 struct adreno_ringbuffer *rb, uint64_t counteraddr)
581{
582 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
583 int ret;
584
585 ret = kgsl_allocate_global(device, &rb->preemption_desc,
586 A6XX_CP_CTXRECORD_SIZE_IN_BYTES, 0, KGSL_MEMDESC_PRIVILEGED,
587 "preemption_desc");
588 if (ret)
589 return ret;
590
Harshdeep Dhatt58b70eb2017-03-28 09:21:40 -0600591 ret = kgsl_allocate_user(device, &rb->secure_preemption_desc,
592 A6XX_CP_CTXRECORD_SIZE_IN_BYTES,
593 KGSL_MEMFLAGS_SECURE | KGSL_MEMDESC_PRIVILEGED);
594 if (ret)
595 return ret;
596
597 ret = kgsl_iommu_map_global_secure_pt_entry(device,
598 &rb->secure_preemption_desc);
599 if (ret)
600 return ret;
601
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600602 ret = kgsl_allocate_global(device, &rb->perfcounter_save_restore_desc,
603 A6XX_CP_PERFCOUNTER_SAVE_RESTORE_SIZE, 0,
604 KGSL_MEMDESC_PRIVILEGED, "perfcounter_save_restore_desc");
605 if (ret)
606 return ret;
607
608 kgsl_sharedmem_writel(device, &rb->preemption_desc,
609 PREEMPT_RECORD(magic), A6XX_CP_CTXRECORD_MAGIC_REF);
610 kgsl_sharedmem_writel(device, &rb->preemption_desc,
611 PREEMPT_RECORD(info), 0);
612 kgsl_sharedmem_writel(device, &rb->preemption_desc,
613 PREEMPT_RECORD(data), 0);
614 kgsl_sharedmem_writel(device, &rb->preemption_desc,
615 PREEMPT_RECORD(cntl), A6XX_CP_RB_CNTL_DEFAULT);
616 kgsl_sharedmem_writel(device, &rb->preemption_desc,
617 PREEMPT_RECORD(rptr), 0);
618 kgsl_sharedmem_writel(device, &rb->preemption_desc,
619 PREEMPT_RECORD(wptr), 0);
620 kgsl_sharedmem_writeq(device, &rb->preemption_desc,
621 PREEMPT_RECORD(rptr_addr), SCRATCH_RPTR_GPU_ADDR(device,
622 rb->id));
623 kgsl_sharedmem_writeq(device, &rb->preemption_desc,
624 PREEMPT_RECORD(rbase), rb->buffer_desc.gpuaddr);
625 kgsl_sharedmem_writeq(device, &rb->preemption_desc,
626 PREEMPT_RECORD(counter), counteraddr);
627
628 return 0;
629}
630
631#ifdef CONFIG_QCOM_KGSL_IOMMU
632static int a6xx_preemption_iommu_init(struct adreno_device *adreno_dev)
633{
634 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
635 struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device);
636
637 /* Allocate mem for storing preemption smmu record */
638 return kgsl_allocate_global(device, &iommu->smmu_info, PAGE_SIZE,
639 KGSL_MEMFLAGS_GPUREADONLY, KGSL_MEMDESC_PRIVILEGED,
640 "smmu_info");
641}
642
643static void a6xx_preemption_iommu_close(struct adreno_device *adreno_dev)
644{
645 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
646 struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device);
647
648 kgsl_free_global(device, &iommu->smmu_info);
649}
650#else
651static int a6xx_preemption_iommu_init(struct adreno_device *adreno_dev)
652{
653 return -ENODEV;
654}
655
656static void a6xx_preemption_iommu_close(struct adreno_device *adreno_dev)
657{
658}
659#endif
660
661static void a6xx_preemption_close(struct kgsl_device *device)
662{
663 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
664 struct adreno_preemption *preempt = &adreno_dev->preempt;
665 struct adreno_ringbuffer *rb;
666 unsigned int i;
667
668 del_timer(&preempt->timer);
669 kgsl_free_global(device, &preempt->counters);
670 a6xx_preemption_iommu_close(adreno_dev);
671
672 FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
673 kgsl_free_global(device, &rb->preemption_desc);
674 kgsl_free_global(device, &rb->perfcounter_save_restore_desc);
Harshdeep Dhatt58b70eb2017-03-28 09:21:40 -0600675 kgsl_iommu_unmap_global_secure_pt_entry(device,
676 &rb->secure_preemption_desc);
677 kgsl_sharedmem_free(&rb->secure_preemption_desc);
Harshdeep Dhatt0cdc8992017-05-31 15:44:05 -0600678 }
679}
680
681int a6xx_preemption_init(struct adreno_device *adreno_dev)
682{
683 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
684 struct adreno_preemption *preempt = &adreno_dev->preempt;
685 struct adreno_ringbuffer *rb;
686 int ret;
687 unsigned int i;
688 uint64_t addr;
689
690 /* We are dependent on IOMMU to make preemption go on the CP side */
691 if (kgsl_mmu_get_mmutype(device) != KGSL_MMU_TYPE_IOMMU)
692 return -ENODEV;
693
694 INIT_WORK(&preempt->work, _a6xx_preemption_worker);
695
696 setup_timer(&preempt->timer, _a6xx_preemption_timer,
697 (unsigned long) adreno_dev);
698
699 /* Allocate mem for storing preemption counters */
700 ret = kgsl_allocate_global(device, &preempt->counters,
701 adreno_dev->num_ringbuffers *
702 A6XX_CP_CTXRECORD_PREEMPTION_COUNTER_SIZE, 0, 0,
703 "preemption_counters");
704 if (ret)
705 goto err;
706
707 addr = preempt->counters.gpuaddr;
708
709 /* Allocate mem for storing preemption switch record */
710 FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
711 ret = a6xx_preemption_ringbuffer_init(adreno_dev, rb, addr);
712 if (ret)
713 goto err;
714
715 addr += A6XX_CP_CTXRECORD_PREEMPTION_COUNTER_SIZE;
716 }
717
718 ret = a6xx_preemption_iommu_init(adreno_dev);
719
720err:
721 if (ret)
722 a6xx_preemption_close(device);
723
724 return ret;
725}
Harshdeep Dhatt2e42f122017-05-31 17:27:19 -0600726
727void a6xx_preemption_context_destroy(struct kgsl_context *context)
728{
729 struct kgsl_device *device = context->device;
730 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
731
Harshdeep Dhatt7ee8a862017-11-20 17:51:54 -0700732 if (!adreno_is_preemption_enabled(adreno_dev))
Harshdeep Dhatt2e42f122017-05-31 17:27:19 -0600733 return;
734
735 gpumem_free_entry(context->user_ctxt_record);
Lynus Vaz0bf63cc2017-09-18 21:19:54 +0530736
737 /* Put the extra ref from gpumem_alloc_entry() */
738 kgsl_mem_entry_put(context->user_ctxt_record);
Harshdeep Dhatt2e42f122017-05-31 17:27:19 -0600739}
740
741int a6xx_preemption_context_init(struct kgsl_context *context)
742{
743 struct kgsl_device *device = context->device;
744 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
Harshdeep Dhatt58b70eb2017-03-28 09:21:40 -0600745 uint64_t flags = 0;
Harshdeep Dhatt2e42f122017-05-31 17:27:19 -0600746
Harshdeep Dhatt7ee8a862017-11-20 17:51:54 -0700747 if (!adreno_is_preemption_enabled(adreno_dev))
Harshdeep Dhatt2e42f122017-05-31 17:27:19 -0600748 return 0;
749
Harshdeep Dhatt58b70eb2017-03-28 09:21:40 -0600750 if (context->flags & KGSL_CONTEXT_SECURE)
751 flags |= KGSL_MEMFLAGS_SECURE;
752
Lynus Vaz0bf63cc2017-09-18 21:19:54 +0530753 /*
754 * gpumem_alloc_entry takes an extra refcount. Put it only when
755 * destroying the context to keep the context record valid
756 */
Harshdeep Dhatt2e42f122017-05-31 17:27:19 -0600757 context->user_ctxt_record = gpumem_alloc_entry(context->dev_priv,
Harshdeep Dhatt58b70eb2017-03-28 09:21:40 -0600758 A6XX_CP_CTXRECORD_USER_RESTORE_SIZE, flags);
Harshdeep Dhatt2e42f122017-05-31 17:27:19 -0600759 if (IS_ERR(context->user_ctxt_record)) {
760 int ret = PTR_ERR(context->user_ctxt_record);
761
762 context->user_ctxt_record = NULL;
763 return ret;
764 }
765
766 return 0;
767}