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 ******************************************************************************/
31 #include "services_headers.h"
32 #include "buffer_manager.h"
34 #include "sysconfig.h"
38 #include "pvr_bridge.h"
39 #include "sgx_bridge_km.h"
40 #include "sgxinfokm.h"
42 #include "pvr_debug.h"
45 IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle,
46 PVRSRV_TRANSFER_SGX_KICK * psKick)
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;
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;
64 CCB_DATA_FROM_OFFSET(PVR3DIF4_TRANSFERCMD_SHARED, psCCBMemInfo,
65 psKick, ui32SharedCmdCCBOffset);
67 if (psTransferCmd->ui32NumStatusVals > SGXTQ_MAX_STATUS) {
68 return PVRSRV_ERROR_INVALID_PARAMS;
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;
78 if (psKick->hTASyncInfo != IMG_NULL) {
79 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psKick->hTASyncInfo;
81 psTransferCmd->ui32TASyncWriteOpsPendingVal =
82 psSyncInfo->psSyncData->ui32WriteOpsPending++;
83 psTransferCmd->ui32TASyncReadOpsPendingVal =
84 psSyncInfo->psSyncData->ui32ReadOpsPending;
86 psTransferCmd->sTASyncWriteOpsCompleteDevVAddr =
87 psSyncInfo->sWriteOpsCompleteDevVAddr;
88 psTransferCmd->sTASyncReadOpsCompleteDevVAddr =
89 psSyncInfo->sReadOpsCompleteDevVAddr;
91 psTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0;
92 psTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0;
95 if (psKick->h3DSyncInfo != IMG_NULL) {
96 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psKick->h3DSyncInfo;
98 psTransferCmd->ui323DSyncWriteOpsPendingVal =
99 psSyncInfo->psSyncData->ui32WriteOpsPending++;
100 psTransferCmd->ui323DSyncReadOpsPendingVal =
101 psSyncInfo->psSyncData->ui32ReadOpsPending;
103 psTransferCmd->s3DSyncWriteOpsCompleteDevVAddr =
104 psSyncInfo->sWriteOpsCompleteDevVAddr;
105 psTransferCmd->s3DSyncReadOpsCompleteDevVAddr =
106 psSyncInfo->sReadOpsCompleteDevVAddr;
108 psTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0;
109 psTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0;
112 psTransferCmd->ui32NumSrcSync = psKick->ui32NumSrcSync;
113 psTransferCmd->ui32NumDstSync = psKick->ui32NumDstSync;
115 if (psKick->ui32NumSrcSync > 0) {
117 (PVRSRV_KERNEL_SYNC_INFO *) psKick->ahSrcSyncInfo[0];
119 psTransferCmd->ui32SrcWriteOpPendingVal =
120 psSyncInfo->psSyncData->ui32WriteOpsPending;
121 psTransferCmd->ui32SrcReadOpPendingVal =
122 psSyncInfo->psSyncData->ui32ReadOpsPending;
124 psTransferCmd->sSrcWriteOpsCompleteDevAddr =
125 psSyncInfo->sWriteOpsCompleteDevVAddr;
126 psTransferCmd->sSrcReadOpsCompleteDevAddr =
127 psSyncInfo->sReadOpsCompleteDevVAddr;
129 if (psKick->ui32NumDstSync > 0) {
131 (PVRSRV_KERNEL_SYNC_INFO *) psKick->ahDstSyncInfo[0];
133 psTransferCmd->ui32DstWriteOpPendingVal =
134 psSyncInfo->psSyncData->ui32WriteOpsPending;
135 psTransferCmd->ui32DstReadOpPendingVal =
136 psSyncInfo->psSyncData->ui32ReadOpsPending;
138 psTransferCmd->sDstWriteOpsCompleteDevAddr =
139 psSyncInfo->sWriteOpsCompleteDevVAddr;
140 psTransferCmd->sDstReadOpsCompleteDevAddr =
141 psSyncInfo->sReadOpsCompleteDevVAddr;
144 if (psKick->ui32NumSrcSync > 0) {
146 (PVRSRV_KERNEL_SYNC_INFO *) psKick->ahSrcSyncInfo[0];
147 psSyncInfo->psSyncData->ui32ReadOpsPending++;
150 if (psKick->ui32NumDstSync > 0) {
152 (PVRSRV_KERNEL_SYNC_INFO *) psKick->ahDstSyncInfo[0];
153 psSyncInfo->psSyncData->ui32WriteOpsPending++;
156 if (psKick->ui32NumSrcSync > 1) {
157 for (i = 1; i < psKick->ui32NumSrcSync; i++) {
159 (PVRSRV_KERNEL_SYNC_INFO *) psKick->
162 psTransferCmd->sCtlStatusInfo[psKick->
163 ui32StatusFirstSync].
165 psSyncInfo->psSyncData->ui32ReadOpsPending++;
167 psTransferCmd->sCtlStatusInfo[psKick->
168 ui32StatusFirstSync].
170 psSyncInfo->sReadOpsCompleteDevVAddr;
172 psKick->ui32StatusFirstSync++;
176 if (psKick->ui32NumDstSync > 1) {
177 for (i = 1; i < psKick->ui32NumDstSync; i++) {
179 (PVRSRV_KERNEL_SYNC_INFO *) psKick->
182 psTransferCmd->sCtlStatusInfo[psKick->
183 ui32StatusFirstSync].
185 psSyncInfo->psSyncData->ui32WriteOpsPending++;
187 psTransferCmd->sCtlStatusInfo[psKick->
188 ui32StatusFirstSync].
190 psSyncInfo->sWriteOpsCompleteDevVAddr;
192 psKick->ui32StatusFirstSync++;
196 if (PDumpIsCaptureFrameKM()) {
197 PDUMPCOMMENT("Shared part of transfer command\r\n");
198 PDUMPMEM(psTransferCmd,
200 psKick->ui32CCBDumpWOff,
201 sizeof(PVR3DIF4_TRANSFERCMD_SHARED),
202 0, MAKEUNIQUETAG(psCCBMemInfo));
204 if (psKick->ui32NumSrcSync > 0) {
205 psSyncInfo = psKick->ahSrcSyncInfo[0];
208 ("Hack src surface write op in transfer cmd\r\n");
209 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
211 psKick->ui32CCBDumpWOff +
212 offsetof(PVR3DIF4_TRANSFERCMD_SHARED,
213 ui32SrcWriteOpPendingVal),
214 sizeof(psSyncInfo->psSyncData->
215 ui32LastOpDumpVal), 0,
216 MAKEUNIQUETAG(psCCBMemInfo));
219 ("Hack src surface read op in transfer cmd\r\n");
220 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
222 psKick->ui32CCBDumpWOff +
223 offsetof(PVR3DIF4_TRANSFERCMD_SHARED,
224 ui32SrcReadOpPendingVal),
225 sizeof(psSyncInfo->psSyncData->
226 ui32LastReadOpDumpVal), 0,
227 MAKEUNIQUETAG(psCCBMemInfo));
229 if (psKick->ui32NumDstSync > 0) {
230 psSyncInfo = psKick->ahDstSyncInfo[0];
233 ("Hack dest surface write op in transfer cmd\r\n");
234 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
236 psKick->ui32CCBDumpWOff +
237 offsetof(PVR3DIF4_TRANSFERCMD_SHARED,
238 ui32DstWriteOpPendingVal),
239 sizeof(psSyncInfo->psSyncData->
240 ui32LastOpDumpVal), 0,
241 MAKEUNIQUETAG(psCCBMemInfo));
244 ("Hack dest surface read op in transfer cmd\r\n");
245 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
247 psKick->ui32CCBDumpWOff +
248 offsetof(PVR3DIF4_TRANSFERCMD_SHARED,
249 ui32DstReadOpPendingVal),
250 sizeof(psSyncInfo->psSyncData->
251 ui32LastReadOpDumpVal), 0,
252 MAKEUNIQUETAG(psCCBMemInfo));
255 if (psKick->ui32NumSrcSync > 0) {
257 (PVRSRV_KERNEL_SYNC_INFO *) psKick->
259 psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
262 if (psKick->ui32NumDstSync > 0) {
264 (PVRSRV_KERNEL_SYNC_INFO *) psKick->
266 psSyncInfo->psSyncData->ui32LastOpDumpVal++;
271 sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_TRANSFERCMD;
272 sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr;
275 SGXScheduleCCBCommandKM(hDevHandle, PVRSRV_SGX_COMMAND_EDM_KICK,
276 &sCommand, KERNEL_ID);