1 /**********************************************************************
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
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.
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.
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.
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
25 ******************************************************************************/
28 #include "services_headers.h"
30 #include "sgxinfokm.h"
32 #include "sgxapi_km.h"
35 #include "sgx_bridge_km.h"
37 #include "pvr_debug.h"
40 enum PVRSRV_ERROR SGXDoKickKM(void *hDevHandle, struct SGX_CCB_KICK *psCCBKick,
43 enum PVRSRV_ERROR eError;
44 struct PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
45 struct PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo =
46 (struct PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hCCBKernelMemInfo;
47 struct SGXMKIF_CMDTA_SHARED *psTACmd;
49 struct PVRSRV_DEVICE_NODE *psDeviceNode;
50 struct PVRSRV_SGXDEV_INFO *psDevInfo;
52 psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevHandle;
53 psDevInfo = (struct PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
55 if (psCCBKick->bKickRender)
56 ++psDevInfo->ui32KickTARenderCounter;
57 ++psDevInfo->ui32KickTACounter;
59 if (!CCB_OFFSET_IS_VALID
60 (struct SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick,
62 PVR_DPF(PVR_DBG_ERROR, "SGXDoKickKM: Invalid CCB offset");
63 return PVRSRV_ERROR_INVALID_PARAMS;
66 CCB_DATA_FROM_OFFSET(struct SGXMKIF_CMDTA_SHARED, psCCBMemInfo,
67 psCCBKick, ui32CCBOffset);
69 if (psCCBKick->hTA3DSyncInfo) {
70 struct PVRSRV_DEVICE_SYNC_OBJECT *ta3d_dep;
73 (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo;
75 ta3d_dep = &psTACmd->sTA3DDependency;
77 * Ugly hack to account for the two possible sizes of
78 * struct SGXMKIF_CMDTA_SHARED which is based on the
79 * corresponding IOCTL ABI version used.
81 if (max_3dstat_vals != SGX_MAX_3D_STATUS_VALS)
82 ta3d_dep = (struct PVRSRV_DEVICE_SYNC_OBJECT *)
83 ((u8 *)ta3d_dep - sizeof(struct CTL_STATUS) *
84 (SGX_MAX_3D_STATUS_VALS - max_3dstat_vals));
86 ta3d_dep->sWriteOpsCompleteDevVAddr =
87 psSyncInfo->sWriteOpsCompleteDevVAddr;
89 ta3d_dep->ui32WriteOpsPendingVal =
90 psSyncInfo->psSyncData->ui32WriteOpsPending;
92 if (psCCBKick->bTADependency)
93 psSyncInfo->psSyncData->ui32WriteOpsPending++;
96 if (psCCBKick->hTASyncInfo != NULL) {
97 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
98 psCCBKick->hTASyncInfo;
100 psTACmd->sTATQSyncReadOpsCompleteDevVAddr =
101 psSyncInfo->sReadOpsCompleteDevVAddr;
102 psTACmd->sTATQSyncWriteOpsCompleteDevVAddr =
103 psSyncInfo->sWriteOpsCompleteDevVAddr;
105 psTACmd->ui32TATQSyncReadOpsPendingVal =
106 psSyncInfo->psSyncData->ui32ReadOpsPending++;
107 psTACmd->ui32TATQSyncWriteOpsPendingVal =
108 psSyncInfo->psSyncData->ui32WriteOpsPending;
111 if (psCCBKick->h3DSyncInfo != NULL) {
112 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
113 psCCBKick->h3DSyncInfo;
115 psTACmd->s3DTQSyncReadOpsCompleteDevVAddr =
116 psSyncInfo->sReadOpsCompleteDevVAddr;
117 psTACmd->s3DTQSyncWriteOpsCompleteDevVAddr =
118 psSyncInfo->sWriteOpsCompleteDevVAddr;
120 psTACmd->ui323DTQSyncReadOpsPendingVal =
121 psSyncInfo->psSyncData->ui32ReadOpsPending++;
122 psTACmd->ui323DTQSyncWriteOpsPendingVal =
123 psSyncInfo->psSyncData->ui32WriteOpsPending;
126 psTACmd->ui32NumTAStatusVals = psCCBKick->ui32NumTAStatusVals;
127 if (psCCBKick->ui32NumTAStatusVals != 0) {
128 for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) {
129 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
130 psCCBKick->ahTAStatusSyncInfo[i];
132 psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr =
133 psSyncInfo->sReadOpsCompleteDevVAddr;
135 psTACmd->sCtlTAStatusInfo[i].ui32StatusValue =
136 psSyncInfo->psSyncData->ui32ReadOpsPending;
140 psTACmd->ui32Num3DStatusVals = psCCBKick->ui32Num3DStatusVals;
141 if (psCCBKick->ui32Num3DStatusVals != 0) {
142 for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) {
144 (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
145 ah3DStatusSyncInfo[i];
147 psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr =
148 psSyncInfo->sReadOpsCompleteDevVAddr;
150 psTACmd->sCtl3DStatusInfo[i].ui32StatusValue =
151 psSyncInfo->psSyncData->ui32ReadOpsPending;
155 psTACmd->ui32NumSrcSyncs = psCCBKick->ui32NumSrcSyncs;
156 for (i = 0; i < psCCBKick->ui32NumSrcSyncs; i++) {
158 (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
159 ahSrcKernelSyncInfo[i];
161 psTACmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr =
162 psSyncInfo->sWriteOpsCompleteDevVAddr;
163 psTACmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr =
164 psSyncInfo->sReadOpsCompleteDevVAddr;
166 psTACmd->asSrcSyncs[i].ui32ReadOpsPendingVal =
167 psSyncInfo->psSyncData->ui32ReadOpsPending++;
169 psTACmd->asSrcSyncs[i].ui32WriteOpsPendingVal =
170 psSyncInfo->psSyncData->ui32WriteOpsPending;
174 if (psCCBKick->bFirstKickOrResume &&
175 psCCBKick->ui32NumDstSyncObjects > 0) {
176 struct PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo =
177 (struct PVRSRV_KERNEL_MEM_INFO *)psCCBKick->
178 hKernelHWSyncListMemInfo;
179 struct SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList =
180 psHWDstSyncListMemInfo->pvLinAddrKM;
181 u32 ui32NumDstSyncs = psCCBKick->ui32NumDstSyncObjects;
183 PVR_ASSERT(((struct PVRSRV_KERNEL_MEM_INFO *)psCCBKick->
184 hKernelHWSyncListMemInfo)->ui32AllocSize >=
185 (sizeof(struct SGXMKIF_HWDEVICE_SYNC_LIST) +
186 (sizeof(struct PVRSRV_DEVICE_SYNC_OBJECT) *
189 psHWDeviceSyncList->ui32NumSyncObjects = ui32NumDstSyncs;
191 if (PDumpIsCaptureFrameKM()) {
192 PDUMPCOMMENT("HWDeviceSyncList for TACmd\r\n");
194 psHWDstSyncListMemInfo, 0,
195 sizeof(struct SGXMKIF_HWDEVICE_SYNC_LIST),
196 0, MAKEUNIQUETAG(psHWDstSyncListMemInfo));
199 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
203 psHWDeviceSyncList->asSyncData[i].
204 sWriteOpsCompleteDevVAddr =
205 psSyncInfo->sWriteOpsCompleteDevVAddr;
207 psHWDeviceSyncList->asSyncData[i].
208 sReadOpsCompleteDevVAddr =
209 psSyncInfo->sReadOpsCompleteDevVAddr;
211 psHWDeviceSyncList->asSyncData[i].
212 ui32ReadOpsPendingVal =
213 psSyncInfo->psSyncData->ui32ReadOpsPending;
215 psHWDeviceSyncList->asSyncData[i].
216 ui32WriteOpsPendingVal =
217 psSyncInfo->psSyncData->
218 ui32WriteOpsPending++;
221 if (PDumpIsCaptureFrameKM()) {
222 u32 ui32ModifiedValue;
223 u32 ui32SyncOffset = offsetof(
224 struct SGXMKIF_HWDEVICE_SYNC_LIST,
227 struct PVRSRV_DEVICE_SYNC_OBJECT));
228 u32 ui32WOpsOffset = ui32SyncOffset +
230 struct PVRSRV_DEVICE_SYNC_OBJECT,
231 ui32WriteOpsPendingVal);
232 u32 ui32ROpsOffset = ui32SyncOffset +
234 struct PVRSRV_DEVICE_SYNC_OBJECT,
235 ui32ReadOpsPendingVal);
237 PDUMPCOMMENT("HWDeviceSyncObject for RT: "
240 PDUMPMEM(NULL, psHWDstSyncListMemInfo,
241 ui32SyncOffset, sizeof(
242 struct PVRSRV_DEVICE_SYNC_OBJECT),
244 psHWDstSyncListMemInfo));
246 if ((psSyncInfo->psSyncData->
247 ui32LastOpDumpVal == 0) &&
248 (psSyncInfo->psSyncData->
249 ui32LastReadOpDumpVal == 0)) {
251 PDUMPCOMMENT("Init RT ROpsComplete\r\n",
253 PDUMPMEM(&psSyncInfo->psSyncData->
254 ui32LastReadOpDumpVal,
255 psSyncInfo->psSyncDataMemInfoKM,
258 ui32ReadOpsComplete),
259 sizeof(psSyncInfo->psSyncData->
260 ui32ReadOpsComplete),
262 MAKEUNIQUETAG(psSyncInfo->
263 psSyncDataMemInfoKM));
265 PDUMPCOMMENT("Init RT WOpsComplete\r\n");
266 PDUMPMEM(&psSyncInfo->psSyncData->
268 psSyncInfo->psSyncDataMemInfoKM,
269 offsetof(struct PVRSRV_SYNC_DATA,
270 ui32WriteOpsComplete),
271 sizeof(psSyncInfo->psSyncData->
272 ui32WriteOpsComplete),
273 0, MAKEUNIQUETAG(psSyncInfo->
274 psSyncDataMemInfoKM));
277 psSyncInfo->psSyncData->ui32LastOpDumpVal++;
279 ui32ModifiedValue = psSyncInfo->psSyncData->
280 ui32LastOpDumpVal - 1;
282 PDUMPCOMMENT("Modify RT %d WOpPendingVal "
283 "in HWDevSyncList\r\n", i);
285 PDUMPMEM(&ui32ModifiedValue,
286 psHWDstSyncListMemInfo, ui32WOpsOffset,
288 MAKEUNIQUETAG(psHWDstSyncListMemInfo));
290 PDUMPCOMMENT("Modify RT %d ROpsPendingVal "
291 "in HWDevSyncList\r\n", i);
293 PDUMPMEM(&psSyncInfo->psSyncData->
294 ui32LastReadOpDumpVal,
295 psHWDstSyncListMemInfo,
296 ui32ROpsOffset, sizeof(u32), 0,
297 MAKEUNIQUETAG(psHWDstSyncListMemInfo));
301 psHWDeviceSyncList->asSyncData[i].
302 sWriteOpsCompleteDevVAddr.uiAddr = 0;
303 psHWDeviceSyncList->asSyncData[i].
304 sReadOpsCompleteDevVAddr.uiAddr = 0;
306 psHWDeviceSyncList->asSyncData[i].
307 ui32ReadOpsPendingVal = 0;
308 psHWDeviceSyncList->asSyncData[i].
309 ui32WriteOpsPendingVal = 0;
313 if (PDumpIsCaptureFrameKM()) {
314 PDUMPCOMMENT("Shared part of TA command\r\n");
316 PDUMPMEM(psTACmd, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff,
317 sizeof(struct SGXMKIF_CMDTA_SHARED), 0,
318 MAKEUNIQUETAG(psCCBMemInfo));
320 for (i = 0; i < psCCBKick->ui32NumSrcSyncs; i++) {
321 u32 ui32ModifiedValue;
323 (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
324 ahSrcKernelSyncInfo[i];
326 if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
327 (psSyncInfo->psSyncData->ui32LastReadOpDumpVal ==
329 PDUMPCOMMENT("Init RT ROpsComplete\r\n", i);
330 PDUMPMEM(&psSyncInfo->psSyncData->
331 ui32LastReadOpDumpVal,
332 psSyncInfo->psSyncDataMemInfoKM,
333 offsetof(struct PVRSRV_SYNC_DATA,
334 ui32ReadOpsComplete),
335 sizeof(psSyncInfo->psSyncData->
336 ui32ReadOpsComplete), 0,
337 MAKEUNIQUETAG(psSyncInfo->
338 psSyncDataMemInfoKM));
339 PDUMPCOMMENT("Init RT WOpsComplete\r\n");
340 PDUMPMEM(&psSyncInfo->psSyncData->
342 psSyncInfo->psSyncDataMemInfoKM,
343 offsetof(struct PVRSRV_SYNC_DATA,
344 ui32WriteOpsComplete),
345 sizeof(psSyncInfo->psSyncData->
346 ui32WriteOpsComplete), 0,
347 MAKEUNIQUETAG(psSyncInfo->
348 psSyncDataMemInfoKM));
351 psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
354 psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1;
356 PDUMPCOMMENT("Modify SrcSync %d ROpsPendingVal\r\n", i);
358 PDUMPMEM(&ui32ModifiedValue,
360 psCCBKick->ui32CCBDumpWOff +
361 offsetof(struct SGXMKIF_CMDTA_SHARED,
364 sizeof(struct PVRSRV_DEVICE_SYNC_OBJECT)) +
365 offsetof(struct PVRSRV_DEVICE_SYNC_OBJECT,
366 ui32ReadOpsPendingVal), sizeof(u32),
367 0, MAKEUNIQUETAG(psCCBMemInfo));
369 PDUMPCOMMENT("Modify SrcSync %d WOpPendingVal\r\n", i);
371 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
373 psCCBKick->ui32CCBDumpWOff +
374 offsetof(struct SGXMKIF_CMDTA_SHARED,
377 sizeof(struct PVRSRV_DEVICE_SYNC_OBJECT)) +
378 offsetof(struct PVRSRV_DEVICE_SYNC_OBJECT,
379 ui32WriteOpsPendingVal), sizeof(u32),
380 0, MAKEUNIQUETAG(psCCBMemInfo));
384 for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) {
386 (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
387 ahTAStatusSyncInfo[i];
388 PDUMPCOMMENT("Modify TA status value in TA cmd\r\n");
389 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
391 psCCBKick->ui32CCBDumpWOff +
392 offsetof(struct SGXMKIF_CMDTA_SHARED,
393 sCtlTAStatusInfo[i].ui32StatusValue),
394 sizeof(u32), 0, MAKEUNIQUETAG(psCCBMemInfo));
397 for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) {
398 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
399 psCCBKick->ah3DStatusSyncInfo[i];
401 PDUMPCOMMENT("Modify 3D status value in TA cmd\r\n");
403 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
405 psCCBKick->ui32CCBDumpWOff +
406 offsetof(struct SGXMKIF_CMDTA_SHARED,
407 sCtl3DStatusInfo[i].ui32StatusValue),
408 sizeof(u32), 0, MAKEUNIQUETAG(psCCBMemInfo));
413 eError = SGXScheduleCCBCommandKM(hDevHandle, psCCBKick->eCommand,
414 &psCCBKick->sCommand, KERNEL_ID, 0);
415 if (eError == PVRSRV_ERROR_RETRY) {
416 if (psCCBKick->bFirstKickOrResume &&
417 psCCBKick->ui32NumDstSyncObjects > 0) {
418 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
419 psCCBKick->sDstSyncHandle;
421 psSyncInfo->psSyncData->ui32WriteOpsPending--;
423 if (PDumpIsCaptureFrameKM())
424 psSyncInfo->psSyncData->
430 for (i = 0; i < psCCBKick->ui32NumSrcSyncs; i++) {
432 (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
433 ahSrcKernelSyncInfo[i];
434 psSyncInfo->psSyncData->ui32ReadOpsPending--;
438 } else if (PVRSRV_OK != eError) {
439 PVR_DPF(PVR_DBG_ERROR,
440 "SGXDoKickKM: SGXScheduleCCBCommandKM failed.");
444 #if defined(NO_HARDWARE)
446 if (psCCBKick->hTA3DSyncInfo) {
448 (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo;
450 if (psCCBKick->bTADependency) {
451 psSyncInfo->psSyncData->ui32WriteOpsComplete =
452 psSyncInfo->psSyncData->ui32WriteOpsPending;
456 if (psCCBKick->hTASyncInfo != NULL) {
458 (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo;
460 psSyncInfo->psSyncData->ui32ReadOpsComplete =
461 psSyncInfo->psSyncData->ui32ReadOpsPending;
464 if (psCCBKick->h3DSyncInfo != NULL) {
466 (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo;
468 psSyncInfo->psSyncData->ui32ReadOpsComplete =
469 psSyncInfo->psSyncData->ui32ReadOpsPending;
472 for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) {
474 (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
475 ahTAStatusSyncInfo[i];
476 psSyncInfo->psSyncData->ui32ReadOpsComplete =
477 psTACmd->sCtlTAStatusInfo[i].ui32StatusValue;
480 for (i = 0; i < psCCBKick->ui32NumSrcSyncs; i++) {
482 (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
483 ahSrcKernelSyncInfo[i];
485 psSyncInfo->psSyncData->ui32ReadOpsComplete =
486 psSyncInfo->psSyncData->ui32ReadOpsPending;
490 if (psCCBKick->bTerminateOrAbort) {
491 if (psCCBKick->ui32NumDstSyncObjects > 0) {
492 struct PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo =
493 (struct PVRSRV_KERNEL_MEM_INFO *)psCCBKick->
494 hKernelHWSyncListMemInfo;
495 struct SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList =
496 psHWDstSyncListMemInfo->pvLinAddrKM;
499 (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
502 psSyncInfo->psSyncData->ui32WriteOpsComplete =
503 psHWDeviceSyncList->asSyncData[0].
504 ui32WriteOpsPendingVal + 1;
507 for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) {
509 (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
510 ah3DStatusSyncInfo[i];
511 psSyncInfo->psSyncData->ui32ReadOpsComplete =
512 psTACmd->sCtl3DStatusInfo[i].ui32StatusValue;