1 /*
2 * Copyright 2021 Alyssa Rosenzweig
3 * SPDX-License-Identifier: MIT
4 */
5
6 #pragma once
7
8 #include "util/simple_mtx.h"
9 #include "util/sparse_array.h"
10 #include "util/timespec.h"
11 #include "util/vma.h"
12 #include "agx_bo.h"
13 #include "agx_formats.h"
14
15 enum agx_dbg {
16 AGX_DBG_TRACE = BITFIELD_BIT(0),
17 /* bit 1 unused */
18 AGX_DBG_NO16 = BITFIELD_BIT(2),
19 AGX_DBG_DIRTY = BITFIELD_BIT(3),
20 AGX_DBG_PRECOMPILE = BITFIELD_BIT(4),
21 AGX_DBG_PERF = BITFIELD_BIT(5),
22 AGX_DBG_NOCOMPRESS = BITFIELD_BIT(6),
23 AGX_DBG_NOCLUSTER = BITFIELD_BIT(7),
24 AGX_DBG_SYNC = BITFIELD_BIT(8),
25 AGX_DBG_STATS = BITFIELD_BIT(9),
26 AGX_DBG_RESOURCE = BITFIELD_BIT(10),
27 AGX_DBG_BATCH = BITFIELD_BIT(11),
28 AGX_DBG_NOWC = BITFIELD_BIT(12),
29 AGX_DBG_SYNCTVB = BITFIELD_BIT(13),
30 AGX_DBG_SMALLTILE = BITFIELD_BIT(14),
31 AGX_DBG_NOMSAA = BITFIELD_BIT(15),
32 AGX_DBG_NOSHADOW = BITFIELD_BIT(16),
33 AGX_DBG_VARYINGS = BITFIELD_BIT(17),
34 AGX_DBG_SCRATCH = BITFIELD_BIT(18),
35 AGX_DBG_COMPBLIT = BITFIELD_BIT(19),
36 AGX_DBG_FEEDBACK = BITFIELD_BIT(20),
37 };
38
39 /* Dummy partial declarations, pending real UAPI */
40 enum drm_asahi_cmd_type { DRM_ASAHI_CMD_TYPE_PLACEHOLDER_FOR_DOWNSTREAM_UAPI };
41 enum drm_asahi_sync_type { DRM_ASAHI_SYNC_SYNCOBJ };
42 struct drm_asahi_sync {
43 uint32_t sync_type;
44 uint32_t handle;
45 };
46 struct drm_asahi_params_global {
47 uint64_t vm_page_size;
48 uint64_t vm_user_start;
49 uint64_t vm_user_end;
50 uint64_t vm_shader_start;
51 uint64_t vm_shader_end;
52 uint32_t chip_id;
53 uint32_t num_clusters_total;
54 uint32_t gpu_generation;
55 uint32_t gpu_variant;
56 uint32_t num_dies;
57 uint32_t timer_frequency_hz;
58 uint32_t num_cores_per_cluster;
59 uint64_t core_masks[32];
60 };
61
62 /* How many power-of-two levels in the BO cache do we want? 2^14 minimum chosen
63 * as it is the page size that all allocations are rounded to
64 */
65 #define MIN_BO_CACHE_BUCKET (14) /* 2^14 = 16KB */
66 #define MAX_BO_CACHE_BUCKET (22) /* 2^22 = 4MB */
67
68 /* Fencepost problem, hence the off-by-one */
69 #define NR_BO_CACHE_BUCKETS (MAX_BO_CACHE_BUCKET - MIN_BO_CACHE_BUCKET + 1)
70
71 /* Forward decl only, do not pull in all of NIR */
72 struct nir_shader;
73
74 struct agx_device {
75 uint32_t debug;
76
77 /* NIR library of AGX helpers/shaders. Immutable once created. */
78 const struct nir_shader *libagx;
79
80 char name[64];
81 struct drm_asahi_params_global params;
82 uint64_t next_global_id, last_global_id;
83
84 /* Device handle */
85 int fd;
86
87 /* VM handle */
88 uint32_t vm_id;
89
90 /* VMA heaps */
91 simple_mtx_t vma_lock;
92 uint64_t shader_base;
93 struct util_vma_heap main_heap;
94 struct util_vma_heap usc_heap;
95 uint64_t guard_size;
96
97 struct renderonly *ro;
98
99 pthread_mutex_t bo_map_lock;
100 struct util_sparse_array bo_map;
101 uint32_t max_handle;
102
103 struct {
104 simple_mtx_t lock;
105
106 /* List containing all cached BOs sorted in LRU (Least Recently Used)
107 * order so we can quickly evict BOs that are more than 1 second old.
108 */
109 struct list_head lru;
110
111 /* The BO cache is a set of buckets with power-of-two sizes. Each bucket
112 * is a linked list of free panfrost_bo objects.
113 */
114 struct list_head buckets[NR_BO_CACHE_BUCKETS];
115
116 /* Current size of the BO cache in bytes (sum of sizes of cached BOs) */
117 size_t size;
118
119 /* Number of hits/misses for the BO cache */
120 uint64_t hits, misses;
121 } bo_cache;
122
123 struct agx_bo *helper;
124 };
125
126 bool agx_open_device(void *memctx, struct agx_device *dev);
127
128 void agx_close_device(struct agx_device *dev);
129
130 static inline struct agx_bo *
agx_lookup_bo(struct agx_device * dev,uint32_t handle)131 agx_lookup_bo(struct agx_device *dev, uint32_t handle)
132 {
133 return util_sparse_array_get(&dev->bo_map, handle);
134 }
135
136 void agx_bo_mmap(struct agx_bo *bo);
137
138 uint64_t agx_get_global_id(struct agx_device *dev);
139
140 uint32_t agx_create_command_queue(struct agx_device *dev, uint32_t caps);
141
142 int agx_import_sync_file(struct agx_device *dev, struct agx_bo *bo, int fd);
143 int agx_export_sync_file(struct agx_device *dev, struct agx_bo *bo);
144
145 void agx_debug_fault(struct agx_device *dev, uint64_t addr);
146
147 uint64_t agx_get_gpu_timestamp(struct agx_device *dev);
148
149 static inline uint64_t
agx_gpu_time_to_ns(struct agx_device * dev,uint64_t gpu_time)150 agx_gpu_time_to_ns(struct agx_device *dev, uint64_t gpu_time)
151 {
152 return (gpu_time * NSEC_PER_SEC) / dev->params.timer_frequency_hz;
153 }
154