1 /* 2 // Copyright(c)2014 IntelCorporation 3 // 4 // LicensedundertheApacheLicense,Version2.0(the"License"); 5 // youmaynotusethisfileexceptincompliancewiththeLicense. 6 // YoumayobtainacopyoftheLicenseat 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unlessrequiredbyapplicablelaworagreedtoinwriting,software 11 // distributedundertheLicenseisdistributedonan"ASIS"BASIS, 12 // WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied. 13 // SeetheLicenseforthespecificlanguagegoverningpermissionsand 14 // limitationsundertheLicense. 15 */ 16 #include <common/utils/HwcTrace.h> 17 #include <common/base/Drm.h> 18 #include <Hwcomposer.h> 19 #include <ips/tangier/TngGrallocBufferMapper.h> 20 #include <ips/common/WsbmWrapper.h> 21 22 namespace android { 23 namespace intel { 24 25 TngGrallocBufferMapper::TngGrallocBufferMapper(IMG_gralloc_module_public_t& module, 26 DataBuffer& buffer) 27 : GrallocBufferMapperBase(buffer), 28 mIMGGrallocModule(reinterpret_cast<IMG_gralloc_module_t&>(module)), 29 mBufferObject(0) 30 { 31 CTRACE(); 32 33 const native_handle_t *h = (native_handle_t *)mHandle; 34 35 mClonedHandle = native_handle_create(h->numFds, h->numInts); 36 if (mClonedHandle == 0) { 37 ELOGTRACE("Failed to create handle, out of memory!"); 38 return; 39 } 40 for (int i = 0; i < h->numFds; i++) 41 { 42 mClonedHandle->data[i] = (h->data[i] >= 0) ? dup(h->data[i]) : -1; 43 } 44 memcpy(mClonedHandle->data + h->numFds, h->data + h->numFds, h->numInts*sizeof(int)); 45 } 46 47 TngGrallocBufferMapper::~TngGrallocBufferMapper() 48 { 49 CTRACE(); 50 51 if (mClonedHandle == 0) 52 return; 53 native_handle_close(mClonedHandle); 54 native_handle_delete(mClonedHandle); 55 } 56 57 bool TngGrallocBufferMapper::gttMap(void *vaddr, 58 uint32_t size, 59 uint32_t gttAlign, 60 int *offset) 61 { 62 struct psb_gtt_mapping_arg arg; 63 bool ret; 64 65 ALOGTRACE("vaddr = %p, size = %d", vaddr, size); 66 67 if (!vaddr || !size || !offset) { 68 VLOGTRACE("invalid parameters"); 69 return false; 70 } 71 72 arg.type = PSB_GTT_MAP_TYPE_VIRTUAL; 73 arg.page_align = gttAlign; 74 arg.vaddr = (uint32_t)vaddr; 75 arg.size = size; 76 77 Drm *drm = Hwcomposer::getInstance().getDrm(); 78 ret = drm->writeReadIoctl(DRM_PSB_GTT_MAP, &arg, sizeof(arg)); 79 if (ret == false) { 80 ELOGTRACE("gtt mapping failed"); 81 return false; 82 } 83 84 VLOGTRACE("offset = %#x", arg.offset_pages); 85 *offset = arg.offset_pages; 86 return true; 87 } 88 89 bool TngGrallocBufferMapper::gttUnmap(void *vaddr) 90 { 91 struct psb_gtt_mapping_arg arg; 92 bool ret; 93 94 ALOGTRACE("vaddr = %p", vaddr); 95 96 if (!vaddr) { 97 ELOGTRACE("invalid parameter"); 98 return false; 99 } 100 101 arg.type = PSB_GTT_MAP_TYPE_VIRTUAL; 102 arg.vaddr = (uint32_t)vaddr; 103 104 Drm *drm = Hwcomposer::getInstance().getDrm(); 105 ret = drm->writeIoctl(DRM_PSB_GTT_UNMAP, &arg, sizeof(arg)); 106 if (ret == false) { 107 ELOGTRACE("gtt unmapping failed"); 108 return false; 109 } 110 111 return true; 112 } 113 114 bool TngGrallocBufferMapper::map() 115 { 116 void *vaddr[SUB_BUFFER_MAX]; 117 uint32_t size[SUB_BUFFER_MAX]; 118 int gttOffsetInPage = 0; 119 bool ret; 120 int err; 121 int i; 122 123 CTRACE(); 124 // get virtual address 125 err = mIMGGrallocModule.GetBufferCPUAddresses( 126 (gralloc_module_t const*)&mIMGGrallocModule, 127 (buffer_handle_t)mClonedHandle, 128 vaddr, 129 size); 130 if (err) { 131 ELOGTRACE("failed to map. err = %d", err); 132 return false; 133 } 134 135 for (i = 0; i < SUB_BUFFER_MAX; i++) { 136 // skip gtt mapping for empty sub buffers 137 if (!vaddr[i] || !size[i]) 138 continue; 139 140 // map to gtt 141 ret = gttMap(vaddr[i], size[i], 0, >tOffsetInPage); 142 if (!ret) { 143 VLOGTRACE("failed to map %d into gtt", i); 144 break; 145 } 146 147 mCpuAddress[i] = vaddr[i]; 148 mSize[i] = size[i]; 149 mGttOffsetInPage[i] = gttOffsetInPage; 150 // TODO: set kernel handle 151 mKHandle[i] = 0; 152 } 153 154 if (i == SUB_BUFFER_MAX) { 155 return true; 156 } 157 158 // error handling 159 for (i = 0; i < SUB_BUFFER_MAX; i++) { 160 if (mCpuAddress[i]) { 161 gttUnmap(mCpuAddress[i]); 162 } 163 } 164 165 err = mIMGGrallocModule.PutBufferCPUAddresses( 166 (gralloc_module_t const*)&mIMGGrallocModule, 167 (buffer_handle_t)mClonedHandle); 168 return false; 169 } 170 171 bool TngGrallocBufferMapper::unmap() 172 { 173 int i; 174 int err; 175 176 CTRACE(); 177 178 for (i = 0; i < SUB_BUFFER_MAX; i++) { 179 if (mCpuAddress[i]) 180 gttUnmap(mCpuAddress[i]); 181 182 mGttOffsetInPage[i] = 0; 183 mCpuAddress[i] = 0; 184 mSize[i] = 0; 185 } 186 187 err = mIMGGrallocModule.PutBufferCPUAddresses( 188 (gralloc_module_t const*)&mIMGGrallocModule, 189 (buffer_handle_t)mClonedHandle); 190 if (err) { 191 ELOGTRACE("failed to unmap. err = %d", err); 192 } 193 return err; 194 } 195 196 uint32_t TngGrallocBufferMapper::getKHandle(int subIndex) 197 { 198 uint32_t ret = GrallocBufferMapperBase::getKHandle(subIndex); 199 if (subIndex == 0 && ret == 0) { 200 if (mapKhandle()) 201 return mKHandle[subIndex]; 202 } 203 204 return ret; 205 } 206 207 bool TngGrallocBufferMapper::mapKhandle() 208 { 209 // TODO: this is a complete hack and temporary workaround 210 // need support from DDK to map khandle 211 void *wsbmBufferObject = 0; 212 int ret = psbWsbmWrapTTMBuffer2(mHandle, &wsbmBufferObject); 213 if (ret != 0) { 214 ELOGTRACE("Wrap ttm buffer failed!"); 215 return false; 216 } 217 218 ret = psbWsbmCreateFromUB(wsbmBufferObject, mWidth * mHeight, mCpuAddress[0]); 219 if (ret != 0) { 220 ELOGTRACE("Create from UB failed!"); 221 return false; 222 } 223 224 mKHandle[0] = psbWsbmGetKBufHandle(wsbmBufferObject); 225 psbWsbmUnReference(wsbmBufferObject); 226 return true; 227 } 228 229 uint32_t TngGrallocBufferMapper::getFbHandle(int subIndex) 230 { 231 void *vaddr[SUB_BUFFER_MAX]; 232 uint32_t size[SUB_BUFFER_MAX]; 233 int err; 234 235 CTRACE(); 236 237 if (subIndex < 0 || subIndex >= SUB_BUFFER_MAX) { 238 return 0; 239 } 240 241 // get virtual address 242 err = mIMGGrallocModule.GetBufferCPUAddresses( 243 (gralloc_module_t const*)&mIMGGrallocModule, 244 (buffer_handle_t)mClonedHandle, 245 vaddr, 246 size); 247 if (err) { 248 ELOGTRACE("failed to map. err = %d", err); 249 return 0; 250 } 251 252 return (uint32_t)vaddr[subIndex]; 253 } 254 255 void TngGrallocBufferMapper::putFbHandle() 256 { 257 int err = mIMGGrallocModule.PutBufferCPUAddresses( 258 (gralloc_module_t const*)&mIMGGrallocModule, 259 (buffer_handle_t)mClonedHandle); 260 if (err) { 261 ELOGTRACE("failed to unmap. err = %d", err); 262 } 263 return; 264 265 } 266 267 } // namespace intel 268 } // namespace android 269