1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (c) 2019 Etnaviv Project 3bf215546Sopenharmony_ci * Copyright (c) 2019 Zodiac Inflight Innovations 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sub license, 9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 13bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 14bf215546Sopenharmony_ci * of the Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci * Authors: 25bf215546Sopenharmony_ci * Christian Gmeiner <christian.gmeiner@gmail.com> 26bf215546Sopenharmony_ci */ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include <stdio.h> 29bf215546Sopenharmony_ci#include <sys/ioctl.h> 30bf215546Sopenharmony_ci#include "drm-uapi/etnaviv_drm.h" 31bf215546Sopenharmony_ci#include "drm-shim/drm_shim.h" 32bf215546Sopenharmony_ci#include "util/u_debug.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_cibool drm_shim_driver_prefers_first_render_node = true; 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_cistruct etna_shim_gpu 37bf215546Sopenharmony_ci{ 38bf215546Sopenharmony_ci const char *name; 39bf215546Sopenharmony_ci const uint64_t *reg_map; 40bf215546Sopenharmony_ci}; 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_cistatic const struct etna_shim_gpu gpus[] = { 43bf215546Sopenharmony_ci { 44bf215546Sopenharmony_ci .name = "GC400", 45bf215546Sopenharmony_ci .reg_map = (const uint64_t[]){ 46bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_MODEL] = 0x400, 47bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_REVISION] = 0x4652, 48bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_0] = 0xa0e9e004, 49bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_1] = 0xe1299fff, 50bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_2] = 0xbe13b219, 51bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_3] = 0xce110010, 52bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_4] = 0x8000001, 53bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_5] = 0x20102, 54bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_6] = 0x120000, 55bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_7] = 0x0, 56bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_STREAM_COUNT] = 0x4, 57bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_REGISTER_MAX] = 0x40, 58bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_THREAD_COUNT] = 0x80, 59bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_VERTEX_CACHE_SIZE] = 0x8, 60bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_SHADER_CORE_COUNT] = 0x1, 61bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_PIXEL_PIPES] = 0x1, 62bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_VERTEX_OUTPUT_BUFFER_SIZE] = 0x80, 63bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_BUFFER_SIZE] = 0x0, 64bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_INSTRUCTION_COUNT] = 0x100, 65bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_NUM_CONSTANTS] = 0x140, 66bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_NUM_VARYINGS] = 0x8, 67bf215546Sopenharmony_ci [ETNAVIV_PARAM_SOFTPIN_START_ADDR] = ~0ULL, 68bf215546Sopenharmony_ci } 69bf215546Sopenharmony_ci }, 70bf215546Sopenharmony_ci { 71bf215546Sopenharmony_ci .name = "GC2000", 72bf215546Sopenharmony_ci .reg_map = (const uint64_t[]){ 73bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_MODEL] = 0x2000, 74bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_REVISION] = 0x5108, 75bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_0] = 0xe0296cad, 76bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_1] = 0xc9799eff, 77bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_2] = 0x2efbf2d9, 78bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_3] = 0x0, 79bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_4] = 0x0, 80bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_5] = 0x0, 81bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_6] = 0x0, 82bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_7] = 0x0, 83bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_STREAM_COUNT] = 0x8, 84bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_REGISTER_MAX] = 0x40, 85bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_THREAD_COUNT] = 0x400, 86bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_VERTEX_CACHE_SIZE] = 0x10, 87bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_SHADER_CORE_COUNT] = 0x4, 88bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_PIXEL_PIPES] = 0x2, 89bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_VERTEX_OUTPUT_BUFFER_SIZE] = 0x200, 90bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_BUFFER_SIZE] = 0x0, 91bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_INSTRUCTION_COUNT] = 0x200, 92bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_NUM_CONSTANTS] = 0xa8, 93bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_NUM_VARYINGS] = 0xb, 94bf215546Sopenharmony_ci [ETNAVIV_PARAM_SOFTPIN_START_ADDR] = ~0ULL, 95bf215546Sopenharmony_ci } 96bf215546Sopenharmony_ci }, 97bf215546Sopenharmony_ci { 98bf215546Sopenharmony_ci .name = "GC3000", 99bf215546Sopenharmony_ci .reg_map = (const uint64_t[]){ 100bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_MODEL] = 0x3000, 101bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_REVISION] = 0x5450, 102bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_0] = 0xe0287cad, 103bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_1] = 0xc9799efb, 104bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_2] = 0xfefbfadb, 105bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_3] = 0xeb9d4bbf, 106bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_4] = 0xedffdced, 107bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_5] = 0x930d2f47, 108bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_6] = 0x10000133, 109bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_7] = 0x0, 110bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_STREAM_COUNT] = 0x10, 111bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_REGISTER_MAX] = 0x40, 112bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_THREAD_COUNT] = 0x400, 113bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_VERTEX_CACHE_SIZE] = 0x10, 114bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_SHADER_CORE_COUNT] = 0x4, 115bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_PIXEL_PIPES] = 0x2, 116bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_VERTEX_OUTPUT_BUFFER_SIZE] = 0x400, 117bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_BUFFER_SIZE] = 0x0, 118bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_INSTRUCTION_COUNT] = 0x100, 119bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_NUM_CONSTANTS] = 0x140, 120bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_NUM_VARYINGS] = 0x10, 121bf215546Sopenharmony_ci [ETNAVIV_PARAM_SOFTPIN_START_ADDR] = ~0ULL, 122bf215546Sopenharmony_ci } 123bf215546Sopenharmony_ci }, 124bf215546Sopenharmony_ci { 125bf215546Sopenharmony_ci .name = "GC7000L", 126bf215546Sopenharmony_ci .reg_map = (const uint64_t[]){ 127bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_MODEL] = 0x7000, 128bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_REVISION] = 0x6214, 129bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_0] = 0xe0287cad, 130bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_1] = 0xc1799eff, 131bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_2] = 0xfefbfad9, 132bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_3] = 0xeb9d4fbf, 133bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_4] = 0xedfffced, 134bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_5] = 0xdb0dafc7, 135bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_6] = 0xbb5ac333, 136bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_FEATURES_7] = 0xfc8ee200, 137bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_STREAM_COUNT] = 0x10, 138bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_REGISTER_MAX] = 0x40, 139bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_THREAD_COUNT] = 0x400, 140bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_VERTEX_CACHE_SIZE] = 0x10, 141bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_SHADER_CORE_COUNT] = 0x4, 142bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_PIXEL_PIPES] = 0x2, 143bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_VERTEX_OUTPUT_BUFFER_SIZE] = 0x400, 144bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_BUFFER_SIZE] = 0x0, 145bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_INSTRUCTION_COUNT] = 0x200, 146bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_NUM_CONSTANTS] = 0x140, 147bf215546Sopenharmony_ci [ETNAVIV_PARAM_GPU_NUM_VARYINGS] = 0x10, 148bf215546Sopenharmony_ci [ETNAVIV_PARAM_SOFTPIN_START_ADDR] = 0x00400000, 149bf215546Sopenharmony_ci } 150bf215546Sopenharmony_ci } 151bf215546Sopenharmony_ci}; 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_cistatic const struct etna_shim_gpu *shim_gpu; 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_cistatic int 156bf215546Sopenharmony_cietnaviv_ioctl_noop(int fd, unsigned long request, void *arg) 157bf215546Sopenharmony_ci{ 158bf215546Sopenharmony_ci return 0; 159bf215546Sopenharmony_ci} 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_cistatic int 162bf215546Sopenharmony_cietnaviv_ioctl_gem_new(int fd, unsigned long request, void *arg) 163bf215546Sopenharmony_ci{ 164bf215546Sopenharmony_ci struct shim_fd *shim_fd = drm_shim_fd_lookup(fd); 165bf215546Sopenharmony_ci struct drm_etnaviv_gem_new *create = arg; 166bf215546Sopenharmony_ci struct shim_bo *bo = calloc(1, sizeof(*bo)); 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci drm_shim_bo_init(bo, create->size); 169bf215546Sopenharmony_ci create->handle = drm_shim_bo_get_handle(shim_fd, bo); 170bf215546Sopenharmony_ci drm_shim_bo_put(bo); 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci return 0; 173bf215546Sopenharmony_ci} 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_cistatic int 176bf215546Sopenharmony_cietnaviv_ioctl_gem_info(int fd, unsigned long request, void *arg) 177bf215546Sopenharmony_ci{ 178bf215546Sopenharmony_ci struct shim_fd *shim_fd = drm_shim_fd_lookup(fd); 179bf215546Sopenharmony_ci struct drm_etnaviv_gem_info *args = arg; 180bf215546Sopenharmony_ci struct shim_bo *bo = drm_shim_bo_lookup(shim_fd, args->handle); 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_ci args->offset = drm_shim_bo_get_mmap_offset(shim_fd, bo); 183bf215546Sopenharmony_ci drm_shim_bo_put(bo); 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci return 0; 186bf215546Sopenharmony_ci} 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_cistatic int 189bf215546Sopenharmony_cietnaviv_ioctl_get_param(int fd, unsigned long request, void *arg) 190bf215546Sopenharmony_ci{ 191bf215546Sopenharmony_ci struct drm_etnaviv_param *gp = arg; 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci if (gp->param > ETNAVIV_PARAM_SOFTPIN_START_ADDR) { 194bf215546Sopenharmony_ci fprintf(stderr, "Unknown DRM_IOCTL_ETNAVIV_GET_PARAM %d\n", gp->param); 195bf215546Sopenharmony_ci return -1; 196bf215546Sopenharmony_ci } 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_ci gp->value = shim_gpu->reg_map[gp->param]; 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci return 0; 201bf215546Sopenharmony_ci} 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_cistatic ioctl_fn_t driver_ioctls[] = { 204bf215546Sopenharmony_ci [DRM_ETNAVIV_GET_PARAM] = etnaviv_ioctl_get_param, 205bf215546Sopenharmony_ci [DRM_ETNAVIV_GEM_NEW] = etnaviv_ioctl_gem_new, 206bf215546Sopenharmony_ci [DRM_ETNAVIV_GEM_INFO] = etnaviv_ioctl_gem_info, 207bf215546Sopenharmony_ci [DRM_ETNAVIV_GEM_CPU_PREP] = etnaviv_ioctl_noop, 208bf215546Sopenharmony_ci [DRM_ETNAVIV_GEM_CPU_FINI] = etnaviv_ioctl_noop, 209bf215546Sopenharmony_ci [DRM_ETNAVIV_GEM_SUBMIT] = etnaviv_ioctl_noop, 210bf215546Sopenharmony_ci [DRM_ETNAVIV_WAIT_FENCE] = etnaviv_ioctl_noop, 211bf215546Sopenharmony_ci [DRM_ETNAVIV_GEM_USERPTR] = etnaviv_ioctl_noop, 212bf215546Sopenharmony_ci [DRM_ETNAVIV_GEM_WAIT] = etnaviv_ioctl_noop, 213bf215546Sopenharmony_ci [DRM_ETNAVIV_PM_QUERY_DOM] = etnaviv_ioctl_noop, 214bf215546Sopenharmony_ci [DRM_ETNAVIV_PM_QUERY_SIG] = etnaviv_ioctl_noop, 215bf215546Sopenharmony_ci}; 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_civoid 218bf215546Sopenharmony_cidrm_shim_driver_init(void) 219bf215546Sopenharmony_ci{ 220bf215546Sopenharmony_ci shim_device.bus_type = DRM_BUS_PLATFORM; 221bf215546Sopenharmony_ci shim_device.driver_name = "etnaviv"; 222bf215546Sopenharmony_ci shim_device.driver_ioctls = driver_ioctls; 223bf215546Sopenharmony_ci shim_device.driver_ioctl_count = ARRAY_SIZE(driver_ioctls); 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci /* etnaviv uses the DRM version to expose features, instead of getparam. */ 226bf215546Sopenharmony_ci shim_device.version_major = 1; 227bf215546Sopenharmony_ci shim_device.version_minor = 1; 228bf215546Sopenharmony_ci shim_device.version_patchlevel = 0; 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci drm_shim_override_file("DRIVER=etnaviv\n" 231bf215546Sopenharmony_ci "MODALIAS=platform:etnaviv\n", 232bf215546Sopenharmony_ci "/sys/dev/char/%d:%d/device/uevent", 233bf215546Sopenharmony_ci DRM_MAJOR, render_node_minor); 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci /* decide what GPU to emulate */ 236bf215546Sopenharmony_ci const char *gpu = debug_get_option("ETNA_SHIM_GPU", "GC2000"); 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci for (unsigned i = 0; i < ARRAY_SIZE(gpus); i++) { 239bf215546Sopenharmony_ci if (strncasecmp(gpu, gpus[i].name, strlen(gpus[i].name)) == 0) { 240bf215546Sopenharmony_ci shim_gpu = &gpus[i]; 241bf215546Sopenharmony_ci break; 242bf215546Sopenharmony_ci } 243bf215546Sopenharmony_ci } 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_ci /* NOTE: keep keep default value and fallback index in sync */ 246bf215546Sopenharmony_ci if (!shim_gpu) 247bf215546Sopenharmony_ci shim_gpu = &gpus[1]; 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci fprintf(stderr, "Using %s as shim gpu\n", shim_gpu->name); 250bf215546Sopenharmony_ci} 251