• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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