1/* exynos_drm_buf.c 2 * 3 * Copyright (c) 2011 Samsung Electronics Co., Ltd. 4 * Author: Inki Dae <inki.dae@samsung.com> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26#include "drmP.h" 27#include "drm.h" 28 29#include "exynos_drm_drv.h" 30#include "exynos_drm_gem.h" 31#include "exynos_drm_buf.h" 32 33static int lowlevel_buffer_allocate(struct drm_device *dev, 34 struct exynos_drm_gem_buf *buffer) 35{ 36 DRM_DEBUG_KMS("%s\n", __FILE__); 37 38 buffer->kvaddr = dma_alloc_writecombine(dev->dev, buffer->size, 39 &buffer->dma_addr, GFP_KERNEL); 40 if (!buffer->kvaddr) { 41 DRM_ERROR("failed to allocate buffer.\n"); 42 return -ENOMEM; 43 } 44 45 DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", 46 (unsigned long)buffer->kvaddr, 47 (unsigned long)buffer->dma_addr, 48 buffer->size); 49 50 return 0; 51} 52 53static void lowlevel_buffer_deallocate(struct drm_device *dev, 54 struct exynos_drm_gem_buf *buffer) 55{ 56 DRM_DEBUG_KMS("%s.\n", __FILE__); 57 58 if (buffer->dma_addr && buffer->size) 59 dma_free_writecombine(dev->dev, buffer->size, buffer->kvaddr, 60 (dma_addr_t)buffer->dma_addr); 61 else 62 DRM_DEBUG_KMS("buffer data are invalid.\n"); 63} 64 65struct exynos_drm_gem_buf *exynos_drm_buf_create(struct drm_device *dev, 66 unsigned int size) 67{ 68 struct exynos_drm_gem_buf *buffer; 69 70 DRM_DEBUG_KMS("%s.\n", __FILE__); 71 DRM_DEBUG_KMS("desired size = 0x%x\n", size); 72 73 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); 74 if (!buffer) { 75 DRM_ERROR("failed to allocate exynos_drm_gem_buf.\n"); 76 return NULL; 77 } 78 79 buffer->size = size; 80 81 /* 82 * allocate memory region with size and set the memory information 83 * to vaddr and dma_addr of a buffer object. 84 */ 85 if (lowlevel_buffer_allocate(dev, buffer) < 0) { 86 kfree(buffer); 87 return NULL; 88 } 89 90 return buffer; 91} 92 93void exynos_drm_buf_destroy(struct drm_device *dev, 94 struct exynos_drm_gem_buf *buffer) 95{ 96 DRM_DEBUG_KMS("%s.\n", __FILE__); 97 98 if (!buffer) { 99 DRM_DEBUG_KMS("buffer is null.\n"); 100 return; 101 } 102 103 lowlevel_buffer_deallocate(dev, buffer); 104 105 kfree(buffer); 106 buffer = NULL; 107} 108 109MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); 110MODULE_DESCRIPTION("Samsung SoC DRM Buffer Management Module"); 111MODULE_LICENSE("GPL"); 112