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 ******************************************************************************/
27 #if defined(TRANSFER_QUEUE)
32 #include "services_headers.h"
33 #include "buffer_manager.h"
35 #include "sysconfig.h"
39 #include "pvr_bridge.h"
40 #include "sgx_bridge_km.h"
41 #include "sgxinfokm.h"
43 #include "pvr_debug.h"
46 IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle,
47 PVRSRV_TRANSFER_SGX_KICK * psKick)
49 PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo =
50 (PVRSRV_KERNEL_MEM_INFO *) psKick->hCCBMemInfo;
51 PVRSRV_SGX_COMMAND sCommand = { 0 };
52 PVR3DIF4_TRANSFERCMD_SHARED *psTransferCmd;
53 PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
57 if (!CCB_OFFSET_IS_VALID
58 (PVR3DIF4_TRANSFERCMD_SHARED, psCCBMemInfo, psKick,
59 ui32SharedCmdCCBOffset)) {
60 PVR_DPF((PVR_DBG_ERROR,
61 "SGXSubmitTransferKM: Invalid CCB offset"));
62 return PVRSRV_ERROR_INVALID_PARAMS;
65 CCB_DATA_FROM_OFFSET(PVR3DIF4_TRANSFERCMD_SHARED, psCCBMemInfo,
66 psKick, ui32SharedCmdCCBOffset);
68 if (psTransferCmd->ui32NumStatusVals > SGXTQ_MAX_STATUS) {
69 return PVRSRV_ERROR_INVALID_PARAMS;
72 if (psKick->ui32StatusFirstSync +
73 (psKick->ui32NumSrcSync ? (psKick->ui32NumSrcSync - 1) : 0) +
74 (psKick->ui32NumDstSync ? (psKick->ui32NumDstSync - 1) : 0) >
75 psTransferCmd->ui32NumStatusVals) {
76 return PVRSRV_ERROR_INVALID_PARAMS;
79 if (psKick->hTASyncInfo != IMG_NULL) {
80 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psKick->hTASyncInfo;
82 psTransferCmd->ui32TASyncWriteOpsPendingVal =
83 psSyncInfo->psSyncData->ui32WriteOpsPending++;
84 psTransferCmd->ui32TASyncReadOpsPendingVal =
85 psSyncInfo->psSyncData->ui32ReadOpsPending;
87 psTransferCmd->sTASyncWriteOpsCompleteDevVAddr =
88 psSyncInfo->sWriteOpsCompleteDevVAddr;
89 psTransferCmd->sTASyncReadOpsCompleteDevVAddr =
90 psSyncInfo->sReadOpsCompleteDevVAddr;
92 psTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0;
93 psTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0;
96 if (psKick->h3DSyncInfo != IMG_NULL) {
97 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psKick->h3DSyncInfo;
99 psTransferCmd->ui323DSyncWriteOpsPendingVal =
100 psSyncInfo->psSyncData->ui32WriteOpsPending++;
101 psTransferCmd->ui323DSyncReadOpsPendingVal =
102 psSyncInfo->psSyncData->ui32ReadOpsPending;
104 psTransferCmd->s3DSyncWriteOpsCompleteDevVAddr =
105 psSyncInfo->sWriteOpsCompleteDevVAddr;
106 psTransferCmd->s3DSyncReadOpsCompleteDevVAddr =
107 psSyncInfo->sReadOpsCompleteDevVAddr;
109 psTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0;
110 psTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0;
113 psTransferCmd->ui32NumSrcSync = psKick->ui32NumSrcSync;
114 psTransferCmd->ui32NumDstSync = psKick->ui32NumDstSync;
116 if (psKick->ui32NumSrcSync > 0) {
118 (PVRSRV_KERNEL_SYNC_INFO *) psKick->ahSrcSyncInfo[0];
120 psTransferCmd->ui32SrcWriteOpPendingVal =
121 psSyncInfo->psSyncData->ui32WriteOpsPending;
122 psTransferCmd->ui32SrcReadOpPendingVal =
123 psSyncInfo->psSyncData->ui32ReadOpsPending;
125 psTransferCmd->sSrcWriteOpsCompleteDevAddr =
126 psSyncInfo->sWriteOpsCompleteDevVAddr;
127 psTransferCmd->sSrcReadOpsCompleteDevAddr =
128 psSyncInfo->sReadOpsCompleteDevVAddr;
130 if (psKick->ui32NumDstSync > 0) {
132 (PVRSRV_KERNEL_SYNC_INFO *) psKick->ahDstSyncInfo[0];
134 psTransferCmd->ui32DstWriteOpPendingVal =
135 psSyncInfo->psSyncData->ui32WriteOpsPending;
136 psTransferCmd->ui32DstReadOpPendingVal =
137 psSyncInfo->psSyncData->ui32ReadOpsPending;
139 psTransferCmd->sDstWriteOpsCompleteDevAddr =
140 psSyncInfo->sWriteOpsCompleteDevVAddr;
141 psTransferCmd->sDstReadOpsCompleteDevAddr =
142 psSyncInfo->sReadOpsCompleteDevVAddr;
145 if (psKick->ui32NumSrcSync > 0) {
147 (PVRSRV_KERNEL_SYNC_INFO *) psKick->ahSrcSyncInfo[0];
148 psSyncInfo->psSyncData->ui32ReadOpsPending++;
151 if (psKick->ui32NumDstSync > 0) {
153 (PVRSRV_KERNEL_SYNC_INFO *) psKick->ahDstSyncInfo[0];
154 psSyncInfo->psSyncData->ui32WriteOpsPending++;
157 if (psKick->ui32NumSrcSync > 1) {
158 for (i = 1; i < psKick->ui32NumSrcSync; i++) {
160 (PVRSRV_KERNEL_SYNC_INFO *) psKick->
163 psTransferCmd->sCtlStatusInfo[psKick->
164 ui32StatusFirstSync].
166 psSyncInfo->psSyncData->ui32ReadOpsPending++;
168 psTransferCmd->sCtlStatusInfo[psKick->
169 ui32StatusFirstSync].
171 psSyncInfo->sReadOpsCompleteDevVAddr;
173 psKick->ui32StatusFirstSync++;
177 if (psKick->ui32NumDstSync > 1) {
178 for (i = 1; i < psKick->ui32NumDstSync; i++) {
180 (PVRSRV_KERNEL_SYNC_INFO *) psKick->
183 psTransferCmd->sCtlStatusInfo[psKick->
184 ui32StatusFirstSync].
186 psSyncInfo->psSyncData->ui32WriteOpsPending++;
188 psTransferCmd->sCtlStatusInfo[psKick->
189 ui32StatusFirstSync].
191 psSyncInfo->sWriteOpsCompleteDevVAddr;
193 psKick->ui32StatusFirstSync++;
197 if (PDumpIsCaptureFrameKM()) {
198 PDUMPCOMMENT("Shared part of transfer command\r\n");
199 PDUMPMEM(psTransferCmd,
201 psKick->ui32CCBDumpWOff,
202 sizeof(PVR3DIF4_TRANSFERCMD_SHARED),
203 0, MAKEUNIQUETAG(psCCBMemInfo));
205 if (psKick->ui32NumSrcSync > 0) {
206 psSyncInfo = psKick->ahSrcSyncInfo[0];
209 ("Hack src surface write op in transfer cmd\r\n");
210 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
212 psKick->ui32CCBDumpWOff +
213 offsetof(PVR3DIF4_TRANSFERCMD_SHARED,
214 ui32SrcWriteOpPendingVal),
215 sizeof(psSyncInfo->psSyncData->
216 ui32LastOpDumpVal), 0,
217 MAKEUNIQUETAG(psCCBMemInfo));
220 ("Hack src surface read op in transfer cmd\r\n");
221 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
223 psKick->ui32CCBDumpWOff +
224 offsetof(PVR3DIF4_TRANSFERCMD_SHARED,
225 ui32SrcReadOpPendingVal),
226 sizeof(psSyncInfo->psSyncData->
227 ui32LastReadOpDumpVal), 0,
228 MAKEUNIQUETAG(psCCBMemInfo));
230 if (psKick->ui32NumDstSync > 0) {
231 psSyncInfo = psKick->ahDstSyncInfo[0];
234 ("Hack dest surface write op in transfer cmd\r\n");
235 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
237 psKick->ui32CCBDumpWOff +
238 offsetof(PVR3DIF4_TRANSFERCMD_SHARED,
239 ui32DstWriteOpPendingVal),
240 sizeof(psSyncInfo->psSyncData->
241 ui32LastOpDumpVal), 0,
242 MAKEUNIQUETAG(psCCBMemInfo));
245 ("Hack dest surface read op in transfer cmd\r\n");
246 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
248 psKick->ui32CCBDumpWOff +
249 offsetof(PVR3DIF4_TRANSFERCMD_SHARED,
250 ui32DstReadOpPendingVal),
251 sizeof(psSyncInfo->psSyncData->
252 ui32LastReadOpDumpVal), 0,
253 MAKEUNIQUETAG(psCCBMemInfo));
256 if (psKick->ui32NumSrcSync > 0) {
258 (PVRSRV_KERNEL_SYNC_INFO *) psKick->
260 psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
263 if (psKick->ui32NumDstSync > 0) {
265 (PVRSRV_KERNEL_SYNC_INFO *) psKick->
267 psSyncInfo->psSyncData->ui32LastOpDumpVal++;
272 sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_TRANSFERCMD;
273 sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr;
276 SGXScheduleCCBCommandKM(hDevHandle, PVRSRV_SGX_COMMAND_EDM_KICK,
277 &sCommand, KERNEL_ID);
279 #if defined(NO_HARDWARE)
281 for (i = 0; i < psKick->ui32NumSrcSync; i++) {
283 (PVRSRV_KERNEL_SYNC_INFO *) psKick->ahSrcSyncInfo[i];
284 psSyncInfo->psSyncData->ui32ReadOpsComplete =
285 psSyncInfo->psSyncData->ui32ReadOpsPending;
288 for (i = 0; i < psKick->ui32NumDstSync; i++) {
290 (PVRSRV_KERNEL_SYNC_INFO *) psKick->ahDstSyncInfo[i];
291 psSyncInfo->psSyncData->ui32WriteOpsComplete =
292 psSyncInfo->psSyncData->ui32WriteOpsPending;
296 if (psKick->hTASyncInfo != IMG_NULL) {
297 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psKick->hTASyncInfo;
299 psSyncInfo->psSyncData->ui32WriteOpsComplete =
300 psSyncInfo->psSyncData->ui32WriteOpsPending;
303 if (psKick->h3DSyncInfo != IMG_NULL) {
304 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psKick->h3DSyncInfo;
306 psSyncInfo->psSyncData->ui32WriteOpsComplete =
307 psSyncInfo->psSyncData->ui32WriteOpsPending;
314 #if defined(SGX_FEATURE_2D_HARDWARE)
315 IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle,
316 PVRSRV_2D_SGX_KICK * psKick)
318 PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo =
319 (PVRSRV_KERNEL_MEM_INFO *) psKick->hCCBMemInfo;
320 PVRSRV_SGX_COMMAND sCommand = { 0 };
321 PVR3DIF4_2DCMD_SHARED *ps2DCmd;
322 PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
326 if (!CCB_OFFSET_IS_VALID
327 (PVR3DIF4_2DCMD_SHARED, psCCBMemInfo, psKick,
328 ui32SharedCmdCCBOffset)) {
329 PVR_DPF((PVR_DBG_ERROR, "SGXSubmit2DKM: Invalid CCB offset"));
330 return PVRSRV_ERROR_INVALID_PARAMS;
333 CCB_DATA_FROM_OFFSET(PVR3DIF4_2DCMD_SHARED, psCCBMemInfo, psKick,
334 ui32SharedCmdCCBOffset);
336 OSMemSet(ps2DCmd, 0, sizeof(*ps2DCmd));
338 if (psKick->hTASyncInfo != IMG_NULL) {
339 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psKick->hTASyncInfo;
341 ps2DCmd->sTASyncData.ui32WriteOpPendingVal =
342 psSyncInfo->psSyncData->ui32WriteOpsPending++;
343 ps2DCmd->sTASyncData.ui32ReadOpPendingVal =
344 psSyncInfo->psSyncData->ui32ReadOpsPending;
346 ps2DCmd->sTASyncData.sWriteOpsCompleteDevVAddr =
347 psSyncInfo->sWriteOpsCompleteDevVAddr;
348 ps2DCmd->sTASyncData.sReadOpsCompleteDevVAddr =
349 psSyncInfo->sReadOpsCompleteDevVAddr;
352 if (psKick->h3DSyncInfo != IMG_NULL) {
353 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psKick->h3DSyncInfo;
355 ps2DCmd->s3DSyncData.ui32WriteOpPendingVal =
356 psSyncInfo->psSyncData->ui32WriteOpsPending++;
357 ps2DCmd->s3DSyncData.ui32ReadOpPendingVal =
358 psSyncInfo->psSyncData->ui32ReadOpsPending;
360 ps2DCmd->s3DSyncData.sWriteOpsCompleteDevVAddr =
361 psSyncInfo->sWriteOpsCompleteDevVAddr;
362 ps2DCmd->s3DSyncData.sReadOpsCompleteDevVAddr =
363 psSyncInfo->sReadOpsCompleteDevVAddr;
366 ps2DCmd->ui32NumSrcSync = psKick->ui32NumSrcSync;
367 for (i = 0; i < psKick->ui32NumSrcSync; i++) {
368 psSyncInfo = psKick->ahSrcSyncInfo[i];
370 ps2DCmd->sSrcSyncData[i].ui32WriteOpPendingVal =
371 psSyncInfo->psSyncData->ui32WriteOpsPending;
372 ps2DCmd->sSrcSyncData[i].ui32ReadOpPendingVal =
373 psSyncInfo->psSyncData->ui32ReadOpsPending;
375 ps2DCmd->sSrcSyncData[i].sWriteOpsCompleteDevVAddr =
376 psSyncInfo->sWriteOpsCompleteDevVAddr;
377 ps2DCmd->sSrcSyncData[i].sReadOpsCompleteDevVAddr =
378 psSyncInfo->sReadOpsCompleteDevVAddr;
381 if (psKick->hDstSyncInfo != IMG_NULL) {
382 psSyncInfo = psKick->hDstSyncInfo;
384 ps2DCmd->sDstSyncData.ui32WriteOpPendingVal =
385 psSyncInfo->psSyncData->ui32WriteOpsPending;
386 ps2DCmd->sDstSyncData.ui32ReadOpPendingVal =
387 psSyncInfo->psSyncData->ui32ReadOpsPending;
389 ps2DCmd->sDstSyncData.sWriteOpsCompleteDevVAddr =
390 psSyncInfo->sWriteOpsCompleteDevVAddr;
391 ps2DCmd->sDstSyncData.sReadOpsCompleteDevVAddr =
392 psSyncInfo->sReadOpsCompleteDevVAddr;
395 for (i = 0; i < psKick->ui32NumSrcSync; i++) {
396 psSyncInfo = psKick->ahSrcSyncInfo[i];
397 psSyncInfo->psSyncData->ui32ReadOpsPending++;
400 if (psKick->hDstSyncInfo != IMG_NULL) {
401 psSyncInfo = psKick->hDstSyncInfo;
402 psSyncInfo->psSyncData->ui32WriteOpsPending++;
405 if (PDumpIsCaptureFrameKM()) {
407 PDUMPCOMMENT("Shared part of 2D command\r\n");
410 psKick->ui32CCBDumpWOff,
411 sizeof(PVR3DIF4_2DCMD_SHARED),
412 0, MAKEUNIQUETAG(psCCBMemInfo));
414 for (i = 0; i < psKick->ui32NumSrcSync; i++) {
415 psSyncInfo = psKick->ahSrcSyncInfo[i];
417 PDUMPCOMMENT("Hack src surface write op in 2D cmd\r\n");
418 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
420 psKick->ui32CCBDumpWOff +
421 offsetof(PVR3DIF4_2DCMD_SHARED,
423 ui32WriteOpPendingVal),
424 sizeof(psSyncInfo->psSyncData->
425 ui32LastOpDumpVal), 0,
426 MAKEUNIQUETAG(psCCBMemInfo));
428 PDUMPCOMMENT("Hack src surface read op in 2D cmd\r\n");
429 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
431 psKick->ui32CCBDumpWOff +
432 offsetof(PVR3DIF4_2DCMD_SHARED,
433 sSrcSyncData[i].ui32ReadOpPendingVal),
434 sizeof(psSyncInfo->psSyncData->
435 ui32LastReadOpDumpVal), 0,
436 MAKEUNIQUETAG(psCCBMemInfo));
439 if (psKick->hDstSyncInfo != IMG_NULL) {
440 psSyncInfo = psKick->hDstSyncInfo;
443 ("Hack dest surface write op in 2D cmd\r\n");
444 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
446 psKick->ui32CCBDumpWOff +
447 offsetof(PVR3DIF4_2DCMD_SHARED,
448 sDstSyncData.ui32WriteOpPendingVal),
449 sizeof(psSyncInfo->psSyncData->
450 ui32LastOpDumpVal), 0,
451 MAKEUNIQUETAG(psCCBMemInfo));
453 PDUMPCOMMENT("Hack dest surface read op in 2D cmd\r\n");
454 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
456 psKick->ui32CCBDumpWOff +
457 offsetof(PVR3DIF4_2DCMD_SHARED,
458 sDstSyncData.ui32ReadOpPendingVal),
459 sizeof(psSyncInfo->psSyncData->
460 ui32LastReadOpDumpVal), 0,
461 MAKEUNIQUETAG(psCCBMemInfo));
464 for (i = 0; i < psKick->ui32NumSrcSync; i++) {
465 psSyncInfo = psKick->ahSrcSyncInfo[i];
466 psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
469 if (psKick->hDstSyncInfo != IMG_NULL) {
470 psSyncInfo = psKick->hDstSyncInfo;
471 psSyncInfo->psSyncData->ui32LastOpDumpVal++;
476 sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_2DCMD;
477 sCommand.ui32Data[1] = psKick->sHW2DContextDevVAddr.uiAddr;
480 SGXScheduleCCBCommandKM(hDevHandle, PVRSRV_SGX_COMMAND_EDM_KICK,
481 &sCommand, KERNEL_ID);
483 #if defined(NO_HARDWARE)
485 for (i = 0; i < psKick->ui32NumSrcSync; i++) {
487 (PVRSRV_KERNEL_SYNC_INFO *) psKick->ahSrcSyncInfo[i];
488 psSyncInfo->psSyncData->ui32ReadOpsComplete =
489 psSyncInfo->psSyncData->ui32ReadOpsPending;
492 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psKick->hDstSyncInfo;
493 psSyncInfo->psSyncData->ui32WriteOpsComplete =
494 psSyncInfo->psSyncData->ui32WriteOpsPending;
496 if (psKick->hTASyncInfo != IMG_NULL) {
497 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psKick->hTASyncInfo;
499 psSyncInfo->psSyncData->ui32WriteOpsComplete =
500 psSyncInfo->psSyncData->ui32WriteOpsPending;
503 if (psKick->h3DSyncInfo != IMG_NULL) {
504 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psKick->h3DSyncInfo;
506 psSyncInfo->psSyncData->ui32WriteOpsComplete =
507 psSyncInfo->psSyncData->ui32WriteOpsPending;