1 /* Copyright (c) 2013-2014, 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 <stdio.h> 32 #include <string.h> 33 #include <linux/msm_ion.h> 34 35 /** buffer_allocate: 36 * 37 * Arguments: 38 * @p_buffer: ION buffer 39 * 40 * Return: 41 * buffer address 42 * 43 * Description: 44 * allocates ION buffer 45 * 46 **/ 47 void *buffer_allocate(buffer_t *p_buffer, int cached) 48 { 49 void *l_buffer = NULL; 50 51 int lrc = 0; 52 struct ion_handle_data lhandle_data; 53 54 p_buffer->alloc.len = p_buffer->size; 55 p_buffer->alloc.align = 4096; 56 p_buffer->alloc.flags = (cached) ? ION_FLAG_CACHED : 0; 57 p_buffer->alloc.heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID; 58 59 p_buffer->ion_fd = open("/dev/ion", O_RDONLY); 60 if(p_buffer->ion_fd < 0) { 61 CDBG_ERROR("%s :Ion open failed", __func__); 62 goto ION_ALLOC_FAILED; 63 } 64 65 /* Make it page size aligned */ 66 p_buffer->alloc.len = (p_buffer->alloc.len + 4095U) & (~4095U); 67 lrc = ioctl(p_buffer->ion_fd, ION_IOC_ALLOC, &p_buffer->alloc); 68 if (lrc < 0) { 69 CDBG_ERROR("%s :ION allocation failed len %zu", __func__, 70 p_buffer->alloc.len); 71 goto ION_ALLOC_FAILED; 72 } 73 74 p_buffer->ion_info_fd.handle = p_buffer->alloc.handle; 75 lrc = ioctl(p_buffer->ion_fd, ION_IOC_SHARE, 76 &p_buffer->ion_info_fd); 77 if (lrc < 0) { 78 CDBG_ERROR("%s :ION map failed %s", __func__, strerror(errno)); 79 goto ION_MAP_FAILED; 80 } 81 82 p_buffer->p_pmem_fd = p_buffer->ion_info_fd.fd; 83 84 l_buffer = mmap(NULL, p_buffer->alloc.len, PROT_READ | PROT_WRITE, 85 MAP_SHARED,p_buffer->p_pmem_fd, 0); 86 87 if (l_buffer == MAP_FAILED) { 88 CDBG_ERROR("%s :ION_MMAP_FAILED: %s (%d)", __func__, 89 strerror(errno), errno); 90 goto ION_MAP_FAILED; 91 } 92 93 return l_buffer; 94 95 ION_MAP_FAILED: 96 lhandle_data.handle = p_buffer->ion_info_fd.handle; 97 ioctl(p_buffer->ion_fd, ION_IOC_FREE, &lhandle_data); 98 return NULL; 99 ION_ALLOC_FAILED: 100 return NULL; 101 102 } 103 104 /** buffer_deallocate: 105 * 106 * Arguments: 107 * @p_buffer: ION buffer 108 * 109 * Return: 110 * buffer address 111 * 112 * Description: 113 * deallocates ION buffer 114 * 115 **/ 116 int buffer_deallocate(buffer_t *p_buffer) 117 { 118 int lrc = 0; 119 size_t lsize = (p_buffer->size + 4095U) & (~4095U); 120 121 struct ion_handle_data lhandle_data; 122 lrc = munmap(p_buffer->addr, lsize); 123 124 close(p_buffer->ion_info_fd.fd); 125 126 lhandle_data.handle = p_buffer->ion_info_fd.handle; 127 ioctl(p_buffer->ion_fd, ION_IOC_FREE, &lhandle_data); 128 129 close(p_buffer->ion_fd); 130 return lrc; 131 } 132 133 /** buffer_invalidate: 134 * 135 * Arguments: 136 * @p_buffer: ION buffer 137 * 138 * Return: 139 * error val 140 * 141 * Description: 142 * Invalidates the cached buffer 143 * 144 **/ 145 int buffer_invalidate(buffer_t *p_buffer) 146 { 147 int lrc = 0; 148 struct ion_flush_data cache_inv_data; 149 struct ion_custom_data custom_data; 150 151 memset(&cache_inv_data, 0, sizeof(cache_inv_data)); 152 memset(&custom_data, 0, sizeof(custom_data)); 153 cache_inv_data.vaddr = p_buffer->addr; 154 cache_inv_data.fd = p_buffer->ion_info_fd.fd; 155 cache_inv_data.handle = p_buffer->ion_info_fd.handle; 156 cache_inv_data.length = (unsigned int)p_buffer->size; 157 custom_data.cmd = (unsigned int)ION_IOC_INV_CACHES; 158 custom_data.arg = (unsigned long)&cache_inv_data; 159 160 lrc = ioctl(p_buffer->ion_fd, ION_IOC_CUSTOM, &custom_data); 161 if (lrc < 0) 162 CDBG_ERROR("%s: Cache Invalidate failed: %s\n", __func__, strerror(errno)); 163 164 return lrc; 165 } 166