1/* 2 * Copyright (c) 2021 Etnaviv Project 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24#include <limits.h> 25#include <stdio.h> 26#include <stdlib.h> 27#include <sys/ioctl.h> 28#include "drm-uapi/vc4_drm.h" 29#include "drm-shim/drm_shim.h" 30 31bool drm_shim_driver_prefers_first_render_node = true; 32 33static int 34vc4_ioctl_noop(int fd, unsigned long request, void *arg) 35{ 36 return 0; 37} 38 39static int 40vc4_ioctl_create_bo(int fd, unsigned long request, void *arg) 41{ 42 struct shim_fd *shim_fd = drm_shim_fd_lookup(fd); 43 struct drm_vc4_create_bo *create = arg; 44 struct shim_bo *bo = calloc(1, sizeof(*bo)); 45 46 drm_shim_bo_init(bo, create->size); 47 create->handle = drm_shim_bo_get_handle(shim_fd, bo); 48 drm_shim_bo_put(bo); 49 50 return 0; 51} 52 53static int 54vc4_ioctl_mmap_bo(int fd, unsigned long request, void *arg) 55{ 56 struct shim_fd *shim_fd = drm_shim_fd_lookup(fd); 57 struct drm_vc4_mmap_bo *map = arg; 58 struct shim_bo *bo = drm_shim_bo_lookup(shim_fd, map->handle); 59 60 map->offset = drm_shim_bo_get_mmap_offset(shim_fd, bo); 61 62 drm_shim_bo_put(bo); 63 64 return 0; 65} 66 67static int 68vc4_ioctl_get_param(int fd, unsigned long request, void *arg) 69{ 70 struct drm_vc4_get_param *gp = arg; 71 static const uint32_t param_map[] = { 72 [DRM_VC4_PARAM_V3D_IDENT0] = 0x2000000, 73 [DRM_VC4_PARAM_V3D_IDENT1] = 0x0000001, 74 }; 75 76 switch (gp->param) { 77 case DRM_VC4_PARAM_SUPPORTS_BRANCHES: 78 case DRM_VC4_PARAM_SUPPORTS_ETC1: 79 case DRM_VC4_PARAM_SUPPORTS_THREADED_FS: 80 case DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER: 81 gp->value = 1; 82 return 0; 83 84 case DRM_VC4_PARAM_SUPPORTS_MADVISE: 85 case DRM_VC4_PARAM_SUPPORTS_PERFMON: 86 gp->value = 0; 87 return 0; 88 89 default: 90 break; 91 } 92 93 if (gp->param < ARRAY_SIZE(param_map) && param_map[gp->param]) { 94 gp->value = param_map[gp->param]; 95 return 0; 96 } 97 98 fprintf(stderr, "Unknown DRM_IOCTL_VC4_GET_PARAM %d\n", gp->param); 99 return -1; 100} 101 102static ioctl_fn_t driver_ioctls[] = { 103 [DRM_VC4_CREATE_BO] = vc4_ioctl_create_bo, 104 [DRM_VC4_MMAP_BO] = vc4_ioctl_mmap_bo, 105 [DRM_VC4_GET_PARAM] = vc4_ioctl_get_param, 106 [DRM_VC4_GET_TILING] = vc4_ioctl_noop, 107 [DRM_VC4_LABEL_BO] = vc4_ioctl_noop, 108}; 109 110void 111drm_shim_driver_init(void) 112{ 113 shim_device.bus_type = DRM_BUS_PLATFORM; 114 shim_device.driver_name = "vc4"; 115 shim_device.driver_ioctls = driver_ioctls; 116 shim_device.driver_ioctl_count = ARRAY_SIZE(driver_ioctls); 117 118 drm_shim_override_file("OF_FULLNAME=/rdb/vc4\n" 119 "OF_COMPATIBLE_N=1\n" 120 "OF_COMPATIBLE_0=brcm,7278-vc4\n", 121 "/sys/dev/char/%d:%d/device/uevent", 122 DRM_MAJOR, render_node_minor); 123} 124