1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2019 Google LLC 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include <limits.h> 25bf215546Sopenharmony_ci#include <stdio.h> 26bf215546Sopenharmony_ci#include <stdlib.h> 27bf215546Sopenharmony_ci#include "drm-shim/drm_shim.h" 28bf215546Sopenharmony_ci#include "drm-uapi/msm_drm.h" 29bf215546Sopenharmony_ci#include <sys/ioctl.h> 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include "util/u_math.h" 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_cibool drm_shim_driver_prefers_first_render_node = true; 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_cistruct msm_device_info { 36bf215546Sopenharmony_ci uint32_t gpu_id; 37bf215546Sopenharmony_ci uint32_t chip_id; 38bf215546Sopenharmony_ci uint32_t gmem_size; 39bf215546Sopenharmony_ci}; 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_cistatic const struct msm_device_info *device_info; 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_cistatic int 44bf215546Sopenharmony_cimsm_ioctl_noop(int fd, unsigned long request, void *arg) 45bf215546Sopenharmony_ci{ 46bf215546Sopenharmony_ci return 0; 47bf215546Sopenharmony_ci} 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_cistatic int 50bf215546Sopenharmony_cimsm_ioctl_gem_new(int fd, unsigned long request, void *arg) 51bf215546Sopenharmony_ci{ 52bf215546Sopenharmony_ci struct shim_fd *shim_fd = drm_shim_fd_lookup(fd); 53bf215546Sopenharmony_ci struct drm_msm_gem_new *create = arg; 54bf215546Sopenharmony_ci size_t size = ALIGN(create->size, 4096); 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci if (!size) 57bf215546Sopenharmony_ci return -EINVAL; 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci struct shim_bo *bo = calloc(1, sizeof(*bo)); 60bf215546Sopenharmony_ci int ret; 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci ret = drm_shim_bo_init(bo, size); 63bf215546Sopenharmony_ci if (ret) { 64bf215546Sopenharmony_ci free(bo); 65bf215546Sopenharmony_ci return ret; 66bf215546Sopenharmony_ci } 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci create->handle = drm_shim_bo_get_handle(shim_fd, bo); 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci drm_shim_bo_put(bo); 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci return 0; 73bf215546Sopenharmony_ci} 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_cistatic int 76bf215546Sopenharmony_cimsm_ioctl_gem_info(int fd, unsigned long request, void *arg) 77bf215546Sopenharmony_ci{ 78bf215546Sopenharmony_ci struct shim_fd *shim_fd = drm_shim_fd_lookup(fd); 79bf215546Sopenharmony_ci struct drm_msm_gem_info *args = arg; 80bf215546Sopenharmony_ci struct shim_bo *bo = drm_shim_bo_lookup(shim_fd, args->handle); 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci if (!bo) 83bf215546Sopenharmony_ci return -ENOENT; 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_ci switch (args->info) { 86bf215546Sopenharmony_ci case MSM_INFO_GET_OFFSET: 87bf215546Sopenharmony_ci args->value = drm_shim_bo_get_mmap_offset(shim_fd, bo); 88bf215546Sopenharmony_ci break; 89bf215546Sopenharmony_ci case MSM_INFO_GET_IOVA: 90bf215546Sopenharmony_ci args->value = bo->mem_addr; 91bf215546Sopenharmony_ci break; 92bf215546Sopenharmony_ci case MSM_INFO_SET_IOVA: 93bf215546Sopenharmony_ci case MSM_INFO_SET_NAME: 94bf215546Sopenharmony_ci break; 95bf215546Sopenharmony_ci default: 96bf215546Sopenharmony_ci fprintf(stderr, "Unknown DRM_IOCTL_MSM_GEM_INFO %d\n", args->info); 97bf215546Sopenharmony_ci drm_shim_bo_put(bo); 98bf215546Sopenharmony_ci return -1; 99bf215546Sopenharmony_ci } 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci drm_shim_bo_put(bo); 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci return 0; 104bf215546Sopenharmony_ci} 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_cistatic int 107bf215546Sopenharmony_cimsm_ioctl_get_param(int fd, unsigned long request, void *arg) 108bf215546Sopenharmony_ci{ 109bf215546Sopenharmony_ci struct drm_msm_param *gp = arg; 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci switch (gp->param) { 112bf215546Sopenharmony_ci case MSM_PARAM_GPU_ID: 113bf215546Sopenharmony_ci gp->value = device_info->gpu_id; 114bf215546Sopenharmony_ci return 0; 115bf215546Sopenharmony_ci case MSM_PARAM_GMEM_SIZE: 116bf215546Sopenharmony_ci gp->value = device_info->gmem_size; 117bf215546Sopenharmony_ci return 0; 118bf215546Sopenharmony_ci case MSM_PARAM_GMEM_BASE: 119bf215546Sopenharmony_ci gp->value = 0x100000; 120bf215546Sopenharmony_ci return 0; 121bf215546Sopenharmony_ci case MSM_PARAM_CHIP_ID: 122bf215546Sopenharmony_ci gp->value = device_info->chip_id; 123bf215546Sopenharmony_ci return 0; 124bf215546Sopenharmony_ci case MSM_PARAM_NR_RINGS: 125bf215546Sopenharmony_ci gp->value = 1; 126bf215546Sopenharmony_ci return 0; 127bf215546Sopenharmony_ci case MSM_PARAM_MAX_FREQ: 128bf215546Sopenharmony_ci gp->value = 1000000; 129bf215546Sopenharmony_ci return 0; 130bf215546Sopenharmony_ci case MSM_PARAM_TIMESTAMP: 131bf215546Sopenharmony_ci gp->value = 0; 132bf215546Sopenharmony_ci return 0; 133bf215546Sopenharmony_ci case MSM_PARAM_PP_PGTABLE: 134bf215546Sopenharmony_ci gp->value = 1; 135bf215546Sopenharmony_ci return 0; 136bf215546Sopenharmony_ci case MSM_PARAM_FAULTS: 137bf215546Sopenharmony_ci case MSM_PARAM_SUSPENDS: 138bf215546Sopenharmony_ci gp->value = 0; 139bf215546Sopenharmony_ci return 0; 140bf215546Sopenharmony_ci case MSM_PARAM_VA_START: 141bf215546Sopenharmony_ci case MSM_PARAM_VA_SIZE: 142bf215546Sopenharmony_ci gp->value = 0x100000000ULL; 143bf215546Sopenharmony_ci return 0; 144bf215546Sopenharmony_ci default: 145bf215546Sopenharmony_ci fprintf(stderr, "Unknown DRM_IOCTL_MSM_GET_PARAM %d\n", gp->param); 146bf215546Sopenharmony_ci return -1; 147bf215546Sopenharmony_ci } 148bf215546Sopenharmony_ci} 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_cistatic int 151bf215546Sopenharmony_cimsm_ioctl_gem_madvise(int fd, unsigned long request, void *arg) 152bf215546Sopenharmony_ci{ 153bf215546Sopenharmony_ci struct drm_msm_gem_madvise *args = arg; 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci args->retained = true; 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci return 0; 158bf215546Sopenharmony_ci} 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_cistatic ioctl_fn_t driver_ioctls[] = { 161bf215546Sopenharmony_ci [DRM_MSM_GET_PARAM] = msm_ioctl_get_param, 162bf215546Sopenharmony_ci [DRM_MSM_SET_PARAM] = msm_ioctl_noop, 163bf215546Sopenharmony_ci [DRM_MSM_GEM_NEW] = msm_ioctl_gem_new, 164bf215546Sopenharmony_ci [DRM_MSM_GEM_INFO] = msm_ioctl_gem_info, 165bf215546Sopenharmony_ci [DRM_MSM_GEM_CPU_PREP] = msm_ioctl_noop, 166bf215546Sopenharmony_ci [DRM_MSM_GEM_CPU_FINI] = msm_ioctl_noop, 167bf215546Sopenharmony_ci [DRM_MSM_GEM_SUBMIT] = msm_ioctl_noop, 168bf215546Sopenharmony_ci [DRM_MSM_WAIT_FENCE] = msm_ioctl_noop, 169bf215546Sopenharmony_ci [DRM_MSM_GEM_MADVISE] = msm_ioctl_gem_madvise, 170bf215546Sopenharmony_ci [DRM_MSM_SUBMITQUEUE_NEW] = msm_ioctl_noop, 171bf215546Sopenharmony_ci [DRM_MSM_SUBMITQUEUE_CLOSE] = msm_ioctl_noop, 172bf215546Sopenharmony_ci [DRM_MSM_SUBMITQUEUE_QUERY] = msm_ioctl_noop, 173bf215546Sopenharmony_ci}; 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_ci#define CHIPID(maj, min, rev, pat) \ 176bf215546Sopenharmony_ci ((maj << 24) | (min << 16) | (rev << 8) | (pat)) 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_cistatic const struct msm_device_info device_infos[] = { 179bf215546Sopenharmony_ci { 180bf215546Sopenharmony_ci /* First entry is default */ 181bf215546Sopenharmony_ci .gpu_id = 630, 182bf215546Sopenharmony_ci .chip_id = CHIPID(6, 3, 0, 0xff), 183bf215546Sopenharmony_ci .gmem_size = 1024 * 1024, 184bf215546Sopenharmony_ci }, 185bf215546Sopenharmony_ci { 186bf215546Sopenharmony_ci .gpu_id = 200, 187bf215546Sopenharmony_ci .chip_id = CHIPID(2, 0, 0, 0), 188bf215546Sopenharmony_ci .gmem_size = 256 * 1024, 189bf215546Sopenharmony_ci }, 190bf215546Sopenharmony_ci { 191bf215546Sopenharmony_ci .gpu_id = 201, 192bf215546Sopenharmony_ci .chip_id = CHIPID(2, 0, 0, 1), 193bf215546Sopenharmony_ci .gmem_size = 128 * 1024, 194bf215546Sopenharmony_ci }, 195bf215546Sopenharmony_ci { 196bf215546Sopenharmony_ci .gpu_id = 220, 197bf215546Sopenharmony_ci .chip_id = CHIPID(2, 2, 0, 0xff), 198bf215546Sopenharmony_ci .gmem_size = 512 * 1024, 199bf215546Sopenharmony_ci }, 200bf215546Sopenharmony_ci { 201bf215546Sopenharmony_ci .gpu_id = 305, 202bf215546Sopenharmony_ci .chip_id = CHIPID(3, 0, 5, 0xff), 203bf215546Sopenharmony_ci .gmem_size = 256 * 1024, 204bf215546Sopenharmony_ci }, 205bf215546Sopenharmony_ci { 206bf215546Sopenharmony_ci .gpu_id = 307, 207bf215546Sopenharmony_ci .chip_id = CHIPID(3, 0, 6, 0), 208bf215546Sopenharmony_ci .gmem_size = 128 * 1024, 209bf215546Sopenharmony_ci }, 210bf215546Sopenharmony_ci { 211bf215546Sopenharmony_ci .gpu_id = 320, 212bf215546Sopenharmony_ci .chip_id = CHIPID(3, 2, 0xff, 0xff), 213bf215546Sopenharmony_ci .gmem_size = 512 * 1024, 214bf215546Sopenharmony_ci }, 215bf215546Sopenharmony_ci { 216bf215546Sopenharmony_ci .gpu_id = 330, 217bf215546Sopenharmony_ci .chip_id = CHIPID(3, 3, 0, 0xff), 218bf215546Sopenharmony_ci .gmem_size = 1024 * 1024, 219bf215546Sopenharmony_ci }, 220bf215546Sopenharmony_ci { 221bf215546Sopenharmony_ci .gpu_id = 420, 222bf215546Sopenharmony_ci .chip_id = CHIPID(4, 2, 0, 0xff), 223bf215546Sopenharmony_ci .gmem_size = 1536 * 1024, 224bf215546Sopenharmony_ci }, 225bf215546Sopenharmony_ci { 226bf215546Sopenharmony_ci .gpu_id = 430, 227bf215546Sopenharmony_ci .chip_id = CHIPID(4, 3, 0, 0xff), 228bf215546Sopenharmony_ci .gmem_size = 1536 * 1024, 229bf215546Sopenharmony_ci }, 230bf215546Sopenharmony_ci { 231bf215546Sopenharmony_ci .gpu_id = 510, 232bf215546Sopenharmony_ci .chip_id = CHIPID(5, 1, 0, 0xff), 233bf215546Sopenharmony_ci .gmem_size = 256 * 1024, 234bf215546Sopenharmony_ci }, 235bf215546Sopenharmony_ci { 236bf215546Sopenharmony_ci .gpu_id = 530, 237bf215546Sopenharmony_ci .chip_id = CHIPID(5, 3, 0, 2), 238bf215546Sopenharmony_ci .gmem_size = 1024 * 1024, 239bf215546Sopenharmony_ci }, 240bf215546Sopenharmony_ci { 241bf215546Sopenharmony_ci .gpu_id = 540, 242bf215546Sopenharmony_ci .chip_id = CHIPID(5, 4, 0, 2), 243bf215546Sopenharmony_ci .gmem_size = 1024 * 1024, 244bf215546Sopenharmony_ci }, 245bf215546Sopenharmony_ci { 246bf215546Sopenharmony_ci .gpu_id = 618, 247bf215546Sopenharmony_ci .chip_id = CHIPID(6, 1, 8, 0xff), 248bf215546Sopenharmony_ci .gmem_size = 512 * 1024, 249bf215546Sopenharmony_ci }, 250bf215546Sopenharmony_ci { 251bf215546Sopenharmony_ci .gpu_id = 630, 252bf215546Sopenharmony_ci .chip_id = CHIPID(6, 3, 0, 0xff), 253bf215546Sopenharmony_ci .gmem_size = 1024 * 1024, 254bf215546Sopenharmony_ci }, 255bf215546Sopenharmony_ci { 256bf215546Sopenharmony_ci .gpu_id = 660, 257bf215546Sopenharmony_ci .chip_id = CHIPID(6, 6, 0, 0xff), 258bf215546Sopenharmony_ci .gmem_size = 1024 * 1024 + 512 * 1024, 259bf215546Sopenharmony_ci }, 260bf215546Sopenharmony_ci}; 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_cistatic void 263bf215546Sopenharmony_cimsm_driver_get_device_info(void) 264bf215546Sopenharmony_ci{ 265bf215546Sopenharmony_ci const char *env = getenv("FD_GPU_ID"); 266bf215546Sopenharmony_ci 267bf215546Sopenharmony_ci if (!env) { 268bf215546Sopenharmony_ci device_info = &device_infos[0]; 269bf215546Sopenharmony_ci return; 270bf215546Sopenharmony_ci } 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci int gpu_id = atoi(env); 273bf215546Sopenharmony_ci for (int i = 0; i < ARRAY_SIZE(device_infos); i++) { 274bf215546Sopenharmony_ci if (device_infos[i].gpu_id == gpu_id) { 275bf215546Sopenharmony_ci device_info = &device_infos[i]; 276bf215546Sopenharmony_ci return; 277bf215546Sopenharmony_ci } 278bf215546Sopenharmony_ci } 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci fprintf(stderr, "FD_GPU_ID unrecognized, shim supports %d", 281bf215546Sopenharmony_ci device_infos[0].gpu_id); 282bf215546Sopenharmony_ci for (int i = 1; i < ARRAY_SIZE(device_infos); i++) 283bf215546Sopenharmony_ci fprintf(stderr, ", %d", device_infos[i].gpu_id); 284bf215546Sopenharmony_ci fprintf(stderr, "\n"); 285bf215546Sopenharmony_ci abort(); 286bf215546Sopenharmony_ci} 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_civoid 289bf215546Sopenharmony_cidrm_shim_driver_init(void) 290bf215546Sopenharmony_ci{ 291bf215546Sopenharmony_ci shim_device.bus_type = DRM_BUS_PLATFORM; 292bf215546Sopenharmony_ci shim_device.driver_name = "msm"; 293bf215546Sopenharmony_ci shim_device.driver_ioctls = driver_ioctls; 294bf215546Sopenharmony_ci shim_device.driver_ioctl_count = ARRAY_SIZE(driver_ioctls); 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci /* msm uses the DRM version to expose features, instead of getparam. */ 297bf215546Sopenharmony_ci shim_device.version_major = 1; 298bf215546Sopenharmony_ci shim_device.version_minor = 9; 299bf215546Sopenharmony_ci shim_device.version_patchlevel = 0; 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci msm_driver_get_device_info(); 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci drm_shim_override_file("OF_FULLNAME=/rdb/msm\n" 304bf215546Sopenharmony_ci "OF_COMPATIBLE_N=1\n" 305bf215546Sopenharmony_ci "OF_COMPATIBLE_0=qcom,adreno\n", 306bf215546Sopenharmony_ci "/sys/dev/char/%d:%d/device/uevent", DRM_MAJOR, 307bf215546Sopenharmony_ci render_node_minor); 308bf215546Sopenharmony_ci} 309