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 <HwcTrace.h> 17 #include <Drm.h> 18 #include <Hwcomposer.h> 19 #include <tangier/TngGrallocBufferMapper.h> 20 #include <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(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 ALOGE("%s: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 ATRACE("vaddr = %p, size = %d", vaddr, size); 66 67 if (!vaddr || !size || !offset) { 68 VTRACE("invalid parameters"); 69 return false; 70 } 71 72 arg.type = PSB_GTT_MAP_TYPE_VIRTUAL; 73 arg.page_align = gttAlign; 74 arg.vaddr = (unsigned long)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 ETRACE("gtt mapping failed"); 81 return false; 82 } 83 84 VTRACE("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 ATRACE("vaddr = %p", vaddr); 95 96 if (!vaddr) { 97 ETRACE("invalid parameter"); 98 return false; 99 } 100 101 arg.type = PSB_GTT_MAP_TYPE_VIRTUAL; 102 arg.vaddr = (unsigned long)vaddr; 103 104 Drm *drm = Hwcomposer::getInstance().getDrm(); 105 ret = drm->writeIoctl(DRM_PSB_GTT_UNMAP, &arg, sizeof(arg)); 106 if (ret == false) { 107 ETRACE("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.getCpuAddress(&mIMGGrallocModule, 126 (buffer_handle_t)mClonedHandle, 127 vaddr, 128 size); 129 if (err) { 130 ETRACE("failed to map. err = %d", err); 131 return false; 132 } 133 134 for (i = 0; i < SUB_BUFFER_MAX; i++) { 135 // skip gtt mapping for empty sub buffers 136 if (!vaddr[i] || !size[i]) 137 continue; 138 139 // map to gtt 140 ret = gttMap(vaddr[i], size[i], 0, >tOffsetInPage); 141 if (!ret) { 142 VTRACE("failed to map %d into gtt", i); 143 break; 144 } 145 146 mCpuAddress[i] = vaddr[i]; 147 mSize[i] = size[i]; 148 mGttOffsetInPage[i] = gttOffsetInPage; 149 // TODO: set kernel handle 150 mKHandle[i] = 0; 151 } 152 153 if (i == SUB_BUFFER_MAX) { 154 return true; 155 } 156 157 // error handling 158 for (i = 0; i < SUB_BUFFER_MAX; i++) { 159 if (mCpuAddress[i]) { 160 gttUnmap(mCpuAddress[i]); 161 } 162 } 163 164 err = mIMGGrallocModule.putCpuAddress(&mIMGGrallocModule, 165 (buffer_handle_t)mClonedHandle); 166 return false; 167 } 168 169 bool TngGrallocBufferMapper::unmap() 170 { 171 int i; 172 int err; 173 174 CTRACE(); 175 176 for (i = 0; i < SUB_BUFFER_MAX; i++) { 177 if (mCpuAddress[i]) 178 gttUnmap(mCpuAddress[i]); 179 180 mGttOffsetInPage[i] = 0; 181 mCpuAddress[i] = 0; 182 mSize[i] = 0; 183 } 184 185 err = mIMGGrallocModule.putCpuAddress(&mIMGGrallocModule, 186 (buffer_handle_t)mClonedHandle); 187 if (err) { 188 ETRACE("failed to unmap. err = %d", err); 189 } 190 return err; 191 } 192 193 buffer_handle_t TngGrallocBufferMapper::getKHandle(int subIndex) 194 { 195 buffer_handle_t ret = GrallocBufferMapperBase::getKHandle(subIndex); 196 if (subIndex == 0 && ret == 0) { 197 if (mapKhandle()) 198 return mKHandle[subIndex]; 199 } 200 201 return ret; 202 } 203 204 bool TngGrallocBufferMapper::mapKhandle() 205 { 206 // TODO: this is a complete hack and temporary workaround 207 // need support from DDK to map khandle 208 void *wsbmBufferObject = 0; 209 int ret = psbWsbmWrapTTMBuffer2((uint64_t)mHandle, &wsbmBufferObject); 210 if (ret != 0) { 211 ETRACE("Wrap ttm buffer failed!"); 212 return false; 213 } 214 215 ret = psbWsbmCreateFromUB(wsbmBufferObject, mWidth * mHeight, mCpuAddress[0]); 216 if (ret != 0) { 217 ETRACE("Create from UB failed!"); 218 return false; 219 } 220 221 mKHandle[0] = (buffer_handle_t)(unsigned long)psbWsbmGetKBufHandle(wsbmBufferObject); 222 psbWsbmUnReference(wsbmBufferObject); 223 return true; 224 } 225 226 buffer_handle_t TngGrallocBufferMapper::getFbHandle(int subIndex) 227 { 228 void *vaddr[SUB_BUFFER_MAX]; 229 uint32_t size[SUB_BUFFER_MAX]; 230 int err; 231 232 CTRACE(); 233 234 if (subIndex < 0 || subIndex >= SUB_BUFFER_MAX) { 235 return 0; 236 } 237 238 // get virtual address 239 err = mIMGGrallocModule.getCpuAddress(&mIMGGrallocModule, 240 (buffer_handle_t)mClonedHandle, 241 vaddr, 242 size); 243 if (err) { 244 ETRACE("failed to map. err = %d", err); 245 return 0; 246 } 247 248 return (buffer_handle_t)vaddr[subIndex]; 249 } 250 251 void TngGrallocBufferMapper::putFbHandle() 252 { 253 int err = mIMGGrallocModule.putCpuAddress(&mIMGGrallocModule, 254 (buffer_handle_t)mClonedHandle); 255 if (err) { 256 ETRACE("failed to unmap. err = %d", err); 257 } 258 return; 259 260 } 261 262 } // namespace intel 263 } // namespace android 264