17ec681f3Smrg/* 27ec681f3Smrg * Copyright (c) 2021 Etnaviv Project 37ec681f3Smrg * 47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 57ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 67ec681f3Smrg * to deal in the Software without restriction, including without limitation 77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 97ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 107ec681f3Smrg * 117ec681f3Smrg * The above copyright notice and this permission notice (including the next 127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 137ec681f3Smrg * Software. 147ec681f3Smrg * 157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 187ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 197ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 207ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 217ec681f3Smrg * DEALINGS IN THE SOFTWARE. 227ec681f3Smrg */ 237ec681f3Smrg 247ec681f3Smrg#include <limits.h> 257ec681f3Smrg#include <stdio.h> 267ec681f3Smrg#include <stdlib.h> 277ec681f3Smrg#include <sys/ioctl.h> 287ec681f3Smrg#include "drm-uapi/vc4_drm.h" 297ec681f3Smrg#include "drm-shim/drm_shim.h" 307ec681f3Smrg 317ec681f3Smrgbool drm_shim_driver_prefers_first_render_node = true; 327ec681f3Smrg 337ec681f3Smrgstatic int 347ec681f3Smrgvc4_ioctl_noop(int fd, unsigned long request, void *arg) 357ec681f3Smrg{ 367ec681f3Smrg return 0; 377ec681f3Smrg} 387ec681f3Smrg 397ec681f3Smrgstatic int 407ec681f3Smrgvc4_ioctl_create_bo(int fd, unsigned long request, void *arg) 417ec681f3Smrg{ 427ec681f3Smrg struct shim_fd *shim_fd = drm_shim_fd_lookup(fd); 437ec681f3Smrg struct drm_vc4_create_bo *create = arg; 447ec681f3Smrg struct shim_bo *bo = calloc(1, sizeof(*bo)); 457ec681f3Smrg 467ec681f3Smrg drm_shim_bo_init(bo, create->size); 477ec681f3Smrg create->handle = drm_shim_bo_get_handle(shim_fd, bo); 487ec681f3Smrg drm_shim_bo_put(bo); 497ec681f3Smrg 507ec681f3Smrg return 0; 517ec681f3Smrg} 527ec681f3Smrg 537ec681f3Smrgstatic int 547ec681f3Smrgvc4_ioctl_mmap_bo(int fd, unsigned long request, void *arg) 557ec681f3Smrg{ 567ec681f3Smrg struct shim_fd *shim_fd = drm_shim_fd_lookup(fd); 577ec681f3Smrg struct drm_vc4_mmap_bo *map = arg; 587ec681f3Smrg struct shim_bo *bo = drm_shim_bo_lookup(shim_fd, map->handle); 597ec681f3Smrg 607ec681f3Smrg map->offset = drm_shim_bo_get_mmap_offset(shim_fd, bo); 617ec681f3Smrg 627ec681f3Smrg drm_shim_bo_put(bo); 637ec681f3Smrg 647ec681f3Smrg return 0; 657ec681f3Smrg} 667ec681f3Smrg 677ec681f3Smrgstatic int 687ec681f3Smrgvc4_ioctl_get_param(int fd, unsigned long request, void *arg) 697ec681f3Smrg{ 707ec681f3Smrg struct drm_vc4_get_param *gp = arg; 717ec681f3Smrg static const uint32_t param_map[] = { 727ec681f3Smrg [DRM_VC4_PARAM_V3D_IDENT0] = 0x2000000, 737ec681f3Smrg [DRM_VC4_PARAM_V3D_IDENT1] = 0x0000001, 747ec681f3Smrg }; 757ec681f3Smrg 767ec681f3Smrg switch (gp->param) { 777ec681f3Smrg case DRM_VC4_PARAM_SUPPORTS_BRANCHES: 787ec681f3Smrg case DRM_VC4_PARAM_SUPPORTS_ETC1: 797ec681f3Smrg case DRM_VC4_PARAM_SUPPORTS_THREADED_FS: 807ec681f3Smrg case DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER: 817ec681f3Smrg gp->value = 1; 827ec681f3Smrg return 0; 837ec681f3Smrg 847ec681f3Smrg case DRM_VC4_PARAM_SUPPORTS_MADVISE: 857ec681f3Smrg case DRM_VC4_PARAM_SUPPORTS_PERFMON: 867ec681f3Smrg gp->value = 0; 877ec681f3Smrg return 0; 887ec681f3Smrg 897ec681f3Smrg default: 907ec681f3Smrg break; 917ec681f3Smrg } 927ec681f3Smrg 937ec681f3Smrg if (gp->param < ARRAY_SIZE(param_map) && param_map[gp->param]) { 947ec681f3Smrg gp->value = param_map[gp->param]; 957ec681f3Smrg return 0; 967ec681f3Smrg } 977ec681f3Smrg 987ec681f3Smrg fprintf(stderr, "Unknown DRM_IOCTL_VC4_GET_PARAM %d\n", gp->param); 997ec681f3Smrg return -1; 1007ec681f3Smrg} 1017ec681f3Smrg 1027ec681f3Smrgstatic ioctl_fn_t driver_ioctls[] = { 1037ec681f3Smrg [DRM_VC4_CREATE_BO] = vc4_ioctl_create_bo, 1047ec681f3Smrg [DRM_VC4_MMAP_BO] = vc4_ioctl_mmap_bo, 1057ec681f3Smrg [DRM_VC4_GET_PARAM] = vc4_ioctl_get_param, 1067ec681f3Smrg [DRM_VC4_GET_TILING] = vc4_ioctl_noop, 1077ec681f3Smrg [DRM_VC4_LABEL_BO] = vc4_ioctl_noop, 1087ec681f3Smrg}; 1097ec681f3Smrg 1107ec681f3Smrgvoid 1117ec681f3Smrgdrm_shim_driver_init(void) 1127ec681f3Smrg{ 1137ec681f3Smrg shim_device.bus_type = DRM_BUS_PLATFORM; 1147ec681f3Smrg shim_device.driver_name = "vc4"; 1157ec681f3Smrg shim_device.driver_ioctls = driver_ioctls; 1167ec681f3Smrg shim_device.driver_ioctl_count = ARRAY_SIZE(driver_ioctls); 1177ec681f3Smrg 1187ec681f3Smrg drm_shim_override_file("OF_FULLNAME=/rdb/vc4\n" 1197ec681f3Smrg "OF_COMPATIBLE_N=1\n" 1207ec681f3Smrg "OF_COMPATIBLE_0=brcm,7278-vc4\n", 1217ec681f3Smrg "/sys/dev/char/%d:%d/device/uevent", 1227ec681f3Smrg DRM_MAJOR, render_node_minor); 1237ec681f3Smrg} 124