fixes for bc_cat
[sgx.git] / pvr / bufferclass_example.c
1 /**********************************************************************
2  *
3  * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful but, except
10  * as otherwise stated in writing, without any warranty; without even the
11  * implied warranty of merchantability or fitness for a particular purpose.
12  * See the GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * The full GNU General Public License is included in this distribution in
19  * the file called "COPYING".
20  *
21  * Contact Information:
22  * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23  * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24  *
25  ******************************************************************************/
26
27 #include "bufferclass_example.h"
28
29 static void *gpvAnchor;
30 static IMG_BOOL(*pfnGetPVRJTable)(struct PVRSRV_BC_BUFFER2SRV_KMJTABLE *);
31
32 struct BC_EXAMPLE_DEVINFO *GetAnchorPtr(void)
33 {
34         return (struct BC_EXAMPLE_DEVINFO *)gpvAnchor;
35 }
36
37 static void SetAnchorPtr(struct BC_EXAMPLE_DEVINFO *psDevInfo)
38 {
39         gpvAnchor = (void *) psDevInfo;
40 }
41
42 static enum PVRSRV_ERROR OpenBCDevice(void **phDevice)
43 {
44         struct BC_EXAMPLE_DEVINFO *psDevInfo;
45
46         psDevInfo = GetAnchorPtr();
47
48         *phDevice = (void *) psDevInfo;
49
50         return PVRSRV_OK;
51 }
52
53 static enum PVRSRV_ERROR CloseBCDevice(void *hDevice)
54 {
55         PVR_UNREFERENCED_PARAMETER(hDevice);
56
57         return PVRSRV_OK;
58 }
59
60 static enum PVRSRV_ERROR GetBCBuffer(void *hDevice,
61                                 u32 ui32BufferNumber,
62                                 struct PVRSRV_SYNC_DATA *psSyncData,
63                                 void **phBuffer)
64 {
65         struct BC_EXAMPLE_DEVINFO *psDevInfo;
66
67         if (!hDevice || !phBuffer)
68                 return PVRSRV_ERROR_INVALID_PARAMS;
69
70         psDevInfo = (struct BC_EXAMPLE_DEVINFO *)hDevice;
71
72         if (ui32BufferNumber < psDevInfo->sBufferInfo.ui32BufferCount) {
73                 psDevInfo->psSystemBuffer[ui32BufferNumber].psSyncData =
74                     psSyncData;
75                 *phBuffer =
76                     (void *) &psDevInfo->psSystemBuffer[ui32BufferNumber];
77         } else {
78                 return PVRSRV_ERROR_INVALID_PARAMS;
79         }
80
81         return PVRSRV_OK;
82 }
83
84 static enum PVRSRV_ERROR GetBCInfo(void *hDevice, struct BUFFER_INFO *psBCInfo)
85 {
86         struct BC_EXAMPLE_DEVINFO *psDevInfo;
87
88         if (!hDevice || !psBCInfo)
89                 return PVRSRV_ERROR_INVALID_PARAMS;
90
91         psDevInfo = (struct BC_EXAMPLE_DEVINFO *)hDevice;
92
93         *psBCInfo = psDevInfo->sBufferInfo;
94
95         return PVRSRV_OK;
96 }
97
98 static enum PVRSRV_ERROR GetBCBufferAddr(void *hDevice, void *hBuffer,
99                             struct IMG_SYS_PHYADDR **ppsSysAddr,
100                             u32 *pui32ByteSize, void __iomem **ppvCpuVAddr,
101                             void **phOSMapInfo, IMG_BOOL *pbIsContiguous)
102 {
103         struct BC_EXAMPLE_BUFFER *psBuffer;
104
105         if (!hDevice || !hBuffer || !ppsSysAddr || !pui32ByteSize)
106                 return PVRSRV_ERROR_INVALID_PARAMS;
107
108         psBuffer = (struct BC_EXAMPLE_BUFFER *)hBuffer;
109
110         *ppsSysAddr = &psBuffer->sPageAlignSysAddr;
111         *ppvCpuVAddr = psBuffer->sCPUVAddr;
112
113         *pui32ByteSize = psBuffer->ui32Size;
114
115         *phOSMapInfo = NULL;
116         *pbIsContiguous = IMG_TRUE;
117
118         return PVRSRV_OK;
119 }
120
121 enum PVRSRV_ERROR BC_Example_Init(void)
122 {
123         struct BC_EXAMPLE_DEVINFO *psDevInfo;
124         struct IMG_CPU_PHYADDR sSystemBufferCPUPAddr;
125         u32 i;
126
127         psDevInfo = GetAnchorPtr();
128
129         if (psDevInfo == NULL) {
130
131                 psDevInfo = (struct BC_EXAMPLE_DEVINFO *)
132                         BCAllocKernelMem(sizeof(struct BC_EXAMPLE_DEVINFO));
133
134                 if (!psDevInfo)
135                         return PVRSRV_ERROR_OUT_OF_MEMORY;
136
137                 SetAnchorPtr((void *) psDevInfo);
138
139                 psDevInfo->ui32RefCount = 0;
140
141                 if (BCOpenPVRServices(&psDevInfo->hPVRServices) != PVRSRV_OK)
142                         return PVRSRV_ERROR_INIT_FAILURE;
143                 if (BCGetLibFuncAddr
144                     (psDevInfo->hPVRServices, "PVRGetBufferClassJTable",
145                      &pfnGetPVRJTable) != PVRSRV_OK)
146                         return PVRSRV_ERROR_INIT_FAILURE;
147
148                 if (!(*pfnGetPVRJTable) (&psDevInfo->sPVRJTable))
149                         return PVRSRV_ERROR_INIT_FAILURE;
150
151                 psDevInfo->ui32NumBuffers = 0;
152
153                 psDevInfo->psSystemBuffer =
154                     BCAllocKernelMem(sizeof(struct BC_EXAMPLE_BUFFER) *
155                                      BC_EXAMPLE_NUM_BUFFERS);
156
157                 if (!psDevInfo->psSystemBuffer)
158                         return PVRSRV_ERROR_OUT_OF_MEMORY;
159
160                 psDevInfo->sBufferInfo.pixelformat = BC_EXAMPLE_PIXELFORMAT;
161                 psDevInfo->sBufferInfo.ui32Width = BC_EXAMPLE_WIDTH;
162                 psDevInfo->sBufferInfo.ui32Height = BC_EXAMPLE_HEIGHT;
163                 psDevInfo->sBufferInfo.ui32ByteStride = BC_EXAMPLE_STRIDE;
164                 psDevInfo->sBufferInfo.ui32BufferDeviceID = BC_EXAMPLE_DEVICEID;
165                 psDevInfo->sBufferInfo.ui32Flags =
166                     PVRSRV_BC_FLAGS_YUVCSC_FULL_RANGE |
167                     PVRSRV_BC_FLAGS_YUVCSC_BT601;
168
169                 for (i = 0; i < BC_EXAMPLE_NUM_BUFFERS; i++) {
170                         u32 ui32Size =
171                             BC_EXAMPLE_HEIGHT * BC_EXAMPLE_STRIDE;
172
173                         if (psDevInfo->sBufferInfo.pixelformat ==
174                             PVRSRV_PIXEL_FORMAT_NV12)
175
176                                 ui32Size +=
177                                     ((BC_EXAMPLE_STRIDE >> 1) *
178                                      (BC_EXAMPLE_HEIGHT >> 1) << 1);
179
180                         if (BCAllocContigMemory(ui32Size,
181                                                 &psDevInfo->psSystemBuffer[i].
182                                                         hMemHandle,
183                                                 &psDevInfo->psSystemBuffer[i].
184                                                         sCPUVAddr,
185                                                 &sSystemBufferCPUPAddr) !=
186                             PVRSRV_OK)
187                                 break;
188
189                         psDevInfo->ui32NumBuffers++;
190
191                         psDevInfo->psSystemBuffer[i].ui32Size = ui32Size;
192                         psDevInfo->psSystemBuffer[i].sSysAddr =
193                             CpuPAddrToSysPAddrBC(sSystemBufferCPUPAddr);
194                         psDevInfo->psSystemBuffer[i].sPageAlignSysAddr.uiAddr =
195                             (psDevInfo->psSystemBuffer[i].sSysAddr.
196                                                      uiAddr & 0xFFFFF000);
197                         psDevInfo->psSystemBuffer[i].psSyncData = NULL;
198                 }
199
200                 psDevInfo->sBufferInfo.ui32BufferCount =
201                     psDevInfo->ui32NumBuffers;
202
203                 psDevInfo->sBCJTable.ui32TableSize =
204                     sizeof(struct PVRSRV_BC_SRV2BUFFER_KMJTABLE);
205                 psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice;
206                 psDevInfo->sBCJTable.pfnCloseBCDevice = CloseBCDevice;
207                 psDevInfo->sBCJTable.pfnGetBCBuffer = GetBCBuffer;
208                 psDevInfo->sBCJTable.pfnGetBCInfo = GetBCInfo;
209                 psDevInfo->sBCJTable.pfnGetBufferAddr = GetBCBufferAddr;
210
211                 if (psDevInfo->sPVRJTable.
212                     pfnPVRSRVRegisterBCDevice(&psDevInfo->sBCJTable,
213                                               &psDevInfo->ui32DeviceID) !=
214                     PVRSRV_OK)
215                         return PVRSRV_ERROR_DEVICE_REGISTER_FAILED;
216         }
217
218         psDevInfo->ui32RefCount++;
219
220         return PVRSRV_OK;
221 }
222
223 enum PVRSRV_ERROR BC_Example_Deinit(void)
224 {
225         struct BC_EXAMPLE_DEVINFO *psDevInfo;
226         u32 i;
227         psDevInfo = GetAnchorPtr();
228
229         if (psDevInfo == NULL)
230                 return PVRSRV_ERROR_GENERIC;
231
232         psDevInfo->ui32RefCount--;
233
234         if (psDevInfo->ui32RefCount == 0) {
235
236                 struct PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable =
237                     &psDevInfo->sPVRJTable;
238
239                 if (psJTable->
240                         pfnPVRSRVRemoveBCDevice(psDevInfo->ui32DeviceID) !=
241                     PVRSRV_OK)
242                         return PVRSRV_ERROR_GENERIC;
243
244                 if (BCClosePVRServices(psDevInfo->hPVRServices) != PVRSRV_OK) {
245                         psDevInfo->hPVRServices = NULL;
246                         return PVRSRV_ERROR_GENERIC;
247                 }
248
249                 for (i = 0; i < psDevInfo->ui32NumBuffers; i++)
250                         BCFreeContigMemory(psDevInfo->psSystemBuffer[i].
251                                                    ui32Size,
252                                            psDevInfo->psSystemBuffer[i].
253                                                    hMemHandle,
254                                            psDevInfo->psSystemBuffer[i].
255                                                    sCPUVAddr,
256                                            SysPAddrToCpuPAddrBC(psDevInfo->
257                                                                 psSystemBuffer
258                                                                 [i].sSysAddr));
259
260                 BCFreeKernelMem(psDevInfo);
261
262                 SetAnchorPtr(NULL);
263         }
264
265         return PVRSRV_OK;
266 }