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"
45 enum PVRSRV_ERROR SGXSubmitTransferKM(void *hDevHandle,
46 struct PVRSRV_TRANSFER_SGX_KICK *psKick,
47 struct PVRSRV_PER_PROCESS_DATA *proc)
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;
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;
65 CCB_DATA_FROM_OFFSET(struct SGXMKIF_TRANSFERCMD_SHARED,
66 psCCBMemInfo, psKick, ui32SharedCmdCCBOffset);
68 if (psKick->hTASyncInfo != NULL) {
69 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
72 psSharedTransferCmd->ui32TASyncWriteOpsPendingVal =
73 psSyncInfo->psSyncData->ui32WriteOpsPending++;
74 psSharedTransferCmd->ui32TASyncReadOpsPendingVal =
75 psSyncInfo->psSyncData->ui32ReadOpsPending;
77 psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr =
78 psSyncInfo->sWriteOpsCompleteDevVAddr;
79 psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr =
80 psSyncInfo->sReadOpsCompleteDevVAddr;
82 psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0;
83 psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0;
86 if (psKick->h3DSyncInfo != NULL) {
87 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
90 psSharedTransferCmd->ui323DSyncWriteOpsPendingVal =
91 psSyncInfo->psSyncData->ui32WriteOpsPending++;
92 psSharedTransferCmd->ui323DSyncReadOpsPendingVal =
93 psSyncInfo->psSyncData->ui32ReadOpsPending;
95 psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr =
96 psSyncInfo->sWriteOpsCompleteDevVAddr;
97 psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr =
98 psSyncInfo->sReadOpsCompleteDevVAddr;
100 psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0;
101 psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0;
104 if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) {
105 if (psKick->ui32NumSrcSync > 0) {
107 (struct PVRSRV_KERNEL_SYNC_INFO *)
108 psKick->ahSrcSyncInfo[0];
110 psSharedTransferCmd->ui32SrcWriteOpPendingVal =
111 psSyncInfo->psSyncData->ui32WriteOpsPending;
112 psSharedTransferCmd->ui32SrcReadOpPendingVal =
113 psSyncInfo->psSyncData->ui32ReadOpsPending;
115 psSharedTransferCmd->sSrcWriteOpsCompleteDevAddr =
116 psSyncInfo->sWriteOpsCompleteDevVAddr;
117 psSharedTransferCmd->sSrcReadOpsCompleteDevAddr =
118 psSyncInfo->sReadOpsCompleteDevVAddr;
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;
133 if (psKick->ui32NumSrcSync > 0) {
134 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
135 psKick->ahSrcSyncInfo[0];
136 psSyncInfo->psSyncData->ui32ReadOpsPending++;
139 if (psKick->ui32NumDstSync > 0) {
141 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
143 psSyncInfo->psSyncData->ui32WriteOpsPending++;
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);
154 if (PDumpIsCaptureFrameKM() ||
155 ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) {
156 PDUMPCOMMENT("Shared part of transfer command\r\n");
157 PDUMPMEM(psSharedTransferCmd,
159 psKick->ui32CCBDumpWOff,
160 sizeof(struct SGXMKIF_TRANSFERCMD_SHARED),
161 psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo));
163 if ((psKick->ui32NumSrcSync > 0) &&
164 ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) ==
166 psSyncInfo = psKick->ahSrcSyncInfo[0];
169 ("Hack src surface write op in transfer cmd\r\n");
170 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
172 psKick->ui32CCBDumpWOff +
173 offsetof(struct SGXMKIF_TRANSFERCMD_SHARED,
174 ui32SrcWriteOpPendingVal),
175 sizeof(psSyncInfo->psSyncData->
177 psKick->ui32PDumpFlags,
178 MAKEUNIQUETAG(psCCBMemInfo));
181 ("Hack src surface read op in transfer cmd\r\n");
182 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
184 psKick->ui32CCBDumpWOff +
185 offsetof(struct SGXMKIF_TRANSFERCMD_SHARED,
186 ui32SrcReadOpPendingVal),
187 sizeof(psSyncInfo->psSyncData->
188 ui32LastReadOpDumpVal),
189 psKick->ui32PDumpFlags,
190 MAKEUNIQUETAG(psCCBMemInfo));
192 if ((psKick->ui32NumDstSync > 0) &&
193 ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) ==
195 psSyncInfo = psKick->ahDstSyncInfo[0];
198 ("Hack dest surface write op in transfer cmd\r\n");
199 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
201 psKick->ui32CCBDumpWOff +
202 offsetof(struct SGXMKIF_TRANSFERCMD_SHARED,
203 ui32DstWriteOpPendingVal),
204 sizeof(psSyncInfo->psSyncData->
206 psKick->ui32PDumpFlags,
207 MAKEUNIQUETAG(psCCBMemInfo));
210 ("Hack dest surface read op in transfer cmd\r\n");
211 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
213 psKick->ui32CCBDumpWOff +
214 offsetof(struct SGXMKIF_TRANSFERCMD_SHARED,
215 ui32DstReadOpPendingVal),
216 sizeof(psSyncInfo->psSyncData->
217 ui32LastReadOpDumpVal),
218 psKick->ui32PDumpFlags,
219 MAKEUNIQUETAG(psCCBMemInfo));
222 if ((psKick->ui32NumSrcSync > 0) &&
223 ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) ==
226 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
228 psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
232 if ((psKick->ui32NumDstSync > 0) &&
233 ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) ==
236 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
238 psSyncInfo->psSyncData->ui32LastOpDumpVal++;
243 sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_TRANSFERCMD;
244 sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr;
246 /* To aid in determining the next power down delay */
247 sgx_mark_new_command(hDevHandle);
249 eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_COMMAND_EDM_KICK,
250 &sCommand, KERNEL_ID,
251 psKick->ui32PDumpFlags);
253 #if defined(NO_HARDWARE)
254 if (!(psKick->ui32Flags & SGXMKIF_TQFLAGS_NOSYNCUPDATE)) {
257 for (i = 0; i < psKick->ui32NumSrcSync; i++) {
259 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
261 psSyncInfo->psSyncData->ui32ReadOpsComplete =
262 psSyncInfo->psSyncData->ui32ReadOpsPending;
265 for (i = 0; i < psKick->ui32NumDstSync; i++) {
267 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
269 psSyncInfo->psSyncData->ui32WriteOpsComplete =
270 psSyncInfo->psSyncData->ui32WriteOpsPending;
274 if (psKick->hTASyncInfo != NULL) {
276 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
279 psSyncInfo->psSyncData->ui32WriteOpsComplete =
280 psSyncInfo->psSyncData->ui32WriteOpsPending;
283 if (psKick->h3DSyncInfo != NULL) {
284 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
287 psSyncInfo->psSyncData->ui32WriteOpsComplete =
288 psSyncInfo->psSyncData->ui32WriteOpsPending;