Home | History | Annotate | Download | only in tangier
      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(const hw_device_t& gralloc,
     26                                                DataBuffer& buffer)
     27     : GrallocBufferMapperBase(buffer),
     28       mGralloc(gralloc),
     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 = gralloc_get_buffer_cpu_addresses_img(&mGralloc,
    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, &gttOffsetInPage);
    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 = gralloc_put_buffer_cpu_addresses_img(&mGralloc,
    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 = gralloc_put_buffer_cpu_addresses_img(&mGralloc,
    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 = gralloc_get_buffer_cpu_addresses_img(&mGralloc,
    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 = gralloc_put_buffer_cpu_addresses_img(&mGralloc,
    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