gpu: pvr: pass proc info to sgxkick and sgxtransfer
[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 "pvr_pdump.h"
36 #include "mmu.h"
37 #include "pvr_bridge.h"
38 #include "sgx_bridge_km.h"
39 #include "sgxinfokm.h"
40 #include "osfunc.h"
41 #include "pvr_debug.h"
42 #include "sgxutils.h"
43 #include "perproc.h"
44
45 enum PVRSRV_ERROR SGXSubmitTransferKM(void *hDevHandle,
46                                         struct PVRSRV_TRANSFER_SGX_KICK *psKick,
47                                         struct PVRSRV_PER_PROCESS_DATA *proc)
48 {
49         struct PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo =
50             (struct PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo;
51         struct SGXMKIF_COMMAND sCommand = { 0 };
52         struct SGXMKIF_TRANSFERCMD_SHARED *psSharedTransferCmd;
53         struct PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
54         enum PVRSRV_ERROR eError;
55
56         if (!CCB_OFFSET_IS_VALID
57             (struct SGXMKIF_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
64         psSharedTransferCmd =
65             CCB_DATA_FROM_OFFSET(struct SGXMKIF_TRANSFERCMD_SHARED,
66                                  psCCBMemInfo, psKick, ui32SharedCmdCCBOffset);
67
68         if (psKick->hTASyncInfo != NULL) {
69                 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
70                         psKick->hTASyncInfo;
71
72                 psSharedTransferCmd->ui32TASyncWriteOpsPendingVal =
73                     psSyncInfo->psSyncData->ui32WriteOpsPending++;
74                 psSharedTransferCmd->ui32TASyncReadOpsPendingVal =
75                     psSyncInfo->psSyncData->ui32ReadOpsPending;
76
77                 psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr =
78                     psSyncInfo->sWriteOpsCompleteDevVAddr;
79                 psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr =
80                     psSyncInfo->sReadOpsCompleteDevVAddr;
81         } else {
82                 psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0;
83                 psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0;
84         }
85
86         if (psKick->h3DSyncInfo != NULL) {
87                 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
88                                                         psKick->h3DSyncInfo;
89
90                 psSharedTransferCmd->ui323DSyncWriteOpsPendingVal =
91                     psSyncInfo->psSyncData->ui32WriteOpsPending++;
92                 psSharedTransferCmd->ui323DSyncReadOpsPendingVal =
93                     psSyncInfo->psSyncData->ui32ReadOpsPending;
94
95                 psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr =
96                     psSyncInfo->sWriteOpsCompleteDevVAddr;
97                 psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr =
98                     psSyncInfo->sReadOpsCompleteDevVAddr;
99         } else {
100                 psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0;
101                 psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0;
102         }
103
104         if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) {
105                 if (psKick->ui32NumSrcSync > 0) {
106                         psSyncInfo =
107                             (struct PVRSRV_KERNEL_SYNC_INFO *)
108                                                 psKick->ahSrcSyncInfo[0];
109
110                         psSharedTransferCmd->ui32SrcWriteOpPendingVal =
111                             psSyncInfo->psSyncData->ui32WriteOpsPending;
112                         psSharedTransferCmd->ui32SrcReadOpPendingVal =
113                             psSyncInfo->psSyncData->ui32ReadOpsPending;
114
115                         psSharedTransferCmd->sSrcWriteOpsCompleteDevAddr =
116                             psSyncInfo->sWriteOpsCompleteDevVAddr;
117                         psSharedTransferCmd->sSrcReadOpsCompleteDevAddr =
118                             psSyncInfo->sReadOpsCompleteDevVAddr;
119                 }
120                 if (psKick->ui32NumDstSync > 0) {
121                         psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
122                                                 psKick->ahDstSyncInfo[0];
123                         psSharedTransferCmd->ui32DstWriteOpPendingVal =
124                             psSyncInfo->psSyncData->ui32WriteOpsPending;
125                         psSharedTransferCmd->ui32DstReadOpPendingVal =
126                             psSyncInfo->psSyncData->ui32ReadOpsPending;
127                         psSharedTransferCmd->sDstWriteOpsCompleteDevAddr =
128                             psSyncInfo->sWriteOpsCompleteDevVAddr;
129                         psSharedTransferCmd->sDstReadOpsCompleteDevAddr =
130                             psSyncInfo->sReadOpsCompleteDevVAddr;
131                 }
132
133                 if (psKick->ui32NumSrcSync > 0) {
134                         psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
135                                                 psKick->ahSrcSyncInfo[0];
136                         psSyncInfo->psSyncData->ui32ReadOpsPending++;
137
138                 }
139                 if (psKick->ui32NumDstSync > 0) {
140                         psSyncInfo =
141                             (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
142                                                             ahDstSyncInfo[0];
143                         psSyncInfo->psSyncData->ui32WriteOpsPending++;
144                 }
145         }
146
147         if (psKick->ui32NumDstSync > 1 || psKick->ui32NumSrcSync > 1) {
148                 PVR_DPF(PVR_DBG_ERROR,
149                         "Transfer command doesn't support "
150                         "more than 1 sync object per src/dst\ndst: %d, src: %d",
151                          psKick->ui32NumDstSync, psKick->ui32NumSrcSync);
152         }
153 #if defined(PDUMP)
154         if (PDumpIsCaptureFrameKM() ||
155             ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) {
156                 PDUMPCOMMENT("Shared part of transfer command\r\n");
157                 PDUMPMEM(psSharedTransferCmd,
158                          psCCBMemInfo,
159                          psKick->ui32CCBDumpWOff,
160                          sizeof(struct SGXMKIF_TRANSFERCMD_SHARED),
161                          psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo));
162
163                 if ((psKick->ui32NumSrcSync > 0) &&
164                     ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) ==
165                      0UL)) {
166                         psSyncInfo = psKick->ahSrcSyncInfo[0];
167
168                         PDUMPCOMMENT
169                             ("Hack src surface write op in transfer cmd\r\n");
170                         PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
171                                  psCCBMemInfo,
172                                  psKick->ui32CCBDumpWOff +
173                                  offsetof(struct SGXMKIF_TRANSFERCMD_SHARED,
174                                             ui32SrcWriteOpPendingVal),
175                                  sizeof(psSyncInfo->psSyncData->
176                                         ui32LastOpDumpVal),
177                                  psKick->ui32PDumpFlags,
178                                  MAKEUNIQUETAG(psCCBMemInfo));
179
180                         PDUMPCOMMENT
181                             ("Hack src surface read op in transfer cmd\r\n");
182                         PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
183                                  psCCBMemInfo,
184                                  psKick->ui32CCBDumpWOff +
185                                  offsetof(struct SGXMKIF_TRANSFERCMD_SHARED,
186                                           ui32SrcReadOpPendingVal),
187                                  sizeof(psSyncInfo->psSyncData->
188                                         ui32LastReadOpDumpVal),
189                                  psKick->ui32PDumpFlags,
190                                  MAKEUNIQUETAG(psCCBMemInfo));
191                 }
192                 if ((psKick->ui32NumDstSync > 0) &&
193                     ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) ==
194                       0UL)) {
195                         psSyncInfo = psKick->ahDstSyncInfo[0];
196
197                         PDUMPCOMMENT
198                             ("Hack dest surface write op in transfer cmd\r\n");
199                         PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
200                                  psCCBMemInfo,
201                                  psKick->ui32CCBDumpWOff +
202                                  offsetof(struct SGXMKIF_TRANSFERCMD_SHARED,
203                                           ui32DstWriteOpPendingVal),
204                                  sizeof(psSyncInfo->psSyncData->
205                                         ui32LastOpDumpVal),
206                                  psKick->ui32PDumpFlags,
207                                  MAKEUNIQUETAG(psCCBMemInfo));
208
209                         PDUMPCOMMENT
210                             ("Hack dest surface read op in transfer cmd\r\n");
211                         PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
212                                  psCCBMemInfo,
213                                  psKick->ui32CCBDumpWOff +
214                                  offsetof(struct SGXMKIF_TRANSFERCMD_SHARED,
215                                           ui32DstReadOpPendingVal),
216                                  sizeof(psSyncInfo->psSyncData->
217                                         ui32LastReadOpDumpVal),
218                                  psKick->ui32PDumpFlags,
219                                  MAKEUNIQUETAG(psCCBMemInfo));
220                 }
221
222                 if ((psKick->ui32NumSrcSync > 0) &&
223                     ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) ==
224                      0UL)) {
225                         psSyncInfo =
226                             (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
227                                                             ahSrcSyncInfo[0];
228                         psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
229
230                 }
231
232                 if ((psKick->ui32NumDstSync > 0) &&
233                     ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) ==
234                      0UL)) {
235                         psSyncInfo =
236                             (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
237                                                             ahDstSyncInfo[0];
238                         psSyncInfo->psSyncData->ui32LastOpDumpVal++;
239                 }
240         }
241 #endif
242
243         sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_TRANSFERCMD;
244         sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr;
245
246         /* To aid in determining the next power down delay */
247         sgx_mark_new_command(hDevHandle);
248
249         eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_COMMAND_EDM_KICK,
250                                     &sCommand, KERNEL_ID,
251                                     psKick->ui32PDumpFlags);
252
253 #if defined(NO_HARDWARE)
254         if (!(psKick->ui32Flags & SGXMKIF_TQFLAGS_NOSYNCUPDATE)) {
255                 u32 i;
256
257                 for (i = 0; i < psKick->ui32NumSrcSync; i++) {
258                         psSyncInfo =
259                             (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
260                                                             ahSrcSyncInfo[i];
261                         psSyncInfo->psSyncData->ui32ReadOpsComplete =
262                             psSyncInfo->psSyncData->ui32ReadOpsPending;
263                 }
264
265                 for (i = 0; i < psKick->ui32NumDstSync; i++) {
266                         psSyncInfo =
267                             (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
268                                                             ahDstSyncInfo[i];
269                         psSyncInfo->psSyncData->ui32WriteOpsComplete =
270                             psSyncInfo->psSyncData->ui32WriteOpsPending;
271
272                 }
273
274                 if (psKick->hTASyncInfo != NULL) {
275                         psSyncInfo =
276                             (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
277                                                             hTASyncInfo;
278
279                         psSyncInfo->psSyncData->ui32WriteOpsComplete =
280                             psSyncInfo->psSyncData->ui32WriteOpsPending;
281                 }
282
283                 if (psKick->h3DSyncInfo != NULL) {
284                         psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
285                                                     h3DSyncInfo;
286
287                         psSyncInfo->psSyncData->ui32WriteOpsComplete =
288                             psSyncInfo->psSyncData->ui32WriteOpsPending;
289                 }
290         }
291 #endif
292
293         return eError;
294 }
295