1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2016 Red Hat.
3*61046927SAndroid Build Coastguard Worker * Copyright © 2016 Bas Nieuwenhuizen
4*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
5*61046927SAndroid Build Coastguard Worker *
6*61046927SAndroid Build Coastguard Worker * based in part on anv driver which is:
7*61046927SAndroid Build Coastguard Worker * Copyright © 2015 Intel Corporation
8*61046927SAndroid Build Coastguard Worker */
9*61046927SAndroid Build Coastguard Worker
10*61046927SAndroid Build Coastguard Worker #include <fcntl.h>
11*61046927SAndroid Build Coastguard Worker
12*61046927SAndroid Build Coastguard Worker #ifdef MAJOR_IN_MKDEV
13*61046927SAndroid Build Coastguard Worker #include <sys/mkdev.h>
14*61046927SAndroid Build Coastguard Worker #endif
15*61046927SAndroid Build Coastguard Worker #ifdef MAJOR_IN_SYSMACROS
16*61046927SAndroid Build Coastguard Worker #include <sys/sysmacros.h>
17*61046927SAndroid Build Coastguard Worker #endif
18*61046927SAndroid Build Coastguard Worker
19*61046927SAndroid Build Coastguard Worker #include <sys/mman.h>
20*61046927SAndroid Build Coastguard Worker
21*61046927SAndroid Build Coastguard Worker #include "vk_debug_utils.h"
22*61046927SAndroid Build Coastguard Worker
23*61046927SAndroid Build Coastguard Worker #include "util/libdrm.h"
24*61046927SAndroid Build Coastguard Worker
25*61046927SAndroid Build Coastguard Worker #include "tu_device.h"
26*61046927SAndroid Build Coastguard Worker #include "tu_knl.h"
27*61046927SAndroid Build Coastguard Worker #include "tu_rmv.h"
28*61046927SAndroid Build Coastguard Worker
29*61046927SAndroid Build Coastguard Worker
30*61046927SAndroid Build Coastguard Worker VkResult
tu_bo_init_new_explicit_iova(struct tu_device * dev,struct vk_object_base * base,struct tu_bo ** out_bo,uint64_t size,uint64_t client_iova,VkMemoryPropertyFlags mem_property,enum tu_bo_alloc_flags flags,const char * name)31*61046927SAndroid Build Coastguard Worker tu_bo_init_new_explicit_iova(struct tu_device *dev,
32*61046927SAndroid Build Coastguard Worker struct vk_object_base *base,
33*61046927SAndroid Build Coastguard Worker struct tu_bo **out_bo,
34*61046927SAndroid Build Coastguard Worker uint64_t size,
35*61046927SAndroid Build Coastguard Worker uint64_t client_iova,
36*61046927SAndroid Build Coastguard Worker VkMemoryPropertyFlags mem_property,
37*61046927SAndroid Build Coastguard Worker enum tu_bo_alloc_flags flags, const char *name)
38*61046927SAndroid Build Coastguard Worker {
39*61046927SAndroid Build Coastguard Worker struct tu_instance *instance = dev->physical_device->instance;
40*61046927SAndroid Build Coastguard Worker
41*61046927SAndroid Build Coastguard Worker VkResult result =
42*61046927SAndroid Build Coastguard Worker dev->instance->knl->bo_init(dev, base, out_bo, size, client_iova,
43*61046927SAndroid Build Coastguard Worker mem_property, flags, name);
44*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
45*61046927SAndroid Build Coastguard Worker return result;
46*61046927SAndroid Build Coastguard Worker
47*61046927SAndroid Build Coastguard Worker vk_address_binding_report(&instance->vk, base ? base : &dev->vk.base,
48*61046927SAndroid Build Coastguard Worker (*out_bo)->iova, (*out_bo)->size,
49*61046927SAndroid Build Coastguard Worker VK_DEVICE_ADDRESS_BINDING_TYPE_BIND_EXT);
50*61046927SAndroid Build Coastguard Worker
51*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
52*61046927SAndroid Build Coastguard Worker }
53*61046927SAndroid Build Coastguard Worker
54*61046927SAndroid Build Coastguard Worker VkResult
tu_bo_init_dmabuf(struct tu_device * dev,struct tu_bo ** bo,uint64_t size,int fd)55*61046927SAndroid Build Coastguard Worker tu_bo_init_dmabuf(struct tu_device *dev,
56*61046927SAndroid Build Coastguard Worker struct tu_bo **bo,
57*61046927SAndroid Build Coastguard Worker uint64_t size,
58*61046927SAndroid Build Coastguard Worker int fd)
59*61046927SAndroid Build Coastguard Worker {
60*61046927SAndroid Build Coastguard Worker return dev->instance->knl->bo_init_dmabuf(dev, bo, size, fd);
61*61046927SAndroid Build Coastguard Worker }
62*61046927SAndroid Build Coastguard Worker
63*61046927SAndroid Build Coastguard Worker int
tu_bo_export_dmabuf(struct tu_device * dev,struct tu_bo * bo)64*61046927SAndroid Build Coastguard Worker tu_bo_export_dmabuf(struct tu_device *dev, struct tu_bo *bo)
65*61046927SAndroid Build Coastguard Worker {
66*61046927SAndroid Build Coastguard Worker return dev->instance->knl->bo_export_dmabuf(dev, bo);
67*61046927SAndroid Build Coastguard Worker }
68*61046927SAndroid Build Coastguard Worker
69*61046927SAndroid Build Coastguard Worker void
tu_bo_finish(struct tu_device * dev,struct tu_bo * bo)70*61046927SAndroid Build Coastguard Worker tu_bo_finish(struct tu_device *dev, struct tu_bo *bo)
71*61046927SAndroid Build Coastguard Worker {
72*61046927SAndroid Build Coastguard Worker struct tu_instance *instance = dev->physical_device->instance;
73*61046927SAndroid Build Coastguard Worker
74*61046927SAndroid Build Coastguard Worker vk_address_binding_report(&instance->vk, bo->base ? bo->base : &dev->vk.base,
75*61046927SAndroid Build Coastguard Worker bo->iova, bo->size,
76*61046927SAndroid Build Coastguard Worker VK_DEVICE_ADDRESS_BINDING_TYPE_UNBIND_EXT);
77*61046927SAndroid Build Coastguard Worker
78*61046927SAndroid Build Coastguard Worker dev->instance->knl->bo_finish(dev, bo);
79*61046927SAndroid Build Coastguard Worker }
80*61046927SAndroid Build Coastguard Worker
81*61046927SAndroid Build Coastguard Worker VkResult
tu_bo_map(struct tu_device * dev,struct tu_bo * bo,void * placed_addr)82*61046927SAndroid Build Coastguard Worker tu_bo_map(struct tu_device *dev, struct tu_bo *bo, void *placed_addr)
83*61046927SAndroid Build Coastguard Worker {
84*61046927SAndroid Build Coastguard Worker if (bo->map && (placed_addr == NULL || placed_addr == bo->map))
85*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
86*61046927SAndroid Build Coastguard Worker else if (bo->map)
87*61046927SAndroid Build Coastguard Worker /* The BO is already mapped, but with a different address. */
88*61046927SAndroid Build Coastguard Worker return vk_errorf(dev, VK_ERROR_MEMORY_MAP_FAILED, "Cannot remap BO to a different address");
89*61046927SAndroid Build Coastguard Worker
90*61046927SAndroid Build Coastguard Worker return dev->instance->knl->bo_map(dev, bo, placed_addr);
91*61046927SAndroid Build Coastguard Worker }
92*61046927SAndroid Build Coastguard Worker
93*61046927SAndroid Build Coastguard Worker VkResult
tu_bo_unmap(struct tu_device * dev,struct tu_bo * bo,bool reserve)94*61046927SAndroid Build Coastguard Worker tu_bo_unmap(struct tu_device *dev, struct tu_bo *bo, bool reserve)
95*61046927SAndroid Build Coastguard Worker {
96*61046927SAndroid Build Coastguard Worker if (!bo->map || bo->never_unmap)
97*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
98*61046927SAndroid Build Coastguard Worker
99*61046927SAndroid Build Coastguard Worker TU_RMV(bo_unmap, dev, bo);
100*61046927SAndroid Build Coastguard Worker
101*61046927SAndroid Build Coastguard Worker if (reserve) {
102*61046927SAndroid Build Coastguard Worker void *map = mmap(bo->map, bo->size, PROT_NONE,
103*61046927SAndroid Build Coastguard Worker MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
104*61046927SAndroid Build Coastguard Worker if (map == MAP_FAILED)
105*61046927SAndroid Build Coastguard Worker return vk_errorf(dev, VK_ERROR_MEMORY_MAP_FAILED,
106*61046927SAndroid Build Coastguard Worker "Failed to replace mapping with reserved memory");
107*61046927SAndroid Build Coastguard Worker } else {
108*61046927SAndroid Build Coastguard Worker munmap(bo->map, bo->size);
109*61046927SAndroid Build Coastguard Worker }
110*61046927SAndroid Build Coastguard Worker
111*61046927SAndroid Build Coastguard Worker bo->map = NULL;
112*61046927SAndroid Build Coastguard Worker
113*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
114*61046927SAndroid Build Coastguard Worker }
115*61046927SAndroid Build Coastguard Worker
116*61046927SAndroid Build Coastguard Worker static inline void
tu_sync_cacheline_to_gpu(void const * p)117*61046927SAndroid Build Coastguard Worker tu_sync_cacheline_to_gpu(void const *p __attribute__((unused)))
118*61046927SAndroid Build Coastguard Worker {
119*61046927SAndroid Build Coastguard Worker #if DETECT_ARCH_AARCH64
120*61046927SAndroid Build Coastguard Worker /* Clean data cache. */
121*61046927SAndroid Build Coastguard Worker __asm volatile("dc cvac, %0" : : "r" (p) : "memory");
122*61046927SAndroid Build Coastguard Worker #elif (DETECT_ARCH_X86 || DETECT_ARCH_X86_64)
123*61046927SAndroid Build Coastguard Worker __builtin_ia32_clflush(p);
124*61046927SAndroid Build Coastguard Worker #elif DETECT_ARCH_ARM
125*61046927SAndroid Build Coastguard Worker /* DCCMVAC - same as DC CVAC on aarch64.
126*61046927SAndroid Build Coastguard Worker * Seems to be illegal to call from userspace.
127*61046927SAndroid Build Coastguard Worker */
128*61046927SAndroid Build Coastguard Worker //__asm volatile("mcr p15, 0, %0, c7, c10, 1" : : "r" (p) : "memory");
129*61046927SAndroid Build Coastguard Worker unreachable("Cache line clean is unsupported on ARMv7");
130*61046927SAndroid Build Coastguard Worker #endif
131*61046927SAndroid Build Coastguard Worker }
132*61046927SAndroid Build Coastguard Worker
133*61046927SAndroid Build Coastguard Worker static inline void
tu_sync_cacheline_from_gpu(void const * p)134*61046927SAndroid Build Coastguard Worker tu_sync_cacheline_from_gpu(void const *p __attribute__((unused)))
135*61046927SAndroid Build Coastguard Worker {
136*61046927SAndroid Build Coastguard Worker #if DETECT_ARCH_AARCH64
137*61046927SAndroid Build Coastguard Worker /* Clean and Invalidate data cache, there is no separate Invalidate. */
138*61046927SAndroid Build Coastguard Worker __asm volatile("dc civac, %0" : : "r" (p) : "memory");
139*61046927SAndroid Build Coastguard Worker #elif (DETECT_ARCH_X86 || DETECT_ARCH_X86_64)
140*61046927SAndroid Build Coastguard Worker __builtin_ia32_clflush(p);
141*61046927SAndroid Build Coastguard Worker #elif DETECT_ARCH_ARM
142*61046927SAndroid Build Coastguard Worker /* DCCIMVAC - same as DC CIVAC on aarch64.
143*61046927SAndroid Build Coastguard Worker * Seems to be illegal to call from userspace.
144*61046927SAndroid Build Coastguard Worker */
145*61046927SAndroid Build Coastguard Worker //__asm volatile("mcr p15, 0, %0, c7, c14, 1" : : "r" (p) : "memory");
146*61046927SAndroid Build Coastguard Worker unreachable("Cache line invalidate is unsupported on ARMv7");
147*61046927SAndroid Build Coastguard Worker #endif
148*61046927SAndroid Build Coastguard Worker }
149*61046927SAndroid Build Coastguard Worker
150*61046927SAndroid Build Coastguard Worker void
tu_bo_sync_cache(struct tu_device * dev,struct tu_bo * bo,VkDeviceSize offset,VkDeviceSize size,enum tu_mem_sync_op op)151*61046927SAndroid Build Coastguard Worker tu_bo_sync_cache(struct tu_device *dev,
152*61046927SAndroid Build Coastguard Worker struct tu_bo *bo,
153*61046927SAndroid Build Coastguard Worker VkDeviceSize offset,
154*61046927SAndroid Build Coastguard Worker VkDeviceSize size,
155*61046927SAndroid Build Coastguard Worker enum tu_mem_sync_op op)
156*61046927SAndroid Build Coastguard Worker {
157*61046927SAndroid Build Coastguard Worker uintptr_t level1_dcache_size = dev->physical_device->level1_dcache_size;
158*61046927SAndroid Build Coastguard Worker char *start = (char *) bo->map + offset;
159*61046927SAndroid Build Coastguard Worker char *end = start + (size == VK_WHOLE_SIZE ? (bo->size - offset) : size);
160*61046927SAndroid Build Coastguard Worker
161*61046927SAndroid Build Coastguard Worker start = (char *) ((uintptr_t) start & ~(level1_dcache_size - 1));
162*61046927SAndroid Build Coastguard Worker
163*61046927SAndroid Build Coastguard Worker for (; start < end; start += level1_dcache_size) {
164*61046927SAndroid Build Coastguard Worker if (op == TU_MEM_SYNC_CACHE_TO_GPU) {
165*61046927SAndroid Build Coastguard Worker tu_sync_cacheline_to_gpu(start);
166*61046927SAndroid Build Coastguard Worker } else {
167*61046927SAndroid Build Coastguard Worker tu_sync_cacheline_from_gpu(start);
168*61046927SAndroid Build Coastguard Worker }
169*61046927SAndroid Build Coastguard Worker }
170*61046927SAndroid Build Coastguard Worker }
171*61046927SAndroid Build Coastguard Worker
172*61046927SAndroid Build Coastguard Worker uint32_t
tu_get_l1_dcache_size()173*61046927SAndroid Build Coastguard Worker tu_get_l1_dcache_size()
174*61046927SAndroid Build Coastguard Worker {
175*61046927SAndroid Build Coastguard Worker if (!(DETECT_ARCH_AARCH64 || DETECT_ARCH_X86 || DETECT_ARCH_X86_64))
176*61046927SAndroid Build Coastguard Worker return 0;
177*61046927SAndroid Build Coastguard Worker
178*61046927SAndroid Build Coastguard Worker #if DETECT_ARCH_AARCH64 && \
179*61046927SAndroid Build Coastguard Worker (!defined(_SC_LEVEL1_DCACHE_LINESIZE) || DETECT_OS_ANDROID)
180*61046927SAndroid Build Coastguard Worker /* Bionic does not implement _SC_LEVEL1_DCACHE_LINESIZE properly: */
181*61046927SAndroid Build Coastguard Worker uint64_t ctr_el0;
182*61046927SAndroid Build Coastguard Worker asm("mrs\t%x0, ctr_el0" : "=r"(ctr_el0));
183*61046927SAndroid Build Coastguard Worker return 4 << ((ctr_el0 >> 16) & 0xf);
184*61046927SAndroid Build Coastguard Worker #elif defined(_SC_LEVEL1_DCACHE_LINESIZE)
185*61046927SAndroid Build Coastguard Worker return sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
186*61046927SAndroid Build Coastguard Worker #else
187*61046927SAndroid Build Coastguard Worker return 0;
188*61046927SAndroid Build Coastguard Worker #endif
189*61046927SAndroid Build Coastguard Worker }
190*61046927SAndroid Build Coastguard Worker
tu_bo_allow_dump(struct tu_device * dev,struct tu_bo * bo)191*61046927SAndroid Build Coastguard Worker void tu_bo_allow_dump(struct tu_device *dev, struct tu_bo *bo)
192*61046927SAndroid Build Coastguard Worker {
193*61046927SAndroid Build Coastguard Worker dev->instance->knl->bo_allow_dump(dev, bo);
194*61046927SAndroid Build Coastguard Worker }
195*61046927SAndroid Build Coastguard Worker
196*61046927SAndroid Build Coastguard Worker void
tu_bo_set_metadata(struct tu_device * dev,struct tu_bo * bo,void * metadata,uint32_t metadata_size)197*61046927SAndroid Build Coastguard Worker tu_bo_set_metadata(struct tu_device *dev, struct tu_bo *bo,
198*61046927SAndroid Build Coastguard Worker void *metadata, uint32_t metadata_size)
199*61046927SAndroid Build Coastguard Worker {
200*61046927SAndroid Build Coastguard Worker if (!dev->instance->knl->bo_set_metadata)
201*61046927SAndroid Build Coastguard Worker return;
202*61046927SAndroid Build Coastguard Worker dev->instance->knl->bo_set_metadata(dev, bo, metadata, metadata_size);
203*61046927SAndroid Build Coastguard Worker }
204*61046927SAndroid Build Coastguard Worker
205*61046927SAndroid Build Coastguard Worker int
tu_bo_get_metadata(struct tu_device * dev,struct tu_bo * bo,void * metadata,uint32_t metadata_size)206*61046927SAndroid Build Coastguard Worker tu_bo_get_metadata(struct tu_device *dev, struct tu_bo *bo,
207*61046927SAndroid Build Coastguard Worker void *metadata, uint32_t metadata_size)
208*61046927SAndroid Build Coastguard Worker {
209*61046927SAndroid Build Coastguard Worker if (!dev->instance->knl->bo_get_metadata)
210*61046927SAndroid Build Coastguard Worker return -ENOSYS;
211*61046927SAndroid Build Coastguard Worker return dev->instance->knl->bo_get_metadata(dev, bo, metadata, metadata_size);
212*61046927SAndroid Build Coastguard Worker }
213*61046927SAndroid Build Coastguard Worker
214*61046927SAndroid Build Coastguard Worker VkResult
tu_drm_device_init(struct tu_device * dev)215*61046927SAndroid Build Coastguard Worker tu_drm_device_init(struct tu_device *dev)
216*61046927SAndroid Build Coastguard Worker {
217*61046927SAndroid Build Coastguard Worker return dev->instance->knl->device_init(dev);
218*61046927SAndroid Build Coastguard Worker }
219*61046927SAndroid Build Coastguard Worker
220*61046927SAndroid Build Coastguard Worker void
tu_drm_device_finish(struct tu_device * dev)221*61046927SAndroid Build Coastguard Worker tu_drm_device_finish(struct tu_device *dev)
222*61046927SAndroid Build Coastguard Worker {
223*61046927SAndroid Build Coastguard Worker dev->instance->knl->device_finish(dev);
224*61046927SAndroid Build Coastguard Worker }
225*61046927SAndroid Build Coastguard Worker
226*61046927SAndroid Build Coastguard Worker int
tu_device_get_gpu_timestamp(struct tu_device * dev,uint64_t * ts)227*61046927SAndroid Build Coastguard Worker tu_device_get_gpu_timestamp(struct tu_device *dev,
228*61046927SAndroid Build Coastguard Worker uint64_t *ts)
229*61046927SAndroid Build Coastguard Worker {
230*61046927SAndroid Build Coastguard Worker return dev->instance->knl->device_get_gpu_timestamp(dev, ts);
231*61046927SAndroid Build Coastguard Worker }
232*61046927SAndroid Build Coastguard Worker
233*61046927SAndroid Build Coastguard Worker int
tu_device_get_suspend_count(struct tu_device * dev,uint64_t * suspend_count)234*61046927SAndroid Build Coastguard Worker tu_device_get_suspend_count(struct tu_device *dev,
235*61046927SAndroid Build Coastguard Worker uint64_t *suspend_count)
236*61046927SAndroid Build Coastguard Worker {
237*61046927SAndroid Build Coastguard Worker return dev->instance->knl->device_get_suspend_count(dev, suspend_count);
238*61046927SAndroid Build Coastguard Worker }
239*61046927SAndroid Build Coastguard Worker
240*61046927SAndroid Build Coastguard Worker VkResult
tu_device_wait_u_trace(struct tu_device * dev,struct tu_u_trace_syncobj * syncobj)241*61046927SAndroid Build Coastguard Worker tu_device_wait_u_trace(struct tu_device *dev, struct tu_u_trace_syncobj *syncobj)
242*61046927SAndroid Build Coastguard Worker {
243*61046927SAndroid Build Coastguard Worker return dev->instance->knl->device_wait_u_trace(dev, syncobj);
244*61046927SAndroid Build Coastguard Worker }
245*61046927SAndroid Build Coastguard Worker
246*61046927SAndroid Build Coastguard Worker VkResult
tu_device_check_status(struct vk_device * vk_device)247*61046927SAndroid Build Coastguard Worker tu_device_check_status(struct vk_device *vk_device)
248*61046927SAndroid Build Coastguard Worker {
249*61046927SAndroid Build Coastguard Worker struct tu_device *dev = container_of(vk_device, struct tu_device, vk);
250*61046927SAndroid Build Coastguard Worker return dev->instance->knl->device_check_status(dev);
251*61046927SAndroid Build Coastguard Worker }
252*61046927SAndroid Build Coastguard Worker
253*61046927SAndroid Build Coastguard Worker int
tu_drm_submitqueue_new(struct tu_device * dev,int priority,uint32_t * queue_id)254*61046927SAndroid Build Coastguard Worker tu_drm_submitqueue_new(struct tu_device *dev,
255*61046927SAndroid Build Coastguard Worker int priority,
256*61046927SAndroid Build Coastguard Worker uint32_t *queue_id)
257*61046927SAndroid Build Coastguard Worker {
258*61046927SAndroid Build Coastguard Worker return dev->instance->knl->submitqueue_new(dev, priority, queue_id);
259*61046927SAndroid Build Coastguard Worker }
260*61046927SAndroid Build Coastguard Worker
261*61046927SAndroid Build Coastguard Worker void
tu_drm_submitqueue_close(struct tu_device * dev,uint32_t queue_id)262*61046927SAndroid Build Coastguard Worker tu_drm_submitqueue_close(struct tu_device *dev, uint32_t queue_id)
263*61046927SAndroid Build Coastguard Worker {
264*61046927SAndroid Build Coastguard Worker dev->instance->knl->submitqueue_close(dev, queue_id);
265*61046927SAndroid Build Coastguard Worker }
266*61046927SAndroid Build Coastguard Worker
267*61046927SAndroid Build Coastguard Worker VkResult
tu_queue_submit(struct vk_queue * vk_queue,struct vk_queue_submit * submit)268*61046927SAndroid Build Coastguard Worker tu_queue_submit(struct vk_queue *vk_queue, struct vk_queue_submit *submit)
269*61046927SAndroid Build Coastguard Worker {
270*61046927SAndroid Build Coastguard Worker struct tu_queue *queue = container_of(vk_queue, struct tu_queue, vk);
271*61046927SAndroid Build Coastguard Worker return queue->device->instance->knl->queue_submit(queue, submit);
272*61046927SAndroid Build Coastguard Worker }
273*61046927SAndroid Build Coastguard Worker
274*61046927SAndroid Build Coastguard Worker /**
275*61046927SAndroid Build Coastguard Worker * Enumeration entrypoint specific to non-drm devices (ie. kgsl)
276*61046927SAndroid Build Coastguard Worker */
277*61046927SAndroid Build Coastguard Worker VkResult
tu_enumerate_devices(struct vk_instance * vk_instance)278*61046927SAndroid Build Coastguard Worker tu_enumerate_devices(struct vk_instance *vk_instance)
279*61046927SAndroid Build Coastguard Worker {
280*61046927SAndroid Build Coastguard Worker #ifdef TU_HAS_KGSL
281*61046927SAndroid Build Coastguard Worker struct tu_instance *instance =
282*61046927SAndroid Build Coastguard Worker container_of(vk_instance, struct tu_instance, vk);
283*61046927SAndroid Build Coastguard Worker
284*61046927SAndroid Build Coastguard Worker static const char path[] = "/dev/kgsl-3d0";
285*61046927SAndroid Build Coastguard Worker int fd;
286*61046927SAndroid Build Coastguard Worker
287*61046927SAndroid Build Coastguard Worker fd = open(path, O_RDWR | O_CLOEXEC);
288*61046927SAndroid Build Coastguard Worker if (fd < 0) {
289*61046927SAndroid Build Coastguard Worker if (errno == ENOENT)
290*61046927SAndroid Build Coastguard Worker return VK_ERROR_INCOMPATIBLE_DRIVER;
291*61046927SAndroid Build Coastguard Worker
292*61046927SAndroid Build Coastguard Worker return vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
293*61046927SAndroid Build Coastguard Worker "failed to open device %s", path);
294*61046927SAndroid Build Coastguard Worker }
295*61046927SAndroid Build Coastguard Worker
296*61046927SAndroid Build Coastguard Worker VkResult result = tu_knl_kgsl_load(instance, fd);
297*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
298*61046927SAndroid Build Coastguard Worker close(fd);
299*61046927SAndroid Build Coastguard Worker return result;
300*61046927SAndroid Build Coastguard Worker }
301*61046927SAndroid Build Coastguard Worker
302*61046927SAndroid Build Coastguard Worker if (TU_DEBUG(STARTUP))
303*61046927SAndroid Build Coastguard Worker mesa_logi("Found compatible device '%s'.", path);
304*61046927SAndroid Build Coastguard Worker
305*61046927SAndroid Build Coastguard Worker return result;
306*61046927SAndroid Build Coastguard Worker #else
307*61046927SAndroid Build Coastguard Worker return VK_ERROR_INCOMPATIBLE_DRIVER;
308*61046927SAndroid Build Coastguard Worker #endif
309*61046927SAndroid Build Coastguard Worker }
310*61046927SAndroid Build Coastguard Worker
311*61046927SAndroid Build Coastguard Worker /**
312*61046927SAndroid Build Coastguard Worker * Enumeration entrypoint for drm devices
313*61046927SAndroid Build Coastguard Worker */
314*61046927SAndroid Build Coastguard Worker VkResult
tu_physical_device_try_create(struct vk_instance * vk_instance,struct _drmDevice * drm_device,struct vk_physical_device ** out)315*61046927SAndroid Build Coastguard Worker tu_physical_device_try_create(struct vk_instance *vk_instance,
316*61046927SAndroid Build Coastguard Worker struct _drmDevice *drm_device,
317*61046927SAndroid Build Coastguard Worker struct vk_physical_device **out)
318*61046927SAndroid Build Coastguard Worker {
319*61046927SAndroid Build Coastguard Worker struct tu_instance *instance =
320*61046927SAndroid Build Coastguard Worker container_of(vk_instance, struct tu_instance, vk);
321*61046927SAndroid Build Coastguard Worker
322*61046927SAndroid Build Coastguard Worker /* Note that "msm" is a platform device, but "virtio_gpu" is a pci
323*61046927SAndroid Build Coastguard Worker * device. In general we shouldn't care about the bus type.
324*61046927SAndroid Build Coastguard Worker */
325*61046927SAndroid Build Coastguard Worker if (!(drm_device->available_nodes & (1 << DRM_NODE_RENDER)))
326*61046927SAndroid Build Coastguard Worker return VK_ERROR_INCOMPATIBLE_DRIVER;
327*61046927SAndroid Build Coastguard Worker
328*61046927SAndroid Build Coastguard Worker const char *primary_path = drm_device->nodes[DRM_NODE_PRIMARY];
329*61046927SAndroid Build Coastguard Worker const char *path = drm_device->nodes[DRM_NODE_RENDER];
330*61046927SAndroid Build Coastguard Worker drmVersionPtr version;
331*61046927SAndroid Build Coastguard Worker int fd;
332*61046927SAndroid Build Coastguard Worker int master_fd = -1;
333*61046927SAndroid Build Coastguard Worker
334*61046927SAndroid Build Coastguard Worker fd = open(path, O_RDWR | O_CLOEXEC);
335*61046927SAndroid Build Coastguard Worker if (fd < 0) {
336*61046927SAndroid Build Coastguard Worker return vk_startup_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
337*61046927SAndroid Build Coastguard Worker "failed to open device %s", path);
338*61046927SAndroid Build Coastguard Worker }
339*61046927SAndroid Build Coastguard Worker
340*61046927SAndroid Build Coastguard Worker version = drmGetVersion(fd);
341*61046927SAndroid Build Coastguard Worker if (!version) {
342*61046927SAndroid Build Coastguard Worker close(fd);
343*61046927SAndroid Build Coastguard Worker return vk_startup_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
344*61046927SAndroid Build Coastguard Worker "failed to query kernel driver version for device %s",
345*61046927SAndroid Build Coastguard Worker path);
346*61046927SAndroid Build Coastguard Worker }
347*61046927SAndroid Build Coastguard Worker
348*61046927SAndroid Build Coastguard Worker struct tu_physical_device *device = NULL;
349*61046927SAndroid Build Coastguard Worker
350*61046927SAndroid Build Coastguard Worker VkResult result = VK_ERROR_INCOMPATIBLE_DRIVER;
351*61046927SAndroid Build Coastguard Worker if (strcmp(version->name, "msm") == 0) {
352*61046927SAndroid Build Coastguard Worker #ifdef TU_HAS_MSM
353*61046927SAndroid Build Coastguard Worker result = tu_knl_drm_msm_load(instance, fd, version, &device);
354*61046927SAndroid Build Coastguard Worker #endif
355*61046927SAndroid Build Coastguard Worker } else if (strcmp(version->name, "virtio_gpu") == 0) {
356*61046927SAndroid Build Coastguard Worker #ifdef TU_HAS_VIRTIO
357*61046927SAndroid Build Coastguard Worker result = tu_knl_drm_virtio_load(instance, fd, version, &device);
358*61046927SAndroid Build Coastguard Worker #endif
359*61046927SAndroid Build Coastguard Worker } else if (TU_DEBUG(STARTUP)) {
360*61046927SAndroid Build Coastguard Worker result = vk_startup_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
361*61046927SAndroid Build Coastguard Worker "device %s (%s) is not compatible with turnip",
362*61046927SAndroid Build Coastguard Worker path, version->name);
363*61046927SAndroid Build Coastguard Worker }
364*61046927SAndroid Build Coastguard Worker
365*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
366*61046927SAndroid Build Coastguard Worker goto out;
367*61046927SAndroid Build Coastguard Worker
368*61046927SAndroid Build Coastguard Worker assert(device);
369*61046927SAndroid Build Coastguard Worker
370*61046927SAndroid Build Coastguard Worker if (instance->vk.enabled_extensions.KHR_display) {
371*61046927SAndroid Build Coastguard Worker master_fd = open(primary_path, O_RDWR | O_CLOEXEC);
372*61046927SAndroid Build Coastguard Worker }
373*61046927SAndroid Build Coastguard Worker
374*61046927SAndroid Build Coastguard Worker device->master_fd = master_fd;
375*61046927SAndroid Build Coastguard Worker device->kgsl_dma_fd = -1;
376*61046927SAndroid Build Coastguard Worker
377*61046927SAndroid Build Coastguard Worker assert(strlen(path) < ARRAY_SIZE(device->fd_path));
378*61046927SAndroid Build Coastguard Worker snprintf(device->fd_path, ARRAY_SIZE(device->fd_path), "%s", path);
379*61046927SAndroid Build Coastguard Worker
380*61046927SAndroid Build Coastguard Worker struct stat st;
381*61046927SAndroid Build Coastguard Worker
382*61046927SAndroid Build Coastguard Worker if (stat(primary_path, &st) == 0) {
383*61046927SAndroid Build Coastguard Worker device->has_master = true;
384*61046927SAndroid Build Coastguard Worker device->master_major = major(st.st_rdev);
385*61046927SAndroid Build Coastguard Worker device->master_minor = minor(st.st_rdev);
386*61046927SAndroid Build Coastguard Worker } else {
387*61046927SAndroid Build Coastguard Worker device->has_master = false;
388*61046927SAndroid Build Coastguard Worker device->master_major = 0;
389*61046927SAndroid Build Coastguard Worker device->master_minor = 0;
390*61046927SAndroid Build Coastguard Worker }
391*61046927SAndroid Build Coastguard Worker
392*61046927SAndroid Build Coastguard Worker if (stat(path, &st) == 0) {
393*61046927SAndroid Build Coastguard Worker device->has_local = true;
394*61046927SAndroid Build Coastguard Worker device->local_major = major(st.st_rdev);
395*61046927SAndroid Build Coastguard Worker device->local_minor = minor(st.st_rdev);
396*61046927SAndroid Build Coastguard Worker } else {
397*61046927SAndroid Build Coastguard Worker result = vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
398*61046927SAndroid Build Coastguard Worker "failed to stat DRM render node %s", path);
399*61046927SAndroid Build Coastguard Worker goto out;
400*61046927SAndroid Build Coastguard Worker }
401*61046927SAndroid Build Coastguard Worker
402*61046927SAndroid Build Coastguard Worker result = tu_physical_device_init(device, instance);
403*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
404*61046927SAndroid Build Coastguard Worker goto out;
405*61046927SAndroid Build Coastguard Worker
406*61046927SAndroid Build Coastguard Worker if (TU_DEBUG(STARTUP))
407*61046927SAndroid Build Coastguard Worker mesa_logi("Found compatible device '%s' (%s).", path, version->name);
408*61046927SAndroid Build Coastguard Worker
409*61046927SAndroid Build Coastguard Worker *out = &device->vk;
410*61046927SAndroid Build Coastguard Worker
411*61046927SAndroid Build Coastguard Worker out:
412*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
413*61046927SAndroid Build Coastguard Worker if (master_fd != -1)
414*61046927SAndroid Build Coastguard Worker close(master_fd);
415*61046927SAndroid Build Coastguard Worker close(fd);
416*61046927SAndroid Build Coastguard Worker vk_free(&instance->vk.alloc, device);
417*61046927SAndroid Build Coastguard Worker }
418*61046927SAndroid Build Coastguard Worker
419*61046927SAndroid Build Coastguard Worker drmFreeVersion(version);
420*61046927SAndroid Build Coastguard Worker
421*61046927SAndroid Build Coastguard Worker return result;
422*61046927SAndroid Build Coastguard Worker }
423