aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/cdv/bc_video/bufferclass_video.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/cdv/bc_video/bufferclass_video.c')
-rw-r--r--drivers/staging/cdv/bc_video/bufferclass_video.c327
1 files changed, 327 insertions, 0 deletions
diff --git a/drivers/staging/cdv/bc_video/bufferclass_video.c b/drivers/staging/cdv/bc_video/bufferclass_video.c
new file mode 100644
index 000000000000..3464b4652c7f
--- /dev/null
+++ b/drivers/staging/cdv/bc_video/bufferclass_video.c
@@ -0,0 +1,327 @@
+/***************************************************************************
+ *
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ ******************************************************************************/
+
+#if defined(__linux__)
+#include <linux/string.h>
+#else
+#include <string.h>
+#endif
+
+#include "bufferclass_video.h"
+#include "bufferclass_video_linux.h"
+
+#define VBUFFERCLASS_DEVICE_NAME "Video Bufferclass Device"
+#define CBUFFERCLASS_DEVICE_NAME "Camera Bufferclass Device"
+
+static void *gpvAnchorVideo[BC_VIDEO_DEVICE_MAX_ID];
+
+static void *gpcAnchor;
+static PFN_BC_GET_PVRJTABLE pfnGetPVRJTable = IMG_NULL;
+
+BC_VIDEO_DEVINFO *
+GetAnchorPtr (int id)
+{
+ BC_VIDEO_DEVINFO *AnchorPtr = NULL;
+ if (id < BC_VIDEO_DEVICE_MAX_ID)
+ AnchorPtr = gpvAnchorVideo[id];
+ else if (id == BC_CAMERA_DEVICEID)
+ AnchorPtr = gpcAnchor;
+ return AnchorPtr;
+}
+
+static void
+SetAnchorPtr (BC_VIDEO_DEVINFO * psDevInfo, int id)
+{
+ if (id < BC_VIDEO_DEVICE_MAX_ID)
+ gpvAnchorVideo[id] = (void *) psDevInfo;
+ else if (id == BC_CAMERA_DEVICEID)
+ gpcAnchor = (void *) psDevInfo;
+}
+
+static PVRSRV_ERROR
+OpenVBCDevice (IMG_UINT32 uDeviceID, IMG_HANDLE * phDevice)
+{
+ BC_VIDEO_DEVINFO *psDevInfo;
+ int id;
+ *phDevice = NULL;
+ for(id = 0; id < BC_VIDEO_DEVICE_MAX_ID; id++){
+ psDevInfo = GetAnchorPtr(id);
+ if(psDevInfo != NULL && psDevInfo->ulDeviceID == uDeviceID){
+ *phDevice = (IMG_HANDLE) psDevInfo;
+ break;
+ }
+ }
+
+ return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR OpenCBCDevice(IMG_UINT32 uDeviceID, IMG_HANDLE *phDevice)
+{
+ BC_VIDEO_DEVINFO *psDevInfo;
+
+ UNREFERENCED_PARAMETER(uDeviceID);
+ psDevInfo = GetAnchorPtr(BC_CAMERA_DEVICEID);
+
+ *phDevice = (IMG_HANDLE)psDevInfo;
+
+ return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR
+CloseBCDevice (IMG_UINT32 uDeviceID, IMG_HANDLE hDevice)
+{
+ UNREFERENCED_PARAMETER (uDeviceID);
+ UNREFERENCED_PARAMETER (hDevice);
+
+ return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR
+GetBCBuffer (IMG_HANDLE hDevice,
+ IMG_UINT32 ui32BufferNumber,
+ PVRSRV_SYNC_DATA * psSyncData, IMG_HANDLE * phBuffer)
+{
+ BC_VIDEO_DEVINFO *psDevInfo;
+
+ if (!hDevice || !phBuffer)
+ {
+ return (PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+ psDevInfo = (BC_VIDEO_DEVINFO *) hDevice;
+
+ if (ui32BufferNumber < psDevInfo->sBufferInfo.ui32BufferCount)
+ {
+ psDevInfo->psSystemBuffer[ui32BufferNumber].psSyncData = psSyncData;
+ *phBuffer = (IMG_HANDLE) & psDevInfo->psSystemBuffer[ui32BufferNumber];
+ }
+ else
+ {
+ return (PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+ return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR
+GetBCInfo (IMG_HANDLE hDevice, BUFFER_INFO * psBCInfo)
+{
+ BC_VIDEO_DEVINFO *psDevInfo;
+
+ if (!hDevice || !psBCInfo)
+ {
+ return (PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+ psDevInfo = (BC_VIDEO_DEVINFO *) hDevice;
+
+ *psBCInfo = psDevInfo->sBufferInfo;
+
+ return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR
+GetBCBufferAddr (IMG_HANDLE hDevice,
+ IMG_HANDLE hBuffer,
+ IMG_SYS_PHYADDR ** ppsSysAddr,
+ IMG_UINT32 * pui32ByteSize,
+ IMG_VOID ** ppvCpuVAddr,
+ IMG_HANDLE * phOSMapInfo,
+ IMG_BOOL * pbIsContiguous, IMG_UINT32 * pui32TilingStride)
+{
+ BC_VIDEO_BUFFER *psBuffer;
+
+ UNREFERENCED_PARAMETER (pui32TilingStride);
+ if (!hDevice || !hBuffer || !ppsSysAddr || !pui32ByteSize)
+ {
+ return (PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+ psBuffer = (BC_VIDEO_BUFFER *) hBuffer;
+
+ *ppvCpuVAddr = psBuffer->sCPUVAddr;
+
+ *phOSMapInfo = IMG_NULL;
+ *pui32ByteSize = (IMG_UINT32) psBuffer->ulSize;
+
+ *ppsSysAddr = psBuffer->psSysAddr;
+ *pbIsContiguous = psBuffer->is_conti_addr;
+
+ return (PVRSRV_OK);
+}
+
+
+BCE_ERROR
+BC_Video_Register (int id)
+{
+ BC_VIDEO_DEVINFO *psDevInfo;
+
+ psDevInfo = GetAnchorPtr (id);
+
+ if (psDevInfo == NULL)
+ {
+ psDevInfo =
+ (BC_VIDEO_DEVINFO *) BCAllocKernelMem (sizeof (BC_VIDEO_DEVINFO));
+
+ if (!psDevInfo)
+ {
+ return (BCE_ERROR_OUT_OF_MEMORY);
+ }
+
+ SetAnchorPtr ((void *) psDevInfo, id);
+
+ psDevInfo->ulRefCount = 0;
+
+ if (BCOpenPVRServices (&psDevInfo->hPVRServices) != BCE_OK)
+ {
+ return (BCE_ERROR_INIT_FAILURE);
+ }
+ if (BCGetLibFuncAddr
+ (psDevInfo->hPVRServices, "PVRGetBufferClassJTable",
+ &pfnGetPVRJTable) != BCE_OK)
+ {
+ return (BCE_ERROR_INIT_FAILURE);
+ }
+
+ if (!(*pfnGetPVRJTable) (&psDevInfo->sPVRJTable))
+ {
+ return (BCE_ERROR_INIT_FAILURE);
+ }
+
+ psDevInfo->ulNumBuffers = 0;
+
+ psDevInfo->sBufferInfo.pixelformat = PVRSRV_PIXEL_FORMAT_UNKNOWN;
+ psDevInfo->sBufferInfo.ui32Width = 0;
+ psDevInfo->sBufferInfo.ui32Height = 0;
+ psDevInfo->sBufferInfo.ui32ByteStride = 0;
+ psDevInfo->sBufferInfo.ui32BufferDeviceID = id;
+ psDevInfo->sBufferInfo.ui32Flags = 0;
+ psDevInfo->sBufferInfo.ui32BufferCount =
+ (IMG_UINT32) psDevInfo->ulNumBuffers;
+
+ if (id < BC_VIDEO_DEVICE_MAX_ID)
+ {
+ strncpy (psDevInfo->sBufferInfo.szDeviceName,
+ VBUFFERCLASS_DEVICE_NAME, MAX_BUFFER_DEVICE_NAME_SIZE);
+ psDevInfo->sBCJTable.pfnOpenBCDevice = OpenVBCDevice;
+ }
+ else if (id == BC_CAMERA_DEVICEID)
+ {
+ strncpy (psDevInfo->sBufferInfo.szDeviceName,
+ CBUFFERCLASS_DEVICE_NAME, MAX_BUFFER_DEVICE_NAME_SIZE);
+ psDevInfo->sBCJTable.pfnOpenBCDevice = OpenCBCDevice;
+ }
+
+ psDevInfo->sBCJTable.ui32TableSize =
+ sizeof (PVRSRV_BC_SRV2BUFFER_KMJTABLE);
+ psDevInfo->sBCJTable.pfnCloseBCDevice = CloseBCDevice;
+ psDevInfo->sBCJTable.pfnGetBCBuffer = GetBCBuffer;
+ psDevInfo->sBCJTable.pfnGetBCInfo = GetBCInfo;
+ psDevInfo->sBCJTable.pfnGetBufferAddr = GetBCBufferAddr;
+
+ if (psDevInfo->sPVRJTable.
+ pfnPVRSRVRegisterBCDevice (&psDevInfo->sBCJTable,
+ &psDevInfo->ulDeviceID) != PVRSRV_OK)
+ {
+ return (BCE_ERROR_DEVICE_REGISTER_FAILED);
+ }
+ }
+
+ psDevInfo->ulRefCount++;
+
+ return (BCE_OK);
+}
+
+BCE_ERROR
+BC_Video_Unregister (int id)
+{
+ BC_VIDEO_DEVINFO *psDevInfo;
+
+ psDevInfo = GetAnchorPtr (id);
+
+ if (psDevInfo == NULL)
+ {
+ return (BCE_ERROR_GENERIC);
+ }
+
+ psDevInfo->ulRefCount--;
+
+ if (psDevInfo->ulRefCount == 0)
+ {
+ PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable = &psDevInfo->sPVRJTable;
+
+ if (psJTable->pfnPVRSRVRemoveBCDevice (psDevInfo->ulDeviceID) !=
+ PVRSRV_OK)
+ {
+ return (BCE_ERROR_GENERIC);
+ }
+
+ if (BCClosePVRServices (psDevInfo->hPVRServices) != BCE_OK)
+ {
+ psDevInfo->hPVRServices = NULL;
+ return (BCE_ERROR_GENERIC);
+ }
+
+ if (psDevInfo->psSystemBuffer)
+ {
+ BCFreeKernelMem (psDevInfo->psSystemBuffer);
+ }
+
+ BCFreeKernelMem (psDevInfo);
+
+ SetAnchorPtr (NULL, id);
+ }
+ return (BCE_OK);
+}
+
+BCE_ERROR
+BC_Video_Init (int id)
+{
+ BCE_ERROR eError;
+
+ eError = BC_Video_Register (id);
+ if (eError != BCE_OK)
+ {
+ return eError;
+ }
+
+ return (BCE_OK);
+}
+
+BCE_ERROR
+BC_Video_Deinit (int id)
+{
+ BCE_ERROR eError;
+
+ BC_DestroyBuffers (id);
+
+ eError = BC_Video_Unregister (id);
+ if (eError != BCE_OK)
+ {
+ return eError;
+ }
+
+ return (BCE_OK);
+}