aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/pvr/sgx/sgxinit.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/pvr/sgx/sgxinit.c')
-rw-r--r--drivers/gpu/pvr/sgx/sgxinit.c2507
1 files changed, 2507 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/sgx/sgxinit.c b/drivers/gpu/pvr/sgx/sgxinit.c
new file mode 100644
index 00000000000..2471915d10f
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxinit.c
@@ -0,0 +1,2507 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
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.
8 *
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.
13 *
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.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include <stddef.h>
28
29#include "sgxdefs.h"
30#include "sgxmmu.h"
31#include "services_headers.h"
32#include "buffer_manager.h"
33#include "sgxapi_km.h"
34#include "sgxinfo.h"
35#include "sgx_mkif_km.h"
36#include "sgxconfig.h"
37#include "sysconfig.h"
38#include "pvr_bridge_km.h"
39
40#include "sgx_bridge_km.h"
41
42#include "pdump_km.h"
43#include "ra.h"
44#include "mmu.h"
45#include "handle.h"
46#include "perproc.h"
47
48#include "sgxutils.h"
49#include "pvrversion.h"
50#include "sgx_options.h"
51
52#include "lists.h"
53#include "srvkm.h"
54
55#define VAR(x) #x
56
57
58#define CHECK_SIZE(NAME) \
59{ \
60 if (psSGXStructSizes->ui32Sizeof_##NAME != psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME) \
61 { \
62 PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Size check failed for SGXMKIF_%s (client) = %d bytes, (ukernel) = %d bytes\n", \
63 VAR(NAME), \
64 psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME, \
65 psSGXStructSizes->ui32Sizeof_##NAME )); \
66 bStructSizesFailed = IMG_TRUE; \
67 } \
68}
69
70#if defined (SYS_USING_INTERRUPTS)
71IMG_BOOL SGX_ISRHandler(IMG_VOID *pvData);
72#endif
73
74
75static
76PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO *psDevInfo,
77 PVRSRV_DEVICE_NODE *psDeviceNode);
78#if defined(PDUMP)
79static
80PVRSRV_ERROR SGXResetPDump(PVRSRV_DEVICE_NODE *psDeviceNode);
81#endif
82
83static IMG_VOID SGXCommandComplete(PVRSRV_DEVICE_NODE *psDeviceNode)
84{
85#if defined(OS_SUPPORTS_IN_LISR)
86 if (OSInLISR(psDeviceNode->psSysData))
87 {
88
89 psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;
90 }
91 else
92 {
93 SGXScheduleProcessQueuesKM(psDeviceNode);
94 }
95#else
96 SGXScheduleProcessQueuesKM(psDeviceNode);
97#endif
98}
99
100static IMG_UINT32 DeinitDevInfo(PVRSRV_SGXDEV_INFO *psDevInfo)
101{
102 if (psDevInfo->psKernelCCBInfo != IMG_NULL)
103 {
104
105
106 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_SGX_CCB_INFO), psDevInfo->psKernelCCBInfo, IMG_NULL);
107 }
108
109 return PVRSRV_OK;
110}
111
112static PVRSRV_ERROR InitDevInfo(PVRSRV_PER_PROCESS_DATA *psPerProc,
113 PVRSRV_DEVICE_NODE *psDeviceNode,
114 SGX_BRIDGE_INIT_INFO *psInitInfo)
115{
116 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
117 PVRSRV_ERROR eError;
118
119 PVRSRV_SGX_CCB_INFO *psKernelCCBInfo = IMG_NULL;
120
121 PVR_UNREFERENCED_PARAMETER(psPerProc);
122 psDevInfo->sScripts = psInitInfo->sScripts;
123
124 psDevInfo->psKernelCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBMemInfo;
125 psDevInfo->psKernelCCB = (PVRSRV_SGX_KERNEL_CCB *) psDevInfo->psKernelCCBMemInfo->pvLinAddrKM;
126
127 psDevInfo->psKernelCCBCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBCtlMemInfo;
128 psDevInfo->psKernelCCBCtl = (PVRSRV_SGX_CCB_CTL *) psDevInfo->psKernelCCBCtlMemInfo->pvLinAddrKM;
129
130 psDevInfo->psKernelCCBEventKickerMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBEventKickerMemInfo;
131 psDevInfo->pui32KernelCCBEventKicker = (IMG_UINT32 *)psDevInfo->psKernelCCBEventKickerMemInfo->pvLinAddrKM;
132
133 psDevInfo->psKernelSGXHostCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXHostCtlMemInfo;
134 psDevInfo->psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM;
135
136 psDevInfo->psKernelSGXTA3DCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXTA3DCtlMemInfo;
137
138 psDevInfo->psKernelSGXMiscMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXMiscMemInfo;
139
140#if defined(SGX_SUPPORT_HWPROFILING)
141 psDevInfo->psKernelHWProfilingMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWProfilingMemInfo;
142#endif
143#if defined(SUPPORT_SGX_HWPERF)
144 psDevInfo->psKernelHWPerfCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWPerfCBMemInfo;
145#endif
146 psDevInfo->psKernelTASigBufferMemInfo = psInitInfo->hKernelTASigBufferMemInfo;
147 psDevInfo->psKernel3DSigBufferMemInfo = psInitInfo->hKernel3DSigBufferMemInfo;
148#if defined(FIX_HW_BRN_29702)
149 psDevInfo->psKernelCFIMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCFIMemInfo;
150#endif
151#if defined(FIX_HW_BRN_29823)
152 psDevInfo->psKernelDummyTermStreamMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelDummyTermStreamMemInfo;
153#endif
154#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
155 psDevInfo->psKernelEDMStatusBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelEDMStatusBufferMemInfo;
156#endif
157#if defined(SGX_FEATURE_OVERLAPPED_SPM)
158 psDevInfo->psKernelTmpRgnHeaderMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpRgnHeaderMemInfo;
159#endif
160#if defined(SGX_FEATURE_SPM_MODE_0)
161 psDevInfo->psKernelTmpDPMStateMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpDPMStateMemInfo;
162#endif
163
164 psDevInfo->ui32ClientBuildOptions = psInitInfo->ui32ClientBuildOptions;
165
166
167 psDevInfo->sSGXStructSizes = psInitInfo->sSGXStructSizes;
168
169
170
171 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
172 sizeof(PVRSRV_SGX_CCB_INFO),
173 (IMG_VOID **)&psKernelCCBInfo, 0,
174 "SGX Circular Command Buffer Info");
175 if (eError != PVRSRV_OK)
176 {
177 PVR_DPF((PVR_DBG_ERROR,"InitDevInfo: Failed to alloc memory"));
178 goto failed_allockernelccb;
179 }
180
181
182 OSMemSet(psKernelCCBInfo, 0, sizeof(PVRSRV_SGX_CCB_INFO));
183 psKernelCCBInfo->psCCBMemInfo = psDevInfo->psKernelCCBMemInfo;
184 psKernelCCBInfo->psCCBCtlMemInfo = psDevInfo->psKernelCCBCtlMemInfo;
185 psKernelCCBInfo->psCommands = psDevInfo->psKernelCCB->asCommands;
186 psKernelCCBInfo->pui32WriteOffset = &psDevInfo->psKernelCCBCtl->ui32WriteOffset;
187 psKernelCCBInfo->pui32ReadOffset = &psDevInfo->psKernelCCBCtl->ui32ReadOffset;
188 psDevInfo->psKernelCCBInfo = psKernelCCBInfo;
189
190
191
192 OSMemCopy(psDevInfo->aui32HostKickAddr, psInitInfo->aui32HostKickAddr,
193 SGXMKIF_CMD_MAX * sizeof(psDevInfo->aui32HostKickAddr[0]));
194
195 psDevInfo->bForcePTOff = IMG_FALSE;
196
197 psDevInfo->ui32CacheControl = psInitInfo->ui32CacheControl;
198
199 psDevInfo->ui32EDMTaskReg0 = psInitInfo->ui32EDMTaskReg0;
200 psDevInfo->ui32EDMTaskReg1 = psInitInfo->ui32EDMTaskReg1;
201 psDevInfo->ui32ClkGateStatusReg = psInitInfo->ui32ClkGateStatusReg;
202 psDevInfo->ui32ClkGateStatusMask = psInitInfo->ui32ClkGateStatusMask;
203#if defined(SGX_FEATURE_MP)
204 psDevInfo->ui32MasterClkGateStatusReg = psInitInfo->ui32MasterClkGateStatusReg;
205 psDevInfo->ui32MasterClkGateStatusMask = psInitInfo->ui32MasterClkGateStatusMask;
206 psDevInfo->ui32MasterClkGateStatus2Reg = psInitInfo->ui32MasterClkGateStatus2Reg;
207 psDevInfo->ui32MasterClkGateStatus2Mask = psInitInfo->ui32MasterClkGateStatus2Mask;
208#endif
209
210
211
212 OSMemCopy(&psDevInfo->asSGXDevData, &psInitInfo->asInitDevData, sizeof(psDevInfo->asSGXDevData));
213
214 return PVRSRV_OK;
215
216failed_allockernelccb:
217 DeinitDevInfo(psDevInfo);
218
219 return eError;
220}
221
222
223
224
225static PVRSRV_ERROR SGXRunScript(PVRSRV_SGXDEV_INFO *psDevInfo, SGX_INIT_COMMAND *psScript, IMG_UINT32 ui32NumInitCommands)
226{
227 IMG_UINT32 ui32PC;
228 SGX_INIT_COMMAND *psComm;
229
230 for (ui32PC = 0, psComm = psScript;
231 ui32PC < ui32NumInitCommands;
232 ui32PC++, psComm++)
233 {
234 switch (psComm->eOp)
235 {
236 case SGX_INIT_OP_WRITE_HW_REG:
237 {
238 OSWriteHWReg(psDevInfo->pvRegsBaseKM, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value);
239 PDUMPCOMMENT("SGXRunScript: Write HW reg operation");
240 PDUMPREG(SGX_PDUMPREG_NAME, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value);
241 break;
242 }
243#if defined(PDUMP)
244 case SGX_INIT_OP_PDUMP_HW_REG:
245 {
246 PDUMPCOMMENT("SGXRunScript: Dump HW reg operation");
247 PDUMPREG(SGX_PDUMPREG_NAME, psComm->sPDumpHWReg.ui32Offset, psComm->sPDumpHWReg.ui32Value);
248 break;
249 }
250#endif
251 case SGX_INIT_OP_HALT:
252 {
253 return PVRSRV_OK;
254 }
255 case SGX_INIT_OP_ILLEGAL:
256
257 default:
258 {
259 PVR_DPF((PVR_DBG_ERROR,"SGXRunScript: PC %d: Illegal command: %d", ui32PC, psComm->eOp));
260 return PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION;
261 }
262 }
263
264 }
265
266 return PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION;
267}
268
269PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo,
270 IMG_BOOL bHardwareRecovery)
271{
272 PVRSRV_ERROR eError;
273 PVRSRV_KERNEL_MEM_INFO *psSGXHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo;
274 SGXMKIF_HOST_CTL *psSGXHostCtl = psSGXHostCtlMemInfo->pvLinAddrKM;
275 static IMG_BOOL bFirstTime = IMG_TRUE;
276#if defined(PDUMP)
277 IMG_BOOL bPDumpIsSuspended = PDumpIsSuspended();
278#endif
279
280
281
282 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 1\n");
283 eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart1, SGX_MAX_INIT_COMMANDS);
284 if (eError != PVRSRV_OK)
285 {
286 PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 1) failed (%d)", eError));
287 return eError;
288 }
289 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 1\n");
290
291
292 SGXReset(psDevInfo, bFirstTime || bHardwareRecovery, PDUMP_FLAGS_CONTINUOUS);
293
294#if defined(EUR_CR_POWER)
295#if defined(SGX531)
296
297
298
299
300
301 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 1);
302 PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_POWER, 1);
303#else
304
305 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 0);
306 PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_POWER, 0);
307#endif
308#endif
309
310
311 *psDevInfo->pui32KernelCCBEventKicker = 0;
312#if defined(PDUMP)
313 if (!bPDumpIsSuspended)
314 {
315 psDevInfo->ui32KernelCCBEventKickerDumpVal = 0;
316 PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal,
317 psDevInfo->psKernelCCBEventKickerMemInfo, 0,
318 sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS,
319 MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
320 }
321#endif
322
323
324
325 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 2\n");
326 eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart2, SGX_MAX_INIT_COMMANDS);
327 if (eError != PVRSRV_OK)
328 {
329 PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 2) failed (%d)", eError));
330 return eError;
331 }
332 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 2\n");
333
334
335 psSGXHostCtl->ui32HostClock = OSClockus();
336
337 psSGXHostCtl->ui32InitStatus = 0;
338#if defined(PDUMP)
339 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
340 "Reset the SGX microkernel initialisation status\n");
341 PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo,
342 offsetof(SGXMKIF_HOST_CTL, ui32InitStatus),
343 sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
344 MAKEUNIQUETAG(psSGXHostCtlMemInfo));
345 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
346 "Initialise the microkernel\n");
347#endif
348
349#if defined(SGX_FEATURE_MULTI_EVENT_KICK)
350 OSWriteMemoryBarrier();
351 OSWriteHWReg(psDevInfo->pvRegsBaseKM,
352 SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0),
353 EUR_CR_EVENT_KICK2_NOW_MASK);
354#else
355 *psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF;
356 OSWriteMemoryBarrier();
357 OSWriteHWReg(psDevInfo->pvRegsBaseKM,
358 SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0),
359 EUR_CR_EVENT_KICK_NOW_MASK);
360#endif
361
362 OSMemoryBarrier();
363
364#if defined(PDUMP)
365
366
367 if (!bPDumpIsSuspended)
368 {
369#if defined(SGX_FEATURE_MULTI_EVENT_KICK)
370 PDUMPREG(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK);
371#else
372 psDevInfo->ui32KernelCCBEventKickerDumpVal = 1;
373 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
374 "First increment of the SGX event kicker value\n");
375 PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal,
376 psDevInfo->psKernelCCBEventKickerMemInfo,
377 0,
378 sizeof(IMG_UINT32),
379 PDUMP_FLAGS_CONTINUOUS,
380 MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
381 PDUMPREG(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK);
382#endif
383 }
384#endif
385
386#if !defined(NO_HARDWARE)
387
388
389 if (PollForValueKM(&psSGXHostCtl->ui32InitStatus,
390 PVRSRV_USSE_EDM_INIT_COMPLETE,
391 PVRSRV_USSE_EDM_INIT_COMPLETE,
392 MAX_HW_TIME_US/WAIT_TRY_COUNT,
393 WAIT_TRY_COUNT) != PVRSRV_OK)
394 {
395 PVR_DPF((PVR_DBG_ERROR, "SGXInitialise: Wait for uKernel initialisation failed"));
396 PVR_DBG_BREAK;
397 return PVRSRV_ERROR_RETRY;
398 }
399#endif
400
401#if defined(PDUMP)
402 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
403 "Wait for the SGX microkernel initialisation to complete");
404 PDUMPMEMPOL(psSGXHostCtlMemInfo,
405 offsetof(SGXMKIF_HOST_CTL, ui32InitStatus),
406 PVRSRV_USSE_EDM_INIT_COMPLETE,
407 PVRSRV_USSE_EDM_INIT_COMPLETE,
408 PDUMP_POLL_OPERATOR_EQUAL,
409 PDUMP_FLAGS_CONTINUOUS,
410 MAKEUNIQUETAG(psSGXHostCtlMemInfo));
411#endif
412
413#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
414
415
416
417 WorkaroundBRN22997ReadHostPort(psDevInfo);
418#endif
419
420 PVR_ASSERT(psDevInfo->psKernelCCBCtl->ui32ReadOffset == psDevInfo->psKernelCCBCtl->ui32WriteOffset);
421
422 bFirstTime = IMG_FALSE;
423
424 return PVRSRV_OK;
425}
426
427PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie)
428
429{
430 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *) hDevCookie;
431 PVRSRV_ERROR eError;
432
433
434 if (psDevInfo->pvRegsBaseKM == IMG_NULL)
435 {
436 return PVRSRV_OK;
437 }
438
439 eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asDeinitCommands, SGX_MAX_DEINIT_COMMANDS);
440 if (eError != PVRSRV_OK)
441 {
442 PVR_DPF((PVR_DBG_ERROR,"SGXDeinitialise: SGXRunScript failed (%d)", eError));
443 return eError;
444 }
445
446 return PVRSRV_OK;
447}
448
449
450static PVRSRV_ERROR DevInitSGXPart1 (IMG_VOID *pvDeviceNode)
451{
452 IMG_HANDLE hDevMemHeap = IMG_NULL;
453 PVRSRV_SGXDEV_INFO *psDevInfo;
454 IMG_HANDLE hKernelDevMemContext;
455 IMG_DEV_PHYADDR sPDDevPAddr;
456 IMG_UINT32 i;
457 PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
458 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
459 PVRSRV_ERROR eError;
460
461
462 PDUMPCOMMENT("SGX Core Version Information: %s", SGX_CORE_FRIENDLY_NAME);
463
464 #if defined(SGX_FEATURE_MP)
465 PDUMPCOMMENT("SGX Multi-processor: %d cores", SGX_FEATURE_MP_CORE_COUNT);
466 #endif
467
468#if (SGX_CORE_REV == 0)
469 PDUMPCOMMENT("SGX Core Revision Information: head RTL");
470#else
471 PDUMPCOMMENT("SGX Core Revision Information: %d", SGX_CORE_REV);
472#endif
473
474 #if defined(SGX_FEATURE_SYSTEM_CACHE)
475 PDUMPCOMMENT("SGX System Level Cache is present\r\n");
476 #if defined(SGX_BYPASS_SYSTEM_CACHE)
477 PDUMPCOMMENT("SGX System Level Cache is bypassed\r\n");
478 #endif
479 #endif
480
481 PDUMPCOMMENT("SGX Initialisation Part 1");
482
483
484 if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
485 sizeof(PVRSRV_SGXDEV_INFO),
486 (IMG_VOID **)&psDevInfo, IMG_NULL,
487 "SGX Device Info") != PVRSRV_OK)
488 {
489 PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1 : Failed to alloc memory for DevInfo"));
490 return (PVRSRV_ERROR_OUT_OF_MEMORY);
491 }
492 OSMemSet (psDevInfo, 0, sizeof(PVRSRV_SGXDEV_INFO));
493
494
495 psDevInfo->eDeviceType = DEV_DEVICE_TYPE;
496 psDevInfo->eDeviceClass = DEV_DEVICE_CLASS;
497
498
499 psDeviceNode->pvDevice = (IMG_PVOID)psDevInfo;
500
501
502 psDevInfo->pvDeviceMemoryHeap = (IMG_VOID*)psDeviceMemoryHeap;
503
504
505 hKernelDevMemContext = BM_CreateContext(psDeviceNode,
506 &sPDDevPAddr,
507 IMG_NULL,
508 IMG_NULL);
509 if (hKernelDevMemContext == IMG_NULL)
510 {
511 PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1: Failed BM_CreateContext"));
512 return PVRSRV_ERROR_OUT_OF_MEMORY;
513 }
514
515 psDevInfo->sKernelPDDevPAddr = sPDDevPAddr;
516
517
518 for(i=0; i<psDeviceNode->sDevMemoryInfo.ui32HeapCount; i++)
519 {
520 switch(psDeviceMemoryHeap[i].DevMemHeapType)
521 {
522 case DEVICE_MEMORY_HEAP_KERNEL:
523 case DEVICE_MEMORY_HEAP_SHARED:
524 case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
525 {
526 hDevMemHeap = BM_CreateHeap (hKernelDevMemContext,
527 &psDeviceMemoryHeap[i]);
528
529
530
531 psDeviceMemoryHeap[i].hDevMemHeap = hDevMemHeap;
532 break;
533 }
534 }
535 }
536#if defined(PDUMP)
537 if(hDevMemHeap)
538 {
539
540 psDevInfo->sMMUAttrib = *((BM_HEAP*)hDevMemHeap)->psMMUAttrib;
541 }
542#endif
543 eError = MMU_BIFResetPDAlloc(psDevInfo);
544 if (eError != PVRSRV_OK)
545 {
546 PVR_DPF((PVR_DBG_ERROR,"DevInitSGX : Failed to alloc memory for BIF reset"));
547 return eError;
548 }
549
550 return PVRSRV_OK;
551}
552
553IMG_EXPORT
554PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo)
555{
556 PVRSRV_DEVICE_NODE *psDeviceNode;
557 PVRSRV_SGXDEV_INFO *psDevInfo;
558 PVRSRV_ERROR eError;
559
560 PDUMPCOMMENT("SGXGetInfoForSrvinit");
561
562 psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle;
563 psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
564
565 psInitInfo->sPDDevPAddr = psDevInfo->sKernelPDDevPAddr;
566
567 eError = PVRSRVGetDeviceMemHeapsKM(hDevHandle, &psInitInfo->asHeapInfo[0]);
568 if (eError != PVRSRV_OK)
569 {
570 PVR_DPF((PVR_DBG_ERROR,"SGXGetInfoForSrvinit: PVRSRVGetDeviceMemHeapsKM failed (%d)", eError));
571 return eError;
572 }
573
574 return eError;
575}
576
577IMG_EXPORT
578PVRSRV_ERROR DevInitSGXPart2KM (PVRSRV_PER_PROCESS_DATA *psPerProc,
579 IMG_HANDLE hDevHandle,
580 SGX_BRIDGE_INIT_INFO *psInitInfo)
581{
582 PVRSRV_DEVICE_NODE *psDeviceNode;
583 PVRSRV_SGXDEV_INFO *psDevInfo;
584 PVRSRV_ERROR eError;
585 SGX_DEVICE_MAP *psSGXDeviceMap;
586 PVRSRV_DEV_POWER_STATE eDefaultPowerState;
587
588 PDUMPCOMMENT("SGX Initialisation Part 2");
589
590 psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle;
591 psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
592
593
594
595 eError = InitDevInfo(psPerProc, psDeviceNode, psInitInfo);
596 if (eError != PVRSRV_OK)
597 {
598 PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to load EDM program"));
599 goto failed_init_dev_info;
600 }
601
602
603 eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
604 (IMG_VOID**)&psSGXDeviceMap);
605 if (eError != PVRSRV_OK)
606 {
607 PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to get device memory map!"));
608 return PVRSRV_ERROR_INIT_FAILURE;
609 }
610
611
612 if (psSGXDeviceMap->pvRegsCpuVBase)
613 {
614 psDevInfo->pvRegsBaseKM = psSGXDeviceMap->pvRegsCpuVBase;
615 }
616 else
617 {
618
619 psDevInfo->pvRegsBaseKM = OSMapPhysToLin(psSGXDeviceMap->sRegsCpuPBase,
620 psSGXDeviceMap->ui32RegsSize,
621 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
622 IMG_NULL);
623 if (!psDevInfo->pvRegsBaseKM)
624 {
625 PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in regs\n"));
626 return PVRSRV_ERROR_BAD_MAPPING;
627 }
628 }
629 psDevInfo->ui32RegSize = psSGXDeviceMap->ui32RegsSize;
630 psDevInfo->sRegsPhysBase = psSGXDeviceMap->sRegsSysPBase;
631
632
633#if defined(SGX_FEATURE_HOST_PORT)
634 if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT)
635 {
636
637 psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(psSGXDeviceMap->sHPCpuPBase,
638 psSGXDeviceMap->ui32HPSize,
639 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
640 IMG_NULL);
641 if (!psDevInfo->pvHostPortBaseKM)
642 {
643 PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in host port\n"));
644 return PVRSRV_ERROR_BAD_MAPPING;
645 }
646 psDevInfo->ui32HPSize = psSGXDeviceMap->ui32HPSize;
647 psDevInfo->sHPSysPAddr = psSGXDeviceMap->sHPSysPBase;
648 }
649#endif
650
651#if defined (SYS_USING_INTERRUPTS)
652
653
654 psDeviceNode->pvISRData = psDeviceNode;
655
656 PVR_ASSERT(psDeviceNode->pfnDeviceISR == SGX_ISRHandler);
657
658#endif
659
660
661 psDevInfo->psSGXHostCtl->ui32PowerStatus |= PVRSRV_USSE_EDM_POWMAN_NO_WORK;
662 eDefaultPowerState = PVRSRV_DEV_POWER_STATE_OFF;
663
664 eError = PVRSRVRegisterPowerDevice (psDeviceNode->sDevId.ui32DeviceIndex,
665 &SGXPrePowerState, &SGXPostPowerState,
666 &SGXPreClockSpeedChange, &SGXPostClockSpeedChange,
667 (IMG_HANDLE)psDeviceNode,
668 PVRSRV_DEV_POWER_STATE_OFF,
669 eDefaultPowerState);
670 if (eError != PVRSRV_OK)
671 {
672 PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: failed to register device with power manager"));
673 return eError;
674 }
675
676#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
677 eError = WorkaroundBRN22997Alloc(psDeviceNode);
678 if (eError != PVRSRV_OK)
679 {
680 PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to alloc memory for BRN22997 workaround"));
681 return eError;
682 }
683#endif
684
685#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
686
687 psDevInfo->ui32ExtSysCacheRegsSize = psSGXDeviceMap->ui32ExtSysCacheRegsSize;
688 psDevInfo->sExtSysCacheRegsDevPBase = psSGXDeviceMap->sExtSysCacheRegsDevPBase;
689 eError = MMU_MapExtSystemCacheRegs(psDeviceNode);
690 if (eError != PVRSRV_OK)
691 {
692 PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to map external system cache registers"));
693 return eError;
694 }
695#endif
696
697
698
699 OSMemSet(psDevInfo->psKernelCCB, 0, sizeof(PVRSRV_SGX_KERNEL_CCB));
700 OSMemSet(psDevInfo->psKernelCCBCtl, 0, sizeof(PVRSRV_SGX_CCB_CTL));
701 OSMemSet(psDevInfo->pui32KernelCCBEventKicker, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker));
702 PDUMPCOMMENT("Initialise Kernel CCB");
703 PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBMemInfo, 0, sizeof(PVRSRV_SGX_KERNEL_CCB), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBMemInfo));
704 PDUMPCOMMENT("Initialise Kernel CCB Control");
705 PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBCtlMemInfo, 0, sizeof(PVRSRV_SGX_CCB_CTL), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBCtlMemInfo));
706 PDUMPCOMMENT("Initialise Kernel CCB Event Kicker");
707 PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBEventKickerMemInfo, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
708
709 return PVRSRV_OK;
710
711failed_init_dev_info:
712 return eError;
713}
714
715static PVRSRV_ERROR DevDeInitSGX (IMG_VOID *pvDeviceNode)
716{
717 PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
718 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
719 PVRSRV_ERROR eError;
720 IMG_UINT32 ui32Heap;
721 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
722 SGX_DEVICE_MAP *psSGXDeviceMap;
723
724 if (!psDevInfo)
725 {
726
727 PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Null DevInfo"));
728 return PVRSRV_OK;
729 }
730
731#if defined(SUPPORT_HW_RECOVERY)
732 if (psDevInfo->hTimer)
733 {
734 eError = OSRemoveTimer(psDevInfo->hTimer);
735 if (eError != PVRSRV_OK)
736 {
737 PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to remove timer"));
738 return eError;
739 }
740 psDevInfo->hTimer = IMG_NULL;
741 }
742#endif
743
744#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
745
746 eError = MMU_UnmapExtSystemCacheRegs(psDeviceNode);
747 if (eError != PVRSRV_OK)
748 {
749 PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to unmap ext system cache registers"));
750 return eError;
751 }
752#endif
753
754#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
755 WorkaroundBRN22997Free(psDeviceNode);
756#endif
757
758 MMU_BIFResetPDFree(psDevInfo);
759
760
761
762 DeinitDevInfo(psDevInfo);
763
764
765 psDeviceMemoryHeap = (DEVICE_MEMORY_HEAP_INFO *)psDevInfo->pvDeviceMemoryHeap;
766 for(ui32Heap=0; ui32Heap<psDeviceNode->sDevMemoryInfo.ui32HeapCount; ui32Heap++)
767 {
768 switch(psDeviceMemoryHeap[ui32Heap].DevMemHeapType)
769 {
770 case DEVICE_MEMORY_HEAP_KERNEL:
771 case DEVICE_MEMORY_HEAP_SHARED:
772 case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
773 {
774 if (psDeviceMemoryHeap[ui32Heap].hDevMemHeap != IMG_NULL)
775 {
776 BM_DestroyHeap(psDeviceMemoryHeap[ui32Heap].hDevMemHeap);
777 }
778 break;
779 }
780 }
781 }
782
783
784 eError = BM_DestroyContext(psDeviceNode->sDevMemoryInfo.pBMKernelContext, IMG_NULL);
785 if (eError != PVRSRV_OK)
786 {
787 PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX : Failed to destroy kernel context"));
788 return eError;
789 }
790
791
792 eError = PVRSRVRemovePowerDevice (((PVRSRV_DEVICE_NODE*)pvDeviceNode)->sDevId.ui32DeviceIndex);
793 if (eError != PVRSRV_OK)
794 {
795 return eError;
796 }
797
798 eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
799 (IMG_VOID**)&psSGXDeviceMap);
800 if (eError != PVRSRV_OK)
801 {
802 PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to get device memory map!"));
803 return eError;
804 }
805
806
807 if (!psSGXDeviceMap->pvRegsCpuVBase)
808 {
809
810 if (psDevInfo->pvRegsBaseKM != IMG_NULL)
811 {
812 OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM,
813 psDevInfo->ui32RegSize,
814 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
815 IMG_NULL);
816 }
817 }
818
819#if defined(SGX_FEATURE_HOST_PORT)
820 if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT)
821 {
822
823 if (psDevInfo->pvHostPortBaseKM != IMG_NULL)
824 {
825 OSUnMapPhysToLin(psDevInfo->pvHostPortBaseKM,
826 psDevInfo->ui32HPSize,
827 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
828 IMG_NULL);
829 }
830 }
831#endif
832
833
834
835 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
836 sizeof(PVRSRV_SGXDEV_INFO),
837 psDevInfo,
838 0);
839
840 psDeviceNode->pvDevice = IMG_NULL;
841
842 if (psDeviceMemoryHeap != IMG_NULL)
843 {
844
845 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
846 sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID,
847 psDeviceMemoryHeap,
848 0);
849 }
850
851 return PVRSRV_OK;
852}
853
854
855static IMG_VOID SGXDumpDebugReg (PVRSRV_SGXDEV_INFO *psDevInfo,
856 IMG_UINT32 ui32CoreNum,
857 IMG_CHAR *pszName,
858 IMG_UINT32 ui32RegAddr)
859{
860 IMG_UINT32 ui32RegVal;
861 ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(ui32RegAddr, ui32CoreNum));
862 PVR_LOG(("(P%u) %s%08X", ui32CoreNum, pszName, ui32RegVal));
863}
864
865static IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO *psDevInfo,
866 IMG_BOOL bDumpSGXRegs)
867{
868 IMG_UINT32 ui32CoreNum;
869
870 PVR_LOG(("SGX debug (%s)", PVRVERSION_STRING));
871
872 if (bDumpSGXRegs)
873 {
874 PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Linear): 0x%08X", (IMG_UINTPTR_T)psDevInfo->pvRegsBaseKM));
875 PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Physical): 0x%08X", psDevInfo->sRegsPhysBase.uiAddr));
876
877 for (ui32CoreNum = 0; ui32CoreNum < SGX_FEATURE_MP_CORE_COUNT; ui32CoreNum++)
878 {
879
880 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_EVENT_STATUS: ", EUR_CR_EVENT_STATUS);
881 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_EVENT_STATUS2: ", EUR_CR_EVENT_STATUS2);
882 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_CTRL: ", EUR_CR_BIF_CTRL);
883 #if defined(EUR_CR_BIF_BANK0)
884 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_BANK0: ", EUR_CR_BIF_BANK0);
885 #endif
886 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_INT_STAT: ", EUR_CR_BIF_INT_STAT);
887 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_FAULT: ", EUR_CR_BIF_FAULT);
888 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_MEM_REQ_STAT: ", EUR_CR_BIF_MEM_REQ_STAT);
889 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_CLKGATECTL: ", EUR_CR_CLKGATECTL);
890 #if defined(EUR_CR_PDS_PC_BASE)
891 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_PDS_PC_BASE: ", EUR_CR_PDS_PC_BASE);
892 #endif
893 }
894 }
895
896
897
898 QueueDumpDebugInfo();
899
900 {
901
902
903 IMG_UINT32 *pui32HostCtlBuffer = (IMG_UINT32 *)psDevInfo->psSGXHostCtl;
904 IMG_UINT32 ui32LoopCounter;
905
906 PVR_LOG(("SGX Host control:"));
907
908 for (ui32LoopCounter = 0;
909 ui32LoopCounter < sizeof(*psDevInfo->psSGXHostCtl) / sizeof(*pui32HostCtlBuffer);
910 ui32LoopCounter += 4)
911 {
912 PVR_LOG(("\t(HC-%X) 0x%08X 0x%08X 0x%08X 0x%08X", ui32LoopCounter * sizeof(*pui32HostCtlBuffer),
913 pui32HostCtlBuffer[ui32LoopCounter + 0], pui32HostCtlBuffer[ui32LoopCounter + 1],
914 pui32HostCtlBuffer[ui32LoopCounter + 2], pui32HostCtlBuffer[ui32LoopCounter + 3]));
915 }
916 }
917
918 {
919
920
921 IMG_UINT32 *pui32TA3DCtlBuffer = psDevInfo->psKernelSGXTA3DCtlMemInfo->pvLinAddrKM;
922 IMG_UINT32 ui32LoopCounter;
923
924 PVR_LOG(("SGX TA/3D control:"));
925
926 for (ui32LoopCounter = 0;
927 ui32LoopCounter < psDevInfo->psKernelSGXTA3DCtlMemInfo->ui32AllocSize / sizeof(*pui32TA3DCtlBuffer);
928 ui32LoopCounter += 4)
929 {
930 PVR_LOG(("\t(T3C-%X) 0x%08X 0x%08X 0x%08X 0x%08X", ui32LoopCounter * sizeof(*pui32TA3DCtlBuffer),
931 pui32TA3DCtlBuffer[ui32LoopCounter + 0], pui32TA3DCtlBuffer[ui32LoopCounter + 1],
932 pui32TA3DCtlBuffer[ui32LoopCounter + 2], pui32TA3DCtlBuffer[ui32LoopCounter + 3]));
933 }
934 }
935
936 #if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
937 {
938 IMG_UINT32 *pui32MKTraceBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->pvLinAddrKM;
939 IMG_UINT32 ui32LastStatusCode, ui32WriteOffset;
940
941 ui32LastStatusCode = *pui32MKTraceBuffer;
942 pui32MKTraceBuffer++;
943 ui32WriteOffset = *pui32MKTraceBuffer;
944 pui32MKTraceBuffer++;
945
946 PVR_LOG(("Last SGX microkernel status code: %08X", ui32LastStatusCode));
947
948 #if defined(PVRSRV_DUMP_MK_TRACE)
949
950
951 {
952 IMG_UINT32 ui32LoopCounter;
953
954 for (ui32LoopCounter = 0;
955 ui32LoopCounter < SGXMK_TRACE_BUFFER_SIZE;
956 ui32LoopCounter++)
957 {
958 IMG_UINT32 *pui32BufPtr;
959 pui32BufPtr = pui32MKTraceBuffer +
960 (((ui32WriteOffset + ui32LoopCounter) % SGXMK_TRACE_BUFFER_SIZE) * 4);
961 PVR_LOG(("\t(MKT-%X) %08X %08X %08X %08X", ui32LoopCounter,
962 pui32BufPtr[2], pui32BufPtr[3], pui32BufPtr[1], pui32BufPtr[0]));
963 }
964 }
965 #endif
966 }
967 #endif
968
969 {
970
971
972 PVR_LOG(("SGX Kernel CCB WO:0x%X RO:0x%X",
973 psDevInfo->psKernelCCBCtl->ui32WriteOffset,
974 psDevInfo->psKernelCCBCtl->ui32ReadOffset));
975
976 #if defined(PVRSRV_DUMP_KERNEL_CCB)
977 {
978 IMG_UINT32 ui32LoopCounter;
979
980 for (ui32LoopCounter = 0;
981 ui32LoopCounter < sizeof(psDevInfo->psKernelCCB->asCommands) /
982 sizeof(psDevInfo->psKernelCCB->asCommands[0]);
983 ui32LoopCounter++)
984 {
985 SGXMKIF_COMMAND *psCommand = &psDevInfo->psKernelCCB->asCommands[ui32LoopCounter];
986
987 PVR_LOG(("\t(KCCB-%X) %08X %08X - %08X %08X %08X %08X", ui32LoopCounter,
988 psCommand->ui32ServiceAddress, psCommand->ui32CacheControl,
989 psCommand->ui32Data[0], psCommand->ui32Data[1],
990 psCommand->ui32Data[2], psCommand->ui32Data[3]));
991 }
992 }
993 #endif
994 }
995}
996
997
998#if defined(SYS_USING_INTERRUPTS) || defined(SUPPORT_HW_RECOVERY)
999static
1000IMG_VOID HWRecoveryResetSGX (PVRSRV_DEVICE_NODE *psDeviceNode,
1001 IMG_UINT32 ui32Component,
1002 IMG_UINT32 ui32CallerID)
1003{
1004 PVRSRV_ERROR eError;
1005 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
1006 SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
1007
1008 PVR_UNREFERENCED_PARAMETER(ui32Component);
1009
1010
1011
1012 eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE);
1013 if(eError != PVRSRV_OK)
1014 {
1015
1016
1017
1018 PVR_DPF((PVR_DBG_WARNING,"HWRecoveryResetSGX: Power transition in progress"));
1019 return;
1020 }
1021
1022 psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_HWR;
1023
1024 PVR_LOG(("HWRecoveryResetSGX: SGX Hardware Recovery triggered"));
1025
1026 SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_TRUE);
1027
1028
1029 PDUMPSUSPEND();
1030
1031
1032 eError = SGXInitialise(psDevInfo, IMG_TRUE);
1033 if (eError != PVRSRV_OK)
1034 {
1035 PVR_DPF((PVR_DBG_ERROR,"HWRecoveryResetSGX: SGXInitialise failed (%d)", eError));
1036 }
1037
1038
1039 PDUMPRESUME();
1040
1041 PVRSRVPowerUnlock(ui32CallerID);
1042
1043
1044 SGXScheduleProcessQueuesKM(psDeviceNode);
1045
1046
1047
1048 PVRSRVProcessQueues(ui32CallerID, IMG_TRUE);
1049}
1050#endif
1051
1052
1053#if defined(SUPPORT_HW_RECOVERY)
1054IMG_VOID SGXOSTimer(IMG_VOID *pvData)
1055{
1056 PVRSRV_DEVICE_NODE *psDeviceNode = pvData;
1057 PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
1058 static IMG_UINT32 ui32EDMTasks = 0;
1059 static IMG_UINT32 ui32LockupCounter = 0;
1060 static IMG_UINT32 ui32NumResets = 0;
1061 IMG_UINT32 ui32CurrentEDMTasks;
1062 IMG_BOOL bLockup = IMG_FALSE;
1063 IMG_BOOL bPoweredDown;
1064
1065
1066 psDevInfo->ui32TimeStamp++;
1067
1068#if defined(NO_HARDWARE)
1069 bPoweredDown = IMG_TRUE;
1070#else
1071 bPoweredDown = (SGXIsDevicePowered(psDeviceNode)) ? IMG_FALSE : IMG_TRUE;
1072#endif
1073
1074
1075
1076 if (bPoweredDown)
1077 {
1078 ui32LockupCounter = 0;
1079 }
1080 else
1081 {
1082
1083 ui32CurrentEDMTasks = OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg0);
1084 if (psDevInfo->ui32EDMTaskReg1 != 0)
1085 {
1086 ui32CurrentEDMTasks ^= OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg1);
1087 }
1088 if ((ui32CurrentEDMTasks == ui32EDMTasks) &&
1089 (psDevInfo->ui32NumResets == ui32NumResets))
1090 {
1091 ui32LockupCounter++;
1092 if (ui32LockupCounter == 3)
1093 {
1094 ui32LockupCounter = 0;
1095 PVR_DPF((PVR_DBG_ERROR, "SGXOSTimer() detected SGX lockup (0x%x tasks)", ui32EDMTasks));
1096
1097 bLockup = IMG_TRUE;
1098 }
1099 }
1100 else
1101 {
1102 ui32LockupCounter = 0;
1103 ui32EDMTasks = ui32CurrentEDMTasks;
1104 ui32NumResets = psDevInfo->ui32NumResets;
1105 }
1106 }
1107
1108 if (bLockup)
1109 {
1110 SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
1111
1112
1113 psSGXHostCtl->ui32HostDetectedLockups ++;
1114
1115
1116 HWRecoveryResetSGX(psDeviceNode, 0, KERNEL_ID);
1117 }
1118}
1119#endif
1120
1121
1122#if defined(SYS_USING_INTERRUPTS)
1123
1124IMG_BOOL SGX_ISRHandler (IMG_VOID *pvData)
1125{
1126 IMG_BOOL bInterruptProcessed = IMG_FALSE;
1127
1128
1129
1130 {
1131 IMG_UINT32 ui32EventStatus, ui32EventEnable;
1132 IMG_UINT32 ui32EventClear = 0;
1133#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
1134 IMG_UINT32 ui32EventStatus2, ui32EventEnable2;
1135#endif
1136 IMG_UINT32 ui32EventClear2 = 0;
1137 PVRSRV_DEVICE_NODE *psDeviceNode;
1138 PVRSRV_SGXDEV_INFO *psDevInfo;
1139
1140
1141 if(pvData == IMG_NULL)
1142 {
1143 PVR_DPF((PVR_DBG_ERROR, "SGX_ISRHandler: Invalid params\n"));
1144 return bInterruptProcessed;
1145 }
1146
1147 psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
1148 psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
1149
1150 ui32EventStatus = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS);
1151 ui32EventEnable = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE);
1152
1153
1154 ui32EventStatus &= ui32EventEnable;
1155
1156#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
1157 ui32EventStatus2 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2);
1158 ui32EventEnable2 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE2);
1159
1160
1161 ui32EventStatus2 &= ui32EventEnable2;
1162#endif
1163
1164
1165
1166 if (ui32EventStatus & EUR_CR_EVENT_STATUS_SW_EVENT_MASK)
1167 {
1168 ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK;
1169 }
1170
1171#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
1172 if (ui32EventStatus2 & EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_MASK)
1173 {
1174 ui32EventClear2 |= EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_MASK;
1175 }
1176
1177 if (ui32EventStatus2 & EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK)
1178 {
1179 ui32EventClear2 |= EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_MASK;
1180 }
1181#endif
1182
1183 if (ui32EventClear || ui32EventClear2)
1184 {
1185 bInterruptProcessed = IMG_TRUE;
1186
1187
1188 ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK;
1189
1190
1191 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32EventClear);
1192 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR2, ui32EventClear2);
1193 }
1194 }
1195
1196 return bInterruptProcessed;
1197}
1198
1199
1200static IMG_VOID SGX_MISRHandler (IMG_VOID *pvData)
1201{
1202 PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
1203 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
1204 SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
1205
1206 if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) != 0UL) &&
1207 ((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) == 0UL))
1208 {
1209 HWRecoveryResetSGX(psDeviceNode, 0, ISR_ID);
1210 }
1211
1212#if defined(OS_SUPPORTS_IN_LISR)
1213 if (psDeviceNode->bReProcessDeviceCommandComplete)
1214 {
1215 SGXScheduleProcessQueuesKM(psDeviceNode);
1216 }
1217#endif
1218
1219 SGXTestActivePowerEvent(psDeviceNode, ISR_ID);
1220}
1221#endif
1222
1223
1224
1225#if defined(SUPPORT_MEMORY_TILING)
1226PVRSRV_ERROR SGX_AllocMemTilingRange(PVRSRV_DEVICE_NODE *psDeviceNode,
1227 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
1228 IMG_UINT32 ui32TilingStride,
1229 IMG_UINT32 *pui32RangeIndex)
1230{
1231#if defined(SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS)
1232 PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
1233 IMG_UINT32 i;
1234 IMG_UINT32 ui32Start;
1235 IMG_UINT32 ui32End;
1236 IMG_UINT32 ui32Offset;
1237 IMG_UINT32 ui32Val;
1238
1239
1240 for(i=0; i<10; i++)
1241 {
1242 if((psDevInfo->ui32MemTilingUsage & (1U << i)) == 0)
1243 {
1244
1245 psDevInfo->ui32MemTilingUsage |= 1U << i;
1246
1247 *pui32RangeIndex = i;
1248 goto RangeAllocated;
1249 }
1250 }
1251
1252 PVR_DPF((PVR_DBG_ERROR,"SGX_AllocMemTilingRange: all tiling ranges in use"));
1253 return PVRSRV_ERROR_EXCEEDED_HW_LIMITS;
1254
1255RangeAllocated:
1256 ui32Offset = EUR_CR_BIF_TILE0 + (i<<2);
1257
1258 ui32Start = psMemInfo->sDevVAddr.uiAddr;
1259 ui32End = ui32Start + psMemInfo->ui32AllocSize + SGX_MMU_PAGE_SIZE - 1;
1260
1261 ui32Val = ((ui32TilingStride << EUR_CR_BIF_TILE0_CFG_SHIFT) & EUR_CR_BIF_TILE0_CFG_MASK)
1262 | (((ui32End>>20) << EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT) & EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK)
1263 | (((ui32Start>>20) << EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT) & EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK)
1264 | (0x8 << EUR_CR_BIF_TILE0_CFG_SHIFT);
1265
1266
1267 OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val);
1268 PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val);
1269
1270 ui32Offset = EUR_CR_BIF_TILE0_ADDR_EXT + (i<<2);
1271
1272 ui32Val = (((ui32End>>12) << EUR_CR_BIF_TILE0_ADDR_EXT_MAX_SHIFT) & EUR_CR_BIF_TILE0_ADDR_EXT_MAX_MASK)
1273 | (((ui32Start>>12) << EUR_CR_BIF_TILE0_ADDR_EXT_MIN_SHIFT) & EUR_CR_BIF_TILE0_ADDR_EXT_MIN_MASK);
1274
1275
1276 OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val);
1277 PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val);
1278
1279 return PVRSRV_OK;
1280#else
1281 PVR_UNREFERENCED_PARAMETER(psDeviceNode);
1282 PVR_UNREFERENCED_PARAMETER(psMemInfo);
1283 PVR_UNREFERENCED_PARAMETER(ui32TilingStride);
1284 PVR_UNREFERENCED_PARAMETER(pui32RangeIndex);
1285
1286 PVR_DPF((PVR_DBG_ERROR,"SGX_AllocMemTilingRange: device does not support memory tiling"));
1287 return PVRSRV_ERROR_NOT_SUPPORTED;
1288#endif
1289}
1290
1291PVRSRV_ERROR SGX_FreeMemTilingRange(PVRSRV_DEVICE_NODE *psDeviceNode,
1292 IMG_UINT32 ui32RangeIndex)
1293{
1294#if defined(SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS)
1295 PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
1296 IMG_UINT32 ui32Offset;
1297 IMG_UINT32 ui32Val;
1298
1299 if(ui32RangeIndex >= 10)
1300 {
1301 PVR_DPF((PVR_DBG_ERROR,"SGX_FreeMemTilingRange: invalid Range index "));
1302 return PVRSRV_ERROR_INVALID_PARAMS;
1303 }
1304
1305
1306 psDevInfo->ui32MemTilingUsage &= ~(1<<ui32RangeIndex);
1307
1308
1309 ui32Offset = EUR_CR_BIF_TILE0 + (ui32RangeIndex<<2);
1310 ui32Val = 0;
1311
1312
1313 OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val);
1314 PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val);
1315
1316 return PVRSRV_OK;
1317#else
1318 PVR_UNREFERENCED_PARAMETER(psDeviceNode);
1319 PVR_UNREFERENCED_PARAMETER(ui32RangeIndex);
1320
1321 PVR_DPF((PVR_DBG_ERROR,"SGX_FreeMemTilingRange: device does not support memory tiling"));
1322 return PVRSRV_ERROR_NOT_SUPPORTED;
1323#endif
1324}
1325#endif
1326
1327
1328PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode)
1329{
1330 DEVICE_MEMORY_INFO *psDevMemoryInfo;
1331 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
1332
1333
1334 psDeviceNode->sDevId.eDeviceType = DEV_DEVICE_TYPE;
1335 psDeviceNode->sDevId.eDeviceClass = DEV_DEVICE_CLASS;
1336#if defined(PDUMP)
1337 {
1338
1339 SGX_DEVICE_MAP *psSGXDeviceMemMap;
1340 SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
1341 (IMG_VOID**)&psSGXDeviceMemMap);
1342
1343 psDeviceNode->sDevId.pszPDumpDevName = psSGXDeviceMemMap->pszPDumpDevName;
1344 PVR_ASSERT(psDeviceNode->sDevId.pszPDumpDevName != IMG_NULL);
1345 }
1346
1347 psDeviceNode->sDevId.pszPDumpRegName = SGX_PDUMPREG_NAME;
1348#endif
1349
1350 psDeviceNode->pfnInitDevice = &DevInitSGXPart1;
1351 psDeviceNode->pfnDeInitDevice = &DevDeInitSGX;
1352
1353 psDeviceNode->pfnInitDeviceCompatCheck = &SGXDevInitCompatCheck;
1354#if defined(PDUMP)
1355 psDeviceNode->pfnPDumpInitDevice = &SGXResetPDump;
1356 psDeviceNode->pfnMMUGetContextID = &MMU_GetPDumpContextID;
1357#endif
1358
1359
1360 psDeviceNode->pfnMMUInitialise = &MMU_Initialise;
1361 psDeviceNode->pfnMMUFinalise = &MMU_Finalise;
1362 psDeviceNode->pfnMMUInsertHeap = &MMU_InsertHeap;
1363 psDeviceNode->pfnMMUCreate = &MMU_Create;
1364 psDeviceNode->pfnMMUDelete = &MMU_Delete;
1365 psDeviceNode->pfnMMUAlloc = &MMU_Alloc;
1366 psDeviceNode->pfnMMUFree = &MMU_Free;
1367 psDeviceNode->pfnMMUMapPages = &MMU_MapPages;
1368 psDeviceNode->pfnMMUMapShadow = &MMU_MapShadow;
1369 psDeviceNode->pfnMMUUnmapPages = &MMU_UnmapPages;
1370 psDeviceNode->pfnMMUMapScatter = &MMU_MapScatter;
1371 psDeviceNode->pfnMMUGetPhysPageAddr = &MMU_GetPhysPageAddr;
1372 psDeviceNode->pfnMMUGetPDDevPAddr = &MMU_GetPDDevPAddr;
1373
1374#if defined (SYS_USING_INTERRUPTS)
1375
1376
1377 psDeviceNode->pfnDeviceISR = SGX_ISRHandler;
1378 psDeviceNode->pfnDeviceMISR = SGX_MISRHandler;
1379#endif
1380
1381#if defined(SUPPORT_MEMORY_TILING)
1382 psDeviceNode->pfnAllocMemTilingRange = SGX_AllocMemTilingRange;
1383 psDeviceNode->pfnFreeMemTilingRange = SGX_FreeMemTilingRange;
1384#endif
1385
1386
1387
1388 psDeviceNode->pfnDeviceCommandComplete = &SGXCommandComplete;
1389
1390
1391
1392 psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
1393
1394 psDevMemoryInfo->ui32AddressSpaceSizeLog2 = SGX_FEATURE_ADDRESS_SPACE_SIZE;
1395
1396
1397 psDevMemoryInfo->ui32Flags = 0;
1398
1399
1400 if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
1401 sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID,
1402 (IMG_VOID **)&psDevMemoryInfo->psDeviceMemoryHeap, 0,
1403 "Array of Device Memory Heap Info") != PVRSRV_OK)
1404 {
1405 PVR_DPF((PVR_DBG_ERROR,"SGXRegisterDevice : Failed to alloc memory for DEVICE_MEMORY_HEAP_INFO"));
1406 return (PVRSRV_ERROR_OUT_OF_MEMORY);
1407 }
1408 OSMemSet(psDevMemoryInfo->psDeviceMemoryHeap, 0, sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID);
1409
1410 psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
1411
1412
1413
1414
1415
1416 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_HEAP_ID);
1417 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_HEAP_BASE;
1418 psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_HEAP_SIZE;
1419 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1420 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1421 | PVRSRV_HAP_SINGLE_PROCESS;
1422 psDeviceMemoryHeap->pszName = "General";
1423 psDeviceMemoryHeap->pszBSName = "General BS";
1424 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1425
1426 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1427#if !defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
1428
1429 psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
1430#endif
1431 psDeviceMemoryHeap++;
1432
1433
1434
1435 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_TADATA_HEAP_ID);
1436 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_TADATA_HEAP_BASE;
1437 psDeviceMemoryHeap->ui32HeapSize = SGX_TADATA_HEAP_SIZE;
1438 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1439 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1440 | PVRSRV_HAP_MULTI_PROCESS;
1441 psDeviceMemoryHeap->pszName = "TA Data";
1442 psDeviceMemoryHeap->pszBSName = "TA Data BS";
1443 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1444
1445 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1446 psDeviceMemoryHeap++;
1447
1448
1449
1450 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_CODE_HEAP_ID);
1451 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_CODE_HEAP_BASE;
1452 psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_CODE_HEAP_SIZE;
1453 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1454 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1455 | PVRSRV_HAP_MULTI_PROCESS;
1456 psDeviceMemoryHeap->pszName = "Kernel Code";
1457 psDeviceMemoryHeap->pszBSName = "Kernel Code BS";
1458 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
1459
1460 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1461 psDeviceMemoryHeap++;
1462
1463
1464
1465 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_DATA_HEAP_ID);
1466 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_DATA_HEAP_BASE;
1467 psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_DATA_HEAP_SIZE;
1468 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1469 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1470 | PVRSRV_HAP_MULTI_PROCESS;
1471 psDeviceMemoryHeap->pszName = "KernelData";
1472 psDeviceMemoryHeap->pszBSName = "KernelData BS";
1473 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
1474
1475 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1476 psDeviceMemoryHeap++;
1477
1478
1479
1480 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PIXELSHADER_HEAP_ID);
1481 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PIXELSHADER_HEAP_BASE;
1482
1483
1484
1485
1486
1487
1488 psDeviceMemoryHeap->ui32HeapSize = ((10 << SGX_USE_CODE_SEGMENT_RANGE_BITS) - 0x00001000);
1489 PVR_ASSERT(psDeviceMemoryHeap->ui32HeapSize <= SGX_PIXELSHADER_HEAP_SIZE);
1490 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1491 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1492 | PVRSRV_HAP_SINGLE_PROCESS;
1493 psDeviceMemoryHeap->pszName = "PixelShaderUSSE";
1494 psDeviceMemoryHeap->pszBSName = "PixelShaderUSSE BS";
1495 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1496
1497 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1498 psDeviceMemoryHeap++;
1499
1500
1501
1502 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_VERTEXSHADER_HEAP_ID);
1503 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_VERTEXSHADER_HEAP_BASE;
1504
1505 psDeviceMemoryHeap->ui32HeapSize = ((4 << SGX_USE_CODE_SEGMENT_RANGE_BITS) - 0x00001000);
1506 PVR_ASSERT(psDeviceMemoryHeap->ui32HeapSize <= SGX_VERTEXSHADER_HEAP_SIZE);
1507 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1508 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1509 | PVRSRV_HAP_SINGLE_PROCESS;
1510 psDeviceMemoryHeap->pszName = "VertexShaderUSSE";
1511 psDeviceMemoryHeap->pszBSName = "VertexShaderUSSE BS";
1512 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1513
1514 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1515 psDeviceMemoryHeap++;
1516
1517
1518
1519 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSPIXEL_CODEDATA_HEAP_ID);
1520 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSPIXEL_CODEDATA_HEAP_BASE;
1521 psDeviceMemoryHeap->ui32HeapSize = SGX_PDSPIXEL_CODEDATA_HEAP_SIZE;
1522 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1523 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1524 | PVRSRV_HAP_SINGLE_PROCESS;
1525 psDeviceMemoryHeap->pszName = "PDSPixelCodeData";
1526 psDeviceMemoryHeap->pszBSName = "PDSPixelCodeData BS";
1527 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1528
1529 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1530 psDeviceMemoryHeap++;
1531
1532
1533
1534 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSVERTEX_CODEDATA_HEAP_ID);
1535 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSVERTEX_CODEDATA_HEAP_BASE;
1536 psDeviceMemoryHeap->ui32HeapSize = SGX_PDSVERTEX_CODEDATA_HEAP_SIZE;
1537 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1538 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1539 | PVRSRV_HAP_SINGLE_PROCESS;
1540 psDeviceMemoryHeap->pszName = "PDSVertexCodeData";
1541 psDeviceMemoryHeap->pszBSName = "PDSVertexCodeData BS";
1542 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1543
1544 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1545 psDeviceMemoryHeap++;
1546
1547
1548
1549 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_SYNCINFO_HEAP_ID);
1550 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_SYNCINFO_HEAP_BASE;
1551 psDeviceMemoryHeap->ui32HeapSize = SGX_SYNCINFO_HEAP_SIZE;
1552 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1553 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1554 | PVRSRV_HAP_MULTI_PROCESS;
1555 psDeviceMemoryHeap->pszName = "CacheCoherent";
1556 psDeviceMemoryHeap->pszBSName = "CacheCoherent BS";
1557 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
1558
1559 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1560
1561 psDevMemoryInfo->ui32SyncHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
1562 psDeviceMemoryHeap++;
1563
1564
1565
1566 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_3DPARAMETERS_HEAP_ID);
1567 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_3DPARAMETERS_HEAP_BASE;
1568 psDeviceMemoryHeap->ui32HeapSize = SGX_3DPARAMETERS_HEAP_SIZE;
1569 psDeviceMemoryHeap->pszName = "3DParameters";
1570 psDeviceMemoryHeap->pszBSName = "3DParameters BS";
1571#if defined(SUPPORT_PERCONTEXT_PB)
1572 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1573 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1574 | PVRSRV_HAP_SINGLE_PROCESS;
1575 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1576#else
1577 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1578 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1579 | PVRSRV_HAP_MULTI_PROCESS;
1580 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
1581#endif
1582
1583 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1584 psDeviceMemoryHeap++;
1585
1586
1587#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
1588
1589 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_MAPPING_HEAP_ID);
1590 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_MAPPING_HEAP_BASE;
1591 psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_MAPPING_HEAP_SIZE;
1592 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_MULTI_PROCESS;
1593 psDeviceMemoryHeap->pszName = "GeneralMapping";
1594 psDeviceMemoryHeap->pszBSName = "GeneralMapping BS";
1595 #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && defined(FIX_HW_BRN_23410)
1596
1597
1598
1599
1600
1601
1602
1603 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
1604 #else
1605 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1606 #endif
1607
1608
1609 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1610
1611 psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
1612 psDeviceMemoryHeap++;
1613#endif
1614
1615
1616#if defined(SGX_FEATURE_2D_HARDWARE)
1617
1618 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_2D_HEAP_ID);
1619 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_2D_HEAP_BASE;
1620 psDeviceMemoryHeap->ui32HeapSize = SGX_2D_HEAP_SIZE;
1621 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1622 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1623 | PVRSRV_HAP_SINGLE_PROCESS;
1624 psDeviceMemoryHeap->pszName = "2D";
1625 psDeviceMemoryHeap->pszBSName = "2D BS";
1626
1627 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
1628
1629 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1630 psDeviceMemoryHeap++;
1631#endif
1632
1633
1634#if defined(FIX_HW_BRN_26915)
1635
1636
1637 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_CGBUFFER_HEAP_ID);
1638 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_CGBUFFER_HEAP_BASE;
1639 psDeviceMemoryHeap->ui32HeapSize = SGX_CGBUFFER_HEAP_SIZE;
1640 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1641 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1642 | PVRSRV_HAP_SINGLE_PROCESS;
1643 psDeviceMemoryHeap->pszName = "CGBuffer";
1644 psDeviceMemoryHeap->pszBSName = "CGBuffer BS";
1645
1646 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1647
1648 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1649 psDeviceMemoryHeap++;
1650#endif
1651
1652
1653 psDevMemoryInfo->ui32HeapCount = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
1654
1655 return PVRSRV_OK;
1656}
1657
1658#if defined(PDUMP)
1659static
1660PVRSRV_ERROR SGXResetPDump(PVRSRV_DEVICE_NODE *psDeviceNode)
1661{
1662 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)(psDeviceNode->pvDevice);
1663 psDevInfo->psKernelCCBInfo->ui32CCBDumpWOff = 0;
1664 PVR_DPF((PVR_DBG_MESSAGE, "Reset pdump CCB write offset."));
1665
1666 return PVRSRV_OK;
1667}
1668#endif
1669
1670
1671IMG_EXPORT
1672PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE hDevCookie,
1673 SGX_CLIENT_INFO* psClientInfo)
1674{
1675 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
1676
1677
1678
1679 psDevInfo->ui32ClientRefCount++;
1680
1681
1682
1683 psClientInfo->ui32ProcessID = OSGetCurrentProcessIDKM();
1684
1685
1686
1687 OSMemCopy(&psClientInfo->asDevData, &psDevInfo->asSGXDevData, sizeof(psClientInfo->asDevData));
1688
1689
1690 return PVRSRV_OK;
1691}
1692
1693
1694IMG_VOID SGXPanic(PVRSRV_SGXDEV_INFO *psDevInfo)
1695{
1696 PVR_LOG(("SGX panic"));
1697 SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
1698 OSPanic();
1699}
1700
1701
1702PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
1703{
1704 PVRSRV_ERROR eError;
1705 PVRSRV_SGXDEV_INFO *psDevInfo;
1706 IMG_UINT32 ui32BuildOptions, ui32BuildOptionsMismatch;
1707#if !defined(NO_HARDWARE)
1708 PPVRSRV_KERNEL_MEM_INFO psMemInfo;
1709 PVRSRV_SGX_MISCINFO_INFO *psSGXMiscInfoInt;
1710 PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
1711 SGX_MISCINFO_STRUCT_SIZES *psSGXStructSizes;
1712 IMG_BOOL bStructSizesFailed;
1713
1714
1715 IMG_BOOL bCheckCoreRev;
1716 const IMG_UINT32 aui32CoreRevExceptions[] =
1717 {
1718 0x10100, 0x10101
1719 };
1720 const IMG_UINT32 ui32NumCoreExceptions = sizeof(aui32CoreRevExceptions) / (2*sizeof(IMG_UINT32));
1721 IMG_UINT i;
1722#endif
1723
1724
1725 if(psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_SGX)
1726 {
1727 PVR_LOG(("(FAIL) SGXInit: Device not of type SGX"));
1728 eError = PVRSRV_ERROR_INVALID_PARAMS;
1729 goto chk_exit;
1730 }
1731
1732 psDevInfo = psDeviceNode->pvDevice;
1733
1734
1735
1736 ui32BuildOptions = (SGX_BUILD_OPTIONS);
1737 if (ui32BuildOptions != psDevInfo->ui32ClientBuildOptions)
1738 {
1739 ui32BuildOptionsMismatch = ui32BuildOptions ^ psDevInfo->ui32ClientBuildOptions;
1740 if ( (psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch) != 0)
1741 {
1742 PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; "
1743 "extra options present in client-side driver: (0x%x). Please check sgx_options.h",
1744 psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch ));
1745 }
1746
1747 if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0)
1748 {
1749 PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; "
1750 "extra options present in KM: (0x%x). Please check sgx_options.h",
1751 ui32BuildOptions & ui32BuildOptionsMismatch ));
1752 }
1753 eError = PVRSRV_ERROR_BUILD_MISMATCH;
1754 goto chk_exit;
1755 }
1756 else
1757 {
1758 PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Client-side and KM driver build options match. [ OK ]"));
1759 }
1760
1761#if !defined (NO_HARDWARE)
1762 psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
1763
1764
1765 psSGXMiscInfoInt = psMemInfo->pvLinAddrKM;
1766 psSGXMiscInfoInt->ui32MiscInfoFlags = 0;
1767 psSGXMiscInfoInt->ui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_GET_STRUCT_SIZES;
1768 eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode);
1769
1770
1771 if(eError != PVRSRV_OK)
1772 {
1773 PVR_LOG(("(FAIL) SGXInit: Unable to validate device DDK version"));
1774 goto chk_exit;
1775 }
1776 psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
1777 if( (psSGXFeatures->ui32DDKVersion !=
1778 ((PVRVERSION_MAJ << 16) |
1779 (PVRVERSION_MIN << 8) |
1780 PVRVERSION_BRANCH) ) ||
1781 (psSGXFeatures->ui32DDKBuild != PVRVERSION_BUILD) )
1782 {
1783 PVR_LOG(("(FAIL) SGXInit: Incompatible driver DDK revision (%d)/device DDK revision (%d).",
1784 PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild));
1785 eError = PVRSRV_ERROR_DDK_VERSION_MISMATCH;
1786 PVR_DBG_BREAK;
1787 goto chk_exit;
1788 }
1789 else
1790 {
1791 PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: driver DDK (%d) and device DDK (%d) match. [ OK ]",
1792 PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild));
1793 }
1794
1795
1796 if (psSGXFeatures->ui32CoreRevSW == 0)
1797 {
1798
1799
1800 PVR_LOG(("SGXInit: HW core rev (%x) check skipped.",
1801 psSGXFeatures->ui32CoreRev));
1802 }
1803 else
1804 {
1805
1806 bCheckCoreRev = IMG_TRUE;
1807 for(i=0; i<ui32NumCoreExceptions; i+=2)
1808 {
1809 if( (psSGXFeatures->ui32CoreRev==aui32CoreRevExceptions[i]) &&
1810 (psSGXFeatures->ui32CoreRevSW==aui32CoreRevExceptions[i+1]) )
1811 {
1812 PVR_LOG(("SGXInit: HW core rev (%x), SW core rev (%x) check skipped.",
1813 psSGXFeatures->ui32CoreRev,
1814 psSGXFeatures->ui32CoreRevSW));
1815 bCheckCoreRev = IMG_FALSE;
1816 }
1817 }
1818
1819 if (bCheckCoreRev)
1820 {
1821 if (psSGXFeatures->ui32CoreRev != psSGXFeatures->ui32CoreRevSW)
1822 {
1823 PVR_LOG(("(FAIL) SGXInit: Incompatible HW core rev (%x) and SW core rev (%x).",
1824 psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW));
1825 eError = PVRSRV_ERROR_BUILD_MISMATCH;
1826 goto chk_exit;
1827 }
1828 else
1829 {
1830 PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: HW core rev (%x) and SW core rev (%x) match. [ OK ]",
1831 psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW));
1832 }
1833 }
1834 }
1835
1836
1837 psSGXStructSizes = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXStructSizes;
1838
1839 bStructSizesFailed = IMG_FALSE;
1840
1841 CHECK_SIZE(HOST_CTL);
1842 CHECK_SIZE(COMMAND);
1843#if defined(SGX_FEATURE_2D_HARDWARE)
1844 CHECK_SIZE(2DCMD);
1845 CHECK_SIZE(2DCMD_SHARED);
1846#endif
1847 CHECK_SIZE(CMDTA);
1848 CHECK_SIZE(CMDTA_SHARED);
1849 CHECK_SIZE(TRANSFERCMD);
1850 CHECK_SIZE(TRANSFERCMD_SHARED);
1851
1852 CHECK_SIZE(3DREGISTERS);
1853 CHECK_SIZE(HWPBDESC);
1854 CHECK_SIZE(HWRENDERCONTEXT);
1855 CHECK_SIZE(HWRENDERDETAILS);
1856 CHECK_SIZE(HWRTDATA);
1857 CHECK_SIZE(HWRTDATASET);
1858 CHECK_SIZE(HWTRANSFERCONTEXT);
1859
1860 if (bStructSizesFailed == IMG_TRUE)
1861 {
1862 PVR_LOG(("(FAIL) SGXInit: Mismatch in SGXMKIF structure sizes."));
1863 eError = PVRSRV_ERROR_BUILD_MISMATCH;
1864 goto chk_exit;
1865 }
1866 else
1867 {
1868 PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: SGXMKIF structure sizes match. [ OK ]"));
1869 }
1870
1871
1872 ui32BuildOptions = psSGXFeatures->ui32BuildOptions;
1873 if (ui32BuildOptions != (SGX_BUILD_OPTIONS))
1874 {
1875 ui32BuildOptionsMismatch = ui32BuildOptions ^ (SGX_BUILD_OPTIONS);
1876 if ( ((SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch) != 0)
1877 {
1878 PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; "
1879 "extra options present in driver: (0x%x). Please check sgx_options.h",
1880 (SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch ));
1881 }
1882
1883 if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0)
1884 {
1885 PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; "
1886 "extra options present in microkernel: (0x%x). Please check sgx_options.h",
1887 ui32BuildOptions & ui32BuildOptionsMismatch ));
1888 }
1889 eError = PVRSRV_ERROR_BUILD_MISMATCH;
1890 goto chk_exit;
1891 }
1892 else
1893 {
1894 PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Driver and microkernel build options match. [ OK ]"));
1895 }
1896#endif
1897
1898 eError = PVRSRV_OK;
1899chk_exit:
1900#if defined(IGNORE_SGX_INIT_COMPATIBILITY_CHECK)
1901 return PVRSRV_OK;
1902#else
1903 return eError;
1904#endif
1905}
1906
1907static
1908PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO *psDevInfo,
1909 PVRSRV_DEVICE_NODE *psDeviceNode)
1910{
1911 PVRSRV_ERROR eError;
1912 SGXMKIF_COMMAND sCommandData;
1913 PVRSRV_SGX_MISCINFO_INFO *psSGXMiscInfoInt;
1914 PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
1915 SGX_MISCINFO_STRUCT_SIZES *psSGXStructSizes;
1916
1917 PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
1918
1919 if (! psMemInfo->pvLinAddrKM)
1920 {
1921 PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Invalid address."));
1922 return PVRSRV_ERROR_INVALID_PARAMS;
1923 }
1924 psSGXMiscInfoInt = psMemInfo->pvLinAddrKM;
1925 psSGXFeatures = &psSGXMiscInfoInt->sSGXFeatures;
1926 psSGXStructSizes = &psSGXMiscInfoInt->sSGXStructSizes;
1927
1928 psSGXMiscInfoInt->ui32MiscInfoFlags &= ~PVRSRV_USSE_MISCINFO_READY;
1929
1930
1931 OSMemSet(psSGXFeatures, 0, sizeof(*psSGXFeatures));
1932 OSMemSet(psSGXStructSizes, 0, sizeof(*psSGXStructSizes));
1933
1934
1935 sCommandData.ui32Data[1] = psMemInfo->sDevVAddr.uiAddr;
1936
1937 PDUMPCOMMENT("Microkernel kick for SGXGetMiscInfo");
1938 eError = SGXScheduleCCBCommandKM(psDeviceNode,
1939 SGXMKIF_CMD_GETMISCINFO,
1940 &sCommandData,
1941 KERNEL_ID,
1942 0);
1943
1944 if (eError != PVRSRV_OK)
1945 {
1946 PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: SGXScheduleCCBCommandKM failed."));
1947 return eError;
1948 }
1949
1950
1951#if !defined(NO_HARDWARE)
1952 {
1953 IMG_BOOL bExit;
1954
1955 bExit = IMG_FALSE;
1956 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
1957 {
1958 if ((psSGXMiscInfoInt->ui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_READY) != 0)
1959 {
1960 bExit = IMG_TRUE;
1961 break;
1962 }
1963 } END_LOOP_UNTIL_TIMEOUT();
1964
1965
1966 if (!bExit)
1967 {
1968 PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Timeout occurred waiting for misc info."));
1969 return PVRSRV_ERROR_TIMEOUT;
1970 }
1971 }
1972#endif
1973
1974 return PVRSRV_OK;
1975}
1976
1977
1978
1979IMG_EXPORT
1980PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo,
1981 SGX_MISC_INFO *psMiscInfo,
1982 PVRSRV_DEVICE_NODE *psDeviceNode,
1983 IMG_HANDLE hDevMemContext)
1984{
1985 PVRSRV_ERROR eError;
1986 PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
1987 IMG_UINT32 *pui32MiscInfoFlags = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->ui32MiscInfoFlags;
1988
1989
1990 *pui32MiscInfoFlags = 0;
1991
1992#if !defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
1993 PVR_UNREFERENCED_PARAMETER(hDevMemContext);
1994#endif
1995
1996 switch(psMiscInfo->eRequest)
1997 {
1998#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
1999 case SGX_MISC_INFO_REQUEST_SET_BREAKPOINT:
2000 {
2001 IMG_UINT32 ui32MaskDM;
2002 IMG_UINT32 ui32CtrlWEnable;
2003 IMG_UINT32 ui32CtrlREnable;
2004 IMG_UINT32 ui32CtrlTrapEnable;
2005 IMG_UINT32 ui32RegVal;
2006 IMG_UINT32 ui32StartRegVal;
2007 IMG_UINT32 ui32EndRegVal;
2008 SGXMKIF_COMMAND sCommandData;
2009
2010
2011 if(psMiscInfo->uData.sSGXBreakpointInfo.bBPEnable)
2012 {
2013
2014 IMG_DEV_VIRTADDR sBPDevVAddr = psMiscInfo->uData.sSGXBreakpointInfo.sBPDevVAddr;
2015 IMG_DEV_VIRTADDR sBPDevVAddrEnd = psMiscInfo->uData.sSGXBreakpointInfo.sBPDevVAddrEnd;
2016
2017
2018 ui32StartRegVal = sBPDevVAddr.uiAddr & EUR_CR_BREAKPOINT0_START_ADDRESS_MASK;
2019 ui32EndRegVal = sBPDevVAddrEnd.uiAddr & EUR_CR_BREAKPOINT0_END_ADDRESS_MASK;
2020
2021 ui32MaskDM = psMiscInfo->uData.sSGXBreakpointInfo.ui32DataMasterMask;
2022 ui32CtrlWEnable = psMiscInfo->uData.sSGXBreakpointInfo.bWrite;
2023 ui32CtrlREnable = psMiscInfo->uData.sSGXBreakpointInfo.bRead;
2024 ui32CtrlTrapEnable = psMiscInfo->uData.sSGXBreakpointInfo.bTrapped;
2025
2026
2027 ui32RegVal = ((ui32MaskDM<<EUR_CR_BREAKPOINT0_MASK_DM_SHIFT) & EUR_CR_BREAKPOINT0_MASK_DM_MASK) |
2028 ((ui32CtrlWEnable<<EUR_CR_BREAKPOINT0_CTRL_WENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_WENABLE_MASK) |
2029 ((ui32CtrlREnable<<EUR_CR_BREAKPOINT0_CTRL_RENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_RENABLE_MASK) |
2030 ((ui32CtrlTrapEnable<<EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_MASK);
2031 }
2032 else
2033 {
2034
2035 ui32RegVal = ui32StartRegVal = ui32EndRegVal = 0;
2036 }
2037
2038
2039 sCommandData.ui32Data[0] = psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex;
2040 sCommandData.ui32Data[1] = ui32StartRegVal;
2041 sCommandData.ui32Data[2] = ui32EndRegVal;
2042 sCommandData.ui32Data[3] = ui32RegVal;
2043
2044
2045 psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0;
2046
2047 PDUMPCOMMENT("Microkernel kick for setting a data breakpoint");
2048 eError = SGXScheduleCCBCommandKM(psDeviceNode,
2049 SGXMKIF_CMD_DATABREAKPOINT,
2050 &sCommandData,
2051 KERNEL_ID,
2052 0);
2053
2054 if (eError != PVRSRV_OK)
2055 {
2056 PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: SGXScheduleCCBCommandKM failed."));
2057 return eError;
2058 }
2059
2060#if defined(NO_HARDWARE)
2061
2062 psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0;
2063#else
2064 {
2065 IMG_BOOL bExit;
2066
2067 bExit = IMG_FALSE;
2068 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
2069 {
2070 if (psDevInfo->psSGXHostCtl->ui32BPSetClearSignal != 0)
2071 {
2072 bExit = IMG_TRUE;
2073
2074 psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0;
2075 break;
2076 }
2077 } END_LOOP_UNTIL_TIMEOUT();
2078
2079
2080 if (!bExit)
2081 {
2082 PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: Timeout occurred waiting BP set/clear"));
2083 return PVRSRV_ERROR_TIMEOUT;
2084 }
2085 }
2086#endif
2087
2088 return PVRSRV_OK;
2089 }
2090
2091 case SGX_MISC_INFO_REQUEST_WAIT_FOR_BREAKPOINT:
2092 {
2093
2094
2095 PDUMPCOMMENT("Wait for data breakpoint hit");
2096
2097#if defined(NO_HARDWARE) && defined(PDUMP)
2098 {
2099 PDUMPREGPOL(SGX_PDUMPREG_NAME,
2100 EUR_CR_EVENT_STATUS2,
2101 EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK,
2102 EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK);
2103
2104 PDUMPREG(SGX_PDUMPREG_NAME,
2105 EUR_CR_EVENT_HOST_CLEAR2,
2106 EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_MASK);
2107
2108 PDUMPCOMMENT("Breakpoint detected. Wait a bit to show that pipeline stops in simulation");
2109 PDUMPIDL(2000);
2110
2111 PDUMPCOMMENT("Now we can resume");
2112 PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BREAKPOINT_TRAP, EUR_CR_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_BREAKPOINT_TRAP_CONTINUE_MASK);
2113 }
2114#else
2115 {
2116
2117 }
2118#endif
2119 return PVRSRV_OK;
2120 }
2121
2122 case SGX_MISC_INFO_REQUEST_POLL_BREAKPOINT:
2123 {
2124
2125
2126
2127
2128
2129
2130
2131#if !defined(NO_HARDWARE)
2132 IMG_BOOL bTrappedBPMaster;
2133 IMG_BOOL abTrappedBPPerCore[SGX_FEATURE_MP_CORE_COUNT];
2134 IMG_UINT32 ui32CoreNum, ui32TrappedBPCoreNum;
2135 IMG_BOOL bTrappedBPAny;
2136
2137 ui32TrappedBPCoreNum = 0;
2138 bTrappedBPMaster = !!(EUR_CR_MASTER_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT));
2139 bTrappedBPAny = bTrappedBPMaster;
2140 for (ui32CoreNum = 0; ui32CoreNum < SGX_FEATURE_MP_CORE_COUNT; ui32CoreNum++)
2141 {
2142 abTrappedBPPerCore[ui32CoreNum] = !!(EUR_CR_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum)));
2143 if (abTrappedBPPerCore[ui32CoreNum])
2144 {
2145 bTrappedBPAny = IMG_TRUE;
2146 ui32TrappedBPCoreNum = ui32CoreNum;
2147 }
2148 }
2149
2150 psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP = bTrappedBPAny;
2151
2152 if (psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP)
2153 {
2154 IMG_UINT32 ui32Info0, ui32Info1;
2155
2156 ui32Info0 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0:SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP_INFO0, ui32TrappedBPCoreNum));
2157 ui32Info1 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1:SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP_INFO1, ui32TrappedBPCoreNum));
2158
2159 psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT;
2160 psMiscInfo->uData.sSGXBreakpointInfo.sTrappedBPDevVAddr.uiAddr = ui32Info0 & EUR_CR_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK;
2161 psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPBurstLength = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT;
2162 psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBPRead = !!(ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_RNW_MASK);
2163 psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPDataMaster = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT;
2164 psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPTag = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_SHIFT;
2165 psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum = bTrappedBPMaster?65535:ui32TrappedBPCoreNum;
2166 }
2167#endif
2168 return PVRSRV_OK;
2169 }
2170
2171 case SGX_MISC_INFO_REQUEST_RESUME_BREAKPOINT:
2172 {
2173
2174
2175
2176#if !defined(NO_HARDWARE)
2177 IMG_UINT32 ui32CoreNum;
2178 IMG_BOOL bMaster;
2179 IMG_UINT32 ui32OldSeqNum, ui32NewSeqNum;
2180
2181 ui32CoreNum = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum;
2182 bMaster = ui32CoreNum > SGX_FEATURE_MP_CORE_COUNT;
2183 if (bMaster)
2184 {
2185
2186
2187 ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT);
2188 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT_TRAP, EUR_CR_MASTER_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_MASTER_BREAKPOINT_TRAP_CONTINUE_MASK);
2189 do
2190 {
2191 ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT);
2192 }
2193 while (ui32OldSeqNum == ui32NewSeqNum);
2194 }
2195 else
2196 {
2197
2198 ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum));
2199 OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP, ui32CoreNum), EUR_CR_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_BREAKPOINT_TRAP_CONTINUE_MASK);
2200 do
2201 {
2202 ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum));
2203 }
2204 while (ui32OldSeqNum == ui32NewSeqNum);
2205 }
2206#endif
2207 return PVRSRV_OK;
2208 }
2209#endif
2210
2211 case SGX_MISC_INFO_REQUEST_CLOCKSPEED:
2212 {
2213 psMiscInfo->uData.ui32SGXClockSpeed = psDevInfo->ui32CoreClockSpeed;
2214 return PVRSRV_OK;
2215 }
2216
2217 case SGX_MISC_INFO_REQUEST_ACTIVEPOWER:
2218 {
2219 psMiscInfo->uData.sActivePower.ui32NumActivePowerEvents = psDevInfo->psSGXHostCtl->ui32NumActivePowerEvents;
2220 return PVRSRV_OK;
2221 }
2222
2223 case SGX_MISC_INFO_REQUEST_LOCKUPS:
2224 {
2225#if defined(SUPPORT_HW_RECOVERY)
2226 psMiscInfo->uData.sLockups.ui32uKernelDetectedLockups = psDevInfo->psSGXHostCtl->ui32uKernelDetectedLockups;
2227 psMiscInfo->uData.sLockups.ui32HostDetectedLockups = psDevInfo->psSGXHostCtl->ui32HostDetectedLockups;
2228#else
2229 psMiscInfo->uData.sLockups.ui32uKernelDetectedLockups = 0;
2230 psMiscInfo->uData.sLockups.ui32HostDetectedLockups = 0;
2231#endif
2232 return PVRSRV_OK;
2233 }
2234
2235 case SGX_MISC_INFO_REQUEST_SPM:
2236 {
2237
2238 return PVRSRV_OK;
2239 }
2240
2241 case SGX_MISC_INFO_REQUEST_SGXREV:
2242 {
2243 PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
2244 eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode);
2245 if(eError != PVRSRV_OK)
2246 {
2247 PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n",
2248 eError));
2249 return eError;
2250 }
2251 psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
2252
2253
2254 psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
2255
2256
2257 PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: Core 0x%x, sw ID 0x%x, sw Rev 0x%x\n",
2258 psSGXFeatures->ui32CoreRev,
2259 psSGXFeatures->ui32CoreIdSW,
2260 psSGXFeatures->ui32CoreRevSW));
2261 PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: DDK version 0x%x, DDK build 0x%x\n",
2262 psSGXFeatures->ui32DDKVersion,
2263 psSGXFeatures->ui32DDKBuild));
2264
2265
2266 return PVRSRV_OK;
2267 }
2268
2269 case SGX_MISC_INFO_REQUEST_DRIVER_SGXREV:
2270 {
2271 PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
2272
2273 psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
2274
2275
2276 OSMemSet(psMemInfo->pvLinAddrKM, 0,
2277 sizeof(PVRSRV_SGX_MISCINFO_INFO));
2278
2279 psSGXFeatures->ui32DDKVersion =
2280 (PVRVERSION_MAJ << 16) |
2281 (PVRVERSION_MIN << 8) |
2282 PVRVERSION_BRANCH;
2283 psSGXFeatures->ui32DDKBuild = PVRVERSION_BUILD;
2284
2285
2286 psSGXFeatures->ui32BuildOptions = (SGX_BUILD_OPTIONS);
2287
2288#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
2289
2290 psSGXFeatures->sDevVAEDMStatusBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->sDevVAddr;
2291 psSGXFeatures->pvEDMStatusBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->pvLinAddrKM;
2292#endif
2293
2294
2295 psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
2296 return PVRSRV_OK;
2297 }
2298
2299#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
2300 case SGX_MISC_INFO_REQUEST_MEMREAD:
2301 case SGX_MISC_INFO_REQUEST_MEMCOPY:
2302 {
2303 PVRSRV_ERROR eError;
2304 PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
2305 PVRSRV_SGX_MISCINFO_MEMACCESS *psSGXMemSrc;
2306 PVRSRV_SGX_MISCINFO_MEMACCESS *psSGXMemDest;
2307
2308 {
2309
2310 *pui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_MEMREAD;
2311 psSGXMemSrc = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXMemAccessSrc;
2312
2313 if(psMiscInfo->sDevVAddrSrc.uiAddr != 0)
2314 {
2315 psSGXMemSrc->sDevVAddr = psMiscInfo->sDevVAddrSrc;
2316 }
2317 else
2318 {
2319 return PVRSRV_ERROR_INVALID_PARAMS;
2320 }
2321 }
2322
2323 if( psMiscInfo->eRequest == SGX_MISC_INFO_REQUEST_MEMCOPY)
2324 {
2325
2326 *pui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_MEMWRITE;
2327 psSGXMemDest = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXMemAccessDest;
2328
2329 if(psMiscInfo->sDevVAddrDest.uiAddr != 0)
2330 {
2331 psSGXMemDest->sDevVAddr = psMiscInfo->sDevVAddrDest;
2332 }
2333 else
2334 {
2335 return PVRSRV_ERROR_INVALID_PARAMS;
2336 }
2337 }
2338
2339
2340 if(psMiscInfo->hDevMemContext != IMG_NULL)
2341 {
2342 SGXGetMMUPDAddrKM( (IMG_HANDLE)psDeviceNode, hDevMemContext, &psSGXMemSrc->sPDDevPAddr);
2343
2344
2345 psSGXMemDest->sPDDevPAddr = psSGXMemSrc->sPDDevPAddr;
2346 }
2347 else
2348 {
2349 return PVRSRV_ERROR_INVALID_PARAMS;
2350 }
2351
2352
2353 eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode);
2354 if(eError != PVRSRV_OK)
2355 {
2356 PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n",
2357 eError));
2358 return eError;
2359 }
2360 psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
2361
2362#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
2363 if(*pui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_MEMREAD_FAIL)
2364 {
2365 return PVRSRV_ERROR_INVALID_MISCINFO;
2366 }
2367#endif
2368
2369 psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
2370 return PVRSRV_OK;
2371 }
2372#endif
2373
2374#if defined(SUPPORT_SGX_HWPERF)
2375 case SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS:
2376 {
2377 PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS *psSetHWPerfStatus = &psMiscInfo->uData.sSetHWPerfStatus;
2378 const IMG_UINT32 ui32ValidFlags = PVRSRV_SGX_HWPERF_STATUS_RESET_COUNTERS |
2379 PVRSRV_SGX_HWPERF_STATUS_GRAPHICS_ON |
2380 PVRSRV_SGX_HWPERF_STATUS_PERIODIC_ON |
2381 PVRSRV_SGX_HWPERF_STATUS_MK_EXECUTION_ON;
2382 SGXMKIF_COMMAND sCommandData = {0};
2383
2384
2385 if ((psSetHWPerfStatus->ui32NewHWPerfStatus & ~ui32ValidFlags) != 0)
2386 {
2387 return PVRSRV_ERROR_INVALID_PARAMS;
2388 }
2389
2390 #if defined(PDUMP)
2391 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
2392 "SGX ukernel HWPerf status %u\n",
2393 psSetHWPerfStatus->ui32NewHWPerfStatus);
2394 #endif
2395
2396
2397 #if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS)
2398 OSMemCopy(&psDevInfo->psSGXHostCtl->aui32PerfGroup[0],
2399 &psSetHWPerfStatus->aui32PerfGroup[0],
2400 sizeof(psDevInfo->psSGXHostCtl->aui32PerfGroup));
2401 OSMemCopy(&psDevInfo->psSGXHostCtl->aui32PerfBit[0],
2402 &psSetHWPerfStatus->aui32PerfBit[0],
2403 sizeof(psDevInfo->psSGXHostCtl->aui32PerfBit));
2404 #if defined(PDUMP)
2405 PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
2406 offsetof(SGXMKIF_HOST_CTL, aui32PerfGroup),
2407 sizeof(psDevInfo->psSGXHostCtl->aui32PerfGroup),
2408 PDUMP_FLAGS_CONTINUOUS,
2409 MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
2410 PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
2411 offsetof(SGXMKIF_HOST_CTL, aui32PerfBit),
2412 sizeof(psDevInfo->psSGXHostCtl->aui32PerfBit),
2413 PDUMP_FLAGS_CONTINUOUS,
2414 MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
2415 #endif
2416 #else
2417 psDevInfo->psSGXHostCtl->ui32PerfGroup = psSetHWPerfStatus->ui32PerfGroup;
2418 #if defined(PDUMP)
2419 PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
2420 offsetof(SGXMKIF_HOST_CTL, ui32PerfGroup),
2421 sizeof(psDevInfo->psSGXHostCtl->ui32PerfGroup),
2422 PDUMP_FLAGS_CONTINUOUS,
2423 MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
2424 #endif
2425 #endif
2426
2427
2428 sCommandData.ui32Data[0] = psSetHWPerfStatus->ui32NewHWPerfStatus;
2429 eError = SGXScheduleCCBCommandKM(psDeviceNode,
2430 SGXMKIF_CMD_SETHWPERFSTATUS,
2431 &sCommandData,
2432 KERNEL_ID,
2433 0);
2434 return eError;
2435 }
2436#endif
2437
2438 case SGX_MISC_INFO_DUMP_DEBUG_INFO:
2439 {
2440 PVR_LOG(("User requested SGX debug info"));
2441
2442
2443 SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_FALSE);
2444
2445 return PVRSRV_OK;
2446 }
2447
2448 case SGX_MISC_INFO_PANIC:
2449 {
2450 PVR_LOG(("User requested SGX panic"));
2451
2452 SGXPanic(psDeviceNode->pvDevice);
2453
2454 return PVRSRV_OK;
2455 }
2456
2457 default:
2458 {
2459
2460 return PVRSRV_ERROR_INVALID_PARAMS;
2461 }
2462 }
2463}
2464
2465
2466IMG_EXPORT
2467PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE hDevHandle,
2468 IMG_UINT32 ui32ArraySize,
2469 PVRSRV_SGX_HWPERF_CB_ENTRY *psClientHWPerfEntry,
2470 IMG_UINT32 *pui32DataCount,
2471 IMG_UINT32 *pui32ClockSpeed,
2472 IMG_UINT32 *pui32HostTimeStamp)
2473{
2474 PVRSRV_ERROR eError = PVRSRV_OK;
2475 PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
2476 PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
2477 SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM;
2478 IMG_UINT i;
2479
2480 for (i = 0;
2481 psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < ui32ArraySize;
2482 i++)
2483 {
2484 SGXMKIF_HWPERF_CB_ENTRY *psMKPerfEntry = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff];
2485
2486 psClientHWPerfEntry[i].ui32FrameNo = psMKPerfEntry->ui32FrameNo;
2487 psClientHWPerfEntry[i].ui32Type = psMKPerfEntry->ui32Type;
2488 psClientHWPerfEntry[i].ui32Ordinal = psMKPerfEntry->ui32Ordinal;
2489 psClientHWPerfEntry[i].ui32Info = psMKPerfEntry->ui32Info;
2490 psClientHWPerfEntry[i].ui32Clocksx16 = SGXConvertTimeStamp(psDevInfo,
2491 psMKPerfEntry->ui32TimeWraps,
2492 psMKPerfEntry->ui32Time);
2493 OSMemCopy(&psClientHWPerfEntry[i].ui32Counters[0][0],
2494 &psMKPerfEntry->ui32Counters[0][0],
2495 sizeof(psMKPerfEntry->ui32Counters));
2496
2497 psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (SGXMKIF_HWPERF_CB_SIZE - 1);
2498 }
2499
2500 *pui32DataCount = i;
2501 *pui32ClockSpeed = psDevInfo->ui32CoreClockSpeed;
2502 *pui32HostTimeStamp = OSClockus();
2503
2504 return eError;
2505}
2506
2507