• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 // Copyright (c) 2014 Intel Corporation 
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 #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 
TngGrallocBufferMapper(gralloc_module_t const & module,DataBuffer & buffer)25 TngGrallocBufferMapper::TngGrallocBufferMapper(gralloc_module_t const& module,
26                                                     DataBuffer& buffer)
27     : GrallocBufferMapperBase(buffer),
28       mGrallocModule(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 
~TngGrallocBufferMapper()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 
gttMap(void * vaddr,uint32_t size,uint32_t gttAlign,int * offset)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 
gttUnmap(void * vaddr)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 
map()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 = mGrallocModule.perform(&mGrallocModule,
126                                   GRALLOC_MODULE_GET_BUFFER_CPU_ADDRESSES_IMG,
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 = mGrallocModule.perform(&mGrallocModule,
166                                   GRALLOC_MODULE_PUT_BUFFER_CPU_ADDRESSES_IMG,
167                                   (buffer_handle_t)mClonedHandle);
168     return false;
169 }
170 
unmap()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 = mGrallocModule.perform(&mGrallocModule,
188                                   GRALLOC_MODULE_PUT_BUFFER_CPU_ADDRESSES_IMG,
189                                   (buffer_handle_t)mClonedHandle);
190     if (err) {
191         ELOGTRACE("failed to unmap. err = %d", err);
192     }
193     return err;
194 }
195 
getKHandle(int subIndex)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 
mapKhandle()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 
getFbHandle(int subIndex)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 = mGrallocModule.perform(&mGrallocModule,
243                                   GRALLOC_MODULE_GET_BUFFER_CPU_ADDRESSES_IMG,
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 
putFbHandle()255 void TngGrallocBufferMapper::putFbHandle()
256 {
257     int err = mGrallocModule.perform(&mGrallocModule,
258                                   GRALLOC_MODULE_PUT_BUFFER_CPU_ADDRESSES_IMG,
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