1 /* Copyright (c) 2013, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 #include "mm_jpeg_ionbuf.h" 31 #include <linux/msm_ion.h> 32 33 /** buffer_allocate: 34 * 35 * Arguments: 36 * @p_buffer: ION buffer 37 * 38 * Return: 39 * buffer address 40 * 41 * Description: 42 * allocates ION buffer 43 * 44 **/ 45 void *buffer_allocate(buffer_t *p_buffer, int cached) 46 { 47 void *l_buffer = NULL; 48 49 int lrc = 0; 50 struct ion_handle_data lhandle_data; 51 52 p_buffer->alloc.len = p_buffer->size; 53 p_buffer->alloc.align = 4096; 54 p_buffer->alloc.flags = (cached) ? ION_FLAG_CACHED : 0; 55 p_buffer->alloc.heap_mask = 0x1 << ION_IOMMU_HEAP_ID; 56 57 p_buffer->ion_fd = open("/dev/ion", O_RDONLY); 58 if(p_buffer->ion_fd < 0) { 59 CDBG_ERROR("%s :Ion open failed", __func__); 60 goto ION_ALLOC_FAILED; 61 } 62 63 /* Make it page size aligned */ 64 p_buffer->alloc.len = (p_buffer->alloc.len + 4095) & (~4095); 65 lrc = ioctl(p_buffer->ion_fd, ION_IOC_ALLOC, &p_buffer->alloc); 66 if (lrc < 0) { 67 CDBG_ERROR("%s :ION allocation failed len %d", __func__, 68 p_buffer->alloc.len); 69 goto ION_ALLOC_FAILED; 70 } 71 72 p_buffer->ion_info_fd.handle = p_buffer->alloc.handle; 73 lrc = ioctl(p_buffer->ion_fd, ION_IOC_SHARE, 74 &p_buffer->ion_info_fd); 75 if (lrc < 0) { 76 CDBG_ERROR("%s :ION map failed %s", __func__, strerror(errno)); 77 goto ION_MAP_FAILED; 78 } 79 80 p_buffer->p_pmem_fd = p_buffer->ion_info_fd.fd; 81 82 l_buffer = mmap(NULL, p_buffer->alloc.len, PROT_READ | PROT_WRITE, 83 MAP_SHARED,p_buffer->p_pmem_fd, 0); 84 85 if (l_buffer == MAP_FAILED) { 86 CDBG_ERROR("%s :ION_MMAP_FAILED: %s (%d)", __func__, 87 strerror(errno), errno); 88 goto ION_MAP_FAILED; 89 } 90 91 return l_buffer; 92 93 ION_MAP_FAILED: 94 lhandle_data.handle = p_buffer->ion_info_fd.handle; 95 ioctl(p_buffer->ion_fd, ION_IOC_FREE, &lhandle_data); 96 return NULL; 97 ION_ALLOC_FAILED: 98 return NULL; 99 100 } 101 102 /** buffer_deallocate: 103 * 104 * Arguments: 105 * @p_buffer: ION buffer 106 * 107 * Return: 108 * buffer address 109 * 110 * Description: 111 * deallocates ION buffer 112 * 113 **/ 114 int buffer_deallocate(buffer_t *p_buffer) 115 { 116 int lrc = 0; 117 int lsize = (p_buffer->size + 4095) & (~4095); 118 119 struct ion_handle_data lhandle_data; 120 lrc = munmap(p_buffer->addr, lsize); 121 122 close(p_buffer->ion_info_fd.fd); 123 124 lhandle_data.handle = p_buffer->ion_info_fd.handle; 125 ioctl(p_buffer->ion_fd, ION_IOC_FREE, &lhandle_data); 126 127 close(p_buffer->ion_fd); 128 return lrc; 129 } 130 131 /** buffer_invalidate: 132 * 133 * Arguments: 134 * @p_buffer: ION buffer 135 * 136 * Return: 137 * error val 138 * 139 * Description: 140 * Invalidates the cached buffer 141 * 142 **/ 143 int buffer_invalidate(buffer_t *p_buffer) 144 { 145 int lrc = 0; 146 struct ion_flush_data cache_inv_data; 147 struct ion_custom_data custom_data; 148 149 memset(&cache_inv_data, 0, sizeof(cache_inv_data)); 150 memset(&custom_data, 0, sizeof(custom_data)); 151 cache_inv_data.vaddr = p_buffer->addr; 152 cache_inv_data.fd = p_buffer->ion_info_fd.fd; 153 cache_inv_data.handle = p_buffer->ion_info_fd.handle; 154 cache_inv_data.length = p_buffer->size; 155 custom_data.cmd = ION_IOC_INV_CACHES; 156 custom_data.arg = (unsigned long)&cache_inv_data; 157 158 lrc = ioctl(p_buffer->ion_info_fd.fd, ION_IOC_CUSTOM, &custom_data); 159 if (lrc < 0) 160 CDBG_ERROR("%s: Cache Invalidate failed: %s\n", __func__, strerror(errno)); 161 162 return lrc; 163 } 164