1d722e3fbSopenharmony_ci/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ 2d722e3fbSopenharmony_ci 3d722e3fbSopenharmony_ci/* 4d722e3fbSopenharmony_ci * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org> 5d722e3fbSopenharmony_ci * 6d722e3fbSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7d722e3fbSopenharmony_ci * copy of this software and associated documentation files (the "Software"), 8d722e3fbSopenharmony_ci * to deal in the Software without restriction, including without limitation 9d722e3fbSopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10d722e3fbSopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 11d722e3fbSopenharmony_ci * Software is furnished to do so, subject to the following conditions: 12d722e3fbSopenharmony_ci * 13d722e3fbSopenharmony_ci * The above copyright notice and this permission notice (including the next 14d722e3fbSopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 15d722e3fbSopenharmony_ci * Software. 16d722e3fbSopenharmony_ci * 17d722e3fbSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18d722e3fbSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19d722e3fbSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20d722e3fbSopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21d722e3fbSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22d722e3fbSopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23d722e3fbSopenharmony_ci * SOFTWARE. 24d722e3fbSopenharmony_ci * 25d722e3fbSopenharmony_ci * Authors: 26d722e3fbSopenharmony_ci * Rob Clark <robclark@freedesktop.org> 27d722e3fbSopenharmony_ci */ 28d722e3fbSopenharmony_ci 29d722e3fbSopenharmony_ci#include "msm_priv.h" 30d722e3fbSopenharmony_ci 31d722e3fbSopenharmony_cistatic int bo_allocate(struct msm_bo *msm_bo) 32d722e3fbSopenharmony_ci{ 33d722e3fbSopenharmony_ci struct fd_bo *bo = &msm_bo->base; 34d722e3fbSopenharmony_ci if (!msm_bo->offset) { 35d722e3fbSopenharmony_ci struct drm_msm_gem_info req = { 36d722e3fbSopenharmony_ci .handle = bo->handle, 37d722e3fbSopenharmony_ci }; 38d722e3fbSopenharmony_ci int ret; 39d722e3fbSopenharmony_ci 40d722e3fbSopenharmony_ci /* if the buffer is already backed by pages then this 41d722e3fbSopenharmony_ci * doesn't actually do anything (other than giving us 42d722e3fbSopenharmony_ci * the offset) 43d722e3fbSopenharmony_ci */ 44d722e3fbSopenharmony_ci ret = drmCommandWriteRead(bo->dev->fd, DRM_MSM_GEM_INFO, 45d722e3fbSopenharmony_ci &req, sizeof(req)); 46d722e3fbSopenharmony_ci if (ret) { 47d722e3fbSopenharmony_ci ERROR_MSG("alloc failed: %s", strerror(errno)); 48d722e3fbSopenharmony_ci return ret; 49d722e3fbSopenharmony_ci } 50d722e3fbSopenharmony_ci 51d722e3fbSopenharmony_ci msm_bo->offset = req.offset; 52d722e3fbSopenharmony_ci } 53d722e3fbSopenharmony_ci 54d722e3fbSopenharmony_ci return 0; 55d722e3fbSopenharmony_ci} 56d722e3fbSopenharmony_ci 57d722e3fbSopenharmony_cistatic int msm_bo_offset(struct fd_bo *bo, uint64_t *offset) 58d722e3fbSopenharmony_ci{ 59d722e3fbSopenharmony_ci struct msm_bo *msm_bo = to_msm_bo(bo); 60d722e3fbSopenharmony_ci int ret = bo_allocate(msm_bo); 61d722e3fbSopenharmony_ci if (ret) 62d722e3fbSopenharmony_ci return ret; 63d722e3fbSopenharmony_ci *offset = msm_bo->offset; 64d722e3fbSopenharmony_ci return 0; 65d722e3fbSopenharmony_ci} 66d722e3fbSopenharmony_ci 67d722e3fbSopenharmony_cistatic int msm_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op) 68d722e3fbSopenharmony_ci{ 69d722e3fbSopenharmony_ci struct drm_msm_gem_cpu_prep req = { 70d722e3fbSopenharmony_ci .handle = bo->handle, 71d722e3fbSopenharmony_ci .op = op, 72d722e3fbSopenharmony_ci }; 73d722e3fbSopenharmony_ci 74d722e3fbSopenharmony_ci get_abs_timeout(&req.timeout, 5000000000); 75d722e3fbSopenharmony_ci 76d722e3fbSopenharmony_ci return drmCommandWrite(bo->dev->fd, DRM_MSM_GEM_CPU_PREP, &req, sizeof(req)); 77d722e3fbSopenharmony_ci} 78d722e3fbSopenharmony_ci 79d722e3fbSopenharmony_cistatic void msm_bo_cpu_fini(struct fd_bo *bo) 80d722e3fbSopenharmony_ci{ 81d722e3fbSopenharmony_ci struct drm_msm_gem_cpu_fini req = { 82d722e3fbSopenharmony_ci .handle = bo->handle, 83d722e3fbSopenharmony_ci }; 84d722e3fbSopenharmony_ci 85d722e3fbSopenharmony_ci drmCommandWrite(bo->dev->fd, DRM_MSM_GEM_CPU_FINI, &req, sizeof(req)); 86d722e3fbSopenharmony_ci} 87d722e3fbSopenharmony_ci 88d722e3fbSopenharmony_cistatic int msm_bo_madvise(struct fd_bo *bo, int willneed) 89d722e3fbSopenharmony_ci{ 90d722e3fbSopenharmony_ci struct drm_msm_gem_madvise req = { 91d722e3fbSopenharmony_ci .handle = bo->handle, 92d722e3fbSopenharmony_ci .madv = willneed ? MSM_MADV_WILLNEED : MSM_MADV_DONTNEED, 93d722e3fbSopenharmony_ci }; 94d722e3fbSopenharmony_ci int ret; 95d722e3fbSopenharmony_ci 96d722e3fbSopenharmony_ci /* older kernels do not support this: */ 97d722e3fbSopenharmony_ci if (bo->dev->version < FD_VERSION_MADVISE) 98d722e3fbSopenharmony_ci return willneed; 99d722e3fbSopenharmony_ci 100d722e3fbSopenharmony_ci ret = drmCommandWriteRead(bo->dev->fd, DRM_MSM_GEM_MADVISE, &req, sizeof(req)); 101d722e3fbSopenharmony_ci if (ret) 102d722e3fbSopenharmony_ci return ret; 103d722e3fbSopenharmony_ci 104d722e3fbSopenharmony_ci return req.retained; 105d722e3fbSopenharmony_ci} 106d722e3fbSopenharmony_ci 107d722e3fbSopenharmony_cistatic uint64_t msm_bo_iova(struct fd_bo *bo) 108d722e3fbSopenharmony_ci{ 109d722e3fbSopenharmony_ci struct drm_msm_gem_info req = { 110d722e3fbSopenharmony_ci .handle = bo->handle, 111d722e3fbSopenharmony_ci .flags = MSM_INFO_IOVA, 112d722e3fbSopenharmony_ci }; 113d722e3fbSopenharmony_ci 114d722e3fbSopenharmony_ci drmCommandWriteRead(bo->dev->fd, DRM_MSM_GEM_INFO, &req, sizeof(req)); 115d722e3fbSopenharmony_ci 116d722e3fbSopenharmony_ci return req.offset; 117d722e3fbSopenharmony_ci} 118d722e3fbSopenharmony_ci 119d722e3fbSopenharmony_cistatic void msm_bo_destroy(struct fd_bo *bo) 120d722e3fbSopenharmony_ci{ 121d722e3fbSopenharmony_ci struct msm_bo *msm_bo = to_msm_bo(bo); 122d722e3fbSopenharmony_ci free(msm_bo); 123d722e3fbSopenharmony_ci 124d722e3fbSopenharmony_ci} 125d722e3fbSopenharmony_ci 126d722e3fbSopenharmony_cistatic const struct fd_bo_funcs funcs = { 127d722e3fbSopenharmony_ci .offset = msm_bo_offset, 128d722e3fbSopenharmony_ci .cpu_prep = msm_bo_cpu_prep, 129d722e3fbSopenharmony_ci .cpu_fini = msm_bo_cpu_fini, 130d722e3fbSopenharmony_ci .madvise = msm_bo_madvise, 131d722e3fbSopenharmony_ci .iova = msm_bo_iova, 132d722e3fbSopenharmony_ci .destroy = msm_bo_destroy, 133d722e3fbSopenharmony_ci}; 134d722e3fbSopenharmony_ci 135d722e3fbSopenharmony_ci/* allocate a buffer handle: */ 136d722e3fbSopenharmony_cidrm_private int msm_bo_new_handle(struct fd_device *dev, 137d722e3fbSopenharmony_ci uint32_t size, uint32_t flags, uint32_t *handle) 138d722e3fbSopenharmony_ci{ 139d722e3fbSopenharmony_ci struct drm_msm_gem_new req = { 140d722e3fbSopenharmony_ci .size = size, 141d722e3fbSopenharmony_ci .flags = MSM_BO_WC, // TODO figure out proper flags.. 142d722e3fbSopenharmony_ci }; 143d722e3fbSopenharmony_ci int ret; 144d722e3fbSopenharmony_ci 145d722e3fbSopenharmony_ci ret = drmCommandWriteRead(dev->fd, DRM_MSM_GEM_NEW, 146d722e3fbSopenharmony_ci &req, sizeof(req)); 147d722e3fbSopenharmony_ci if (ret) 148d722e3fbSopenharmony_ci return ret; 149d722e3fbSopenharmony_ci 150d722e3fbSopenharmony_ci *handle = req.handle; 151d722e3fbSopenharmony_ci 152d722e3fbSopenharmony_ci return 0; 153d722e3fbSopenharmony_ci} 154d722e3fbSopenharmony_ci 155d722e3fbSopenharmony_ci/* allocate a new buffer object */ 156d722e3fbSopenharmony_cidrm_private struct fd_bo * msm_bo_from_handle(struct fd_device *dev, 157d722e3fbSopenharmony_ci uint32_t size, uint32_t handle) 158d722e3fbSopenharmony_ci{ 159d722e3fbSopenharmony_ci struct msm_bo *msm_bo; 160d722e3fbSopenharmony_ci struct fd_bo *bo; 161d722e3fbSopenharmony_ci 162d722e3fbSopenharmony_ci msm_bo = calloc(1, sizeof(*msm_bo)); 163d722e3fbSopenharmony_ci if (!msm_bo) 164d722e3fbSopenharmony_ci return NULL; 165d722e3fbSopenharmony_ci 166d722e3fbSopenharmony_ci bo = &msm_bo->base; 167d722e3fbSopenharmony_ci bo->funcs = &funcs; 168d722e3fbSopenharmony_ci 169d722e3fbSopenharmony_ci return bo; 170d722e3fbSopenharmony_ci} 171