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 enum PVRSRV_ERROR SGXSubmitTransferKM(void *hDevHandle,
45 struct PVRSRV_TRANSFER_SGX_KICK *psKick)
47 struct PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo =
48 (struct PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo;
49 struct SGXMKIF_COMMAND sCommand = { 0 };
50 struct SGXMKIF_TRANSFERCMD_SHARED *psSharedTransferCmd;
51 struct PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
52 enum PVRSRV_ERROR eError;
54 if (!CCB_OFFSET_IS_VALID
55 (struct SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick,
56 ui32SharedCmdCCBOffset)) {
57 PVR_DPF(PVR_DBG_ERROR,
58 "SGXSubmitTransferKM: Invalid CCB offset");
59 return PVRSRV_ERROR_INVALID_PARAMS;
63 CCB_DATA_FROM_OFFSET(struct SGXMKIF_TRANSFERCMD_SHARED,
64 psCCBMemInfo, psKick, ui32SharedCmdCCBOffset);
66 if (psKick->hTASyncInfo != NULL) {
67 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
70 psSharedTransferCmd->ui32TASyncWriteOpsPendingVal =
71 psSyncInfo->psSyncData->ui32WriteOpsPending++;
72 psSharedTransferCmd->ui32TASyncReadOpsPendingVal =
73 psSyncInfo->psSyncData->ui32ReadOpsPending;
75 psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr =
76 psSyncInfo->sWriteOpsCompleteDevVAddr;
77 psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr =
78 psSyncInfo->sReadOpsCompleteDevVAddr;
80 psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0;
81 psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0;
84 if (psKick->h3DSyncInfo != NULL) {
85 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
88 psSharedTransferCmd->ui323DSyncWriteOpsPendingVal =
89 psSyncInfo->psSyncData->ui32WriteOpsPending++;
90 psSharedTransferCmd->ui323DSyncReadOpsPendingVal =
91 psSyncInfo->psSyncData->ui32ReadOpsPending;
93 psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr =
94 psSyncInfo->sWriteOpsCompleteDevVAddr;
95 psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr =
96 psSyncInfo->sReadOpsCompleteDevVAddr;
98 psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0;
99 psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0;
102 if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) {
103 if (psKick->ui32NumSrcSync > 0) {
105 (struct PVRSRV_KERNEL_SYNC_INFO *)
106 psKick->ahSrcSyncInfo[0];
108 psSharedTransferCmd->ui32SrcWriteOpPendingVal =
109 psSyncInfo->psSyncData->ui32WriteOpsPending;
110 psSharedTransferCmd->ui32SrcReadOpPendingVal =
111 psSyncInfo->psSyncData->ui32ReadOpsPending;
113 psSharedTransferCmd->sSrcWriteOpsCompleteDevAddr =
114 psSyncInfo->sWriteOpsCompleteDevVAddr;
115 psSharedTransferCmd->sSrcReadOpsCompleteDevAddr =
116 psSyncInfo->sReadOpsCompleteDevVAddr;
118 if (psKick->ui32NumDstSync > 0) {
119 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
120 psKick->ahDstSyncInfo[0];
121 psSharedTransferCmd->ui32DstWriteOpPendingVal =
122 psSyncInfo->psSyncData->ui32WriteOpsPending;
123 psSharedTransferCmd->ui32DstReadOpPendingVal =
124 psSyncInfo->psSyncData->ui32ReadOpsPending;
125 psSharedTransferCmd->sDstWriteOpsCompleteDevAddr =
126 psSyncInfo->sWriteOpsCompleteDevVAddr;
127 psSharedTransferCmd->sDstReadOpsCompleteDevAddr =
128 psSyncInfo->sReadOpsCompleteDevVAddr;
131 if (psKick->ui32NumSrcSync > 0) {
132 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
133 psKick->ahSrcSyncInfo[0];
134 psSyncInfo->psSyncData->ui32ReadOpsPending++;
137 if (psKick->ui32NumDstSync > 0) {
139 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
141 psSyncInfo->psSyncData->ui32WriteOpsPending++;
145 if (psKick->ui32NumDstSync > 1 || psKick->ui32NumSrcSync > 1) {
146 PVR_DPF(PVR_DBG_ERROR,
147 "Transfer command doesn't support "
148 "more than 1 sync object per src/dst\ndst: %d, src: %d",
149 psKick->ui32NumDstSync, psKick->ui32NumSrcSync);
152 if (PDumpIsCaptureFrameKM() ||
153 ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) {
154 PDUMPCOMMENT("Shared part of transfer command\r\n");
155 PDUMPMEM(psSharedTransferCmd,
157 psKick->ui32CCBDumpWOff,
158 sizeof(struct SGXMKIF_TRANSFERCMD_SHARED),
159 psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo));
161 if ((psKick->ui32NumSrcSync > 0) &&
162 ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) ==
164 psSyncInfo = psKick->ahSrcSyncInfo[0];
167 ("Hack src surface write op in transfer cmd\r\n");
168 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
170 psKick->ui32CCBDumpWOff +
171 offsetof(struct SGXMKIF_TRANSFERCMD_SHARED,
172 ui32SrcWriteOpPendingVal),
173 sizeof(psSyncInfo->psSyncData->
175 psKick->ui32PDumpFlags,
176 MAKEUNIQUETAG(psCCBMemInfo));
179 ("Hack src surface read op in transfer cmd\r\n");
180 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
182 psKick->ui32CCBDumpWOff +
183 offsetof(struct SGXMKIF_TRANSFERCMD_SHARED,
184 ui32SrcReadOpPendingVal),
185 sizeof(psSyncInfo->psSyncData->
186 ui32LastReadOpDumpVal),
187 psKick->ui32PDumpFlags,
188 MAKEUNIQUETAG(psCCBMemInfo));
190 if ((psKick->ui32NumDstSync > 0) &&
191 ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) ==
193 psSyncInfo = psKick->ahDstSyncInfo[0];
196 ("Hack dest surface write op in transfer cmd\r\n");
197 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
199 psKick->ui32CCBDumpWOff +
200 offsetof(struct SGXMKIF_TRANSFERCMD_SHARED,
201 ui32DstWriteOpPendingVal),
202 sizeof(psSyncInfo->psSyncData->
204 psKick->ui32PDumpFlags,
205 MAKEUNIQUETAG(psCCBMemInfo));
208 ("Hack dest surface read op in transfer cmd\r\n");
209 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
211 psKick->ui32CCBDumpWOff +
212 offsetof(struct SGXMKIF_TRANSFERCMD_SHARED,
213 ui32DstReadOpPendingVal),
214 sizeof(psSyncInfo->psSyncData->
215 ui32LastReadOpDumpVal),
216 psKick->ui32PDumpFlags,
217 MAKEUNIQUETAG(psCCBMemInfo));
220 if ((psKick->ui32NumSrcSync > 0) &&
221 ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) ==
224 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
226 psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
230 if ((psKick->ui32NumDstSync > 0) &&
231 ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) ==
234 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
236 psSyncInfo->psSyncData->ui32LastOpDumpVal++;
241 sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_TRANSFERCMD;
242 sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr;
244 /* To aid in determining the next power down delay */
245 sgx_mark_new_command(hDevHandle);
247 eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_COMMAND_EDM_KICK,
248 &sCommand, KERNEL_ID,
249 psKick->ui32PDumpFlags);
251 #if defined(NO_HARDWARE)
252 if (!(psKick->ui32Flags & SGXMKIF_TQFLAGS_NOSYNCUPDATE)) {
255 for (i = 0; i < psKick->ui32NumSrcSync; i++) {
257 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
259 psSyncInfo->psSyncData->ui32ReadOpsComplete =
260 psSyncInfo->psSyncData->ui32ReadOpsPending;
263 for (i = 0; i < psKick->ui32NumDstSync; i++) {
265 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
267 psSyncInfo->psSyncData->ui32WriteOpsComplete =
268 psSyncInfo->psSyncData->ui32WriteOpsPending;
272 if (psKick->hTASyncInfo != NULL) {
274 (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
277 psSyncInfo->psSyncData->ui32WriteOpsComplete =
278 psSyncInfo->psSyncData->ui32WriteOpsPending;
281 if (psKick->h3DSyncInfo != NULL) {
282 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)psKick->
285 psSyncInfo->psSyncData->ui32WriteOpsComplete =
286 psSyncInfo->psSyncData->ui32WriteOpsPending;