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 ******************************************************************************/
26 #include <linux/module.h>
28 #include "services_headers.h"
29 #include "buffer_manager.h"
30 #include "kernelbuffer.h"
31 #include "pvr_bridge_km.h"
33 struct PVRSRV_DC_SRV2DISP_KMJTABLE;
35 struct PVRSRV_DC_BUFFER {
36 struct PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer;
37 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
38 struct PVRSRV_DC_SWAPCHAIN *psSwapChain;
41 struct PVRSRV_DC_SWAPCHAIN {
43 struct PVRSRV_QUEUE_INFO *psQueue;
44 struct PVRSRV_DC_BUFFER asBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
46 struct PVRSRV_DC_BUFFER *psLastFlipBuffer;
47 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
51 struct PVRSRV_DISPLAYCLASS_INFO {
55 struct PVRSRV_DC_SRV2DISP_KMJTABLE *psFuncTable;
57 struct PVRSRV_DC_BUFFER sSystemBuffer;
60 struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO {
61 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
62 struct RESMAN_ITEM *hResItem;
65 struct PVRSRV_BC_SRV2BUFFER_KMJTABLE;
67 struct PVRSRV_BC_BUFFER {
68 struct PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer;
69 struct PVRSRV_BUFFERCLASS_INFO *psBCInfo;
72 struct PVRSRV_BUFFERCLASS_INFO {
76 struct PVRSRV_BC_SRV2BUFFER_KMJTABLE *psFuncTable;
80 struct PVRSRV_BC_BUFFER *psBuffer;
84 struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO {
85 struct PVRSRV_BUFFERCLASS_INFO *psBCInfo;
89 static struct PVRSRV_DISPLAYCLASS_INFO *DCDeviceHandleToDCInfo(void *hDeviceKM)
91 struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
93 psDCPerContextInfo = (struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)
96 return psDCPerContextInfo->psDCInfo;
99 static struct PVRSRV_BUFFERCLASS_INFO *BCDeviceHandleToBCInfo(void *hDeviceKM)
101 struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
103 psBCPerContextInfo = (struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)
106 return psBCPerContextInfo->psBCInfo;
109 enum PVRSRV_ERROR PVRSRVEnumerateDCKM(enum PVRSRV_DEVICE_CLASS DeviceClass,
110 u32 *pui32DevCount, u32 *pui32DevID)
112 struct PVRSRV_DEVICE_NODE *psDeviceNode;
113 unsigned ui32DevCount = 0;
114 struct SYS_DATA *psSysData;
116 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
117 PVR_DPF(PVR_DBG_ERROR,
118 "PVRSRVEnumerateDCKM: Failed to get SysData");
119 return PVRSRV_ERROR_GENERIC;
122 psDeviceNode = psSysData->psDeviceNodeList;
123 while (psDeviceNode) {
124 if ((psDeviceNode->sDevId.eDeviceClass == DeviceClass) &&
125 (psDeviceNode->sDevId.eDeviceType ==
126 PVRSRV_DEVICE_TYPE_EXT)) {
130 psDeviceNode->sDevId.ui32DeviceIndex;
133 psDeviceNode = psDeviceNode->psNext;
137 *pui32DevCount = ui32DevCount;
138 } else if (pui32DevID == NULL) {
139 PVR_DPF(PVR_DBG_ERROR,
140 "PVRSRVEnumerateDCKM: Invalid parameters");
141 return PVRSRV_ERROR_INVALID_PARAMS;
147 static enum PVRSRV_ERROR PVRSRVRegisterDCDeviceKM(
148 struct PVRSRV_DC_SRV2DISP_KMJTABLE *psFuncTable,
151 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo = NULL;
152 struct PVRSRV_DEVICE_NODE *psDeviceNode;
153 struct SYS_DATA *psSysData;
155 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
156 PVR_DPF(PVR_DBG_ERROR,
157 "PVRSRVRegisterDCDeviceKM: Failed to get SysData");
158 return PVRSRV_ERROR_GENERIC;
161 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
163 (void **) &psDCInfo, NULL) != PVRSRV_OK) {
164 PVR_DPF(PVR_DBG_ERROR,
165 "PVRSRVRegisterDCDeviceKM: Failed psDCInfo alloc");
166 return PVRSRV_ERROR_OUT_OF_MEMORY;
168 OSMemSet(psDCInfo, 0, sizeof(*psDCInfo));
170 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
171 sizeof(struct PVRSRV_DC_SRV2DISP_KMJTABLE),
172 (void **)&psDCInfo->psFuncTable,
173 NULL) != PVRSRV_OK) {
174 PVR_DPF(PVR_DBG_ERROR,
175 "PVRSRVRegisterDCDeviceKM: Failed psFuncTable alloc");
178 OSMemSet(psDCInfo->psFuncTable, 0,
179 sizeof(struct PVRSRV_DC_SRV2DISP_KMJTABLE));
181 *psDCInfo->psFuncTable = *psFuncTable;
183 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
184 sizeof(struct PVRSRV_DEVICE_NODE),
185 (void **) &psDeviceNode, NULL) != PVRSRV_OK) {
186 PVR_DPF(PVR_DBG_ERROR,
187 "PVRSRVRegisterDCDeviceKM: Failed psDeviceNode alloc");
190 OSMemSet(psDeviceNode, 0, sizeof(struct PVRSRV_DEVICE_NODE));
192 psDeviceNode->pvDevice = (void *) psDCInfo;
193 psDeviceNode->ui32pvDeviceSize = sizeof(*psDCInfo);
194 psDeviceNode->ui32RefCount = 1;
195 psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT;
196 psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_DISPLAY;
197 psDeviceNode->psSysData = psSysData;
199 AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex);
200 psDCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
202 *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
204 SysRegisterExternalDevice(psDeviceNode);
206 psDeviceNode->psNext = psSysData->psDeviceNodeList;
207 psSysData->psDeviceNodeList = psDeviceNode;
213 if (psDCInfo->psFuncTable)
214 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
215 sizeof(struct PVRSRV_DC_SRV2DISP_KMJTABLE),
216 psDCInfo->psFuncTable, NULL);
218 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
219 sizeof(struct PVRSRV_DISPLAYCLASS_INFO),
222 return PVRSRV_ERROR_OUT_OF_MEMORY;
225 static enum PVRSRV_ERROR PVRSRVRemoveDCDeviceKM(u32 ui32DevIndex)
227 struct SYS_DATA *psSysData;
228 struct PVRSRV_DEVICE_NODE **ppsDeviceNode, *psDeviceNode;
229 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
231 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
232 PVR_DPF(PVR_DBG_ERROR,
233 "PVRSRVRemoveDCDeviceKM: Failed to get SysData");
234 return PVRSRV_ERROR_GENERIC;
237 ppsDeviceNode = &psSysData->psDeviceNodeList;
238 while (*ppsDeviceNode) {
239 switch ((*ppsDeviceNode)->sDevId.eDeviceClass) {
240 case PVRSRV_DEVICE_CLASS_DISPLAY:
242 if ((*ppsDeviceNode)->sDevId.ui32DeviceIndex ==
252 ppsDeviceNode = &((*ppsDeviceNode)->psNext);
255 PVR_DPF(PVR_DBG_ERROR,
256 "PVRSRVRemoveDCDeviceKM: requested device %d not present",
259 return PVRSRV_ERROR_GENERIC;
263 psDeviceNode = *ppsDeviceNode;
265 psDCInfo = (struct PVRSRV_DISPLAYCLASS_INFO *)psDeviceNode->pvDevice;
267 if (psDCInfo->ui32RefCount == 0) {
268 *ppsDeviceNode = psDeviceNode->psNext;
269 SysRemoveExternalDevice(psDeviceNode);
270 PVR_ASSERT(psDCInfo->ui32RefCount == 0);
271 FreeDeviceID(psSysData, ui32DevIndex);
272 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
273 sizeof(struct PVRSRV_DC_SRV2DISP_KMJTABLE),
274 psDCInfo->psFuncTable, NULL);
275 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
276 sizeof(struct PVRSRV_DISPLAYCLASS_INFO), psDCInfo,
278 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
279 sizeof(struct PVRSRV_DEVICE_NODE), psDeviceNode,
282 PVR_DPF(PVR_DBG_ERROR, "PVRSRVRemoveDCDeviceKM: "
283 "failed as %d Services DC API "
284 "connections are still open",
285 psDCInfo->ui32RefCount);
286 return PVRSRV_ERROR_GENERIC;
292 static enum PVRSRV_ERROR PVRSRVRegisterBCDeviceKM(
293 struct PVRSRV_BC_SRV2BUFFER_KMJTABLE *psFuncTable,
296 struct PVRSRV_BUFFERCLASS_INFO *psBCInfo = NULL;
297 struct PVRSRV_DEVICE_NODE *psDeviceNode;
298 struct SYS_DATA *psSysData;
300 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
301 PVR_DPF(PVR_DBG_ERROR,
302 "PVRSRVRegisterBCDeviceKM: Failed to get SysData");
303 return PVRSRV_ERROR_GENERIC;
306 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
308 (void **) &psBCInfo, NULL) != PVRSRV_OK) {
309 PVR_DPF(PVR_DBG_ERROR,
310 "PVRSRVRegisterBCDeviceKM: Failed psBCInfo alloc");
311 return PVRSRV_ERROR_OUT_OF_MEMORY;
313 OSMemSet(psBCInfo, 0, sizeof(*psBCInfo));
315 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
316 sizeof(struct PVRSRV_BC_SRV2BUFFER_KMJTABLE),
317 (void **) &psBCInfo->psFuncTable,
318 NULL) != PVRSRV_OK) {
319 PVR_DPF(PVR_DBG_ERROR,
320 "PVRSRVRegisterBCDeviceKM: Failed psFuncTable alloc");
323 OSMemSet(psBCInfo->psFuncTable, 0,
324 sizeof(struct PVRSRV_BC_SRV2BUFFER_KMJTABLE));
326 *psBCInfo->psFuncTable = *psFuncTable;
328 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
329 sizeof(struct PVRSRV_DEVICE_NODE),
330 (void **) &psDeviceNode, NULL) != PVRSRV_OK) {
331 PVR_DPF(PVR_DBG_ERROR,
332 "PVRSRVRegisterBCDeviceKM: Failed psDeviceNode alloc");
335 OSMemSet(psDeviceNode, 0, sizeof(struct PVRSRV_DEVICE_NODE));
337 psDeviceNode->pvDevice = (void *) psBCInfo;
338 psDeviceNode->ui32pvDeviceSize = sizeof(*psBCInfo);
339 psDeviceNode->ui32RefCount = 1;
340 psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT;
341 psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_BUFFER;
342 psDeviceNode->psSysData = psSysData;
344 AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex);
345 psBCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
347 *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
349 psDeviceNode->psNext = psSysData->psDeviceNodeList;
350 psSysData->psDeviceNodeList = psDeviceNode;
356 if (psBCInfo->psFuncTable)
357 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
358 sizeof(struct PVRSRV_BC_SRV2BUFFER_KMJTABLE *),
359 psBCInfo->psFuncTable, NULL);
361 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
362 sizeof(struct PVRSRV_BUFFERCLASS_INFO), psBCInfo, NULL);
364 return PVRSRV_ERROR_OUT_OF_MEMORY;
367 static enum PVRSRV_ERROR PVRSRVRemoveBCDeviceKM(u32 ui32DevIndex)
369 struct SYS_DATA *psSysData;
370 struct PVRSRV_DEVICE_NODE **ppsDevNode, *psDevNode;
371 struct PVRSRV_BUFFERCLASS_INFO *psBCInfo;
373 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
374 PVR_DPF(PVR_DBG_ERROR,
375 "PVRSRVRemoveBCDeviceKM: Failed to get SysData");
376 return PVRSRV_ERROR_GENERIC;
379 ppsDevNode = &psSysData->psDeviceNodeList;
380 while (*ppsDevNode) {
381 switch ((*ppsDevNode)->sDevId.eDeviceClass) {
382 case PVRSRV_DEVICE_CLASS_BUFFER:
384 if ((*ppsDevNode)->sDevId.ui32DeviceIndex ==
394 ppsDevNode = &(*ppsDevNode)->psNext;
397 PVR_DPF(PVR_DBG_ERROR,
398 "PVRSRVRemoveBCDeviceKM: requested device %d not present",
401 return PVRSRV_ERROR_GENERIC;
405 psDevNode = *(ppsDevNode);
407 psBCInfo = (struct PVRSRV_BUFFERCLASS_INFO *)psDevNode->pvDevice;
409 if (psBCInfo->ui32RefCount == 0) {
410 *ppsDevNode = psDevNode->psNext;
411 FreeDeviceID(psSysData, ui32DevIndex);
413 (struct PVRSRV_BUFFERCLASS_INFO *)psDevNode->pvDevice;
414 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
415 sizeof(struct PVRSRV_BC_SRV2BUFFER_KMJTABLE),
416 psBCInfo->psFuncTable, NULL);
417 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
418 sizeof(struct PVRSRV_BUFFERCLASS_INFO), psBCInfo,
420 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
421 sizeof(struct PVRSRV_DEVICE_NODE), psDevNode, NULL);
423 PVR_DPF(PVR_DBG_ERROR, "PVRSRVRemoveBCDeviceKM: "
424 "failed as %d Services BC API "
425 "connections are still open",
426 psBCInfo->ui32RefCount);
427 return PVRSRV_ERROR_GENERIC;
433 enum PVRSRV_ERROR PVRSRVCloseDCDeviceKM(void *hDeviceKM,
434 IMG_BOOL bResManCallback)
436 struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
438 PVR_UNREFERENCED_PARAMETER(bResManCallback);
440 psDCPerContextInfo = (struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)
443 ResManFreeResByPtr(psDCPerContextInfo->hResItem);
448 static enum PVRSRV_ERROR CloseDCDeviceCallBack(void *pvParam, u32 ui32Param)
450 struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
451 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
453 PVR_UNREFERENCED_PARAMETER(ui32Param);
455 psDCPerContextInfo = (struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)
457 psDCInfo = psDCPerContextInfo->psDCInfo;
459 psDCInfo->ui32RefCount--;
460 if (psDCInfo->ui32RefCount == 0) {
461 struct PVRSRV_DC_SRV2DISP_KMJTABLE *jtbl;
463 jtbl = psDCInfo->psFuncTable;
465 jtbl->pfnCloseDCDevice(psDCInfo->hExtDevice);
467 PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.
470 psDCInfo->hDevMemContext = NULL;
471 psDCInfo->hExtDevice = NULL;
473 module_put(jtbl->owner);
476 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
477 sizeof(struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO),
478 psDCPerContextInfo, NULL);
483 enum PVRSRV_ERROR PVRSRVOpenDCDeviceKM(
484 struct PVRSRV_PER_PROCESS_DATA *psPerProc,
485 u32 ui32DeviceID, void *hDevCookie,
488 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
489 struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
490 struct PVRSRV_DEVICE_NODE *psDeviceNode;
491 struct SYS_DATA *psSysData;
493 if (!phDeviceKM || !hDevCookie) {
494 PVR_DPF(PVR_DBG_ERROR,
495 "PVRSRVOpenDCDeviceKM: Invalid params");
496 return PVRSRV_ERROR_GENERIC;
499 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
500 PVR_DPF(PVR_DBG_ERROR,
501 "PVRSRVOpenDCDeviceKM: Failed to get SysData");
502 return PVRSRV_ERROR_GENERIC;
505 psDeviceNode = psSysData->psDeviceNodeList;
506 while (psDeviceNode) {
507 if ((psDeviceNode->sDevId.eDeviceClass ==
508 PVRSRV_DEVICE_CLASS_DISPLAY) &&
509 (psDeviceNode->sDevId.ui32DeviceIndex == ui32DeviceID)) {
511 psDCInfo = (struct PVRSRV_DISPLAYCLASS_INFO *)
512 psDeviceNode->pvDevice;
515 psDeviceNode = psDeviceNode->psNext;
518 PVR_DPF(PVR_DBG_ERROR,
519 "PVRSRVOpenDCDeviceKM: no devnode matching index %d",
522 return PVRSRV_ERROR_GENERIC;
526 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psDCPerContextInfo),
527 (void **)&psDCPerContextInfo, NULL) != PVRSRV_OK) {
528 PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenDCDeviceKM: "
529 "Failed psDCPerContextInfo alloc");
530 return PVRSRV_ERROR_OUT_OF_MEMORY;
532 OSMemSet(psDCPerContextInfo, 0, sizeof(*psDCPerContextInfo));
534 if (psDCInfo->ui32RefCount++ == 0) {
535 enum PVRSRV_ERROR eError;
536 struct PVRSRV_DC_SRV2DISP_KMJTABLE *jtbl;
538 psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie;
540 jtbl = psDCInfo->psFuncTable;
541 if (!try_module_get(jtbl->owner)) {
542 PVR_DPF(PVR_DBG_ERROR, "%s: can't get DC module");
543 return PVRSRV_ERROR_INVALID_DEVICE;
546 psDCInfo->hDevMemContext =
547 (void *) psDeviceNode->sDevMemoryInfo.pBMKernelContext;
549 eError = PVRSRVAllocSyncInfoKM(NULL,
550 (void *)psDeviceNode->
551 sDevMemoryInfo.pBMKernelContext,
552 &psDCInfo->sSystemBuffer.
555 if (eError != PVRSRV_OK) {
556 PVR_DPF(PVR_DBG_ERROR,
557 "PVRSRVOpenDCDeviceKM: Failed sync info alloc");
558 psDCInfo->ui32RefCount--;
559 module_put(jtbl->owner);
563 eError = jtbl->pfnOpenDCDevice(ui32DeviceID,
564 &psDCInfo->hExtDevice,
565 (struct PVRSRV_SYNC_DATA *)psDCInfo->sSystemBuffer.
566 sDeviceClassBuffer.psKernelSyncInfo->
567 psSyncDataMemInfoKM->pvLinAddrKM);
568 if (eError != PVRSRV_OK) {
569 PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenDCDeviceKM: "
570 "Failed to open external DC device");
571 psDCInfo->ui32RefCount--;
572 module_put(jtbl->owner);
573 PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.
574 sDeviceClassBuffer.psKernelSyncInfo);
579 psDCPerContextInfo->psDCInfo = psDCInfo;
580 psDCPerContextInfo->hResItem =
581 ResManRegisterRes(psPerProc->hResManContext,
582 RESMAN_TYPE_DISPLAYCLASS_DEVICE,
583 psDCPerContextInfo, 0, CloseDCDeviceCallBack);
585 *phDeviceKM = (void *) psDCPerContextInfo;
590 enum PVRSRV_ERROR PVRSRVEnumDCFormatsKM(void *hDeviceKM,
592 struct DISPLAY_FORMAT *psFormat)
594 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
596 if (!hDeviceKM || !pui32Count || !psFormat) {
597 PVR_DPF(PVR_DBG_ERROR,
598 "PVRSRVEnumDCFormatsKM: Invalid parameters");
599 return PVRSRV_ERROR_INVALID_PARAMS;
602 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
604 return psDCInfo->psFuncTable->pfnEnumDCFormats(psDCInfo->hExtDevice,
605 pui32Count, psFormat);
608 enum PVRSRV_ERROR PVRSRVEnumDCDimsKM(void *hDeviceKM,
609 struct DISPLAY_FORMAT *psFormat,
610 u32 *pui32Count, struct DISPLAY_DIMS *psDim)
612 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
614 if (!hDeviceKM || !pui32Count || !psFormat) {
615 PVR_DPF(PVR_DBG_ERROR,
616 "PVRSRVEnumDCDimsKM: Invalid parameters");
617 return PVRSRV_ERROR_INVALID_PARAMS;
620 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
622 return psDCInfo->psFuncTable->pfnEnumDCDims(psDCInfo->hExtDevice,
623 psFormat, pui32Count, psDim);
626 enum PVRSRV_ERROR PVRSRVGetDCSystemBufferKM(void *hDeviceKM, void **phBuffer)
628 enum PVRSRV_ERROR eError;
629 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
632 if (!hDeviceKM || !phBuffer) {
633 PVR_DPF(PVR_DBG_ERROR,
634 "PVRSRVGetDCSystemBufferKM: Invalid parameters");
635 return PVRSRV_ERROR_INVALID_PARAMS;
638 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
641 psDCInfo->psFuncTable->pfnGetDCSystemBuffer(psDCInfo->hExtDevice,
643 if (eError != PVRSRV_OK) {
644 PVR_DPF(PVR_DBG_ERROR, "PVRSRVGetDCSystemBufferKM: "
645 "Failed to get valid buffer handle from external driver");
649 psDCInfo->sSystemBuffer.sDeviceClassBuffer.pfnGetBufferAddr =
650 psDCInfo->psFuncTable->pfnGetBufferAddr;
651 psDCInfo->sSystemBuffer.sDeviceClassBuffer.hDevMemContext =
652 psDCInfo->hDevMemContext;
653 psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtDevice =
654 psDCInfo->hExtDevice;
655 psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer = hExtBuffer;
657 psDCInfo->sSystemBuffer.psDCInfo = psDCInfo;
659 *phBuffer = (void *) &(psDCInfo->sSystemBuffer);
664 enum PVRSRV_ERROR PVRSRVGetDCInfoKM(void *hDeviceKM,
665 struct DISPLAY_INFO *psDisplayInfo)
667 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
668 enum PVRSRV_ERROR eError;
670 if (!hDeviceKM || !psDisplayInfo) {
671 PVR_DPF(PVR_DBG_ERROR,
672 "PVRSRVGetDCInfoKM: Invalid parameters");
673 return PVRSRV_ERROR_INVALID_PARAMS;
676 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
678 eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice,
680 if (eError != PVRSRV_OK)
683 if (psDisplayInfo->ui32MaxSwapChainBuffers >
684 PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) {
685 psDisplayInfo->ui32MaxSwapChainBuffers =
686 PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS;
692 enum PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(void *hSwapChain)
694 struct PVRSRV_DC_SWAPCHAIN *psSwapChain;
697 PVR_DPF(PVR_DBG_ERROR,
698 "PVRSRVDestroyDCSwapChainKM: Invalid parameters");
699 return PVRSRV_ERROR_INVALID_PARAMS;
702 psSwapChain = hSwapChain;
704 ResManFreeResByPtr(psSwapChain->hResItem);
709 static enum PVRSRV_ERROR DestroyDCSwapChainCallBack(void *pvParam,
712 enum PVRSRV_ERROR eError;
713 struct PVRSRV_DC_SWAPCHAIN *psSwapChain = pvParam;
714 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo = psSwapChain->psDCInfo;
717 PVR_UNREFERENCED_PARAMETER(ui32Param);
719 PVRSRVDestroyCommandQueueKM(psSwapChain->psQueue);
722 psDCInfo->psFuncTable->pfnDestroyDCSwapChain(psDCInfo->hExtDevice,
726 if (eError != PVRSRV_OK) {
727 PVR_DPF(PVR_DBG_ERROR, "DestroyDCSwapChainCallBack: "
728 "Failed to destroy DC swap chain");
732 for (i = 0; i < psSwapChain->ui32BufferCount; i++)
733 if (psSwapChain->asBuffer[i].sDeviceClassBuffer.
735 PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].
739 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct PVRSRV_DC_SWAPCHAIN),
745 enum PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(
746 struct PVRSRV_PER_PROCESS_DATA *psPerProc,
747 void *hDeviceKM, u32 ui32Flags,
748 struct DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
749 struct DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
750 u32 ui32BufferCount, u32 ui32OEMFlags,
751 void **phSwapChain, u32 *pui32SwapChainID)
753 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
754 struct PVRSRV_DC_SWAPCHAIN *psSwapChain = NULL;
755 struct PVRSRV_SYNC_DATA *apsSyncData[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
756 struct PVRSRV_QUEUE_INFO *psQueue = NULL;
757 enum PVRSRV_ERROR eError;
760 if (!hDeviceKM || !psDstSurfAttrib || !psSrcSurfAttrib ||
761 !phSwapChain || !pui32SwapChainID) {
762 PVR_DPF(PVR_DBG_ERROR,
763 "PVRSRVCreateDCSwapChainKM: Invalid parameters");
764 return PVRSRV_ERROR_INVALID_PARAMS;
767 if (ui32BufferCount > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) {
768 PVR_DPF(PVR_DBG_ERROR,
769 "PVRSRVCreateDCSwapChainKM: Too many buffers");
770 return PVRSRV_ERROR_TOOMANYBUFFERS;
773 if (ui32BufferCount < 2) {
774 PVR_DPF(PVR_DBG_ERROR,
775 "PVRSRVCreateDCSwapChainKM: Too few buffers");
776 return PVRSRV_ERROR_TOO_FEW_BUFFERS;
779 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
781 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
782 sizeof(struct PVRSRV_DC_SWAPCHAIN),
783 (void **) &psSwapChain, NULL) != PVRSRV_OK) {
784 PVR_DPF(PVR_DBG_ERROR,
785 "PVRSRVCreateDCSwapChainKM: Failed psSwapChain alloc");
786 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
789 OSMemSet(psSwapChain, 0, sizeof(struct PVRSRV_DC_SWAPCHAIN));
791 eError = PVRSRVCreateCommandQueueKM(1024, &psQueue);
792 if (eError != PVRSRV_OK) {
793 PVR_DPF(PVR_DBG_ERROR,
794 "PVRSRVCreateDCSwapChainKM: Failed to create CmdQueue");
798 psSwapChain->psQueue = psQueue;
800 for (i = 0; i < ui32BufferCount; i++) {
801 eError = PVRSRVAllocSyncInfoKM(NULL,
802 psDCInfo->hDevMemContext,
803 &psSwapChain->asBuffer[i].
806 if (eError != PVRSRV_OK) {
807 PVR_DPF(PVR_DBG_ERROR, "PVRSRVCreateDCSwapChainKM: "
808 "Failed to alloc syninfo for psSwapChain");
812 psSwapChain->asBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr =
813 psDCInfo->psFuncTable->pfnGetBufferAddr;
814 psSwapChain->asBuffer[i].sDeviceClassBuffer.hDevMemContext =
815 psDCInfo->hDevMemContext;
816 psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtDevice =
817 psDCInfo->hExtDevice;
819 psSwapChain->asBuffer[i].psDCInfo = psDCInfo;
820 psSwapChain->asBuffer[i].psSwapChain = psSwapChain;
823 (struct PVRSRV_SYNC_DATA *)psSwapChain->asBuffer[i].
824 sDeviceClassBuffer.psKernelSyncInfo->
825 psSyncDataMemInfoKM->pvLinAddrKM;
828 psSwapChain->ui32BufferCount = ui32BufferCount;
829 psSwapChain->psDCInfo = psDCInfo;
832 psDCInfo->psFuncTable->pfnCreateDCSwapChain(psDCInfo->hExtDevice,
839 &psSwapChain->hExtSwapChain,
841 if (eError != PVRSRV_OK) {
842 PVR_DPF(PVR_DBG_ERROR, "PVRSRVCreateDCSwapChainKM: "
843 "Failed to create 3rd party SwapChain");
847 *phSwapChain = (void *) psSwapChain;
849 psSwapChain->hResItem = ResManRegisterRes(psPerProc->hResManContext,
850 RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN,
852 DestroyDCSwapChainCallBack);
858 for (i = 0; i < ui32BufferCount; i++) {
859 if (psSwapChain->asBuffer[i].sDeviceClassBuffer.
861 PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].
868 PVRSRVDestroyCommandQueueKM(psQueue);
871 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
872 sizeof(struct PVRSRV_DC_SWAPCHAIN), psSwapChain,
879 enum PVRSRV_ERROR PVRSRVSetDCDstRectKM(void *hDeviceKM, void *hSwapChain,
880 struct IMG_RECT *psRect)
882 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
883 struct PVRSRV_DC_SWAPCHAIN *psSwapChain;
885 if (!hDeviceKM || !hSwapChain) {
886 PVR_DPF(PVR_DBG_ERROR,
887 "PVRSRVSetDCDstRectKM: Invalid parameters");
888 return PVRSRV_ERROR_INVALID_PARAMS;
891 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
892 psSwapChain = (struct PVRSRV_DC_SWAPCHAIN *)hSwapChain;
894 return psDCInfo->psFuncTable->pfnSetDCDstRect(psDCInfo->hExtDevice,
895 psSwapChain->hExtSwapChain, psRect);
898 enum PVRSRV_ERROR PVRSRVSetDCSrcRectKM(void *hDeviceKM, void *hSwapChain,
899 struct IMG_RECT *psRect)
901 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
902 struct PVRSRV_DC_SWAPCHAIN *psSwapChain;
904 if (!hDeviceKM || !hSwapChain) {
905 PVR_DPF(PVR_DBG_ERROR,
906 "PVRSRVSetDCSrcRectKM: Invalid parameters");
907 return PVRSRV_ERROR_INVALID_PARAMS;
910 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
911 psSwapChain = (struct PVRSRV_DC_SWAPCHAIN *)hSwapChain;
913 return psDCInfo->psFuncTable->pfnSetDCSrcRect(psDCInfo->hExtDevice,
914 psSwapChain->hExtSwapChain, psRect);
917 enum PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(void *hDeviceKM, void *hSwapChain,
920 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
921 struct PVRSRV_DC_SWAPCHAIN *psSwapChain;
923 if (!hDeviceKM || !hSwapChain) {
924 PVR_DPF(PVR_DBG_ERROR,
925 "PVRSRVSetDCDstColourKeyKM: Invalid parameters");
926 return PVRSRV_ERROR_INVALID_PARAMS;
929 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
930 psSwapChain = (struct PVRSRV_DC_SWAPCHAIN *)hSwapChain;
932 return psDCInfo->psFuncTable->pfnSetDCDstColourKey(psDCInfo->hExtDevice,
933 psSwapChain->hExtSwapChain, ui32CKColour);
936 enum PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(void *hDeviceKM, void *hSwapChain,
939 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
940 struct PVRSRV_DC_SWAPCHAIN *psSwapChain;
942 if (!hDeviceKM || !hSwapChain) {
943 PVR_DPF(PVR_DBG_ERROR,
944 "PVRSRVSetDCSrcColourKeyKM: Invalid parameters");
945 return PVRSRV_ERROR_INVALID_PARAMS;
948 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
949 psSwapChain = (struct PVRSRV_DC_SWAPCHAIN *)hSwapChain;
951 return psDCInfo->psFuncTable->pfnSetDCSrcColourKey(psDCInfo->hExtDevice,
952 psSwapChain->hExtSwapChain, ui32CKColour);
955 enum PVRSRV_ERROR PVRSRVGetDCBuffersKM(void *hDeviceKM, void *hSwapChain,
956 u32 *pui32BufferCount, void **phBuffer)
958 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
959 struct PVRSRV_DC_SWAPCHAIN *psSwapChain;
960 void *ahExtBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
961 enum PVRSRV_ERROR eError;
964 if (!hDeviceKM || !hSwapChain || !phBuffer) {
965 PVR_DPF(PVR_DBG_ERROR,
966 "PVRSRVGetDCBuffersKM: Invalid parameters");
967 return PVRSRV_ERROR_INVALID_PARAMS;
970 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
971 psSwapChain = (struct PVRSRV_DC_SWAPCHAIN *)hSwapChain;
973 eError = psDCInfo->psFuncTable->pfnGetDCBuffers(psDCInfo->hExtDevice,
974 psSwapChain->hExtSwapChain,
975 pui32BufferCount, ahExtBuffer);
977 PVR_ASSERT(*pui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
979 for (i = 0; i < *pui32BufferCount; i++) {
980 psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtBuffer =
982 phBuffer[i] = (void *)&psSwapChain->asBuffer[i];
988 enum PVRSRV_ERROR PVRSRVSwapToDCBufferKM(void *hDeviceKM, void *hBuffer,
989 u32 ui32SwapInterval, void *hPrivateTag,
990 u32 ui32ClipRectCount,
991 struct IMG_RECT *psClipRect)
993 enum PVRSRV_ERROR eError;
994 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
995 struct PVRSRV_DC_BUFFER *psBuffer;
996 struct PVRSRV_QUEUE_INFO *psQueue;
997 struct DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
999 u32 ui32NumSrcSyncs = 1;
1000 struct PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
1001 struct PVRSRV_COMMAND *psCommand;
1003 if (!hDeviceKM || !hBuffer || !psClipRect) {
1004 PVR_DPF(PVR_DBG_ERROR,
1005 "PVRSRVSwapToDCBufferKM: Invalid parameters");
1006 return PVRSRV_ERROR_INVALID_PARAMS;
1009 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1010 psBuffer = (struct PVRSRV_DC_BUFFER *)hBuffer;
1012 psQueue = psBuffer->psSwapChain->psQueue;
1014 apsSrcSync[0] = psBuffer->sDeviceClassBuffer.psKernelSyncInfo;
1015 if (psBuffer->psSwapChain->psLastFlipBuffer &&
1016 psBuffer != psBuffer->psSwapChain->psLastFlipBuffer) {
1018 psBuffer->psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.
1023 eError = PVRSRVInsertCommandKM(psQueue, &psCommand,
1024 psDCInfo->ui32DeviceID, DC_FLIP_COMMAND,
1025 0, NULL, ui32NumSrcSyncs, apsSrcSync,
1026 sizeof(struct DISPLAYCLASS_FLIP_COMMAND) +
1027 (sizeof(struct IMG_RECT) *
1028 ui32ClipRectCount));
1029 if (eError != PVRSRV_OK) {
1030 PVR_DPF(PVR_DBG_ERROR,
1031 "PVRSRVSwapToDCBufferKM: Failed to get space in queue");
1035 psFlipCmd = (struct DISPLAYCLASS_FLIP_COMMAND *)psCommand->pvData;
1036 psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
1037 psFlipCmd->hExtSwapChain = psBuffer->psSwapChain->hExtSwapChain;
1038 psFlipCmd->hExtBuffer = psBuffer->sDeviceClassBuffer.hExtBuffer;
1039 psFlipCmd->hPrivateTag = hPrivateTag;
1040 psFlipCmd->ui32ClipRectCount = ui32ClipRectCount;
1041 psFlipCmd->psClipRect =
1042 (struct IMG_RECT *)((u8 *) psFlipCmd +
1043 sizeof(struct DISPLAYCLASS_FLIP_COMMAND));
1045 for (i = 0; i < ui32ClipRectCount; i++)
1046 psFlipCmd->psClipRect[i] = psClipRect[i];
1048 psFlipCmd->ui32SwapInterval = ui32SwapInterval;
1050 eError = PVRSRVSubmitCommandKM(psQueue, psCommand);
1051 if (eError != PVRSRV_OK) {
1052 PVR_DPF(PVR_DBG_ERROR,
1053 "PVRSRVSwapToDCBufferKM: Failed to submit command");
1057 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) {
1058 if (PVRSRVProcessQueues(IMG_FALSE) !=
1059 PVRSRV_ERROR_PROCESSING_BLOCKED) {
1060 goto ProcessedQueues;
1062 OSWaitus(MAX_HW_TIME_US / WAIT_TRY_COUNT);
1064 END_LOOP_UNTIL_TIMEOUT();
1066 PVR_DPF(PVR_DBG_ERROR,
1067 "PVRSRVSwapToDCBufferKM: Failed to process queues");
1069 eError = PVRSRV_ERROR_GENERIC;
1074 psBuffer->psSwapChain->psLastFlipBuffer = psBuffer;
1080 enum PVRSRV_ERROR PVRSRVSwapToDCSystemKM(void *hDeviceKM, void *hSwapChain)
1082 enum PVRSRV_ERROR eError;
1083 struct PVRSRV_QUEUE_INFO *psQueue;
1084 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1085 struct PVRSRV_DC_SWAPCHAIN *psSwapChain;
1086 struct DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
1087 u32 ui32NumSrcSyncs = 1;
1088 struct PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
1089 struct PVRSRV_COMMAND *psCommand;
1091 if (!hDeviceKM || !hSwapChain) {
1092 PVR_DPF(PVR_DBG_ERROR,
1093 "PVRSRVSwapToDCSystemKM: Invalid parameters");
1094 return PVRSRV_ERROR_INVALID_PARAMS;
1097 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1098 psSwapChain = (struct PVRSRV_DC_SWAPCHAIN *)hSwapChain;
1100 psQueue = psSwapChain->psQueue;
1103 psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo;
1104 if (psSwapChain->psLastFlipBuffer) {
1105 if (apsSrcSync[0] !=
1106 psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.
1109 psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.
1115 eError = PVRSRVInsertCommandKM(psQueue, &psCommand,
1116 psDCInfo->ui32DeviceID, DC_FLIP_COMMAND,
1117 0, NULL, ui32NumSrcSyncs, apsSrcSync,
1118 sizeof(struct DISPLAYCLASS_FLIP_COMMAND));
1119 if (eError != PVRSRV_OK) {
1120 PVR_DPF(PVR_DBG_ERROR,
1121 "PVRSRVSwapToDCSystemKM: Failed to get space in queue");
1125 psFlipCmd = (struct DISPLAYCLASS_FLIP_COMMAND *)psCommand->pvData;
1126 psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
1127 psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain;
1128 psFlipCmd->hExtBuffer =
1129 psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer;
1130 psFlipCmd->hPrivateTag = NULL;
1131 psFlipCmd->ui32ClipRectCount = 0;
1132 psFlipCmd->ui32SwapInterval = 1;
1134 eError = PVRSRVSubmitCommandKM(psQueue, psCommand);
1135 if (eError != PVRSRV_OK) {
1136 PVR_DPF(PVR_DBG_ERROR,
1137 "PVRSRVSwapToDCSystemKM: Failed to submit command");
1141 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) {
1142 if (PVRSRVProcessQueues(IMG_FALSE) !=
1143 PVRSRV_ERROR_PROCESSING_BLOCKED) {
1144 goto ProcessedQueues;
1146 OSWaitus(MAX_HW_TIME_US / WAIT_TRY_COUNT);
1148 END_LOOP_UNTIL_TIMEOUT();
1150 PVR_DPF(PVR_DBG_ERROR,
1151 "PVRSRVSwapToDCSystemKM: Failed to process queues");
1152 eError = PVRSRV_ERROR_GENERIC;
1157 psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer;
1165 static enum PVRSRV_ERROR PVRSRVRegisterSystemISRHandler(
1166 IMG_BOOL (*pfnISRHandler)(void *),
1167 void *pvISRHandlerData,
1168 u32 ui32ISRSourceMask,
1171 struct SYS_DATA *psSysData;
1172 struct PVRSRV_DEVICE_NODE *psDevNode;
1174 PVR_UNREFERENCED_PARAMETER(ui32ISRSourceMask);
1176 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
1177 PVR_DPF(PVR_DBG_ERROR, "PVRSRVRegisterSystemISRHandler: "
1178 "Failed to get SysData");
1179 return PVRSRV_ERROR_GENERIC;
1182 psDevNode = psSysData->psDeviceNodeList;
1184 if (psDevNode->sDevId.ui32DeviceIndex == ui32DeviceID)
1186 psDevNode = psDevNode->psNext;
1189 if (psDevNode == NULL) {
1190 PVR_DPF(PVR_DBG_ERROR, "PVRSRVRegisterSystemISRHandler: "
1191 "Failed to get psDevNode");
1193 return PVRSRV_ERROR_GENERIC;
1196 psDevNode->pvISRData = (void *) pvISRHandlerData;
1198 psDevNode->pfnDeviceISR = pfnISRHandler;
1203 void PVRSRVSetDCState(u32 ui32State)
1205 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1206 struct PVRSRV_DEVICE_NODE *psDeviceNode;
1207 struct SYS_DATA *psSysData;
1209 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
1210 PVR_DPF(PVR_DBG_ERROR,
1211 "PVRSRVSetDCState: Failed to get SysData");
1215 psDeviceNode = psSysData->psDeviceNodeList;
1216 while (psDeviceNode != NULL) {
1217 if (psDeviceNode->sDevId.eDeviceClass ==
1218 PVRSRV_DEVICE_CLASS_DISPLAY) {
1219 psDCInfo = (struct PVRSRV_DISPLAYCLASS_INFO *)
1220 psDeviceNode->pvDevice;
1221 if (psDCInfo->psFuncTable->pfnSetDCState &&
1222 psDCInfo->hExtDevice)
1223 psDCInfo->psFuncTable->pfnSetDCState(
1224 psDCInfo->hExtDevice,
1227 psDeviceNode = psDeviceNode->psNext;
1231 IMG_BOOL PVRGetDisplayClassJTable(struct PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable)
1233 psJTable->ui32TableSize = sizeof(struct PVRSRV_DC_DISP2SRV_KMJTABLE);
1234 psJTable->pfnPVRSRVRegisterDCDevice = PVRSRVRegisterDCDeviceKM;
1235 psJTable->pfnPVRSRVRemoveDCDevice = PVRSRVRemoveDCDeviceKM;
1236 psJTable->pfnPVRSRVOEMFunction = SysOEMFunction;
1237 psJTable->pfnPVRSRVRegisterCmdProcList = PVRSRVRegisterCmdProcListKM;
1238 psJTable->pfnPVRSRVRemoveCmdProcList = PVRSRVRemoveCmdProcListKM;
1239 psJTable->pfnPVRSRVCmdComplete = PVRSRVCommandCompleteKM;
1240 psJTable->pfnPVRSRVRegisterSystemISRHandler =
1241 PVRSRVRegisterSystemISRHandler;
1242 psJTable->pfnPVRSRVRegisterPowerDevice = PVRSRVRegisterPowerDevice;
1246 EXPORT_SYMBOL(PVRGetDisplayClassJTable);
1248 enum PVRSRV_ERROR PVRSRVCloseBCDeviceKM(void *hDeviceKM,
1249 IMG_BOOL bResManCallback)
1251 struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
1253 PVR_UNREFERENCED_PARAMETER(bResManCallback);
1255 psBCPerContextInfo = (struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)
1258 ResManFreeResByPtr(psBCPerContextInfo->hResItem);
1263 static enum PVRSRV_ERROR CloseBCDeviceCallBack(void *pvParam, u32 ui32Param)
1265 struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
1266 struct PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1268 PVR_UNREFERENCED_PARAMETER(ui32Param);
1270 psBCPerContextInfo = (struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)
1272 psBCInfo = psBCPerContextInfo->psBCInfo;
1274 psBCInfo->ui32RefCount--;
1275 if (psBCInfo->ui32RefCount == 0) {
1278 psBCInfo->psFuncTable->pfnCloseBCDevice(psBCInfo->hExtDevice);
1280 for (i = 0; i < psBCInfo->ui32BufferCount; i++)
1281 if (psBCInfo->psBuffer[i].sDeviceClassBuffer.
1283 PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].
1287 if (psBCInfo->psBuffer)
1288 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1289 sizeof(struct PVRSRV_BC_BUFFER),
1290 psBCInfo->psBuffer, NULL);
1293 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1294 sizeof(struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO),
1295 psBCPerContextInfo, NULL);
1300 enum PVRSRV_ERROR PVRSRVOpenBCDeviceKM(
1301 struct PVRSRV_PER_PROCESS_DATA *psPerProc,
1302 u32 ui32DeviceID, void *hDevCookie,
1305 struct PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1306 struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
1307 struct PVRSRV_DEVICE_NODE *psDeviceNode;
1308 struct SYS_DATA *psSysData;
1310 enum PVRSRV_ERROR eError;
1312 if (!phDeviceKM || !hDevCookie) {
1313 PVR_DPF(PVR_DBG_ERROR,
1314 "PVRSRVOpenBCDeviceKM: Invalid params");
1315 return PVRSRV_ERROR_GENERIC;
1318 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
1319 PVR_DPF(PVR_DBG_ERROR,
1320 "PVRSRVOpenBCDeviceKM: Failed to get SysData");
1321 return PVRSRV_ERROR_GENERIC;
1324 psDeviceNode = psSysData->psDeviceNodeList;
1325 while (psDeviceNode) {
1326 if ((psDeviceNode->sDevId.eDeviceClass ==
1327 PVRSRV_DEVICE_CLASS_BUFFER) &&
1328 (psDeviceNode->sDevId.ui32DeviceIndex == ui32DeviceID)) {
1330 psBCInfo = (struct PVRSRV_BUFFERCLASS_INFO *)
1331 psDeviceNode->pvDevice;
1334 psDeviceNode = psDeviceNode->psNext;
1337 PVR_DPF(PVR_DBG_ERROR,
1338 "PVRSRVOpenBCDeviceKM: No devnode matching index %d",
1341 return PVRSRV_ERROR_GENERIC;
1345 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1346 sizeof(*psBCPerContextInfo),
1347 (void **)&psBCPerContextInfo, NULL) != PVRSRV_OK) {
1348 PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: "
1349 "Failed psBCPerContextInfo alloc");
1350 return PVRSRV_ERROR_OUT_OF_MEMORY;
1352 OSMemSet(psBCPerContextInfo, 0, sizeof(*psBCPerContextInfo));
1354 if (psBCInfo->ui32RefCount++ == 0) {
1355 struct BUFFER_INFO sBufferInfo;
1357 psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie;
1359 psBCInfo->hDevMemContext =
1360 (void *) psDeviceNode->sDevMemoryInfo.pBMKernelContext;
1363 psBCInfo->psFuncTable->pfnOpenBCDevice(&psBCInfo->
1365 if (eError != PVRSRV_OK) {
1366 PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: "
1367 "Failed to open external BC device");
1372 psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice,
1374 if (eError != PVRSRV_OK) {
1375 PVR_DPF(PVR_DBG_ERROR,
1376 "PVRSRVOpenBCDeviceKM : Failed to get BC Info");
1380 psBCInfo->ui32BufferCount = sBufferInfo.ui32BufferCount;
1382 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1383 sizeof(struct PVRSRV_BC_BUFFER) *
1384 sBufferInfo.ui32BufferCount,
1385 (void **) &psBCInfo->psBuffer,
1387 if (eError != PVRSRV_OK) {
1388 PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: "
1389 "Failed to allocate BC buffers");
1392 OSMemSet(psBCInfo->psBuffer, 0,
1393 sizeof(struct PVRSRV_BC_BUFFER) *
1394 sBufferInfo.ui32BufferCount);
1396 for (i = 0; i < psBCInfo->ui32BufferCount; i++) {
1398 eError = PVRSRVAllocSyncInfoKM(NULL,
1399 psBCInfo->hDevMemContext,
1400 &psBCInfo->psBuffer[i].sDeviceClassBuffer.
1402 if (eError != PVRSRV_OK) {
1403 PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: "
1404 "Failed sync info alloc");
1408 eError = psBCInfo->psFuncTable->pfnGetBCBuffer(
1409 psBCInfo->hExtDevice, i,
1410 psBCInfo->psBuffer[i].sDeviceClassBuffer.
1413 &psBCInfo->psBuffer[i].sDeviceClassBuffer.
1415 if (eError != PVRSRV_OK) {
1416 PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: "
1417 "Failed to get BC buffers");
1421 psBCInfo->psBuffer[i].sDeviceClassBuffer.
1423 psBCInfo->psFuncTable->pfnGetBufferAddr;
1424 psBCInfo->psBuffer[i].sDeviceClassBuffer.
1425 hDevMemContext = psBCInfo->hDevMemContext;
1426 psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice =
1427 psBCInfo->hExtDevice;
1431 psBCPerContextInfo->psBCInfo = psBCInfo;
1432 psBCPerContextInfo->hResItem =
1433 ResManRegisterRes(psPerProc->hResManContext,
1434 RESMAN_TYPE_BUFFERCLASS_DEVICE,
1435 psBCPerContextInfo, 0, CloseBCDeviceCallBack);
1437 *phDeviceKM = (void *)psBCPerContextInfo;
1443 for (i = 0; i < psBCInfo->ui32BufferCount; i++) {
1444 if (psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) {
1445 PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].
1451 if (psBCInfo->psBuffer) {
1452 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1453 sizeof(struct PVRSRV_BC_BUFFER), psBCInfo->psBuffer,
1460 enum PVRSRV_ERROR PVRSRVGetBCInfoKM(void *hDeviceKM,
1461 struct BUFFER_INFO *psBufferInfo)
1463 struct PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1464 enum PVRSRV_ERROR eError;
1466 if (!hDeviceKM || !psBufferInfo) {
1467 PVR_DPF(PVR_DBG_ERROR,
1468 "PVRSRVGetBCInfoKM: Invalid parameters");
1469 return PVRSRV_ERROR_INVALID_PARAMS;
1472 psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM);
1475 psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice,
1478 if (eError != PVRSRV_OK) {
1479 PVR_DPF(PVR_DBG_ERROR,
1480 "PVRSRVGetBCInfoKM : Failed to get BC Info");
1487 enum PVRSRV_ERROR PVRSRVGetBCBufferKM(void *hDeviceKM, u32 ui32BufferIndex,
1490 struct PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1492 if (!hDeviceKM || !phBuffer) {
1493 PVR_DPF(PVR_DBG_ERROR,
1494 "PVRSRVGetBCBufferKM: Invalid parameters");
1495 return PVRSRV_ERROR_INVALID_PARAMS;
1498 psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM);
1500 if (ui32BufferIndex < psBCInfo->ui32BufferCount) {
1501 *phBuffer = (void *)&psBCInfo->psBuffer[ui32BufferIndex];
1503 PVR_DPF(PVR_DBG_ERROR, "PVRSRVGetBCBufferKM: "
1504 "Buffer index %d out of range (%d)",
1505 ui32BufferIndex, psBCInfo->ui32BufferCount);
1506 return PVRSRV_ERROR_INVALID_PARAMS;
1512 IMG_BOOL PVRGetBufferClassJTable(struct PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable)
1514 psJTable->ui32TableSize = sizeof(struct PVRSRV_BC_BUFFER2SRV_KMJTABLE);
1516 psJTable->pfnPVRSRVRegisterBCDevice = PVRSRVRegisterBCDeviceKM;
1517 psJTable->pfnPVRSRVRemoveBCDevice = PVRSRVRemoveBCDeviceKM;
1521 EXPORT_SYMBOL(PVRGetBufferClassJTable);