1/* 2 * Copyright (C) 2021 Icecream95 3 * Copyright (C) 2019 Google LLC 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 25#include <limits.h> 26#include <stdio.h> 27#include <stdlib.h> 28#include "drm-shim/drm_shim.h" 29#include "drm-uapi/panfrost_drm.h" 30 31#include "util/u_math.h" 32 33bool drm_shim_driver_prefers_first_render_node = true; 34 35static int 36pan_ioctl_noop(int fd, unsigned long request, void *arg) 37{ 38 return 0; 39} 40 41static int 42pan_ioctl_get_param(int fd, unsigned long request, void *arg) 43{ 44 struct drm_panfrost_get_param *gp = arg; 45 46 switch (gp->param) { 47 case DRM_PANFROST_PARAM_GPU_PROD_ID: 48 /* Other GPUs can be set using PAN_GPU_ID */ 49 gp->value = 0x860; 50 return 0; 51 case DRM_PANFROST_PARAM_GPU_REVISION: 52 gp->value = 0; 53 return 0; 54 case DRM_PANFROST_PARAM_SHADER_PRESENT: 55 /* Assume an MP4 GPU */ 56 gp->value = 0xF; 57 return 0; 58 case DRM_PANFROST_PARAM_TEXTURE_FEATURES0: 59 gp->value = 0; 60 return 0; 61 case DRM_PANFROST_PARAM_THREAD_TLS_ALLOC: 62 gp->value = 0; 63 return 0; 64 case DRM_PANFROST_PARAM_TILER_FEATURES: 65 gp->value = 0x809; 66 return 0; 67 default: 68 fprintf(stderr, "Unknown DRM_IOCTL_PANFROST_GET_PARAM %d\n", gp->param); 69 return -1; 70 } 71} 72 73static int 74pan_ioctl_create_bo(int fd, unsigned long request, void *arg) 75{ 76 struct drm_panfrost_create_bo *create = arg; 77 78 struct shim_fd *shim_fd = drm_shim_fd_lookup(fd); 79 struct shim_bo *bo = calloc(1, sizeof(*bo)); 80 size_t size = ALIGN(create->size, 4096); 81 82 drm_shim_bo_init(bo, size); 83 84 create->handle = drm_shim_bo_get_handle(shim_fd, bo); 85 create->offset = bo->mem_addr; 86 87 drm_shim_bo_put(bo); 88 89 return 0; 90} 91 92static int 93pan_ioctl_mmap_bo(int fd, unsigned long request, void *arg) 94{ 95 struct drm_panfrost_mmap_bo *mmap_bo = arg; 96 97 struct shim_fd *shim_fd = drm_shim_fd_lookup(fd); 98 struct shim_bo *bo = drm_shim_bo_lookup(shim_fd, mmap_bo->handle); 99 100 mmap_bo->offset = drm_shim_bo_get_mmap_offset(shim_fd, bo); 101 102 return 0; 103} 104 105static int 106pan_ioctl_madvise(int fd, unsigned long request, void *arg) 107{ 108 struct drm_panfrost_madvise *madvise = arg; 109 110 madvise->retained = 1; 111 112 return 0; 113} 114 115static ioctl_fn_t driver_ioctls[] = { 116 [DRM_PANFROST_SUBMIT] = pan_ioctl_noop, 117 [DRM_PANFROST_WAIT_BO] = pan_ioctl_noop, 118 [DRM_PANFROST_CREATE_BO] = pan_ioctl_create_bo, 119 [DRM_PANFROST_MMAP_BO] = pan_ioctl_mmap_bo, 120 [DRM_PANFROST_GET_PARAM] = pan_ioctl_get_param, 121 [DRM_PANFROST_GET_BO_OFFSET] = pan_ioctl_noop, 122 [DRM_PANFROST_PERFCNT_ENABLE] = pan_ioctl_noop, 123 [DRM_PANFROST_PERFCNT_DUMP] = pan_ioctl_noop, 124 [DRM_PANFROST_MADVISE] = pan_ioctl_madvise, 125}; 126 127void 128drm_shim_driver_init(void) 129{ 130 shim_device.bus_type = DRM_BUS_PLATFORM; 131 shim_device.driver_name = "panfrost"; 132 shim_device.driver_ioctls = driver_ioctls; 133 shim_device.driver_ioctl_count = ARRAY_SIZE(driver_ioctls); 134 135 /* panfrost uses the DRM version to expose features, instead of getparam. */ 136 shim_device.version_major = 1; 137 shim_device.version_minor = 1; 138 shim_device.version_patchlevel = 0; 139 140 drm_shim_override_file("DRIVER=panfrost\n" 141 "OF_FULLNAME=/soc/mali\n" 142 "OF_COMPATIBLE_0=arm,mali-t860\n" 143 "OF_COMPATIBLE_N=1\n", 144 "/sys/dev/char/%d:%d/device/uevent", DRM_MAJOR, 145 render_node_minor); 146} 147