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(*psBCInfo->psFuncTable), psBCInfo->psFuncTable,
361 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psBCInfo), psBCInfo, NULL);
363 return PVRSRV_ERROR_OUT_OF_MEMORY;
366 static enum PVRSRV_ERROR PVRSRVRemoveBCDeviceKM(u32 ui32DevIndex)
368 struct SYS_DATA *psSysData;
369 struct PVRSRV_DEVICE_NODE **ppsDevNode, *psDevNode;
370 struct PVRSRV_BUFFERCLASS_INFO *psBCInfo;
372 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
373 PVR_DPF(PVR_DBG_ERROR,
374 "PVRSRVRemoveBCDeviceKM: Failed to get SysData");
375 return PVRSRV_ERROR_GENERIC;
378 ppsDevNode = &psSysData->psDeviceNodeList;
379 while (*ppsDevNode) {
380 switch ((*ppsDevNode)->sDevId.eDeviceClass) {
381 case PVRSRV_DEVICE_CLASS_BUFFER:
383 if ((*ppsDevNode)->sDevId.ui32DeviceIndex ==
393 ppsDevNode = &(*ppsDevNode)->psNext;
396 PVR_DPF(PVR_DBG_ERROR,
397 "PVRSRVRemoveBCDeviceKM: requested device %d not present",
400 return PVRSRV_ERROR_GENERIC;
404 psDevNode = *(ppsDevNode);
406 psBCInfo = (struct PVRSRV_BUFFERCLASS_INFO *)psDevNode->pvDevice;
408 if (psBCInfo->ui32RefCount == 0) {
409 *ppsDevNode = psDevNode->psNext;
410 FreeDeviceID(psSysData, ui32DevIndex);
412 (struct PVRSRV_BUFFERCLASS_INFO *)psDevNode->pvDevice;
413 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
414 sizeof(struct PVRSRV_BC_SRV2BUFFER_KMJTABLE),
415 psBCInfo->psFuncTable, NULL);
416 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
417 sizeof(struct PVRSRV_BUFFERCLASS_INFO), psBCInfo,
419 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
420 sizeof(struct PVRSRV_DEVICE_NODE), psDevNode, NULL);
422 PVR_DPF(PVR_DBG_ERROR, "PVRSRVRemoveBCDeviceKM: "
423 "failed as %d Services BC API "
424 "connections are still open",
425 psBCInfo->ui32RefCount);
426 return PVRSRV_ERROR_GENERIC;
432 enum PVRSRV_ERROR PVRSRVCloseDCDeviceKM(void *hDeviceKM,
433 IMG_BOOL bResManCallback)
435 struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
437 PVR_UNREFERENCED_PARAMETER(bResManCallback);
439 psDCPerContextInfo = (struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)
442 ResManFreeResByPtr(psDCPerContextInfo->hResItem);
447 static enum PVRSRV_ERROR CloseDCDeviceCallBack(void *pvParam, u32 ui32Param)
449 struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
450 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
452 PVR_UNREFERENCED_PARAMETER(ui32Param);
454 psDCPerContextInfo = (struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)
456 psDCInfo = psDCPerContextInfo->psDCInfo;
458 psDCInfo->ui32RefCount--;
459 if (psDCInfo->ui32RefCount == 0) {
460 struct PVRSRV_DC_SRV2DISP_KMJTABLE *jtbl;
462 jtbl = psDCInfo->psFuncTable;
464 jtbl->pfnCloseDCDevice(psDCInfo->hExtDevice);
466 PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.
469 psDCInfo->hDevMemContext = NULL;
470 psDCInfo->hExtDevice = NULL;
472 module_put(jtbl->owner);
475 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
476 sizeof(struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO),
477 psDCPerContextInfo, NULL);
482 enum PVRSRV_ERROR PVRSRVOpenDCDeviceKM(
483 struct PVRSRV_PER_PROCESS_DATA *psPerProc,
484 u32 ui32DeviceID, void *hDevCookie,
487 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
488 struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
489 struct PVRSRV_DC_SRV2DISP_KMJTABLE *jtbl;
490 struct PVRSRV_DEVICE_NODE *psDeviceNode;
491 struct SYS_DATA *psSysData;
492 enum PVRSRV_ERROR eError;
494 if (!phDeviceKM || !hDevCookie) {
495 PVR_DPF(PVR_DBG_ERROR,
496 "PVRSRVOpenDCDeviceKM: Invalid params");
497 return PVRSRV_ERROR_GENERIC;
500 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
501 PVR_DPF(PVR_DBG_ERROR,
502 "PVRSRVOpenDCDeviceKM: Failed to get SysData");
503 return PVRSRV_ERROR_GENERIC;
506 psDeviceNode = psSysData->psDeviceNodeList;
507 while (psDeviceNode) {
508 if ((psDeviceNode->sDevId.eDeviceClass ==
509 PVRSRV_DEVICE_CLASS_DISPLAY) &&
510 (psDeviceNode->sDevId.ui32DeviceIndex == ui32DeviceID)) {
512 psDCInfo = (struct PVRSRV_DISPLAYCLASS_INFO *)
513 psDeviceNode->pvDevice;
516 psDeviceNode = psDeviceNode->psNext;
519 PVR_DPF(PVR_DBG_ERROR,
520 "PVRSRVOpenDCDeviceKM: no devnode matching index %d",
523 return PVRSRV_ERROR_GENERIC;
527 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psDCPerContextInfo),
528 (void **)&psDCPerContextInfo, NULL) != PVRSRV_OK) {
529 PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenDCDeviceKM: "
530 "Failed psDCPerContextInfo alloc");
531 return PVRSRV_ERROR_OUT_OF_MEMORY;
533 OSMemSet(psDCPerContextInfo, 0, sizeof(*psDCPerContextInfo));
535 if (psDCInfo->ui32RefCount++ == 0) {
536 psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie;
538 jtbl = psDCInfo->psFuncTable;
539 if (!try_module_get(jtbl->owner)) {
540 PVR_DPF(PVR_DBG_ERROR, "%s: can't get DC module");
541 eError = 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");
562 eError = jtbl->pfnOpenDCDevice(ui32DeviceID,
563 &psDCInfo->hExtDevice,
564 (struct PVRSRV_SYNC_DATA *)psDCInfo->sSystemBuffer.
565 sDeviceClassBuffer.psKernelSyncInfo->
566 psSyncDataMemInfoKM->pvLinAddrKM);
567 if (eError != PVRSRV_OK) {
568 PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenDCDeviceKM: "
569 "Failed to open external DC device");
574 psDCPerContextInfo->psDCInfo = psDCInfo;
575 psDCPerContextInfo->hResItem =
576 ResManRegisterRes(psPerProc->hResManContext,
577 RESMAN_TYPE_DISPLAYCLASS_DEVICE,
578 psDCPerContextInfo, 0, CloseDCDeviceCallBack);
580 *phDeviceKM = (void *) psDCPerContextInfo;
584 PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.
585 sDeviceClassBuffer.psKernelSyncInfo);
587 module_put(jtbl->owner);
588 psDCInfo->ui32RefCount--;
590 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psDCPerContextInfo),
591 psDCPerContextInfo, NULL);
596 enum PVRSRV_ERROR PVRSRVEnumDCFormatsKM(void *hDeviceKM,
598 struct DISPLAY_FORMAT *psFormat)
600 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
602 if (!hDeviceKM || !pui32Count || !psFormat) {
603 PVR_DPF(PVR_DBG_ERROR,
604 "PVRSRVEnumDCFormatsKM: Invalid parameters");
605 return PVRSRV_ERROR_INVALID_PARAMS;
608 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
610 return psDCInfo->psFuncTable->pfnEnumDCFormats(psDCInfo->hExtDevice,
611 pui32Count, psFormat);
614 enum PVRSRV_ERROR PVRSRVEnumDCDimsKM(void *hDeviceKM,
615 struct DISPLAY_FORMAT *psFormat,
616 u32 *pui32Count, struct DISPLAY_DIMS *psDim)
618 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
620 if (!hDeviceKM || !pui32Count || !psFormat) {
621 PVR_DPF(PVR_DBG_ERROR,
622 "PVRSRVEnumDCDimsKM: Invalid parameters");
623 return PVRSRV_ERROR_INVALID_PARAMS;
626 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
628 return psDCInfo->psFuncTable->pfnEnumDCDims(psDCInfo->hExtDevice,
629 psFormat, pui32Count, psDim);
632 enum PVRSRV_ERROR PVRSRVGetDCSystemBufferKM(void *hDeviceKM, void **phBuffer)
634 enum PVRSRV_ERROR eError;
635 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
638 if (!hDeviceKM || !phBuffer) {
639 PVR_DPF(PVR_DBG_ERROR,
640 "PVRSRVGetDCSystemBufferKM: Invalid parameters");
641 return PVRSRV_ERROR_INVALID_PARAMS;
644 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
647 psDCInfo->psFuncTable->pfnGetDCSystemBuffer(psDCInfo->hExtDevice,
649 if (eError != PVRSRV_OK) {
650 PVR_DPF(PVR_DBG_ERROR, "PVRSRVGetDCSystemBufferKM: "
651 "Failed to get valid buffer handle from external driver");
655 psDCInfo->sSystemBuffer.sDeviceClassBuffer.pfnGetBufferAddr =
656 psDCInfo->psFuncTable->pfnGetBufferAddr;
657 psDCInfo->sSystemBuffer.sDeviceClassBuffer.hDevMemContext =
658 psDCInfo->hDevMemContext;
659 psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtDevice =
660 psDCInfo->hExtDevice;
661 psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer = hExtBuffer;
663 psDCInfo->sSystemBuffer.psDCInfo = psDCInfo;
665 *phBuffer = (void *) &(psDCInfo->sSystemBuffer);
670 enum PVRSRV_ERROR PVRSRVGetDCInfoKM(void *hDeviceKM,
671 struct DISPLAY_INFO *psDisplayInfo)
673 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
674 enum PVRSRV_ERROR eError;
676 if (!hDeviceKM || !psDisplayInfo) {
677 PVR_DPF(PVR_DBG_ERROR,
678 "PVRSRVGetDCInfoKM: Invalid parameters");
679 return PVRSRV_ERROR_INVALID_PARAMS;
682 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
684 eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice,
686 if (eError != PVRSRV_OK)
689 if (psDisplayInfo->ui32MaxSwapChainBuffers >
690 PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) {
691 psDisplayInfo->ui32MaxSwapChainBuffers =
692 PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS;
698 enum PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(void *hSwapChain)
700 struct PVRSRV_DC_SWAPCHAIN *psSwapChain;
703 PVR_DPF(PVR_DBG_ERROR,
704 "PVRSRVDestroyDCSwapChainKM: Invalid parameters");
705 return PVRSRV_ERROR_INVALID_PARAMS;
708 psSwapChain = hSwapChain;
710 ResManFreeResByPtr(psSwapChain->hResItem);
715 static enum PVRSRV_ERROR DestroyDCSwapChainCallBack(void *pvParam,
718 enum PVRSRV_ERROR eError;
719 struct PVRSRV_DC_SWAPCHAIN *psSwapChain = pvParam;
720 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo = psSwapChain->psDCInfo;
723 PVR_UNREFERENCED_PARAMETER(ui32Param);
725 PVRSRVDestroyCommandQueueKM(psSwapChain->psQueue);
728 psDCInfo->psFuncTable->pfnDestroyDCSwapChain(psDCInfo->hExtDevice,
732 if (eError != PVRSRV_OK) {
733 PVR_DPF(PVR_DBG_ERROR, "DestroyDCSwapChainCallBack: "
734 "Failed to destroy DC swap chain");
738 for (i = 0; i < psSwapChain->ui32BufferCount; i++)
739 if (psSwapChain->asBuffer[i].sDeviceClassBuffer.
741 PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].
745 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct PVRSRV_DC_SWAPCHAIN),
751 enum PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(
752 struct PVRSRV_PER_PROCESS_DATA *psPerProc,
753 void *hDeviceKM, u32 ui32Flags,
754 struct DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
755 struct DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
756 u32 ui32BufferCount, u32 ui32OEMFlags,
757 void **phSwapChain, u32 *pui32SwapChainID)
759 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
760 struct PVRSRV_DC_SWAPCHAIN *psSwapChain = NULL;
761 struct PVRSRV_SYNC_DATA *apsSyncData[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
762 struct PVRSRV_QUEUE_INFO *psQueue = NULL;
763 enum PVRSRV_ERROR eError;
766 if (!hDeviceKM || !psDstSurfAttrib || !psSrcSurfAttrib ||
767 !phSwapChain || !pui32SwapChainID) {
768 PVR_DPF(PVR_DBG_ERROR,
769 "PVRSRVCreateDCSwapChainKM: Invalid parameters");
770 return PVRSRV_ERROR_INVALID_PARAMS;
773 if (ui32BufferCount > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) {
774 PVR_DPF(PVR_DBG_ERROR,
775 "PVRSRVCreateDCSwapChainKM: Too many buffers");
776 return PVRSRV_ERROR_TOOMANYBUFFERS;
779 if (ui32BufferCount < 2) {
780 PVR_DPF(PVR_DBG_ERROR,
781 "PVRSRVCreateDCSwapChainKM: Too few buffers");
782 return PVRSRV_ERROR_TOO_FEW_BUFFERS;
785 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
787 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
788 sizeof(struct PVRSRV_DC_SWAPCHAIN),
789 (void **) &psSwapChain, NULL) != PVRSRV_OK) {
790 PVR_DPF(PVR_DBG_ERROR,
791 "PVRSRVCreateDCSwapChainKM: Failed psSwapChain alloc");
792 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
795 OSMemSet(psSwapChain, 0, sizeof(struct PVRSRV_DC_SWAPCHAIN));
797 eError = PVRSRVCreateCommandQueueKM(1024, &psQueue);
798 if (eError != PVRSRV_OK) {
799 PVR_DPF(PVR_DBG_ERROR,
800 "PVRSRVCreateDCSwapChainKM: Failed to create CmdQueue");
804 psSwapChain->psQueue = psQueue;
806 for (i = 0; i < ui32BufferCount; i++) {
807 eError = PVRSRVAllocSyncInfoKM(NULL,
808 psDCInfo->hDevMemContext,
809 &psSwapChain->asBuffer[i].
812 if (eError != PVRSRV_OK) {
813 PVR_DPF(PVR_DBG_ERROR, "PVRSRVCreateDCSwapChainKM: "
814 "Failed to alloc syninfo for psSwapChain");
818 psSwapChain->asBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr =
819 psDCInfo->psFuncTable->pfnGetBufferAddr;
820 psSwapChain->asBuffer[i].sDeviceClassBuffer.hDevMemContext =
821 psDCInfo->hDevMemContext;
822 psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtDevice =
823 psDCInfo->hExtDevice;
825 psSwapChain->asBuffer[i].psDCInfo = psDCInfo;
826 psSwapChain->asBuffer[i].psSwapChain = psSwapChain;
829 (struct PVRSRV_SYNC_DATA *)psSwapChain->asBuffer[i].
830 sDeviceClassBuffer.psKernelSyncInfo->
831 psSyncDataMemInfoKM->pvLinAddrKM;
834 psSwapChain->ui32BufferCount = ui32BufferCount;
835 psSwapChain->psDCInfo = psDCInfo;
838 psDCInfo->psFuncTable->pfnCreateDCSwapChain(psDCInfo->hExtDevice,
845 &psSwapChain->hExtSwapChain,
847 if (eError != PVRSRV_OK) {
848 PVR_DPF(PVR_DBG_ERROR, "PVRSRVCreateDCSwapChainKM: "
849 "Failed to create 3rd party SwapChain");
853 *phSwapChain = (void *) psSwapChain;
855 psSwapChain->hResItem = ResManRegisterRes(psPerProc->hResManContext,
856 RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN,
858 DestroyDCSwapChainCallBack);
864 for (i = 0; i < ui32BufferCount; i++) {
865 if (psSwapChain->asBuffer[i].sDeviceClassBuffer.
867 PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].
874 PVRSRVDestroyCommandQueueKM(psQueue);
877 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
878 sizeof(struct PVRSRV_DC_SWAPCHAIN), psSwapChain,
885 enum PVRSRV_ERROR PVRSRVSetDCDstRectKM(void *hDeviceKM, void *hSwapChain,
886 struct IMG_RECT *psRect)
888 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
889 struct PVRSRV_DC_SWAPCHAIN *psSwapChain;
891 if (!hDeviceKM || !hSwapChain) {
892 PVR_DPF(PVR_DBG_ERROR,
893 "PVRSRVSetDCDstRectKM: Invalid parameters");
894 return PVRSRV_ERROR_INVALID_PARAMS;
897 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
898 psSwapChain = (struct PVRSRV_DC_SWAPCHAIN *)hSwapChain;
900 return psDCInfo->psFuncTable->pfnSetDCDstRect(psDCInfo->hExtDevice,
901 psSwapChain->hExtSwapChain, psRect);
904 enum PVRSRV_ERROR PVRSRVSetDCSrcRectKM(void *hDeviceKM, void *hSwapChain,
905 struct IMG_RECT *psRect)
907 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
908 struct PVRSRV_DC_SWAPCHAIN *psSwapChain;
910 if (!hDeviceKM || !hSwapChain) {
911 PVR_DPF(PVR_DBG_ERROR,
912 "PVRSRVSetDCSrcRectKM: Invalid parameters");
913 return PVRSRV_ERROR_INVALID_PARAMS;
916 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
917 psSwapChain = (struct PVRSRV_DC_SWAPCHAIN *)hSwapChain;
919 return psDCInfo->psFuncTable->pfnSetDCSrcRect(psDCInfo->hExtDevice,
920 psSwapChain->hExtSwapChain, psRect);
923 enum PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(void *hDeviceKM, void *hSwapChain,
926 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
927 struct PVRSRV_DC_SWAPCHAIN *psSwapChain;
929 if (!hDeviceKM || !hSwapChain) {
930 PVR_DPF(PVR_DBG_ERROR,
931 "PVRSRVSetDCDstColourKeyKM: Invalid parameters");
932 return PVRSRV_ERROR_INVALID_PARAMS;
935 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
936 psSwapChain = (struct PVRSRV_DC_SWAPCHAIN *)hSwapChain;
938 return psDCInfo->psFuncTable->pfnSetDCDstColourKey(psDCInfo->hExtDevice,
939 psSwapChain->hExtSwapChain, ui32CKColour);
942 enum PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(void *hDeviceKM, void *hSwapChain,
945 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
946 struct PVRSRV_DC_SWAPCHAIN *psSwapChain;
948 if (!hDeviceKM || !hSwapChain) {
949 PVR_DPF(PVR_DBG_ERROR,
950 "PVRSRVSetDCSrcColourKeyKM: Invalid parameters");
951 return PVRSRV_ERROR_INVALID_PARAMS;
954 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
955 psSwapChain = (struct PVRSRV_DC_SWAPCHAIN *)hSwapChain;
957 return psDCInfo->psFuncTable->pfnSetDCSrcColourKey(psDCInfo->hExtDevice,
958 psSwapChain->hExtSwapChain, ui32CKColour);
961 enum PVRSRV_ERROR PVRSRVGetDCBuffersKM(void *hDeviceKM, void *hSwapChain,
962 u32 *pui32BufferCount, void **phBuffer)
964 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
965 struct PVRSRV_DC_SWAPCHAIN *psSwapChain;
966 void *ahExtBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
967 enum PVRSRV_ERROR eError;
970 if (!hDeviceKM || !hSwapChain || !phBuffer) {
971 PVR_DPF(PVR_DBG_ERROR,
972 "PVRSRVGetDCBuffersKM: Invalid parameters");
973 return PVRSRV_ERROR_INVALID_PARAMS;
976 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
977 psSwapChain = (struct PVRSRV_DC_SWAPCHAIN *)hSwapChain;
979 eError = psDCInfo->psFuncTable->pfnGetDCBuffers(psDCInfo->hExtDevice,
980 psSwapChain->hExtSwapChain,
981 pui32BufferCount, ahExtBuffer);
983 PVR_ASSERT(*pui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
985 for (i = 0; i < *pui32BufferCount; i++) {
986 psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtBuffer =
988 phBuffer[i] = (void *)&psSwapChain->asBuffer[i];
994 enum PVRSRV_ERROR PVRSRVSwapToDCBufferKM(void *hDeviceKM, void *hBuffer,
995 u32 ui32SwapInterval, void *hPrivateTag,
996 u32 ui32ClipRectCount,
997 struct IMG_RECT *psClipRect)
999 enum PVRSRV_ERROR eError;
1000 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1001 struct PVRSRV_DC_BUFFER *psBuffer;
1002 struct PVRSRV_QUEUE_INFO *psQueue;
1003 struct DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
1005 u32 ui32NumSrcSyncs = 1;
1006 struct PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
1007 struct PVRSRV_COMMAND *psCommand;
1009 if (!hDeviceKM || !hBuffer || !psClipRect) {
1010 PVR_DPF(PVR_DBG_ERROR,
1011 "PVRSRVSwapToDCBufferKM: Invalid parameters");
1012 return PVRSRV_ERROR_INVALID_PARAMS;
1015 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1016 psBuffer = (struct PVRSRV_DC_BUFFER *)hBuffer;
1018 psQueue = psBuffer->psSwapChain->psQueue;
1020 apsSrcSync[0] = psBuffer->sDeviceClassBuffer.psKernelSyncInfo;
1021 if (psBuffer->psSwapChain->psLastFlipBuffer &&
1022 psBuffer != psBuffer->psSwapChain->psLastFlipBuffer) {
1024 psBuffer->psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.
1029 eError = PVRSRVInsertCommandKM(psQueue, &psCommand,
1030 psDCInfo->ui32DeviceID, DC_FLIP_COMMAND,
1031 0, NULL, ui32NumSrcSyncs, apsSrcSync,
1032 sizeof(struct DISPLAYCLASS_FLIP_COMMAND) +
1033 (sizeof(struct IMG_RECT) *
1034 ui32ClipRectCount));
1035 if (eError != PVRSRV_OK) {
1036 PVR_DPF(PVR_DBG_ERROR,
1037 "PVRSRVSwapToDCBufferKM: Failed to get space in queue");
1041 psFlipCmd = (struct DISPLAYCLASS_FLIP_COMMAND *)psCommand->pvData;
1042 psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
1043 psFlipCmd->hExtSwapChain = psBuffer->psSwapChain->hExtSwapChain;
1044 psFlipCmd->hExtBuffer = psBuffer->sDeviceClassBuffer.hExtBuffer;
1045 psFlipCmd->hPrivateTag = hPrivateTag;
1046 psFlipCmd->ui32ClipRectCount = ui32ClipRectCount;
1047 psFlipCmd->psClipRect =
1048 (struct IMG_RECT *)((u8 *) psFlipCmd +
1049 sizeof(struct DISPLAYCLASS_FLIP_COMMAND));
1051 for (i = 0; i < ui32ClipRectCount; i++)
1052 psFlipCmd->psClipRect[i] = psClipRect[i];
1054 psFlipCmd->ui32SwapInterval = ui32SwapInterval;
1056 eError = PVRSRVSubmitCommandKM(psQueue, psCommand);
1057 if (eError != PVRSRV_OK) {
1058 PVR_DPF(PVR_DBG_ERROR,
1059 "PVRSRVSwapToDCBufferKM: Failed to submit command");
1063 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) {
1064 if (PVRSRVProcessQueues(IMG_FALSE) !=
1065 PVRSRV_ERROR_PROCESSING_BLOCKED) {
1066 goto ProcessedQueues;
1068 OSWaitus(MAX_HW_TIME_US / WAIT_TRY_COUNT);
1070 END_LOOP_UNTIL_TIMEOUT();
1072 PVR_DPF(PVR_DBG_ERROR,
1073 "PVRSRVSwapToDCBufferKM: Failed to process queues");
1075 eError = PVRSRV_ERROR_GENERIC;
1080 psBuffer->psSwapChain->psLastFlipBuffer = psBuffer;
1086 enum PVRSRV_ERROR PVRSRVSwapToDCSystemKM(void *hDeviceKM, void *hSwapChain)
1088 enum PVRSRV_ERROR eError;
1089 struct PVRSRV_QUEUE_INFO *psQueue;
1090 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1091 struct PVRSRV_DC_SWAPCHAIN *psSwapChain;
1092 struct DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
1093 u32 ui32NumSrcSyncs = 1;
1094 struct PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
1095 struct PVRSRV_COMMAND *psCommand;
1097 if (!hDeviceKM || !hSwapChain) {
1098 PVR_DPF(PVR_DBG_ERROR,
1099 "PVRSRVSwapToDCSystemKM: Invalid parameters");
1100 return PVRSRV_ERROR_INVALID_PARAMS;
1103 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1104 psSwapChain = (struct PVRSRV_DC_SWAPCHAIN *)hSwapChain;
1106 psQueue = psSwapChain->psQueue;
1109 psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo;
1110 if (psSwapChain->psLastFlipBuffer) {
1111 if (apsSrcSync[0] !=
1112 psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.
1115 psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.
1121 eError = PVRSRVInsertCommandKM(psQueue, &psCommand,
1122 psDCInfo->ui32DeviceID, DC_FLIP_COMMAND,
1123 0, NULL, ui32NumSrcSyncs, apsSrcSync,
1124 sizeof(struct DISPLAYCLASS_FLIP_COMMAND));
1125 if (eError != PVRSRV_OK) {
1126 PVR_DPF(PVR_DBG_ERROR,
1127 "PVRSRVSwapToDCSystemKM: Failed to get space in queue");
1131 psFlipCmd = (struct DISPLAYCLASS_FLIP_COMMAND *)psCommand->pvData;
1132 psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
1133 psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain;
1134 psFlipCmd->hExtBuffer =
1135 psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer;
1136 psFlipCmd->hPrivateTag = NULL;
1137 psFlipCmd->ui32ClipRectCount = 0;
1138 psFlipCmd->ui32SwapInterval = 1;
1140 eError = PVRSRVSubmitCommandKM(psQueue, psCommand);
1141 if (eError != PVRSRV_OK) {
1142 PVR_DPF(PVR_DBG_ERROR,
1143 "PVRSRVSwapToDCSystemKM: Failed to submit command");
1147 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) {
1148 if (PVRSRVProcessQueues(IMG_FALSE) !=
1149 PVRSRV_ERROR_PROCESSING_BLOCKED) {
1150 goto ProcessedQueues;
1152 OSWaitus(MAX_HW_TIME_US / WAIT_TRY_COUNT);
1154 END_LOOP_UNTIL_TIMEOUT();
1156 PVR_DPF(PVR_DBG_ERROR,
1157 "PVRSRVSwapToDCSystemKM: Failed to process queues");
1158 eError = PVRSRV_ERROR_GENERIC;
1163 psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer;
1171 static enum PVRSRV_ERROR PVRSRVRegisterSystemISRHandler(
1172 IMG_BOOL (*pfnISRHandler)(void *),
1173 void *pvISRHandlerData,
1174 u32 ui32ISRSourceMask,
1177 struct SYS_DATA *psSysData;
1178 struct PVRSRV_DEVICE_NODE *psDevNode;
1180 PVR_UNREFERENCED_PARAMETER(ui32ISRSourceMask);
1182 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
1183 PVR_DPF(PVR_DBG_ERROR, "PVRSRVRegisterSystemISRHandler: "
1184 "Failed to get SysData");
1185 return PVRSRV_ERROR_GENERIC;
1188 psDevNode = psSysData->psDeviceNodeList;
1190 if (psDevNode->sDevId.ui32DeviceIndex == ui32DeviceID)
1192 psDevNode = psDevNode->psNext;
1195 if (psDevNode == NULL) {
1196 PVR_DPF(PVR_DBG_ERROR, "PVRSRVRegisterSystemISRHandler: "
1197 "Failed to get psDevNode");
1199 return PVRSRV_ERROR_GENERIC;
1202 psDevNode->pvISRData = (void *) pvISRHandlerData;
1204 psDevNode->pfnDeviceISR = pfnISRHandler;
1209 void PVRSRVSetDCState(u32 ui32State)
1211 struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1212 struct PVRSRV_DEVICE_NODE *psDeviceNode;
1213 struct SYS_DATA *psSysData;
1215 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
1216 PVR_DPF(PVR_DBG_ERROR,
1217 "PVRSRVSetDCState: Failed to get SysData");
1221 psDeviceNode = psSysData->psDeviceNodeList;
1222 while (psDeviceNode != NULL) {
1223 if (psDeviceNode->sDevId.eDeviceClass ==
1224 PVRSRV_DEVICE_CLASS_DISPLAY) {
1225 psDCInfo = (struct PVRSRV_DISPLAYCLASS_INFO *)
1226 psDeviceNode->pvDevice;
1227 if (psDCInfo->psFuncTable->pfnSetDCState &&
1228 psDCInfo->hExtDevice)
1229 psDCInfo->psFuncTable->pfnSetDCState(
1230 psDCInfo->hExtDevice,
1233 psDeviceNode = psDeviceNode->psNext;
1237 IMG_BOOL PVRGetDisplayClassJTable(struct PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable)
1239 psJTable->ui32TableSize = sizeof(struct PVRSRV_DC_DISP2SRV_KMJTABLE);
1240 psJTable->pfnPVRSRVRegisterDCDevice = PVRSRVRegisterDCDeviceKM;
1241 psJTable->pfnPVRSRVRemoveDCDevice = PVRSRVRemoveDCDeviceKM;
1242 psJTable->pfnPVRSRVOEMFunction = SysOEMFunction;
1243 psJTable->pfnPVRSRVRegisterCmdProcList = PVRSRVRegisterCmdProcListKM;
1244 psJTable->pfnPVRSRVRemoveCmdProcList = PVRSRVRemoveCmdProcListKM;
1245 psJTable->pfnPVRSRVCmdComplete = PVRSRVCommandCompleteKM;
1246 psJTable->pfnPVRSRVRegisterSystemISRHandler =
1247 PVRSRVRegisterSystemISRHandler;
1248 psJTable->pfnPVRSRVRegisterPowerDevice = PVRSRVRegisterPowerDevice;
1252 EXPORT_SYMBOL(PVRGetDisplayClassJTable);
1254 enum PVRSRV_ERROR PVRSRVCloseBCDeviceKM(void *hDeviceKM,
1255 IMG_BOOL bResManCallback)
1257 struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
1259 PVR_UNREFERENCED_PARAMETER(bResManCallback);
1261 psBCPerContextInfo = (struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)
1264 ResManFreeResByPtr(psBCPerContextInfo->hResItem);
1269 static enum PVRSRV_ERROR CloseBCDeviceCallBack(void *pvParam, u32 ui32Param)
1271 struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
1272 struct PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1274 PVR_UNREFERENCED_PARAMETER(ui32Param);
1276 psBCPerContextInfo = (struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)
1278 psBCInfo = psBCPerContextInfo->psBCInfo;
1280 psBCInfo->ui32RefCount--;
1281 if (psBCInfo->ui32RefCount == 0) {
1284 psBCInfo->psFuncTable->pfnCloseBCDevice(psBCInfo->hExtDevice);
1286 for (i = 0; i < psBCInfo->ui32BufferCount; i++)
1287 if (psBCInfo->psBuffer[i].sDeviceClassBuffer.
1289 PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].
1293 if (psBCInfo->psBuffer)
1294 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1295 sizeof(struct PVRSRV_BC_BUFFER),
1296 psBCInfo->psBuffer, NULL);
1299 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1300 sizeof(struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO),
1301 psBCPerContextInfo, NULL);
1306 enum PVRSRV_ERROR PVRSRVOpenBCDeviceKM(
1307 struct PVRSRV_PER_PROCESS_DATA *psPerProc,
1308 u32 ui32DeviceID, void *hDevCookie,
1311 struct PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1312 struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
1313 struct PVRSRV_DEVICE_NODE *psDeviceNode;
1314 struct BUFFER_INFO sBufferInfo;
1315 struct SYS_DATA *psSysData;
1317 enum PVRSRV_ERROR eError;
1319 if (!phDeviceKM || !hDevCookie) {
1320 PVR_DPF(PVR_DBG_ERROR,
1321 "PVRSRVOpenBCDeviceKM: Invalid params");
1322 return PVRSRV_ERROR_GENERIC;
1325 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
1326 PVR_DPF(PVR_DBG_ERROR,
1327 "PVRSRVOpenBCDeviceKM: Failed to get SysData");
1328 return PVRSRV_ERROR_GENERIC;
1331 psDeviceNode = psSysData->psDeviceNodeList;
1332 while (psDeviceNode) {
1333 if ((psDeviceNode->sDevId.eDeviceClass ==
1334 PVRSRV_DEVICE_CLASS_BUFFER) &&
1335 (psDeviceNode->sDevId.ui32DeviceIndex == ui32DeviceID)) {
1337 psBCInfo = (struct PVRSRV_BUFFERCLASS_INFO *)
1338 psDeviceNode->pvDevice;
1341 psDeviceNode = psDeviceNode->psNext;
1344 PVR_DPF(PVR_DBG_ERROR,
1345 "PVRSRVOpenBCDeviceKM: No devnode matching index %d",
1348 return PVRSRV_ERROR_GENERIC;
1352 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1353 sizeof(*psBCPerContextInfo),
1354 (void **)&psBCPerContextInfo, NULL) != PVRSRV_OK) {
1355 PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: "
1356 "Failed psBCPerContextInfo alloc");
1357 return PVRSRV_ERROR_OUT_OF_MEMORY;
1359 OSMemSet(psBCPerContextInfo, 0, sizeof(*psBCPerContextInfo));
1361 if (psBCInfo->ui32RefCount++ == 0) {
1362 psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie;
1364 psBCInfo->hDevMemContext =
1365 (void *) psDeviceNode->sDevMemoryInfo.pBMKernelContext;
1368 psBCInfo->psFuncTable->pfnOpenBCDevice(&psBCInfo->
1370 if (eError != PVRSRV_OK) {
1371 PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: "
1372 "Failed to open external BC device");
1377 psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice,
1379 if (eError != PVRSRV_OK) {
1380 PVR_DPF(PVR_DBG_ERROR,
1381 "PVRSRVOpenBCDeviceKM : Failed to get BC Info");
1385 psBCInfo->ui32BufferCount = sBufferInfo.ui32BufferCount;
1387 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1388 sizeof(struct PVRSRV_BC_BUFFER) *
1389 sBufferInfo.ui32BufferCount,
1390 (void **) &psBCInfo->psBuffer,
1392 if (eError != PVRSRV_OK) {
1393 PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: "
1394 "Failed to allocate BC buffers");
1397 OSMemSet(psBCInfo->psBuffer, 0,
1398 sizeof(struct PVRSRV_BC_BUFFER) *
1399 sBufferInfo.ui32BufferCount);
1401 for (i = 0; i < psBCInfo->ui32BufferCount; i++) {
1403 eError = PVRSRVAllocSyncInfoKM(NULL,
1404 psBCInfo->hDevMemContext,
1405 &psBCInfo->psBuffer[i].sDeviceClassBuffer.
1407 if (eError != PVRSRV_OK) {
1408 PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: "
1409 "Failed sync info alloc");
1413 eError = psBCInfo->psFuncTable->pfnGetBCBuffer(
1414 psBCInfo->hExtDevice, i,
1415 psBCInfo->psBuffer[i].sDeviceClassBuffer.
1418 &psBCInfo->psBuffer[i].sDeviceClassBuffer.
1420 if (eError != PVRSRV_OK) {
1421 PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: "
1422 "Failed to get BC buffers");
1426 psBCInfo->psBuffer[i].sDeviceClassBuffer.
1428 psBCInfo->psFuncTable->pfnGetBufferAddr;
1429 psBCInfo->psBuffer[i].sDeviceClassBuffer.
1430 hDevMemContext = psBCInfo->hDevMemContext;
1431 psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice =
1432 psBCInfo->hExtDevice;
1436 psBCPerContextInfo->psBCInfo = psBCInfo;
1437 psBCPerContextInfo->hResItem =
1438 ResManRegisterRes(psPerProc->hResManContext,
1439 RESMAN_TYPE_BUFFERCLASS_DEVICE,
1440 psBCPerContextInfo, 0, CloseBCDeviceCallBack);
1442 *phDeviceKM = (void *)psBCPerContextInfo;
1447 for (i = 0; i < psBCInfo->ui32BufferCount; i++) {
1448 if (psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) {
1449 PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].
1454 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1455 sizeof(struct PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount,
1456 psBCInfo->psBuffer, NULL);
1458 psBCInfo->psFuncTable->pfnCloseBCDevice(psBCInfo->hExtDevice);
1460 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psBCPerContextInfo),
1461 psBCPerContextInfo, NULL);
1462 psBCInfo->ui32RefCount--;
1467 enum PVRSRV_ERROR PVRSRVGetBCInfoKM(void *hDeviceKM,
1468 struct BUFFER_INFO *psBufferInfo)
1470 struct PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1471 enum PVRSRV_ERROR eError;
1473 if (!hDeviceKM || !psBufferInfo) {
1474 PVR_DPF(PVR_DBG_ERROR,
1475 "PVRSRVGetBCInfoKM: Invalid parameters");
1476 return PVRSRV_ERROR_INVALID_PARAMS;
1479 psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM);
1482 psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice,
1485 if (eError != PVRSRV_OK) {
1486 PVR_DPF(PVR_DBG_ERROR,
1487 "PVRSRVGetBCInfoKM : Failed to get BC Info");
1494 enum PVRSRV_ERROR PVRSRVGetBCBufferKM(void *hDeviceKM, u32 ui32BufferIndex,
1497 struct PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1499 if (!hDeviceKM || !phBuffer) {
1500 PVR_DPF(PVR_DBG_ERROR,
1501 "PVRSRVGetBCBufferKM: Invalid parameters");
1502 return PVRSRV_ERROR_INVALID_PARAMS;
1505 psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM);
1507 if (ui32BufferIndex < psBCInfo->ui32BufferCount) {
1508 *phBuffer = (void *)&psBCInfo->psBuffer[ui32BufferIndex];
1510 PVR_DPF(PVR_DBG_ERROR, "PVRSRVGetBCBufferKM: "
1511 "Buffer index %d out of range (%d)",
1512 ui32BufferIndex, psBCInfo->ui32BufferCount);
1513 return PVRSRV_ERROR_INVALID_PARAMS;
1519 IMG_BOOL PVRGetBufferClassJTable(struct PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable)
1521 psJTable->ui32TableSize = sizeof(struct PVRSRV_BC_BUFFER2SRV_KMJTABLE);
1523 psJTable->pfnPVRSRVRegisterBCDevice = PVRSRVRegisterBCDeviceKM;
1524 psJTable->pfnPVRSRVRemoveBCDevice = PVRSRVRemoveBCDeviceKM;
1528 EXPORT_SYMBOL(PVRGetBufferClassJTable);