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 <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, &gttOffsetInPage);
    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