1ed7d177f66885dfbc4e8410154559c4767fefa9fnobled/************************************************************************** 2ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * 3ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA 4ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * All Rights Reserved. 5ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * 6ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * Permission is hereby granted, free of charge, to any person obtaining a 7ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * copy of this software and associated documentation files (the 8ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * "Software"), to deal in the Software without restriction, including 9ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * without limitation the rights to use, copy, modify, merge, publish, 10ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * distribute, sub license, and/or sell copies of the Software, and to 11ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * permit persons to whom the Software is furnished to do so, subject to 12ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * the following conditions: 13ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * 14ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * The above copyright notice and this permission notice (including the 15ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * next paragraph) shall be included in all copies or substantial portions 16ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * of the Software. 17ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * 18ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 22ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 23ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 24ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * USE OR OTHER DEALINGS IN THE SOFTWARE. 25ed7d177f66885dfbc4e8410154559c4767fefa9fnobled * 26ed7d177f66885dfbc4e8410154559c4767fefa9fnobled **************************************************************************/ 27ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 28ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 298e93afc9765f1de613c65a76e9a86e17db96e653Emil Velikov#ifdef HAVE_CONFIG_H 308e93afc9765f1de613c65a76e9a86e17db96e653Emil Velikov#include "config.h" 318e93afc9765f1de613c65a76e9a86e17db96e653Emil Velikov#endif 32ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 33ed7d177f66885dfbc4e8410154559c4767fefa9fnobled#include <errno.h> 34ed7d177f66885dfbc4e8410154559c4767fefa9fnobled#include <stdio.h> 35ed7d177f66885dfbc4e8410154559c4767fefa9fnobled#include <stdlib.h> 36ed7d177f66885dfbc4e8410154559c4767fefa9fnobled#include <string.h> 37ed7d177f66885dfbc4e8410154559c4767fefa9fnobled#include "internal.h" 38ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 39ed7d177f66885dfbc4e8410154559c4767fefa9fnobled#include <sys/ioctl.h> 40ed7d177f66885dfbc4e8410154559c4767fefa9fnobled#include "xf86drm.h" 4142465feb9759ef5a6d79d7e628510cd0a081f913Emil Velikov#include "libdrm_macros.h" 42ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 43ed7d177f66885dfbc4e8410154559c4767fefa9fnobled#include "radeon_drm.h" 44ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 45ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 46ed7d177f66885dfbc4e8410154559c4767fefa9fnobled#define ALIGNMENT 512 47ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 48ed7d177f66885dfbc4e8410154559c4767fefa9fnobledstruct radeon_bo 49ed7d177f66885dfbc4e8410154559c4767fefa9fnobled{ 50ed7d177f66885dfbc4e8410154559c4767fefa9fnobled struct kms_bo base; 51ed7d177f66885dfbc4e8410154559c4767fefa9fnobled unsigned map_count; 52ed7d177f66885dfbc4e8410154559c4767fefa9fnobled}; 53ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 54ed7d177f66885dfbc4e8410154559c4767fefa9fnobledstatic int 55ed7d177f66885dfbc4e8410154559c4767fefa9fnobledradeon_get_prop(struct kms_driver *kms, unsigned key, unsigned *out) 56ed7d177f66885dfbc4e8410154559c4767fefa9fnobled{ 57ed7d177f66885dfbc4e8410154559c4767fefa9fnobled switch (key) { 58ed7d177f66885dfbc4e8410154559c4767fefa9fnobled case KMS_BO_TYPE: 59ed7d177f66885dfbc4e8410154559c4767fefa9fnobled *out = KMS_BO_TYPE_SCANOUT_X8R8G8B8 | KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8; 60ed7d177f66885dfbc4e8410154559c4767fefa9fnobled break; 61ed7d177f66885dfbc4e8410154559c4767fefa9fnobled default: 62ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return -EINVAL; 63ed7d177f66885dfbc4e8410154559c4767fefa9fnobled } 64ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return 0; 65ed7d177f66885dfbc4e8410154559c4767fefa9fnobled} 66ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 67ed7d177f66885dfbc4e8410154559c4767fefa9fnobledstatic int 68ed7d177f66885dfbc4e8410154559c4767fefa9fnobledradeon_destroy(struct kms_driver *kms) 69ed7d177f66885dfbc4e8410154559c4767fefa9fnobled{ 70ed7d177f66885dfbc4e8410154559c4767fefa9fnobled free(kms); 71ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return 0; 72ed7d177f66885dfbc4e8410154559c4767fefa9fnobled} 73ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 74ed7d177f66885dfbc4e8410154559c4767fefa9fnobledstatic int 75ed7d177f66885dfbc4e8410154559c4767fefa9fnobledradeon_bo_create(struct kms_driver *kms, 76ed7d177f66885dfbc4e8410154559c4767fefa9fnobled const unsigned width, const unsigned height, 77ed7d177f66885dfbc4e8410154559c4767fefa9fnobled const enum kms_bo_type type, const unsigned *attr, 78ed7d177f66885dfbc4e8410154559c4767fefa9fnobled struct kms_bo **out) 79ed7d177f66885dfbc4e8410154559c4767fefa9fnobled{ 80ed7d177f66885dfbc4e8410154559c4767fefa9fnobled struct drm_radeon_gem_create arg; 81ed7d177f66885dfbc4e8410154559c4767fefa9fnobled unsigned size, pitch; 82ed7d177f66885dfbc4e8410154559c4767fefa9fnobled struct radeon_bo *bo; 83ed7d177f66885dfbc4e8410154559c4767fefa9fnobled int i, ret; 84ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 85ed7d177f66885dfbc4e8410154559c4767fefa9fnobled for (i = 0; attr[i]; i += 2) { 86ed7d177f66885dfbc4e8410154559c4767fefa9fnobled switch (attr[i]) { 87ed7d177f66885dfbc4e8410154559c4767fefa9fnobled case KMS_WIDTH: 88ed7d177f66885dfbc4e8410154559c4767fefa9fnobled case KMS_HEIGHT: 89ed7d177f66885dfbc4e8410154559c4767fefa9fnobled case KMS_BO_TYPE: 90ed7d177f66885dfbc4e8410154559c4767fefa9fnobled break; 91ed7d177f66885dfbc4e8410154559c4767fefa9fnobled default: 92ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return -EINVAL; 93ed7d177f66885dfbc4e8410154559c4767fefa9fnobled } 94ed7d177f66885dfbc4e8410154559c4767fefa9fnobled } 95ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 96ed7d177f66885dfbc4e8410154559c4767fefa9fnobled switch (type) { 97ed7d177f66885dfbc4e8410154559c4767fefa9fnobled case KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8: 98ed7d177f66885dfbc4e8410154559c4767fefa9fnobled pitch = 4 * 64; 99ed7d177f66885dfbc4e8410154559c4767fefa9fnobled size = 4 * 64 * 64; 100ed7d177f66885dfbc4e8410154559c4767fefa9fnobled break; 101ed7d177f66885dfbc4e8410154559c4767fefa9fnobled case KMS_BO_TYPE_SCANOUT_X8R8G8B8: 102ed7d177f66885dfbc4e8410154559c4767fefa9fnobled pitch = width * 4; 103ed7d177f66885dfbc4e8410154559c4767fefa9fnobled pitch = (pitch + ALIGNMENT - 1) & ~(ALIGNMENT - 1); 104ed7d177f66885dfbc4e8410154559c4767fefa9fnobled size = pitch * height; 105ed7d177f66885dfbc4e8410154559c4767fefa9fnobled break; 106ed7d177f66885dfbc4e8410154559c4767fefa9fnobled default: 107ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return -EINVAL; 108ed7d177f66885dfbc4e8410154559c4767fefa9fnobled } 109ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 110ed7d177f66885dfbc4e8410154559c4767fefa9fnobled bo = calloc(1, sizeof(*bo)); 111ed7d177f66885dfbc4e8410154559c4767fefa9fnobled if (!bo) 112ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return -ENOMEM; 113ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 114ed7d177f66885dfbc4e8410154559c4767fefa9fnobled memset(&arg, 0, sizeof(arg)); 115ed7d177f66885dfbc4e8410154559c4767fefa9fnobled arg.size = size; 116ed7d177f66885dfbc4e8410154559c4767fefa9fnobled arg.alignment = ALIGNMENT; 117ed7d177f66885dfbc4e8410154559c4767fefa9fnobled arg.initial_domain = RADEON_GEM_DOMAIN_CPU; 118ed7d177f66885dfbc4e8410154559c4767fefa9fnobled arg.flags = 0; 119ed7d177f66885dfbc4e8410154559c4767fefa9fnobled arg.handle = 0; 120ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 121ed7d177f66885dfbc4e8410154559c4767fefa9fnobled ret = drmCommandWriteRead(kms->fd, DRM_RADEON_GEM_CREATE, 122ed7d177f66885dfbc4e8410154559c4767fefa9fnobled &arg, sizeof(arg)); 123ed7d177f66885dfbc4e8410154559c4767fefa9fnobled if (ret) 124ed7d177f66885dfbc4e8410154559c4767fefa9fnobled goto err_free; 125ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 126ed7d177f66885dfbc4e8410154559c4767fefa9fnobled bo->base.kms = kms; 127ed7d177f66885dfbc4e8410154559c4767fefa9fnobled bo->base.handle = arg.handle; 128ed7d177f66885dfbc4e8410154559c4767fefa9fnobled bo->base.size = size; 129ed7d177f66885dfbc4e8410154559c4767fefa9fnobled bo->base.pitch = pitch; 130ed7d177f66885dfbc4e8410154559c4767fefa9fnobled bo->base.offset = 0; 131ed7d177f66885dfbc4e8410154559c4767fefa9fnobled bo->map_count = 0; 132ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 133ed7d177f66885dfbc4e8410154559c4767fefa9fnobled *out = &bo->base; 134ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 135ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return 0; 136ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 137ed7d177f66885dfbc4e8410154559c4767fefa9fnoblederr_free: 138ed7d177f66885dfbc4e8410154559c4767fefa9fnobled free(bo); 139ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return ret; 140ed7d177f66885dfbc4e8410154559c4767fefa9fnobled} 141ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 142ed7d177f66885dfbc4e8410154559c4767fefa9fnobledstatic int 143ed7d177f66885dfbc4e8410154559c4767fefa9fnobledradeon_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out) 144ed7d177f66885dfbc4e8410154559c4767fefa9fnobled{ 145ed7d177f66885dfbc4e8410154559c4767fefa9fnobled switch (key) { 146ed7d177f66885dfbc4e8410154559c4767fefa9fnobled default: 147ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return -EINVAL; 148ed7d177f66885dfbc4e8410154559c4767fefa9fnobled } 149ed7d177f66885dfbc4e8410154559c4767fefa9fnobled} 150ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 151ed7d177f66885dfbc4e8410154559c4767fefa9fnobledstatic int 152ed7d177f66885dfbc4e8410154559c4767fefa9fnobledradeon_bo_map(struct kms_bo *_bo, void **out) 153ed7d177f66885dfbc4e8410154559c4767fefa9fnobled{ 154ed7d177f66885dfbc4e8410154559c4767fefa9fnobled struct radeon_bo *bo = (struct radeon_bo *)_bo; 155ed7d177f66885dfbc4e8410154559c4767fefa9fnobled struct drm_radeon_gem_mmap arg; 156ed7d177f66885dfbc4e8410154559c4767fefa9fnobled void *map = NULL; 157ed7d177f66885dfbc4e8410154559c4767fefa9fnobled int ret; 158ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 159ed7d177f66885dfbc4e8410154559c4767fefa9fnobled if (bo->base.ptr) { 160ed7d177f66885dfbc4e8410154559c4767fefa9fnobled bo->map_count++; 161ed7d177f66885dfbc4e8410154559c4767fefa9fnobled *out = bo->base.ptr; 162ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return 0; 163ed7d177f66885dfbc4e8410154559c4767fefa9fnobled } 164ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 165ed7d177f66885dfbc4e8410154559c4767fefa9fnobled memset(&arg, 0, sizeof(arg)); 166ed7d177f66885dfbc4e8410154559c4767fefa9fnobled arg.handle = bo->base.handle; 167ed7d177f66885dfbc4e8410154559c4767fefa9fnobled arg.offset = bo->base.offset; 168ed7d177f66885dfbc4e8410154559c4767fefa9fnobled arg.size = (uint64_t)bo->base.size; 169ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 170ed7d177f66885dfbc4e8410154559c4767fefa9fnobled ret = drmCommandWriteRead(bo->base.kms->fd, DRM_RADEON_GEM_MMAP, 171ed7d177f66885dfbc4e8410154559c4767fefa9fnobled &arg, sizeof(arg)); 172ed7d177f66885dfbc4e8410154559c4767fefa9fnobled if (ret) 173ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return -errno; 174ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 175dadc9eff9fd606335a7b3d5d58065a2e8d629672Emil Velikov map = drm_mmap(0, arg.size, PROT_READ | PROT_WRITE, MAP_SHARED, 176ed7d177f66885dfbc4e8410154559c4767fefa9fnobled bo->base.kms->fd, arg.addr_ptr); 177ed7d177f66885dfbc4e8410154559c4767fefa9fnobled if (map == MAP_FAILED) 178ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return -errno; 179ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 180ed7d177f66885dfbc4e8410154559c4767fefa9fnobled bo->base.ptr = map; 181ed7d177f66885dfbc4e8410154559c4767fefa9fnobled bo->map_count++; 182ed7d177f66885dfbc4e8410154559c4767fefa9fnobled *out = bo->base.ptr; 183ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 184ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return 0; 185ed7d177f66885dfbc4e8410154559c4767fefa9fnobled} 186ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 187ed7d177f66885dfbc4e8410154559c4767fefa9fnobledstatic int 188ed7d177f66885dfbc4e8410154559c4767fefa9fnobledradeon_bo_unmap(struct kms_bo *_bo) 189ed7d177f66885dfbc4e8410154559c4767fefa9fnobled{ 190ed7d177f66885dfbc4e8410154559c4767fefa9fnobled struct radeon_bo *bo = (struct radeon_bo *)_bo; 191ed7d177f66885dfbc4e8410154559c4767fefa9fnobled if (--bo->map_count == 0) { 192dadc9eff9fd606335a7b3d5d58065a2e8d629672Emil Velikov drm_munmap(bo->base.ptr, bo->base.size); 193ed7d177f66885dfbc4e8410154559c4767fefa9fnobled bo->base.ptr = NULL; 194ed7d177f66885dfbc4e8410154559c4767fefa9fnobled } 195ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return 0; 196ed7d177f66885dfbc4e8410154559c4767fefa9fnobled} 197ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 198ed7d177f66885dfbc4e8410154559c4767fefa9fnobledstatic int 199ed7d177f66885dfbc4e8410154559c4767fefa9fnobledradeon_bo_destroy(struct kms_bo *_bo) 200ed7d177f66885dfbc4e8410154559c4767fefa9fnobled{ 201ed7d177f66885dfbc4e8410154559c4767fefa9fnobled struct radeon_bo *bo = (struct radeon_bo *)_bo; 202ed7d177f66885dfbc4e8410154559c4767fefa9fnobled struct drm_gem_close arg; 203ed7d177f66885dfbc4e8410154559c4767fefa9fnobled int ret; 204ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 205ed7d177f66885dfbc4e8410154559c4767fefa9fnobled if (bo->base.ptr) { 206ed7d177f66885dfbc4e8410154559c4767fefa9fnobled /* XXX Sanity check map_count */ 207dadc9eff9fd606335a7b3d5d58065a2e8d629672Emil Velikov drm_munmap(bo->base.ptr, bo->base.size); 208ed7d177f66885dfbc4e8410154559c4767fefa9fnobled bo->base.ptr = NULL; 209ed7d177f66885dfbc4e8410154559c4767fefa9fnobled } 210ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 211ed7d177f66885dfbc4e8410154559c4767fefa9fnobled memset(&arg, 0, sizeof(arg)); 212ed7d177f66885dfbc4e8410154559c4767fefa9fnobled arg.handle = bo->base.handle; 213ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 214ed7d177f66885dfbc4e8410154559c4767fefa9fnobled ret = drmIoctl(bo->base.kms->fd, DRM_IOCTL_GEM_CLOSE, &arg); 215ed7d177f66885dfbc4e8410154559c4767fefa9fnobled if (ret) 216ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return -errno; 217ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 218ed7d177f66885dfbc4e8410154559c4767fefa9fnobled free(bo); 219ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return 0; 220ed7d177f66885dfbc4e8410154559c4767fefa9fnobled} 221ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 222983892d2756b4bcfcd455ec644afe666b9e0e447Emil Velikovdrm_private int 223ed7d177f66885dfbc4e8410154559c4767fefa9fnobledradeon_create(int fd, struct kms_driver **out) 224ed7d177f66885dfbc4e8410154559c4767fefa9fnobled{ 225ed7d177f66885dfbc4e8410154559c4767fefa9fnobled struct kms_driver *kms; 226ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 227ed7d177f66885dfbc4e8410154559c4767fefa9fnobled kms = calloc(1, sizeof(*kms)); 228ed7d177f66885dfbc4e8410154559c4767fefa9fnobled if (!kms) 229ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return -ENOMEM; 230ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 231ed7d177f66885dfbc4e8410154559c4767fefa9fnobled kms->fd = fd; 232ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 233ed7d177f66885dfbc4e8410154559c4767fefa9fnobled kms->bo_create = radeon_bo_create; 234ed7d177f66885dfbc4e8410154559c4767fefa9fnobled kms->bo_map = radeon_bo_map; 235ed7d177f66885dfbc4e8410154559c4767fefa9fnobled kms->bo_unmap = radeon_bo_unmap; 236ed7d177f66885dfbc4e8410154559c4767fefa9fnobled kms->bo_get_prop = radeon_bo_get_prop; 237ed7d177f66885dfbc4e8410154559c4767fefa9fnobled kms->bo_destroy = radeon_bo_destroy; 238ed7d177f66885dfbc4e8410154559c4767fefa9fnobled kms->get_prop = radeon_get_prop; 239ed7d177f66885dfbc4e8410154559c4767fefa9fnobled kms->destroy = radeon_destroy; 240ed7d177f66885dfbc4e8410154559c4767fefa9fnobled *out = kms; 241ed7d177f66885dfbc4e8410154559c4767fefa9fnobled 242ed7d177f66885dfbc4e8410154559c4767fefa9fnobled return 0; 243ed7d177f66885dfbc4e8410154559c4767fefa9fnobled} 244