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"
35 #include "pvr_pdump.h"
37 #include "pvr_bridge.h"
38 #include "sgx_bridge_km.h"
39 #include "sgxinfokm.h"
41 #include "pvr_debug.h"
44 #include "pvr_trace_cmd.h"
46 enum PVRSRV_ERROR SGXSubmitTransferKM(void *hDevHandle,
47 struct PVRSRV_TRANSFER_SGX_KICK *psKick,
48 struct PVRSRV_PER_PROCESS_DATA *proc)
50 struct PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo =
51 (struct PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo;
52 struct SGXMKIF_COMMAND sCommand = { 0 };
53 struct SGXMKIF_TRANSFERCMD_SHARED *psSharedTransferCmd;
54 struct PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
55 struct pvr_trcmd_sgxtransfer *ttrace;
56 enum PVRSRV_ERROR eError;
58 if (!CCB_OFFSET_IS_VALID
59 (struct SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick,
60 ui32SharedCmdCCBOffset)) {
61 PVR_DPF(PVR_DBG_ERROR,
62 "SGXSubmitTransferKM: Invalid CCB offset");
63 return PVRSRV_ERROR_INVALID_PARAMS;
67 CCB_DATA_FROM_OFFSET(struct SGXMKIF_TRANSFERCMD_SHARED,
68 psCCBMemInfo, psKick, ui32SharedCmdCCBOffset);
71 ttrace = pvr_trcmd_alloc(PVR_TRCMD_TFER_KICK, proc->ui32PID, proc->name,
74 if (psKick->hTASyncInfo != NULL) {
75 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
78 psSharedTransferCmd->ui32TASyncWriteOpsPendingVal =
79 psSyncInfo->psSyncData->ui32WriteOpsPending++;
80 psSharedTransferCmd->ui32TASyncReadOpsPendingVal =
81 psSyncInfo->psSyncData->ui32ReadOpsPending;
83 psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr =
84 psSyncInfo->sWriteOpsCompleteDevVAddr;
85 psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr =
86 psSyncInfo->sReadOpsCompleteDevVAddr;
88 pvr_trcmd_set_syn(&ttrace->ta_syn, psSyncInfo);
90 psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0;
91 psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0;
93 pvr_trcmd_clear_syn(&ttrace->ta_syn);
96 if (psKick->h3DSyncInfo != NULL) {
97 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
100 psSharedTransferCmd->ui323DSyncWriteOpsPendingVal =
101 psSyncInfo->psSyncData->ui32WriteOpsPending++;
102 psSharedTransferCmd->ui323DSyncReadOpsPendingVal =
103 psSyncInfo->psSyncData->ui32ReadOpsPending;
105 psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr =
106 psSyncInfo->sWriteOpsCompleteDevVAddr;
107 psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr =
108 psSyncInfo->sReadOpsCompleteDevVAddr;
110 pvr_trcmd_set_syn(&ttrace->_3d_syn, psSyncInfo);
112 psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0;
113 psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0;
115 pvr_trcmd_clear_syn(&ttrace->_3d_syn);
118 if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) {
119 if (psKick->ui32NumSrcSync > 0) {
121 (struct PVRSRV_KERNEL_SYNC_INFO *)
122 psKick->ahSrcSyncInfo[0];
124 psSharedTransferCmd->ui32SrcWriteOpPendingVal =
125 psSyncInfo->psSyncData->ui32WriteOpsPending;
126 psSharedTransferCmd->ui32SrcReadOpPendingVal =
127 psSyncInfo->psSyncData->ui32ReadOpsPending;
129 psSharedTransferCmd->sSrcWriteOpsCompleteDevAddr =
130 psSyncInfo->sWriteOpsCompleteDevVAddr;
131 psSharedTransferCmd->sSrcReadOpsCompleteDevAddr =
132 psSyncInfo->sReadOpsCompleteDevVAddr;
134 if (psKick->ui32NumDstSync > 0) {
135 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
136 psKick->ahDstSyncInfo[0];
137 psSharedTransferCmd->ui32DstWriteOpPendingVal =
138 psSyncInfo->psSyncData->ui32WriteOpsPending;
139 psSharedTransferCmd->ui32DstReadOpPendingVal =
140 psSyncInfo->psSyncData->ui32ReadOpsPending;
141 psSharedTransferCmd->sDstWriteOpsCompleteDevAddr =
142 psSyncInfo->sWriteOpsCompleteDevVAddr;
143 psSharedTransferCmd->sDstReadOpsCompleteDevAddr =
144 psSyncInfo->sReadOpsCompleteDevVAddr;
147 if (psKick->ui32NumSrcSync > 0) {
148 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
149 psKick->ahSrcSyncInfo[0];
150 psSyncInfo->psSyncData->ui32ReadOpsPending++;
152 pvr_trcmd_set_syn(&ttrace->src_syn, psSyncInfo);
154 pvr_trcmd_clear_syn(&ttrace->src_syn);
157 if (psKick->ui32NumDstSync > 0) {
159 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
161 psSyncInfo->psSyncData->ui32WriteOpsPending++;
163 pvr_trcmd_set_syn(&ttrace->dst_syn, psSyncInfo);
165 pvr_trcmd_clear_syn(&ttrace->dst_syn);
168 pvr_trcmd_clear_syn(&ttrace->src_syn);
169 pvr_trcmd_clear_syn(&ttrace->dst_syn);
172 if (psKick->ui32NumDstSync > 1 || psKick->ui32NumSrcSync > 1) {
173 PVR_DPF(PVR_DBG_ERROR,
174 "Transfer command doesn't support "
175 "more than 1 sync object per src/dst\ndst: %d, src: %d",
176 psKick->ui32NumDstSync, psKick->ui32NumSrcSync);
179 if (PDumpIsCaptureFrameKM() ||
180 ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) {
181 PDUMPCOMMENT("Shared part of transfer command\r\n");
182 PDUMPMEM(psSharedTransferCmd,
184 psKick->ui32CCBDumpWOff,
185 sizeof(struct SGXMKIF_TRANSFERCMD_SHARED),
186 psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo));
188 if ((psKick->ui32NumSrcSync > 0) &&
189 ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) ==
191 psSyncInfo = psKick->ahSrcSyncInfo[0];
194 ("Hack src surface write op in transfer cmd\r\n");
195 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
197 psKick->ui32CCBDumpWOff +
198 offsetof(struct SGXMKIF_TRANSFERCMD_SHARED,
199 ui32SrcWriteOpPendingVal),
200 sizeof(psSyncInfo->psSyncData->
202 psKick->ui32PDumpFlags,
203 MAKEUNIQUETAG(psCCBMemInfo));
206 ("Hack src surface read op in transfer cmd\r\n");
207 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
209 psKick->ui32CCBDumpWOff +
210 offsetof(struct SGXMKIF_TRANSFERCMD_SHARED,
211 ui32SrcReadOpPendingVal),
212 sizeof(psSyncInfo->psSyncData->
213 ui32LastReadOpDumpVal),
214 psKick->ui32PDumpFlags,
215 MAKEUNIQUETAG(psCCBMemInfo));
217 if ((psKick->ui32NumDstSync > 0) &&
218 ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) ==
220 psSyncInfo = psKick->ahDstSyncInfo[0];
223 ("Hack dest surface write op in transfer cmd\r\n");
224 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
226 psKick->ui32CCBDumpWOff +
227 offsetof(struct SGXMKIF_TRANSFERCMD_SHARED,
228 ui32DstWriteOpPendingVal),
229 sizeof(psSyncInfo->psSyncData->
231 psKick->ui32PDumpFlags,
232 MAKEUNIQUETAG(psCCBMemInfo));
235 ("Hack dest surface read op in transfer cmd\r\n");
236 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
238 psKick->ui32CCBDumpWOff +
239 offsetof(struct SGXMKIF_TRANSFERCMD_SHARED,
240 ui32DstReadOpPendingVal),
241 sizeof(psSyncInfo->psSyncData->
242 ui32LastReadOpDumpVal),
243 psKick->ui32PDumpFlags,
244 MAKEUNIQUETAG(psCCBMemInfo));
247 if ((psKick->ui32NumSrcSync > 0) &&
248 ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) ==
251 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
253 psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
257 if ((psKick->ui32NumDstSync > 0) &&
258 ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) ==
261 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
263 psSyncInfo->psSyncData->ui32LastOpDumpVal++;
268 sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_TRANSFERCMD;
269 sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr;
271 pvr_trcmd_set_data(&ttrace->ctx,
272 psKick->sHWTransferContextDevVAddr.uiAddr);
275 /* To aid in determining the next power down delay */
276 sgx_mark_new_command(hDevHandle);
278 eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_COMMAND_EDM_KICK,
279 &sCommand, KERNEL_ID,
280 psKick->ui32PDumpFlags);
282 #if defined(NO_HARDWARE)
283 if (!(psKick->ui32Flags & SGXMKIF_TQFLAGS_NOSYNCUPDATE)) {
286 for (i = 0; i < psKick->ui32NumSrcSync; i++) {
288 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
290 psSyncInfo->psSyncData->ui32ReadOpsComplete =
291 psSyncInfo->psSyncData->ui32ReadOpsPending;
294 for (i = 0; i < psKick->ui32NumDstSync; i++) {
296 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
298 psSyncInfo->psSyncData->ui32WriteOpsComplete =
299 psSyncInfo->psSyncData->ui32WriteOpsPending;
303 if (psKick->hTASyncInfo != NULL) {
305 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
308 psSyncInfo->psSyncData->ui32WriteOpsComplete =
309 psSyncInfo->psSyncData->ui32WriteOpsPending;
312 if (psKick->h3DSyncInfo != NULL) {
313 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
316 psSyncInfo->psSyncData->ui32WriteOpsComplete =
317 psSyncInfo->psSyncData->ui32WriteOpsPending;