• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <limits.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include "common/amd_family.h"
5 #include "drm-shim/drm_shim.h"
6 #include "util/log.h"
7 #include <util/u_math.h>
8 #include <radeon_drm.h>
9 
10 bool drm_shim_driver_prefers_first_render_node = true;
11 
12 static enum radeon_family radeon_family = CHIP_RV515;
13 static uint16_t device_id = 0x7140;
14 
15 static int
radeon_ioctl_noop(int fd,unsigned long request,void * arg)16 radeon_ioctl_noop(int fd, unsigned long request, void *arg)
17 {
18    return 0;
19 }
20 
21 static int
radeon_ioctl_info(int fd,unsigned long request,void * arg)22 radeon_ioctl_info(int fd, unsigned long request, void *arg)
23 {
24    struct drm_radeon_info *info = arg;
25    uint32_t *value = (uint32_t *)(intptr_t)info->value;
26 
27    switch (info->request) {
28    case RADEON_INFO_DEVICE_ID:
29       *value = device_id;
30       return 0;
31 
32    case RADEON_INFO_RING_WORKING:
33    case RADEON_INFO_ACCEL_WORKING2:
34    case RADEON_INFO_VA_UNMAP_WORKING:
35       *value = true;
36       return 0;
37 
38    case RADEON_INFO_GPU_RESET_COUNTER:
39       *value = 0;
40       return 0;
41 
42    case RADEON_INFO_IB_VM_MAX_SIZE:
43       if (radeon_family < CHIP_CAYMAN)
44          return -EINVAL;
45       *value = 64 << 10;
46       return 0;
47 
48    case RADEON_INFO_VCE_FW_VERSION:
49    case RADEON_INFO_TILING_CONFIG:
50    case RADEON_INFO_BACKEND_MAP:
51       *value = 0; /* dummy */
52       return 0;
53 
54    case RADEON_INFO_VA_START:
55       return 4096;
56 
57    case RADEON_INFO_MAX_SCLK:
58    case RADEON_INFO_CLOCK_CRYSTAL_FREQ:
59    case RADEON_INFO_NUM_GB_PIPES:
60    case RADEON_INFO_NUM_Z_PIPES:
61    case RADEON_INFO_MAX_PIPES:
62    case RADEON_INFO_MAX_SE:
63    case RADEON_INFO_MAX_SH_PER_SE:
64    case RADEON_INFO_ACTIVE_CU_COUNT:
65    case RADEON_INFO_NUM_BACKENDS:
66    case RADEON_INFO_NUM_TILE_PIPES:
67       *value = 1; /* dummy */
68       return 0;
69 
70    default:
71       fprintf(stderr, "Unknown DRM_IOCTL_RADEON_INFO request 0x%02X\n", info->request);
72       return -1;
73    }
74 }
75 
76 static int
radeon_ioctl_gem_info(int fd,unsigned long request,void * arg)77 radeon_ioctl_gem_info(int fd, unsigned long request, void *arg)
78 {
79    struct drm_radeon_gem_info *info = arg;
80 
81    /* Dummy values. */
82    info->vram_size = 256 * 1024 * 1024;
83    info->vram_visible = info->vram_size;
84    info->gart_size = 512 * 1024 * 1024;
85 
86    return 0;
87 }
88 
89 static int
radeon_ioctl_gem_create(int fd,unsigned long request,void * arg)90 radeon_ioctl_gem_create(int fd, unsigned long request, void *arg)
91 {
92    struct drm_radeon_gem_create *create = arg;
93 
94    struct shim_fd *shim_fd = drm_shim_fd_lookup(fd);
95    struct shim_bo *bo = calloc(1, sizeof(*bo));
96    size_t size = ALIGN(create->size, 4096);
97 
98    drm_shim_bo_init(bo, size);
99 
100    create->handle = drm_shim_bo_get_handle(shim_fd, bo);
101 
102    drm_shim_bo_put(bo);
103 
104    return 0;
105 }
106 
107 static int
radeon_ioctl_gem_mmap(int fd,unsigned long request,void * arg)108 radeon_ioctl_gem_mmap(int fd, unsigned long request, void *arg)
109 {
110    struct drm_radeon_gem_mmap *mmap_bo = arg;
111 
112    struct shim_fd *shim_fd = drm_shim_fd_lookup(fd);
113    struct shim_bo *bo = drm_shim_bo_lookup(shim_fd, mmap_bo->handle);
114 
115    mmap_bo->addr_ptr = drm_shim_bo_get_mmap_offset(shim_fd, bo);
116 
117    return 0;
118 }
119 
120 static int
radeon_ioctl_gem_userptr(int fd,unsigned long request,void * arg)121 radeon_ioctl_gem_userptr(int fd, unsigned long request, void *arg)
122 {
123    /* probed at winsys init, just return no support. */
124    return -EINVAL;
125 }
126 
127 static ioctl_fn_t driver_ioctls[] = {
128    [DRM_RADEON_CS] = radeon_ioctl_noop,
129    [DRM_RADEON_INFO] = radeon_ioctl_info,
130    [DRM_RADEON_GEM_SET_DOMAIN] = radeon_ioctl_noop,
131    [DRM_RADEON_GEM_SET_TILING] = radeon_ioctl_noop,
132    [DRM_RADEON_GEM_WAIT_IDLE] = radeon_ioctl_noop,
133    [DRM_RADEON_GEM_INFO] = radeon_ioctl_gem_info,
134    [DRM_RADEON_GEM_CREATE] = radeon_ioctl_gem_create,
135    [DRM_RADEON_GEM_MMAP] = radeon_ioctl_gem_mmap,
136    [DRM_RADEON_GEM_USERPTR] = radeon_ioctl_gem_userptr,
137 };
138 
139 struct radeon_pci_id {
140    uint16_t device_id;
141    const char *name;
142    enum radeon_family family;
143    const char *family_name;
144 };
145 
146 #define CHIPSET(d, n, f) {.device_id = (d), .name = #n, .family = CHIP_##f, .family_name = #f},
147 static const struct radeon_pci_id radeon_pci_ids[] = {
148 #include "pci_ids/r300_pci_ids.h"
149 #include "pci_ids/r600_pci_ids.h"
150 };
151 #undef CHIPSET
152 
153 static void
radeon_get_device_id()154 radeon_get_device_id()
155 {
156    const char *gpu_id = getenv("RADEON_GPU_ID");
157    if (!gpu_id)
158       return;
159 
160    if (strncmp(gpu_id, "0x", 2) == 0) {
161       device_id = strtoll(gpu_id + 2, NULL, 16);
162       return;
163    }
164 
165    for (int i = 0; i < ARRAY_SIZE(radeon_pci_ids); i++) {
166       if (strcasecmp(gpu_id, radeon_pci_ids[i].name) == 0 ||
167           strcasecmp(gpu_id, radeon_pci_ids[i].family_name) == 0) {
168          device_id = radeon_pci_ids[i].device_id;
169          return;
170       }
171    }
172 
173    mesa_loge("Failed to find radeon GPU named \"%s\"\n", gpu_id);
174    abort();
175 }
176 
177 void
drm_shim_driver_init(void)178 drm_shim_driver_init(void)
179 {
180    radeon_get_device_id();
181 
182    shim_device.bus_type = DRM_BUS_PCI;
183    shim_device.driver_name = "radeon";
184    shim_device.driver_ioctls = driver_ioctls;
185    shim_device.driver_ioctl_count = ARRAY_SIZE(driver_ioctls);
186 
187    shim_device.version_major = 2;
188    shim_device.version_minor = 50;
189    shim_device.version_patchlevel = 0;
190 }
191