1 /* SPDX-License-Identifier: GPL-2.0 or MIT */
2 /* Copyright 2018 Marty E. Plummer <hanetzer@startmail.com> */
3 /* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */
4 /* Copyright 2023 Collabora ltd. */
5
6 #ifndef __PANTHOR_DEVICE_H__
7 #define __PANTHOR_DEVICE_H__
8
9 #include <linux/atomic.h>
10 #include <linux/io-pgtable.h>
11 #include <linux/regulator/consumer.h>
12 #include <linux/pm_runtime.h>
13 #include <linux/sched.h>
14 #include <linux/spinlock.h>
15
16 #include <drm/drm_device.h>
17 #include <drm/drm_gem.h>
18 #include <drm/drm_mm.h>
19 #include <drm/gpu_scheduler.h>
20 #include <drm/panthor_drm.h>
21
22 struct panthor_csf;
23 struct panthor_csf_ctx;
24 struct panthor_device;
25 struct panthor_gpu;
26 struct panthor_group_pool;
27 struct panthor_heap_pool;
28 struct panthor_hw;
29 struct panthor_job;
30 struct panthor_mmu;
31 struct panthor_fw;
32 struct panthor_perfcnt;
33 struct panthor_pwr;
34 struct panthor_vm;
35 struct panthor_vm_pool;
36
37 /**
38 * struct panthor_soc_data - Panthor SoC Data
39 */
40 struct panthor_soc_data {
41 /** @asn_hash_enable: True if GPU_L2_CONFIG_ASN_HASH_ENABLE must be set. */
42 bool asn_hash_enable;
43
44 /** @asn_hash: ASN_HASH values when asn_hash_enable is true. */
45 u32 asn_hash[3];
46 };
47
48 /**
49 * enum panthor_device_pm_state - PM state
50 */
51 enum panthor_device_pm_state {
52 /** @PANTHOR_DEVICE_PM_STATE_SUSPENDED: Device is suspended. */
53 PANTHOR_DEVICE_PM_STATE_SUSPENDED = 0,
54
55 /** @PANTHOR_DEVICE_PM_STATE_RESUMING: Device is being resumed. */
56 PANTHOR_DEVICE_PM_STATE_RESUMING,
57
58 /** @PANTHOR_DEVICE_PM_STATE_ACTIVE: Device is active. */
59 PANTHOR_DEVICE_PM_STATE_ACTIVE,
60
61 /** @PANTHOR_DEVICE_PM_STATE_SUSPENDING: Device is being suspended. */
62 PANTHOR_DEVICE_PM_STATE_SUSPENDING,
63 };
64
65 enum panthor_irq_state {
66 /** @PANTHOR_IRQ_STATE_ACTIVE: IRQ is active and ready to process events. */
67 PANTHOR_IRQ_STATE_ACTIVE = 0,
68 /** @PANTHOR_IRQ_STATE_PROCESSING: IRQ is currently processing events. */
69 PANTHOR_IRQ_STATE_PROCESSING,
70 /** @PANTHOR_IRQ_STATE_SUSPENDED: IRQ is suspended. */
71 PANTHOR_IRQ_STATE_SUSPENDED,
72 /** @PANTHOR_IRQ_STATE_SUSPENDING: IRQ is being suspended. */
73 PANTHOR_IRQ_STATE_SUSPENDING,
74 };
75
76 /**
77 * struct panthor_irq - IRQ data
78 *
79 * Used to automate IRQ handling for the 3 different IRQs we have in this driver.
80 */
81 struct panthor_irq {
82 /** @ptdev: Panthor device */
83 struct panthor_device *ptdev;
84
85 /** @iomem: CPU mapping of IRQ base address */
86 void __iomem *iomem;
87
88 /** @irq: IRQ number. */
89 int irq;
90
91 /** @mask: Values to write to xxx_INT_MASK if active. */
92 u32 mask;
93
94 /**
95 * @mask_lock: protects modifications to _INT_MASK and @mask.
96 *
97 * In paths where _INT_MASK is updated based on a state
98 * transition/check, it's crucial for the state update/check to be
99 * inside the locked section, otherwise it introduces a race window
100 * leading to potential _INT_MASK inconsistencies.
101 */
102 spinlock_t mask_lock;
103
104 /** @state: one of &enum panthor_irq_state reflecting the current state. */
105 atomic_t state;
106 };
107
108 /**
109 * enum panthor_device_profiling_mode - Profiling state
110 */
111 enum panthor_device_profiling_flags {
112 /** @PANTHOR_DEVICE_PROFILING_DISABLED: Profiling is disabled. */
113 PANTHOR_DEVICE_PROFILING_DISABLED = 0,
114
115 /** @PANTHOR_DEVICE_PROFILING_CYCLES: Sampling job cycles. */
116 PANTHOR_DEVICE_PROFILING_CYCLES = BIT(0),
117
118 /** @PANTHOR_DEVICE_PROFILING_TIMESTAMP: Sampling job timestamp. */
119 PANTHOR_DEVICE_PROFILING_TIMESTAMP = BIT(1),
120
121 /** @PANTHOR_DEVICE_PROFILING_ALL: Sampling everything. */
122 PANTHOR_DEVICE_PROFILING_ALL =
123 PANTHOR_DEVICE_PROFILING_CYCLES |
124 PANTHOR_DEVICE_PROFILING_TIMESTAMP,
125 };
126
127 /**
128 * struct panthor_device - Panthor device
129 */
130 struct panthor_device {
131 /** @base: Base drm_device. */
132 struct drm_device base;
133
134 /** @soc_data: Optional SoC data. */
135 const struct panthor_soc_data *soc_data;
136
137 /** @phys_addr: Physical address of the iomem region. */
138 phys_addr_t phys_addr;
139
140 /** @iomem: CPU mapping of the IOMEM region. */
141 void __iomem *iomem;
142
143 /** @clks: GPU clocks. */
144 struct {
145 /** @core: Core clock. */
146 struct clk *core;
147
148 /** @stacks: Stacks clock. This clock is optional. */
149 struct clk *stacks;
150
151 /** @coregroup: Core group clock. This clock is optional. */
152 struct clk *coregroup;
153 } clks;
154
155 /** @coherent: True if the CPU/GPU are memory coherent. */
156 bool coherent;
157
158 /** @gpu_info: GPU information. */
159 struct drm_panthor_gpu_info gpu_info;
160
161 /** @csif_info: Command stream interface information. */
162 struct drm_panthor_csif_info csif_info;
163
164 /** @hw: GPU-specific data. */
165 struct panthor_hw *hw;
166
167 /** @pwr: Power control management data. */
168 struct panthor_pwr *pwr;
169
170 /** @gpu: GPU management data. */
171 struct panthor_gpu *gpu;
172
173 /** @fw: FW management data. */
174 struct panthor_fw *fw;
175
176 /** @mmu: MMU management data. */
177 struct panthor_mmu *mmu;
178
179 /** @scheduler: Scheduler management data. */
180 struct panthor_scheduler *scheduler;
181
182 /** @devfreq: Device frequency scaling management data. */
183 struct panthor_devfreq *devfreq;
184
185 /** @reclaim: Reclaim related stuff */
186 struct {
187 /** @reclaim.shrinker: Shrinker instance */
188 struct shrinker *shrinker;
189
190 /**
191 * @reclaim.unused: BOs with unused pages
192 *
193 * Basically all buffers that got mmapped, vmapped or GPU mapped and
194 * then unmapped. There should be no contention on these buffers,
195 * making them ideal to reclaim.
196 */
197 struct drm_gem_lru unused;
198
199 /**
200 * @reclaim.mmapped: mmap()-ed buffers
201 *
202 * Those are relatively easy to reclaim since we don't need user
203 * agreement, we can simply teardown the mapping and let it fault on
204 * the next access.
205 */
206 struct drm_gem_lru mmapped;
207
208 /**
209 * @reclaim.gpu_mapped_shared: shared BO LRU list
210 *
211 * That's the most tricky BO type to reclaim, because it involves
212 * tearing down all mappings in all VMs where this BO is mapped,
213 * which increases the risk of contention and thus decreases the
214 * likeliness of success.
215 */
216 struct drm_gem_lru gpu_mapped_shared;
217
218 /**
219 * @reclaim.vms: VM LRU list
220 *
221 * VMs that have reclaimable BOs only mapped to a single VM are placed
222 * in this LRU. Reclaiming such BOs implies waiting for VM idleness
223 * (no in-flight GPU jobs targeting this VM), meaning we can't reclaim
224 * those if we're in a context where we can't block/sleep.
225 */
226 struct list_head vms;
227
228 /**
229 * @reclaim.gpu_mapped_count: Global counter of pages that are GPU mapped
230 *
231 * Allows us to get the number of reclaimable pages without walking
232 * the vms and gpu_mapped_shared LRUs.
233 */
234 long gpu_mapped_count;
235
236 /**
237 * @reclaim.retry_count: Number of times we ran the shrinker without being
238 * able to reclaim stuff
239 *
240 * Used to stop scanning GEMs when too many attempts were made
241 * without progress.
242 */
243 atomic_t retry_count;
244
245 #ifdef CONFIG_DEBUG_FS
246 /**
247 * @reclaim.nr_pages_reclaimed_on_last_scan: Number of pages reclaimed on the last
248 * shrinker scan
249 */
250 unsigned long nr_pages_reclaimed_on_last_scan;
251 #endif
252 } reclaim;
253
254 /** @unplug: Device unplug related fields. */
255 struct {
256 /** @lock: Lock used to serialize unplug operations. */
257 struct mutex lock;
258
259 /**
260 * @done: Completion object signaled when the unplug
261 * operation is done.
262 */
263 struct completion done;
264 } unplug;
265
266 /** @reset: Reset related fields. */
267 struct {
268 /** @wq: Ordered worqueud used to schedule reset operations. */
269 struct workqueue_struct *wq;
270
271 /** @work: Reset work. */
272 struct work_struct work;
273
274 /** @pending: Set to true if a reset is pending. */
275 atomic_t pending;
276
277 /**
278 * @fast: True if the post_reset logic can proceed with a fast reset.
279 *
280 * A fast reset is just a reset where the driver doesn't reload the FW sections.
281 *
282 * Any time the firmware is properly suspended, a fast reset can take place.
283 * On the other hand, if the halt operation failed, the driver will reload
284 * all FW sections to make sure we start from a fresh state.
285 */
286 bool fast;
287 } reset;
288
289 /** @pm: Power management related data. */
290 struct {
291 /** @state: Power state. */
292 atomic_t state;
293
294 /**
295 * @mmio_lock: Lock protecting MMIO userspace CPU mappings.
296 *
297 * This is needed to ensure we map the dummy IO pages when
298 * the device is being suspended, and the real IO pages when
299 * the device is being resumed. We can't just do with the
300 * state atomicity to deal with this race.
301 */
302 struct mutex mmio_lock;
303
304 /**
305 * @dummy_latest_flush: Dummy LATEST_FLUSH page.
306 *
307 * Used to replace the real LATEST_FLUSH page when the GPU
308 * is suspended.
309 */
310 struct page *dummy_latest_flush;
311
312 /** @recovery_needed: True when a resume attempt failed. */
313 atomic_t recovery_needed;
314 } pm;
315
316 /** @profile_mask: User-set profiling flags for job accounting. */
317 u32 profile_mask;
318
319 /** @fast_rate: Maximum device clock frequency. Set by DVFS */
320 unsigned long fast_rate;
321
322 #ifdef CONFIG_DEBUG_FS
323 /** @gems: Device-wide list of GEM objects owned by at least one file. */
324 struct {
325 /** @gems.lock: Protects the device-wide list of GEM objects. */
326 struct mutex lock;
327
328 /** @node: Used to keep track of all the device's DRM objects */
329 struct list_head node;
330 } gems;
331 #endif
332 };
333
334 struct panthor_gpu_usage {
335 u64 time;
336 u64 cycles;
337 };
338
339 /**
340 * struct panthor_file - Panthor file
341 */
342 struct panthor_file {
343 /** @ptdev: Device attached to this file. */
344 struct panthor_device *ptdev;
345
346 /** @user_mmio: User MMIO related fields. */
347 struct {
348 /**
349 * @offset: Offset used for user MMIO mappings.
350 *
351 * This offset should not be used to check the type of mapping
352 * except in panthor_mmap(). After that point, MMIO mapping
353 * offsets have been adjusted to match
354 * DRM_PANTHOR_USER_MMIO_OFFSET and that macro should be used
355 * instead.
356 * Make sure this rule is followed at all times, because
357 * userspace is in control of the offset, and can change the
358 * value behind our back. Otherwise it can lead to erroneous
359 * branching happening in kernel space.
360 */
361 u64 offset;
362 } user_mmio;
363
364 /** @vms: VM pool attached to this file. */
365 struct panthor_vm_pool *vms;
366
367 /** @groups: Scheduling group pool attached to this file. */
368 struct panthor_group_pool *groups;
369
370 /** @stats: cycle and timestamp measures for job execution. */
371 struct panthor_gpu_usage stats;
372 };
373
374 int panthor_device_init(struct panthor_device *ptdev);
375 void panthor_device_unplug(struct panthor_device *ptdev);
376
377 /**
378 * panthor_device_schedule_reset() - Schedules a reset operation
379 */
panthor_device_schedule_reset(struct panthor_device * ptdev)380 static inline void panthor_device_schedule_reset(struct panthor_device *ptdev)
381 {
382 if (!atomic_cmpxchg(&ptdev->reset.pending, 0, 1) &&
383 atomic_read(&ptdev->pm.state) == PANTHOR_DEVICE_PM_STATE_ACTIVE)
384 queue_work(ptdev->reset.wq, &ptdev->reset.work);
385 }
386
387 /**
388 * panthor_device_reset_is_pending() - Checks if a reset is pending.
389 *
390 * Return: true if a reset is pending, false otherwise.
391 */
panthor_device_reset_is_pending(struct panthor_device * ptdev)392 static inline bool panthor_device_reset_is_pending(struct panthor_device *ptdev)
393 {
394 return atomic_read(&ptdev->reset.pending) != 0;
395 }
396
397 int panthor_device_mmap_io(struct panthor_device *ptdev,
398 struct vm_area_struct *vma);
399
400 int panthor_device_resume(struct device *dev);
401 int panthor_device_suspend(struct device *dev);
402
panthor_device_resume_and_get(struct panthor_device * ptdev)403 static inline int panthor_device_resume_and_get(struct panthor_device *ptdev)
404 {
405 int ret = pm_runtime_resume_and_get(ptdev->base.dev);
406
407 /* If the resume failed, we need to clear the runtime_error, which
408 * can done by forcing the RPM state to suspended. If multiple
409 * threads called panthor_device_resume_and_get(), we only want
410 * one of them to update the state, hence the cmpxchg. Note that a
411 * thread might enter panthor_device_resume_and_get() and call
412 * pm_runtime_resume_and_get() after another thread had attempted
413 * to resume and failed. This means we will end up with an error
414 * without even attempting a resume ourselves. The only risk here
415 * is to report an error when the second resume attempt might have
416 * succeeded. Given resume errors are not expected, this is probably
417 * something we can live with.
418 */
419 if (ret && atomic_cmpxchg(&ptdev->pm.recovery_needed, 1, 0) == 1)
420 pm_runtime_set_suspended(ptdev->base.dev);
421
422 return ret;
423 }
424
425 enum drm_panthor_exception_type {
426 DRM_PANTHOR_EXCEPTION_OK = 0x00,
427 DRM_PANTHOR_EXCEPTION_TERMINATED = 0x04,
428 DRM_PANTHOR_EXCEPTION_KABOOM = 0x05,
429 DRM_PANTHOR_EXCEPTION_EUREKA = 0x06,
430 DRM_PANTHOR_EXCEPTION_ACTIVE = 0x08,
431 DRM_PANTHOR_EXCEPTION_CS_RES_TERM = 0x0f,
432 DRM_PANTHOR_EXCEPTION_MAX_NON_FAULT = 0x3f,
433 DRM_PANTHOR_EXCEPTION_CS_CONFIG_FAULT = 0x40,
434 DRM_PANTHOR_EXCEPTION_CS_UNRECOVERABLE = 0x41,
435 DRM_PANTHOR_EXCEPTION_CS_ENDPOINT_FAULT = 0x44,
436 DRM_PANTHOR_EXCEPTION_CS_BUS_FAULT = 0x48,
437 DRM_PANTHOR_EXCEPTION_CS_INSTR_INVALID = 0x49,
438 DRM_PANTHOR_EXCEPTION_CS_CALL_STACK_OVERFLOW = 0x4a,
439 DRM_PANTHOR_EXCEPTION_CS_INHERIT_FAULT = 0x4b,
440 DRM_PANTHOR_EXCEPTION_INSTR_INVALID_PC = 0x50,
441 DRM_PANTHOR_EXCEPTION_INSTR_INVALID_ENC = 0x51,
442 DRM_PANTHOR_EXCEPTION_INSTR_BARRIER_FAULT = 0x55,
443 DRM_PANTHOR_EXCEPTION_DATA_INVALID_FAULT = 0x58,
444 DRM_PANTHOR_EXCEPTION_TILE_RANGE_FAULT = 0x59,
445 DRM_PANTHOR_EXCEPTION_ADDR_RANGE_FAULT = 0x5a,
446 DRM_PANTHOR_EXCEPTION_IMPRECISE_FAULT = 0x5b,
447 DRM_PANTHOR_EXCEPTION_OOM = 0x60,
448 DRM_PANTHOR_EXCEPTION_CSF_FW_INTERNAL_ERROR = 0x68,
449 DRM_PANTHOR_EXCEPTION_CSF_RES_EVICTION_TIMEOUT = 0x69,
450 DRM_PANTHOR_EXCEPTION_GPU_BUS_FAULT = 0x80,
451 DRM_PANTHOR_EXCEPTION_GPU_SHAREABILITY_FAULT = 0x88,
452 DRM_PANTHOR_EXCEPTION_SYS_SHAREABILITY_FAULT = 0x89,
453 DRM_PANTHOR_EXCEPTION_GPU_CACHEABILITY_FAULT = 0x8a,
454 DRM_PANTHOR_EXCEPTION_TRANSLATION_FAULT_0 = 0xc0,
455 DRM_PANTHOR_EXCEPTION_TRANSLATION_FAULT_1 = 0xc1,
456 DRM_PANTHOR_EXCEPTION_TRANSLATION_FAULT_2 = 0xc2,
457 DRM_PANTHOR_EXCEPTION_TRANSLATION_FAULT_3 = 0xc3,
458 DRM_PANTHOR_EXCEPTION_TRANSLATION_FAULT_4 = 0xc4,
459 DRM_PANTHOR_EXCEPTION_PERM_FAULT_0 = 0xc8,
460 DRM_PANTHOR_EXCEPTION_PERM_FAULT_1 = 0xc9,
461 DRM_PANTHOR_EXCEPTION_PERM_FAULT_2 = 0xca,
462 DRM_PANTHOR_EXCEPTION_PERM_FAULT_3 = 0xcb,
463 DRM_PANTHOR_EXCEPTION_ACCESS_FLAG_1 = 0xd9,
464 DRM_PANTHOR_EXCEPTION_ACCESS_FLAG_2 = 0xda,
465 DRM_PANTHOR_EXCEPTION_ACCESS_FLAG_3 = 0xdb,
466 DRM_PANTHOR_EXCEPTION_ADDR_SIZE_FAULT_IN = 0xe0,
467 DRM_PANTHOR_EXCEPTION_ADDR_SIZE_FAULT_OUT0 = 0xe4,
468 DRM_PANTHOR_EXCEPTION_ADDR_SIZE_FAULT_OUT1 = 0xe5,
469 DRM_PANTHOR_EXCEPTION_ADDR_SIZE_FAULT_OUT2 = 0xe6,
470 DRM_PANTHOR_EXCEPTION_ADDR_SIZE_FAULT_OUT3 = 0xe7,
471 DRM_PANTHOR_EXCEPTION_MEM_ATTR_FAULT_0 = 0xe8,
472 DRM_PANTHOR_EXCEPTION_MEM_ATTR_FAULT_1 = 0xe9,
473 DRM_PANTHOR_EXCEPTION_MEM_ATTR_FAULT_2 = 0xea,
474 DRM_PANTHOR_EXCEPTION_MEM_ATTR_FAULT_3 = 0xeb,
475 };
476
477 /**
478 * panthor_exception_is_fault() - Checks if an exception is a fault.
479 *
480 * Return: true if the exception is a fault, false otherwise.
481 */
482 static inline bool
panthor_exception_is_fault(u32 exception_code)483 panthor_exception_is_fault(u32 exception_code)
484 {
485 return exception_code > DRM_PANTHOR_EXCEPTION_MAX_NON_FAULT;
486 }
487
488 const char *panthor_exception_name(struct panthor_device *ptdev,
489 u32 exception_code);
490
491 #define INT_RAWSTAT 0x0
492 #define INT_CLEAR 0x4
493 #define INT_MASK 0x8
494 #define INT_STAT 0xc
495
496 /**
497 * PANTHOR_IRQ_HANDLER() - Define interrupt handlers and the interrupt
498 * registration function.
499 *
500 * The boiler-plate to gracefully deal with shared interrupts is
501 * auto-generated. All you have to do is call PANTHOR_IRQ_HANDLER()
502 * just after the actual handler. The handler prototype is:
503 *
504 * void (*handler)(struct panthor_device *, u32 status);
505 */
506 #define PANTHOR_IRQ_HANDLER(__name, __handler) \
507 static irqreturn_t panthor_ ## __name ## _irq_raw_handler(int irq, void *data) \
508 { \
509 struct panthor_irq *pirq = data; \
510 enum panthor_irq_state old_state; \
511 \
512 guard(spinlock_irqsave)(&pirq->mask_lock); \
513 old_state = atomic_cmpxchg(&pirq->state, \
514 PANTHOR_IRQ_STATE_ACTIVE, \
515 PANTHOR_IRQ_STATE_PROCESSING); \
516 if (old_state != PANTHOR_IRQ_STATE_ACTIVE) \
517 return IRQ_NONE; \
518 \
519 if (!gpu_read(pirq->iomem, INT_STAT)) { \
520 atomic_cmpxchg(&pirq->state, \
521 PANTHOR_IRQ_STATE_PROCESSING, \
522 PANTHOR_IRQ_STATE_ACTIVE); \
523 return IRQ_NONE; \
524 } \
525 \
526 gpu_write(pirq->iomem, INT_MASK, 0); \
527 return IRQ_WAKE_THREAD; \
528 } \
529 \
530 static irqreturn_t panthor_ ## __name ## _irq_threaded_handler(int irq, void *data) \
531 { \
532 struct panthor_irq *pirq = data; \
533 struct panthor_device *ptdev = pirq->ptdev; \
534 irqreturn_t ret = IRQ_NONE; \
535 \
536 while (true) { \
537 /* It's safe to access pirq->mask without the lock held here. If a new \
538 * event gets added to the mask and the corresponding IRQ is pending, \
539 * we'll process it right away instead of adding an extra raw -> threaded \
540 * round trip. If an event is removed and the status bit is set, it will \
541 * be ignored, just like it would have been if the mask had been adjusted \
542 * right before the HW event kicks in. TLDR; it's all expected races we're \
543 * covered for. \
544 */ \
545 u32 status = gpu_read(pirq->iomem, INT_RAWSTAT) & pirq->mask; \
546 \
547 if (!status) \
548 break; \
549 \
550 __handler(ptdev, status); \
551 ret = IRQ_HANDLED; \
552 } \
553 \
554 scoped_guard(spinlock_irqsave, &pirq->mask_lock) { \
555 enum panthor_irq_state old_state; \
556 \
557 old_state = atomic_cmpxchg(&pirq->state, \
558 PANTHOR_IRQ_STATE_PROCESSING, \
559 PANTHOR_IRQ_STATE_ACTIVE); \
560 if (old_state == PANTHOR_IRQ_STATE_PROCESSING) \
561 gpu_write(pirq->iomem, INT_MASK, pirq->mask); \
562 } \
563 \
564 return ret; \
565 } \
566 \
567 static inline void panthor_ ## __name ## _irq_suspend(struct panthor_irq *pirq) \
568 { \
569 scoped_guard(spinlock_irqsave, &pirq->mask_lock) { \
570 atomic_set(&pirq->state, PANTHOR_IRQ_STATE_SUSPENDING); \
571 gpu_write(pirq->iomem, INT_MASK, 0); \
572 } \
573 synchronize_irq(pirq->irq); \
574 atomic_set(&pirq->state, PANTHOR_IRQ_STATE_SUSPENDED); \
575 } \
576 \
577 static inline void panthor_ ## __name ## _irq_resume(struct panthor_irq *pirq) \
578 { \
579 guard(spinlock_irqsave)(&pirq->mask_lock); \
580 \
581 atomic_set(&pirq->state, PANTHOR_IRQ_STATE_ACTIVE); \
582 gpu_write(pirq->iomem, INT_CLEAR, pirq->mask); \
583 gpu_write(pirq->iomem, INT_MASK, pirq->mask); \
584 } \
585 \
586 static int panthor_request_ ## __name ## _irq(struct panthor_device *ptdev, \
587 struct panthor_irq *pirq, \
588 int irq, void __iomem *iomem) \
589 { \
590 pirq->ptdev = ptdev; \
591 pirq->irq = irq; \
592 pirq->mask = 0; \
593 pirq->iomem = iomem; \
594 spin_lock_init(&pirq->mask_lock); \
595 atomic_set(&pirq->state, PANTHOR_IRQ_STATE_SUSPENDED); \
596 gpu_write(pirq->iomem, INT_MASK, 0); \
597 \
598 return devm_request_threaded_irq(ptdev->base.dev, irq, \
599 panthor_ ## __name ## _irq_raw_handler, \
600 panthor_ ## __name ## _irq_threaded_handler, \
601 IRQF_SHARED, KBUILD_MODNAME "-" # __name, \
602 pirq); \
603 } \
604 \
605 static inline void panthor_ ## __name ## _irq_enable_events(struct panthor_irq *pirq, u32 mask) \
606 { \
607 guard(spinlock_irqsave)(&pirq->mask_lock); \
608 pirq->mask |= mask; \
609 \
610 /* The only situation where we need to write the new mask is if the IRQ is active. \
611 * If it's being processed, the mask will be restored for us in _irq_threaded_handler() \
612 * on the PROCESSING -> ACTIVE transition. \
613 * If the IRQ is suspended/suspending, the mask is restored at resume time. \
614 */ \
615 if (atomic_read(&pirq->state) == PANTHOR_IRQ_STATE_ACTIVE) \
616 gpu_write(pirq->iomem, INT_MASK, pirq->mask); \
617 } \
618 \
619 static inline void panthor_ ## __name ## _irq_disable_events(struct panthor_irq *pirq, u32 mask)\
620 { \
621 guard(spinlock_irqsave)(&pirq->mask_lock); \
622 pirq->mask &= ~mask; \
623 \
624 /* The only situation where we need to write the new mask is if the IRQ is active. \
625 * If it's being processed, the mask will be restored for us in _irq_threaded_handler() \
626 * on the PROCESSING -> ACTIVE transition. \
627 * If the IRQ is suspended/suspending, the mask is restored at resume time. \
628 */ \
629 if (atomic_read(&pirq->state) == PANTHOR_IRQ_STATE_ACTIVE) \
630 gpu_write(pirq->iomem, INT_MASK, pirq->mask); \
631 }
632
633 extern struct workqueue_struct *panthor_cleanup_wq;
634
gpu_write(void __iomem * iomem,u32 reg,u32 data)635 static inline void gpu_write(void __iomem *iomem, u32 reg, u32 data)
636 {
637 writel(data, iomem + reg);
638 }
639
gpu_read(void __iomem * iomem,u32 reg)640 static inline u32 gpu_read(void __iomem *iomem, u32 reg)
641 {
642 return readl(iomem + reg);
643 }
644
gpu_read_relaxed(void __iomem * iomem,u32 reg)645 static inline u32 gpu_read_relaxed(void __iomem *iomem, u32 reg)
646 {
647 return readl_relaxed(iomem + reg);
648 }
649
gpu_write64(void __iomem * iomem,u32 reg,u64 data)650 static inline void gpu_write64(void __iomem *iomem, u32 reg, u64 data)
651 {
652 gpu_write(iomem, reg, lower_32_bits(data));
653 gpu_write(iomem, reg + 4, upper_32_bits(data));
654 }
655
gpu_read64(void __iomem * iomem,u32 reg)656 static inline u64 gpu_read64(void __iomem *iomem, u32 reg)
657 {
658 return (gpu_read(iomem, reg) | ((u64)gpu_read(iomem, reg + 4) << 32));
659 }
660
gpu_read64_relaxed(void __iomem * iomem,u32 reg)661 static inline u64 gpu_read64_relaxed(void __iomem *iomem, u32 reg)
662 {
663 return (gpu_read_relaxed(iomem, reg) |
664 ((u64)gpu_read_relaxed(iomem, reg + 4) << 32));
665 }
666
gpu_read64_counter(void __iomem * iomem,u32 reg)667 static inline u64 gpu_read64_counter(void __iomem *iomem, u32 reg)
668 {
669 u32 lo, hi1, hi2;
670 do {
671 hi1 = gpu_read(iomem, reg + 4);
672 lo = gpu_read(iomem, reg);
673 hi2 = gpu_read(iomem, reg + 4);
674 } while (hi1 != hi2);
675 return lo | ((u64)hi2 << 32);
676 }
677
678 #define gpu_read_poll_timeout(iomem, reg, val, cond, delay_us, timeout_us) \
679 read_poll_timeout(gpu_read, val, cond, delay_us, timeout_us, false, \
680 iomem, reg)
681
682 #define gpu_read_poll_timeout_atomic(iomem, reg, val, cond, delay_us, \
683 timeout_us) \
684 read_poll_timeout_atomic(gpu_read, val, cond, delay_us, timeout_us, \
685 false, iomem, reg)
686
687 #define gpu_read64_poll_timeout(iomem, reg, val, cond, delay_us, timeout_us) \
688 read_poll_timeout(gpu_read64, val, cond, delay_us, timeout_us, false, \
689 iomem, reg)
690
691 #define gpu_read64_poll_timeout_atomic(iomem, reg, val, cond, delay_us, \
692 timeout_us) \
693 read_poll_timeout_atomic(gpu_read64, val, cond, delay_us, timeout_us, \
694 false, iomem, reg)
695
696 #define gpu_read_relaxed_poll_timeout_atomic(iomem, reg, val, cond, delay_us, \
697 timeout_us) \
698 read_poll_timeout_atomic(gpu_read_relaxed, val, cond, delay_us, \
699 timeout_us, false, iomem, reg)
700
701 #define gpu_read64_relaxed_poll_timeout(iomem, reg, val, cond, delay_us, \
702 timeout_us) \
703 read_poll_timeout(gpu_read64_relaxed, val, cond, delay_us, timeout_us, \
704 false, iomem, reg)
705
706 #endif
707