1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright 2021 Alyssa Rosenzweig
3*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker */
5*61046927SAndroid Build Coastguard Worker
6*61046927SAndroid Build Coastguard Worker #pragma once
7*61046927SAndroid Build Coastguard Worker
8*61046927SAndroid Build Coastguard Worker #include <stdint.h>
9*61046927SAndroid Build Coastguard Worker #include <xf86drm.h>
10*61046927SAndroid Build Coastguard Worker #include "util/ralloc.h"
11*61046927SAndroid Build Coastguard Worker #include "util/simple_mtx.h"
12*61046927SAndroid Build Coastguard Worker #include "util/sparse_array.h"
13*61046927SAndroid Build Coastguard Worker #include "util/timespec.h"
14*61046927SAndroid Build Coastguard Worker #include "util/vma.h"
15*61046927SAndroid Build Coastguard Worker #include "agx_bo.h"
16*61046927SAndroid Build Coastguard Worker #include "decode.h"
17*61046927SAndroid Build Coastguard Worker #include "layout.h"
18*61046927SAndroid Build Coastguard Worker #include "unstable_asahi_drm.h"
19*61046927SAndroid Build Coastguard Worker
20*61046927SAndroid Build Coastguard Worker // TODO: this is a lie right now
21*61046927SAndroid Build Coastguard Worker static const uint64_t AGX_SUPPORTED_INCOMPAT_FEATURES =
22*61046927SAndroid Build Coastguard Worker DRM_ASAHI_FEAT_MANDATORY_ZS_COMPRESSION;
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker enum agx_dbg {
25*61046927SAndroid Build Coastguard Worker AGX_DBG_TRACE = BITFIELD_BIT(0),
26*61046927SAndroid Build Coastguard Worker /* bit 1 unused */
27*61046927SAndroid Build Coastguard Worker AGX_DBG_NO16 = BITFIELD_BIT(2),
28*61046927SAndroid Build Coastguard Worker AGX_DBG_DIRTY = BITFIELD_BIT(3),
29*61046927SAndroid Build Coastguard Worker AGX_DBG_PRECOMPILE = BITFIELD_BIT(4),
30*61046927SAndroid Build Coastguard Worker AGX_DBG_PERF = BITFIELD_BIT(5),
31*61046927SAndroid Build Coastguard Worker AGX_DBG_NOCOMPRESS = BITFIELD_BIT(6),
32*61046927SAndroid Build Coastguard Worker AGX_DBG_NOCLUSTER = BITFIELD_BIT(7),
33*61046927SAndroid Build Coastguard Worker AGX_DBG_SYNC = BITFIELD_BIT(8),
34*61046927SAndroid Build Coastguard Worker AGX_DBG_STATS = BITFIELD_BIT(9),
35*61046927SAndroid Build Coastguard Worker AGX_DBG_RESOURCE = BITFIELD_BIT(10),
36*61046927SAndroid Build Coastguard Worker AGX_DBG_BATCH = BITFIELD_BIT(11),
37*61046927SAndroid Build Coastguard Worker AGX_DBG_NOWC = BITFIELD_BIT(12),
38*61046927SAndroid Build Coastguard Worker AGX_DBG_SYNCTVB = BITFIELD_BIT(13),
39*61046927SAndroid Build Coastguard Worker AGX_DBG_SMALLTILE = BITFIELD_BIT(14),
40*61046927SAndroid Build Coastguard Worker AGX_DBG_NOMSAA = BITFIELD_BIT(15),
41*61046927SAndroid Build Coastguard Worker AGX_DBG_NOSHADOW = BITFIELD_BIT(16),
42*61046927SAndroid Build Coastguard Worker /* bit 17 unused */
43*61046927SAndroid Build Coastguard Worker AGX_DBG_SCRATCH = BITFIELD_BIT(18),
44*61046927SAndroid Build Coastguard Worker /* bit 19 unused */
45*61046927SAndroid Build Coastguard Worker AGX_DBG_FEEDBACK = BITFIELD_BIT(20),
46*61046927SAndroid Build Coastguard Worker AGX_DBG_1QUEUE = BITFIELD_BIT(21),
47*61046927SAndroid Build Coastguard Worker };
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker /* How many power-of-two levels in the BO cache do we want? 2^14 minimum chosen
50*61046927SAndroid Build Coastguard Worker * as it is the page size that all allocations are rounded to
51*61046927SAndroid Build Coastguard Worker */
52*61046927SAndroid Build Coastguard Worker #define MIN_BO_CACHE_BUCKET (14) /* 2^14 = 16KB */
53*61046927SAndroid Build Coastguard Worker #define MAX_BO_CACHE_BUCKET (22) /* 2^22 = 4MB */
54*61046927SAndroid Build Coastguard Worker
55*61046927SAndroid Build Coastguard Worker /* Fencepost problem, hence the off-by-one */
56*61046927SAndroid Build Coastguard Worker #define NR_BO_CACHE_BUCKETS (MAX_BO_CACHE_BUCKET - MIN_BO_CACHE_BUCKET + 1)
57*61046927SAndroid Build Coastguard Worker
58*61046927SAndroid Build Coastguard Worker /* Forward decl only, do not pull in all of NIR */
59*61046927SAndroid Build Coastguard Worker struct nir_shader;
60*61046927SAndroid Build Coastguard Worker
61*61046927SAndroid Build Coastguard Worker #define BARRIER_RENDER (1 << DRM_ASAHI_SUBQUEUE_RENDER)
62*61046927SAndroid Build Coastguard Worker #define BARRIER_COMPUTE (1 << DRM_ASAHI_SUBQUEUE_COMPUTE)
63*61046927SAndroid Build Coastguard Worker
64*61046927SAndroid Build Coastguard Worker typedef struct {
65*61046927SAndroid Build Coastguard Worker struct agx_bo *(*bo_alloc)(struct agx_device *dev, size_t size, size_t align,
66*61046927SAndroid Build Coastguard Worker enum agx_bo_flags flags);
67*61046927SAndroid Build Coastguard Worker int (*bo_bind)(struct agx_device *dev, struct agx_bo *bo, uint64_t addr,
68*61046927SAndroid Build Coastguard Worker size_t size_B, uint64_t offset_B, uint32_t flags,
69*61046927SAndroid Build Coastguard Worker bool unbind);
70*61046927SAndroid Build Coastguard Worker void (*bo_mmap)(struct agx_device *dev, struct agx_bo *bo);
71*61046927SAndroid Build Coastguard Worker ssize_t (*get_params)(struct agx_device *dev, void *buf, size_t size);
72*61046927SAndroid Build Coastguard Worker int (*submit)(struct agx_device *dev, struct drm_asahi_submit *submit,
73*61046927SAndroid Build Coastguard Worker uint32_t vbo_res_id);
74*61046927SAndroid Build Coastguard Worker } agx_device_ops_t;
75*61046927SAndroid Build Coastguard Worker
76*61046927SAndroid Build Coastguard Worker struct agx_device {
77*61046927SAndroid Build Coastguard Worker uint32_t debug;
78*61046927SAndroid Build Coastguard Worker
79*61046927SAndroid Build Coastguard Worker /* NIR library of AGX helpers/shaders. Immutable once created. */
80*61046927SAndroid Build Coastguard Worker const struct nir_shader *libagx;
81*61046927SAndroid Build Coastguard Worker
82*61046927SAndroid Build Coastguard Worker char name[64];
83*61046927SAndroid Build Coastguard Worker struct drm_asahi_params_global params;
84*61046927SAndroid Build Coastguard Worker uint64_t next_global_id, last_global_id;
85*61046927SAndroid Build Coastguard Worker bool is_virtio;
86*61046927SAndroid Build Coastguard Worker agx_device_ops_t ops;
87*61046927SAndroid Build Coastguard Worker
88*61046927SAndroid Build Coastguard Worker /* vdrm device */
89*61046927SAndroid Build Coastguard Worker struct vdrm_device *vdrm;
90*61046927SAndroid Build Coastguard Worker uint32_t next_blob_id;
91*61046927SAndroid Build Coastguard Worker
92*61046927SAndroid Build Coastguard Worker /* Device handle */
93*61046927SAndroid Build Coastguard Worker int fd;
94*61046927SAndroid Build Coastguard Worker
95*61046927SAndroid Build Coastguard Worker /* VM handle */
96*61046927SAndroid Build Coastguard Worker uint32_t vm_id;
97*61046927SAndroid Build Coastguard Worker
98*61046927SAndroid Build Coastguard Worker /* Global queue handle */
99*61046927SAndroid Build Coastguard Worker uint32_t queue_id;
100*61046927SAndroid Build Coastguard Worker
101*61046927SAndroid Build Coastguard Worker /* VMA heaps */
102*61046927SAndroid Build Coastguard Worker simple_mtx_t vma_lock;
103*61046927SAndroid Build Coastguard Worker uint64_t shader_base;
104*61046927SAndroid Build Coastguard Worker struct util_vma_heap main_heap;
105*61046927SAndroid Build Coastguard Worker struct util_vma_heap usc_heap;
106*61046927SAndroid Build Coastguard Worker uint64_t guard_size;
107*61046927SAndroid Build Coastguard Worker
108*61046927SAndroid Build Coastguard Worker struct renderonly *ro;
109*61046927SAndroid Build Coastguard Worker
110*61046927SAndroid Build Coastguard Worker pthread_mutex_t bo_map_lock;
111*61046927SAndroid Build Coastguard Worker struct util_sparse_array bo_map;
112*61046927SAndroid Build Coastguard Worker uint32_t max_handle;
113*61046927SAndroid Build Coastguard Worker
114*61046927SAndroid Build Coastguard Worker struct {
115*61046927SAndroid Build Coastguard Worker simple_mtx_t lock;
116*61046927SAndroid Build Coastguard Worker
117*61046927SAndroid Build Coastguard Worker /* List containing all cached BOs sorted in LRU (Least Recently Used)
118*61046927SAndroid Build Coastguard Worker * order so we can quickly evict BOs that are more than 1 second old.
119*61046927SAndroid Build Coastguard Worker */
120*61046927SAndroid Build Coastguard Worker struct list_head lru;
121*61046927SAndroid Build Coastguard Worker
122*61046927SAndroid Build Coastguard Worker /* The BO cache is a set of buckets with power-of-two sizes. Each bucket
123*61046927SAndroid Build Coastguard Worker * is a linked list of free panfrost_bo objects.
124*61046927SAndroid Build Coastguard Worker */
125*61046927SAndroid Build Coastguard Worker struct list_head buckets[NR_BO_CACHE_BUCKETS];
126*61046927SAndroid Build Coastguard Worker
127*61046927SAndroid Build Coastguard Worker /* Current size of the BO cache in bytes (sum of sizes of cached BOs) */
128*61046927SAndroid Build Coastguard Worker size_t size;
129*61046927SAndroid Build Coastguard Worker
130*61046927SAndroid Build Coastguard Worker /* Number of hits/misses for the BO cache */
131*61046927SAndroid Build Coastguard Worker uint64_t hits, misses;
132*61046927SAndroid Build Coastguard Worker } bo_cache;
133*61046927SAndroid Build Coastguard Worker
134*61046927SAndroid Build Coastguard Worker struct agx_bo *helper;
135*61046927SAndroid Build Coastguard Worker
136*61046927SAndroid Build Coastguard Worker struct agxdecode_ctx *agxdecode;
137*61046927SAndroid Build Coastguard Worker };
138*61046927SAndroid Build Coastguard Worker
139*61046927SAndroid Build Coastguard Worker static inline bool
agx_has_soft_fault(struct agx_device * dev)140*61046927SAndroid Build Coastguard Worker agx_has_soft_fault(struct agx_device *dev)
141*61046927SAndroid Build Coastguard Worker {
142*61046927SAndroid Build Coastguard Worker return dev->params.feat_compat & DRM_ASAHI_FEAT_SOFT_FAULTS;
143*61046927SAndroid Build Coastguard Worker }
144*61046927SAndroid Build Coastguard Worker
145*61046927SAndroid Build Coastguard Worker static uint32_t
agx_usc_addr(struct agx_device * dev,uint64_t addr)146*61046927SAndroid Build Coastguard Worker agx_usc_addr(struct agx_device *dev, uint64_t addr)
147*61046927SAndroid Build Coastguard Worker {
148*61046927SAndroid Build Coastguard Worker assert(addr >= dev->shader_base);
149*61046927SAndroid Build Coastguard Worker assert((addr - dev->shader_base) <= UINT32_MAX);
150*61046927SAndroid Build Coastguard Worker
151*61046927SAndroid Build Coastguard Worker return addr - dev->shader_base;
152*61046927SAndroid Build Coastguard Worker }
153*61046927SAndroid Build Coastguard Worker
154*61046927SAndroid Build Coastguard Worker bool agx_open_device(void *memctx, struct agx_device *dev);
155*61046927SAndroid Build Coastguard Worker
156*61046927SAndroid Build Coastguard Worker void agx_close_device(struct agx_device *dev);
157*61046927SAndroid Build Coastguard Worker
158*61046927SAndroid Build Coastguard Worker static inline struct agx_bo *
agx_lookup_bo(struct agx_device * dev,uint32_t handle)159*61046927SAndroid Build Coastguard Worker agx_lookup_bo(struct agx_device *dev, uint32_t handle)
160*61046927SAndroid Build Coastguard Worker {
161*61046927SAndroid Build Coastguard Worker return util_sparse_array_get(&dev->bo_map, handle);
162*61046927SAndroid Build Coastguard Worker }
163*61046927SAndroid Build Coastguard Worker
164*61046927SAndroid Build Coastguard Worker uint64_t agx_get_global_id(struct agx_device *dev);
165*61046927SAndroid Build Coastguard Worker
166*61046927SAndroid Build Coastguard Worker uint32_t agx_create_command_queue(struct agx_device *dev, uint32_t caps,
167*61046927SAndroid Build Coastguard Worker uint32_t priority);
168*61046927SAndroid Build Coastguard Worker int agx_destroy_command_queue(struct agx_device *dev, uint32_t queue_id);
169*61046927SAndroid Build Coastguard Worker
170*61046927SAndroid Build Coastguard Worker int agx_import_sync_file(struct agx_device *dev, struct agx_bo *bo, int fd);
171*61046927SAndroid Build Coastguard Worker int agx_export_sync_file(struct agx_device *dev, struct agx_bo *bo);
172*61046927SAndroid Build Coastguard Worker
173*61046927SAndroid Build Coastguard Worker void agx_debug_fault(struct agx_device *dev, uint64_t addr);
174*61046927SAndroid Build Coastguard Worker
175*61046927SAndroid Build Coastguard Worker uint64_t agx_get_gpu_timestamp(struct agx_device *dev);
176*61046927SAndroid Build Coastguard Worker
177*61046927SAndroid Build Coastguard Worker static inline uint64_t
agx_gpu_time_to_ns(struct agx_device * dev,uint64_t gpu_time)178*61046927SAndroid Build Coastguard Worker agx_gpu_time_to_ns(struct agx_device *dev, uint64_t gpu_time)
179*61046927SAndroid Build Coastguard Worker {
180*61046927SAndroid Build Coastguard Worker return (gpu_time * NSEC_PER_SEC) / dev->params.timer_frequency_hz;
181*61046927SAndroid Build Coastguard Worker }
182*61046927SAndroid Build Coastguard Worker
183*61046927SAndroid Build Coastguard Worker void agx_get_device_uuid(const struct agx_device *dev, void *uuid);
184*61046927SAndroid Build Coastguard Worker void agx_get_driver_uuid(void *uuid);
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker struct agx_va *agx_va_alloc(struct agx_device *dev, uint32_t size_B,
187*61046927SAndroid Build Coastguard Worker uint32_t align_B, enum agx_va_flags flags,
188*61046927SAndroid Build Coastguard Worker uint64_t fixed_va);
189*61046927SAndroid Build Coastguard Worker void agx_va_free(struct agx_device *dev, struct agx_va *va);
190