20094102.3+0m5
[sgx.git] / pvr / sgxtransfer.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
28 #include <stddef.h>
29
30 #include "sgxdefs.h"
31 #include "services_headers.h"
32 #include "buffer_manager.h"
33 #include "sgxinfo.h"
34 #include "sysconfig.h"
35 #include "regpaths.h"
36 #include "pdump_km.h"
37 #include "mmu.h"
38 #include "pvr_bridge.h"
39 #include "sgx_bridge_km.h"
40 #include "sgxinfokm.h"
41 #include "osfunc.h"
42 #include "pvr_debug.h"
43 #include "sgxutils.h"
44
45 IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle,
46                                             PVRSRV_TRANSFER_SGX_KICK * psKick)
47 {
48         PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo =
49             (PVRSRV_KERNEL_MEM_INFO *) psKick->hCCBMemInfo;
50         PVRSRV_SGX_COMMAND sCommand = { 0 };
51         PVR3DIF4_TRANSFERCMD_SHARED *psTransferCmd;
52         PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
53         IMG_UINT32 i;
54         PVRSRV_ERROR eError;
55
56         if (!CCB_OFFSET_IS_VALID
57             (PVR3DIF4_TRANSFERCMD_SHARED, psCCBMemInfo, psKick,
58              ui32SharedCmdCCBOffset)) {
59                 PVR_DPF((PVR_DBG_ERROR,
60                          "SGXSubmitTransferKM: Invalid CCB offset"));
61                 return PVRSRV_ERROR_INVALID_PARAMS;
62         }
63         psTransferCmd =
64             CCB_DATA_FROM_OFFSET(PVR3DIF4_TRANSFERCMD_SHARED, psCCBMemInfo,
65                                  psKick, ui32SharedCmdCCBOffset);
66
67         if (psTransferCmd->ui32NumStatusVals > SGXTQ_MAX_STATUS) {
68                 return PVRSRV_ERROR_INVALID_PARAMS;
69         }
70
71         if (psKick->ui32StatusFirstSync +
72             (psKick->ui32NumSrcSync ? (psKick->ui32NumSrcSync - 1) : 0) +
73             (psKick->ui32NumDstSync ? (psKick->ui32NumDstSync - 1) : 0) >
74             psTransferCmd->ui32NumStatusVals) {
75                 return PVRSRV_ERROR_INVALID_PARAMS;
76         }
77
78         if (psKick->hTASyncInfo != IMG_NULL) {
79                 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psKick->hTASyncInfo;
80
81                 psTransferCmd->ui32TASyncWriteOpsPendingVal =
82                     psSyncInfo->psSyncData->ui32WriteOpsPending++;
83                 psTransferCmd->ui32TASyncReadOpsPendingVal =
84                     psSyncInfo->psSyncData->ui32ReadOpsPending;
85
86                 psTransferCmd->sTASyncWriteOpsCompleteDevVAddr =
87                     psSyncInfo->sWriteOpsCompleteDevVAddr;
88                 psTransferCmd->sTASyncReadOpsCompleteDevVAddr =
89                     psSyncInfo->sReadOpsCompleteDevVAddr;
90         } else {
91                 psTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0;
92                 psTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0;
93         }
94
95         if (psKick->h3DSyncInfo != IMG_NULL) {
96                 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psKick->h3DSyncInfo;
97
98                 psTransferCmd->ui323DSyncWriteOpsPendingVal =
99                     psSyncInfo->psSyncData->ui32WriteOpsPending++;
100                 psTransferCmd->ui323DSyncReadOpsPendingVal =
101                     psSyncInfo->psSyncData->ui32ReadOpsPending;
102
103                 psTransferCmd->s3DSyncWriteOpsCompleteDevVAddr =
104                     psSyncInfo->sWriteOpsCompleteDevVAddr;
105                 psTransferCmd->s3DSyncReadOpsCompleteDevVAddr =
106                     psSyncInfo->sReadOpsCompleteDevVAddr;
107         } else {
108                 psTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0;
109                 psTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0;
110         }
111
112         psTransferCmd->ui32NumSrcSync = psKick->ui32NumSrcSync;
113         psTransferCmd->ui32NumDstSync = psKick->ui32NumDstSync;
114
115         if (psKick->ui32NumSrcSync > 0) {
116                 psSyncInfo =
117                     (PVRSRV_KERNEL_SYNC_INFO *) psKick->ahSrcSyncInfo[0];
118
119                 psTransferCmd->ui32SrcWriteOpPendingVal =
120                     psSyncInfo->psSyncData->ui32WriteOpsPending;
121                 psTransferCmd->ui32SrcReadOpPendingVal =
122                     psSyncInfo->psSyncData->ui32ReadOpsPending;
123
124                 psTransferCmd->sSrcWriteOpsCompleteDevAddr =
125                     psSyncInfo->sWriteOpsCompleteDevVAddr;
126                 psTransferCmd->sSrcReadOpsCompleteDevAddr =
127                     psSyncInfo->sReadOpsCompleteDevVAddr;
128         }
129         if (psKick->ui32NumDstSync > 0) {
130                 psSyncInfo =
131                     (PVRSRV_KERNEL_SYNC_INFO *) psKick->ahDstSyncInfo[0];
132
133                 psTransferCmd->ui32DstWriteOpPendingVal =
134                     psSyncInfo->psSyncData->ui32WriteOpsPending;
135                 psTransferCmd->ui32DstReadOpPendingVal =
136                     psSyncInfo->psSyncData->ui32ReadOpsPending;
137
138                 psTransferCmd->sDstWriteOpsCompleteDevAddr =
139                     psSyncInfo->sWriteOpsCompleteDevVAddr;
140                 psTransferCmd->sDstReadOpsCompleteDevAddr =
141                     psSyncInfo->sReadOpsCompleteDevVAddr;
142         }
143
144         if (psKick->ui32NumSrcSync > 0) {
145                 psSyncInfo =
146                     (PVRSRV_KERNEL_SYNC_INFO *) psKick->ahSrcSyncInfo[0];
147                 psSyncInfo->psSyncData->ui32ReadOpsPending++;
148
149         }
150         if (psKick->ui32NumDstSync > 0) {
151                 psSyncInfo =
152                     (PVRSRV_KERNEL_SYNC_INFO *) psKick->ahDstSyncInfo[0];
153                 psSyncInfo->psSyncData->ui32WriteOpsPending++;
154         }
155
156         if (psKick->ui32NumSrcSync > 1) {
157                 for (i = 1; i < psKick->ui32NumSrcSync; i++) {
158                         psSyncInfo =
159                             (PVRSRV_KERNEL_SYNC_INFO *) psKick->
160                             ahSrcSyncInfo[i];
161
162                         psTransferCmd->sCtlStatusInfo[psKick->
163                                                       ui32StatusFirstSync].
164                             ui32StatusValue =
165                             psSyncInfo->psSyncData->ui32ReadOpsPending++;
166
167                         psTransferCmd->sCtlStatusInfo[psKick->
168                                                       ui32StatusFirstSync].
169                             sStatusDevAddr =
170                             psSyncInfo->sReadOpsCompleteDevVAddr;
171
172                         psKick->ui32StatusFirstSync++;
173                 }
174         }
175
176         if (psKick->ui32NumDstSync > 1) {
177                 for (i = 1; i < psKick->ui32NumDstSync; i++) {
178                         psSyncInfo =
179                             (PVRSRV_KERNEL_SYNC_INFO *) psKick->
180                             ahDstSyncInfo[i];
181
182                         psTransferCmd->sCtlStatusInfo[psKick->
183                                                       ui32StatusFirstSync].
184                             ui32StatusValue =
185                             psSyncInfo->psSyncData->ui32WriteOpsPending++;
186
187                         psTransferCmd->sCtlStatusInfo[psKick->
188                                                       ui32StatusFirstSync].
189                             sStatusDevAddr =
190                             psSyncInfo->sWriteOpsCompleteDevVAddr;
191
192                         psKick->ui32StatusFirstSync++;
193                 }
194         }
195 #if defined(PDUMP)
196         if (PDumpIsCaptureFrameKM()) {
197                 PDUMPCOMMENT("Shared part of transfer command\r\n");
198                 PDUMPMEM(psTransferCmd,
199                          psCCBMemInfo,
200                          psKick->ui32CCBDumpWOff,
201                          sizeof(PVR3DIF4_TRANSFERCMD_SHARED),
202                          0, MAKEUNIQUETAG(psCCBMemInfo));
203
204                 if (psKick->ui32NumSrcSync > 0) {
205                         psSyncInfo = psKick->ahSrcSyncInfo[0];
206
207                         PDUMPCOMMENT
208                             ("Hack src surface write op in transfer cmd\r\n");
209                         PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
210                                  psCCBMemInfo,
211                                  psKick->ui32CCBDumpWOff +
212                                  offsetof(PVR3DIF4_TRANSFERCMD_SHARED,
213                                           ui32SrcWriteOpPendingVal),
214                                  sizeof(psSyncInfo->psSyncData->
215                                         ui32LastOpDumpVal), 0,
216                                  MAKEUNIQUETAG(psCCBMemInfo));
217
218                         PDUMPCOMMENT
219                             ("Hack src surface read op in transfer cmd\r\n");
220                         PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
221                                  psCCBMemInfo,
222                                  psKick->ui32CCBDumpWOff +
223                                  offsetof(PVR3DIF4_TRANSFERCMD_SHARED,
224                                           ui32SrcReadOpPendingVal),
225                                  sizeof(psSyncInfo->psSyncData->
226                                         ui32LastReadOpDumpVal), 0,
227                                  MAKEUNIQUETAG(psCCBMemInfo));
228                 }
229                 if (psKick->ui32NumDstSync > 0) {
230                         psSyncInfo = psKick->ahDstSyncInfo[0];
231
232                         PDUMPCOMMENT
233                             ("Hack dest surface write op in transfer cmd\r\n");
234                         PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
235                                  psCCBMemInfo,
236                                  psKick->ui32CCBDumpWOff +
237                                  offsetof(PVR3DIF4_TRANSFERCMD_SHARED,
238                                           ui32DstWriteOpPendingVal),
239                                  sizeof(psSyncInfo->psSyncData->
240                                         ui32LastOpDumpVal), 0,
241                                  MAKEUNIQUETAG(psCCBMemInfo));
242
243                         PDUMPCOMMENT
244                             ("Hack dest surface read op in transfer cmd\r\n");
245                         PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
246                                  psCCBMemInfo,
247                                  psKick->ui32CCBDumpWOff +
248                                  offsetof(PVR3DIF4_TRANSFERCMD_SHARED,
249                                           ui32DstReadOpPendingVal),
250                                  sizeof(psSyncInfo->psSyncData->
251                                         ui32LastReadOpDumpVal), 0,
252                                  MAKEUNIQUETAG(psCCBMemInfo));
253                 }
254
255                 if (psKick->ui32NumSrcSync > 0) {
256                         psSyncInfo =
257                             (PVRSRV_KERNEL_SYNC_INFO *) psKick->
258                             ahSrcSyncInfo[0];
259                         psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
260
261                 }
262                 if (psKick->ui32NumDstSync > 0) {
263                         psSyncInfo =
264                             (PVRSRV_KERNEL_SYNC_INFO *) psKick->
265                             ahDstSyncInfo[0];
266                         psSyncInfo->psSyncData->ui32LastOpDumpVal++;
267                 }
268         }
269 #endif
270
271         sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_TRANSFERCMD;
272         sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr;
273
274         eError =
275             SGXScheduleCCBCommandKM(hDevHandle, PVRSRV_SGX_COMMAND_EDM_KICK,
276                                     &sCommand, KERNEL_ID);
277
278
279         return eError;
280 }
281