1 /*
2 * Copyright 2022 Alyssa Rosenzweig
3 * Copyright 2018 Broadcom
4 * SPDX-License-Identifier: MIT
5 */
6
7 #include <string.h>
8
9 #include "../lib/unstable_asahi_drm.h"
10 #include "drm-shim/drm_shim.h"
11
12 bool drm_shim_driver_prefers_first_render_node = true;
13
14 static const struct drm_asahi_params_global params = {
15 .unstable_uabi_version = DRM_ASAHI_UNSTABLE_UABI_VERSION,
16 .gpu_generation = 13,
17 .gpu_variant = 'G',
18 .gpu_revision = 0,
19 .vm_user_start = 0x1000000,
20 .vm_user_end = 0x5000000,
21 .vm_usc_start = 0,
22 .vm_usc_end = 0,
23 .vm_page_size = 4096,
24 };
25
26 struct asahi_bo {
27 struct shim_bo base;
28 uint32_t offset;
29 };
30
31 static struct asahi_bo *
asahi_bo(struct shim_bo * bo)32 asahi_bo(struct shim_bo *bo)
33 {
34 return (struct asahi_bo *)bo;
35 }
36
37 struct asahi_device {
38 uint64_t next_offset;
39 };
40
41 static struct asahi_device asahi = {
42 .next_offset = 0x1000,
43 };
44
45 static int
asahi_ioctl_noop(int fd,unsigned long request,void * arg)46 asahi_ioctl_noop(int fd, unsigned long request, void *arg)
47 {
48 return 0;
49 }
50
51 static int
asahi_ioctl_submit(int fd,unsigned long request,void * arg)52 asahi_ioctl_submit(int fd, unsigned long request, void *arg)
53 {
54 return 0;
55 }
56
57 static int
asahi_ioctl_gem_create(int fd,unsigned long request,void * arg)58 asahi_ioctl_gem_create(int fd, unsigned long request, void *arg)
59 {
60 struct shim_fd *shim_fd = drm_shim_fd_lookup(fd);
61 struct drm_asahi_gem_create *create = arg;
62 struct asahi_bo *bo = calloc(1, sizeof(*bo));
63
64 drm_shim_bo_init(&bo->base, create->size);
65
66 assert(UINT64_MAX - asahi.next_offset > create->size);
67 bo->offset = asahi.next_offset;
68 asahi.next_offset += create->size;
69
70 create->handle = drm_shim_bo_get_handle(shim_fd, &bo->base);
71
72 drm_shim_bo_put(&bo->base);
73
74 return 0;
75 }
76
77 static int
asahi_ioctl_gem_mmap_offset(int fd,unsigned long request,void * arg)78 asahi_ioctl_gem_mmap_offset(int fd, unsigned long request, void *arg)
79 {
80 struct shim_fd *shim_fd = drm_shim_fd_lookup(fd);
81 struct drm_asahi_gem_mmap_offset *map = arg;
82 struct shim_bo *bo = drm_shim_bo_lookup(shim_fd, map->handle);
83
84 map->offset = drm_shim_bo_get_mmap_offset(shim_fd, bo);
85
86 drm_shim_bo_put(bo);
87
88 return 0;
89 }
90
91 static int
asahi_ioctl_get_param(int fd,unsigned long request,void * arg)92 asahi_ioctl_get_param(int fd, unsigned long request, void *arg)
93 {
94 struct drm_asahi_get_params *gp = arg;
95
96 switch (gp->param_group) {
97 case 0:
98 assert(gp->size == sizeof(struct drm_asahi_params_global));
99 memcpy((void *)gp->pointer, ¶ms, gp->size);
100 return 0;
101
102 default:
103 fprintf(stderr, "Unknown DRM_IOCTL_ASAHI_GET_PARAMS %d\n",
104 gp->param_group);
105 return -1;
106 }
107 }
108
109 static ioctl_fn_t driver_ioctls[] = {
110 [DRM_ASAHI_GET_PARAMS] = asahi_ioctl_get_param,
111 [DRM_ASAHI_VM_CREATE] = asahi_ioctl_noop,
112 [DRM_ASAHI_VM_DESTROY] = asahi_ioctl_noop,
113 [DRM_ASAHI_GEM_CREATE] = asahi_ioctl_gem_create,
114 [DRM_ASAHI_GEM_MMAP_OFFSET] = asahi_ioctl_gem_mmap_offset,
115 [DRM_ASAHI_GEM_BIND] = asahi_ioctl_noop,
116 [DRM_ASAHI_QUEUE_CREATE] = asahi_ioctl_noop,
117 [DRM_ASAHI_QUEUE_DESTROY] = asahi_ioctl_noop,
118 [DRM_ASAHI_SUBMIT] = asahi_ioctl_submit,
119 };
120
121 void
drm_shim_driver_init(void)122 drm_shim_driver_init(void)
123 {
124 shim_device.bus_type = DRM_BUS_PLATFORM;
125 shim_device.driver_name = "asahi";
126 shim_device.driver_ioctls = driver_ioctls;
127 shim_device.driver_ioctl_count = ARRAY_SIZE(driver_ioctls);
128
129 drm_shim_override_file("DRIVER=asahi\n"
130 "OF_FULLNAME=/soc/agx\n"
131 "OF_COMPATIBLE_0=apple,gpu-g13g\n"
132 "OF_COMPATIBLE_N=1\n",
133 "/sys/dev/char/%d:%d/device/uevent", DRM_MAJOR,
134 render_node_minor);
135 }
136