1 /* 2 * Copyright (C) Texas Instruments - http://www.ti.com/ 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "CameraHal.h" 18 #include "TICameraParameters.h" 19 20 extern "C" { 21 22 //#include <timm_osal_interfaces.h> 23 //#include <timm_osal_trace.h> 24 25 26 }; 27 28 namespace Ti { 29 namespace Camera { 30 31 ///@todo Move these constants to a common header file, preferably in tiler.h 32 #define STRIDE_8BIT (4 * 1024) 33 #define STRIDE_16BIT (4 * 1024) 34 35 #define ALLOCATION_2D 2 36 37 ///Utility Macro Declarations 38 39 /*--------------------MemoryManager Class STARTS here-----------------------------*/ 40 MemoryManager::MemoryManager() { 41 mIonFd = -1; 42 } 43 44 MemoryManager::~MemoryManager() { 45 if ( mIonFd >= 0 ) { 46 ion_close(mIonFd); 47 mIonFd = -1; 48 } 49 } 50 51 status_t MemoryManager::initialize() { 52 if ( mIonFd == -1 ) { 53 mIonFd = ion_open(); 54 if ( mIonFd < 0 ) { 55 CAMHAL_LOGE("ion_open() failed, error: %d", mIonFd); 56 mIonFd = -1; 57 return NO_INIT; 58 } 59 } 60 61 return OK; 62 } 63 64 CameraBuffer* MemoryManager::allocateBufferList(int width, int height, const char* format, int &size, int numBufs) 65 { 66 LOG_FUNCTION_NAME; 67 68 CAMHAL_ASSERT(mIonFd != -1); 69 70 ///We allocate numBufs+1 because the last entry will be marked NULL to indicate end of array, which is used when freeing 71 ///the buffers 72 const uint numArrayEntriesC = (uint)(numBufs+1); 73 74 ///Allocate a buffer array 75 CameraBuffer *buffers = new CameraBuffer [numArrayEntriesC]; 76 if(!buffers) { 77 CAMHAL_LOGEB("Allocation failed when creating buffers array of %d CameraBuffer elements", numArrayEntriesC); 78 goto error; 79 } 80 81 ///Initialize the array with zeros - this will help us while freeing the array in case of error 82 ///If a value of an array element is NULL, it means we didnt allocate it 83 memset(buffers, 0, sizeof(CameraBuffer) * numArrayEntriesC); 84 85 //2D Allocations are not supported currently 86 if(size != 0) { 87 struct ion_handle *handle; 88 int mmap_fd; 89 size_t stride; 90 91 ///1D buffers 92 for (int i = 0; i < numBufs; i++) { 93 unsigned char *data; 94 int ret = ion_alloc(mIonFd, size, 0, 1 << ION_HEAP_TYPE_CARVEOUT, 95 &handle); 96 if((ret < 0) || ((int)handle == -ENOMEM)) { 97 ret = ion_alloc_tiler(mIonFd, (size_t)size, 1, TILER_PIXEL_FMT_PAGE, 98 OMAP_ION_HEAP_TILER_MASK, &handle, &stride); 99 } 100 101 if((ret < 0) || ((int)handle == -ENOMEM)) { 102 CAMHAL_LOGEB("FAILED to allocate ion buffer of size=%d. ret=%d(0x%x)", size, ret, ret); 103 goto error; 104 } 105 106 CAMHAL_LOGDB("Before mapping, handle = %p, nSize = %d", handle, size); 107 if ((ret = ion_map(mIonFd, handle, size, PROT_READ | PROT_WRITE, MAP_SHARED, 0, 108 &data, &mmap_fd)) < 0) { 109 CAMHAL_LOGEB("Userspace mapping of ION buffers returned error %d", ret); 110 ion_free(mIonFd, handle); 111 goto error; 112 } 113 114 buffers[i].type = CAMERA_BUFFER_ION; 115 buffers[i].opaque = data; 116 buffers[i].mapped = data; 117 buffers[i].ion_handle = handle; 118 buffers[i].ion_fd = mIonFd; 119 buffers[i].fd = mmap_fd; 120 buffers[i].size = size; 121 buffers[i].format = CameraHal::getPixelFormatConstant(format); 122 123 } 124 } 125 126 LOG_FUNCTION_NAME_EXIT; 127 128 return buffers; 129 130 error: 131 132 CAMHAL_LOGE("Freeing buffers already allocated after error occurred"); 133 if(buffers) 134 freeBufferList(buffers); 135 136 if ( NULL != mErrorNotifier.get() ) 137 mErrorNotifier->errorNotify(-ENOMEM); 138 LOG_FUNCTION_NAME_EXIT; 139 140 return NULL; 141 } 142 143 CameraBuffer* MemoryManager::getBufferList(int *numBufs) { 144 LOG_FUNCTION_NAME; 145 if (numBufs) *numBufs = -1; 146 147 return NULL; 148 } 149 150 //TODO: Get needed data to map tiler buffers 151 //Return dummy data for now 152 uint32_t * MemoryManager::getOffsets() 153 { 154 LOG_FUNCTION_NAME; 155 156 LOG_FUNCTION_NAME_EXIT; 157 158 return NULL; 159 } 160 161 int MemoryManager::getFd() 162 { 163 LOG_FUNCTION_NAME; 164 165 LOG_FUNCTION_NAME_EXIT; 166 167 return -1; 168 } 169 170 int MemoryManager::freeBufferList(CameraBuffer *buffers) 171 { 172 status_t ret = NO_ERROR; 173 LOG_FUNCTION_NAME; 174 175 int i; 176 177 if(!buffers) 178 { 179 CAMHAL_LOGEA("NULL pointer passed to freebuffer"); 180 LOG_FUNCTION_NAME_EXIT; 181 return BAD_VALUE; 182 } 183 184 i = 0; 185 while(buffers[i].type == CAMERA_BUFFER_ION) 186 { 187 if(buffers[i].size) 188 { 189 munmap(buffers[i].opaque, buffers[i].size); 190 close(buffers[i].fd); 191 ion_free(mIonFd, buffers[i].ion_handle); 192 } 193 else 194 { 195 CAMHAL_LOGEA("Not a valid Memory Manager buffer"); 196 } 197 i++; 198 } 199 200 delete [] buffers; 201 202 LOG_FUNCTION_NAME_EXIT; 203 return ret; 204 } 205 206 status_t MemoryManager::setErrorHandler(ErrorNotifier *errorNotifier) 207 { 208 status_t ret = NO_ERROR; 209 210 LOG_FUNCTION_NAME; 211 212 if ( NULL == errorNotifier ) 213 { 214 CAMHAL_LOGEA("Invalid Error Notifier reference"); 215 ret = -EINVAL; 216 } 217 218 if ( NO_ERROR == ret ) 219 { 220 mErrorNotifier = errorNotifier; 221 } 222 223 LOG_FUNCTION_NAME_EXIT; 224 225 return ret; 226 } 227 228 } // namespace Camera 229 } // namespace Ti 230 231 232 /*--------------------MemoryManager Class ENDS here-----------------------------*/ 233