[Meego-kernel] [PATCH 03/22] GFX: Add bc_video driver for texture streaming
hitesh.k.patel at intel.com
hitesh.k.patel at intel.com
Thu Dec 16 10:51:39 PST 2010
From: Randy Xu <randy.xu at intel.com>
Add buffer clas video driver to support future Texture
streaming feature.
Signed-off-by: Randy Xu <randy.xu at intel.com>
Signed-off-by: Hitesh K. Patel <hitesh.k.patel at intel.com>
---
drivers/staging/mrst/bc_video/bufferclass_video.c | 327 +++++++
drivers/staging/mrst/bc_video/bufferclass_video.h | 171 ++++
.../mrst/bc_video/bufferclass_video_linux.c | 891 ++++++++++++++++++++
.../mrst/bc_video/bufferclass_video_linux.h | 67 ++
drivers/staging/mrst/drv/psb_drv.c | 34 +-
drivers/staging/mrst/medfield/Makefile | 7 +-
drivers/staging/mrst/moorestown/Makefile | 5 +
.../system/moorestown/sys_pvr_drm_export.h | 4 +
.../mrst/pvr/services4/system/moorestown/sysinfo.h | 2 +-
.../services4/system/unified/sys_pvr_drm_export.h | 4 +
.../mrst/pvr/services4/system/unified/sysinfo.h | 2 +-
11 files changed, 1507 insertions(+), 7 deletions(-)
create mode 100644 drivers/staging/mrst/bc_video/bufferclass_video.c
create mode 100644 drivers/staging/mrst/bc_video/bufferclass_video.h
create mode 100644 drivers/staging/mrst/bc_video/bufferclass_video_linux.c
create mode 100644 drivers/staging/mrst/bc_video/bufferclass_video_linux.h
diff --git a/drivers/staging/mrst/bc_video/bufferclass_video.c b/drivers/staging/mrst/bc_video/bufferclass_video.c
new file mode 100644
index 0000000..49cddb3
--- /dev/null
+++ b/drivers/staging/mrst/bc_video/bufferclass_video.c
@@ -0,0 +1,327 @@
+/***************************************************************************
+ *
+ * Copyright © 2010 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);
+}
diff --git a/drivers/staging/mrst/bc_video/bufferclass_video.h b/drivers/staging/mrst/bc_video/bufferclass_video.h
new file mode 100644
index 0000000..8c43fe4
--- /dev/null
+++ b/drivers/staging/mrst/bc_video/bufferclass_video.h
@@ -0,0 +1,171 @@
+/**********************************************************************
+ *
+ * Copyright © 2010 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.
+ *
+ ******************************************************************************/
+
+#ifndef __BC_VIDEO_H__
+#define __BC_VIDEO_H__
+
+#include "img_defs.h"
+#include "servicesext.h"
+#include "kernelbuffer.h"
+#include <kernel.h>
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+ enum BC_memory
+ {
+ BC_MEMORY_MMAP = 1,
+ BC_MEMORY_USERPTR = 2,
+ };
+
+ /*
+ * the following types are tested for fourcc in struct bc_buf_params_t
+ * NV12
+ * UYVY
+ * RGB565 - not tested yet
+ * YUYV
+ */
+ typedef struct bc_buf_params
+ {
+ int count; /*number of buffers, [in/out] */
+ int width; /*buffer width in pixel, multiple of 8 or 32 */
+ int height; /*buffer height in pixel */
+ int stride;
+ unsigned int fourcc; /*buffer pixel format */
+ enum BC_memory type;
+ } bc_buf_params_t;
+
+ extern IMG_IMPORT IMG_BOOL
+ PVRGetBufferClassJTable (PVRSRV_BC_BUFFER2SRV_KMJTABLE * psJTable);
+
+#define BC_VIDEO_DEVICE_MAX_ID 5
+#define BC_CAMERA_DEVICEID 8
+
+ typedef void *BCE_HANDLE;
+
+ typedef enum tag_bce_bool
+ {
+ BCE_FALSE = 0,
+ BCE_TRUE = 1,
+ } BCE_BOOL, *BCE_PBOOL;
+
+ typedef struct BC_VIDEO_BUFFER_TAG
+ {
+ unsigned long ulSize;
+ BCE_HANDLE hMemHandle;
+
+ IMG_SYS_PHYADDR *psSysAddr;
+
+ IMG_CPU_VIRTADDR sCPUVAddr;
+ PVRSRV_SYNC_DATA *psSyncData;
+
+ struct BC_VIDEO_BUFFER_TAG *psNext;
+ int sBufferHandle;
+ IMG_BOOL is_conti_addr;
+ } BC_VIDEO_BUFFER;
+
+ typedef struct BC_VIDEO_DEVINFO_TAG
+ {
+ IMG_UINT32 ulDeviceID;
+
+ BC_VIDEO_BUFFER *psSystemBuffer;
+
+ unsigned long ulNumBuffers;
+
+ PVRSRV_BC_BUFFER2SRV_KMJTABLE sPVRJTable;
+
+ PVRSRV_BC_SRV2BUFFER_KMJTABLE sBCJTable;
+
+ BCE_HANDLE hPVRServices;
+
+ unsigned long ulRefCount;
+
+ BUFFER_INFO sBufferInfo;
+ enum BC_memory buf_type;
+ } BC_VIDEO_DEVINFO;
+
+ typedef enum _BCE_ERROR_
+ {
+ BCE_OK = 0,
+ BCE_ERROR_GENERIC = 1,
+ BCE_ERROR_OUT_OF_MEMORY = 2,
+ BCE_ERROR_TOO_FEW_BUFFERS = 3,
+ BCE_ERROR_INVALID_PARAMS = 4,
+ BCE_ERROR_INIT_FAILURE = 5,
+ BCE_ERROR_CANT_REGISTER_CALLBACK = 6,
+ BCE_ERROR_INVALID_DEVICE = 7,
+ BCE_ERROR_DEVICE_REGISTER_FAILED = 8,
+ BCE_ERROR_NO_PRIMARY = 9
+ } BCE_ERROR;
+
+#ifndef UNREFERENCED_PARAMETER
+#define UNREFERENCED_PARAMETER(param) (param) = (param)
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+ BCE_ERROR BC_Video_Register (int id);
+ BCE_ERROR BC_Video_Unregister (int id);
+ BCE_ERROR BC_Video_Buffers_Create (int id);
+ BCE_ERROR BC_Video_Buffers_Destroy (int id);
+ BCE_ERROR BC_Video_Init (int id);
+ BCE_ERROR BC_Video_Deinit (int id);
+
+ BCE_ERROR BCOpenPVRServices (BCE_HANDLE * phPVRServices);
+ BCE_ERROR BCClosePVRServices (BCE_HANDLE hPVRServices);
+
+ void *BCAllocKernelMem (unsigned long ulSize);
+ void BCFreeKernelMem (void *pvMem);
+
+ BCE_ERROR BCAllocDiscontigMemory (unsigned long ulSize,
+ BCE_HANDLE unref__ * phMemHandle,
+ IMG_CPU_VIRTADDR * pLinAddr,
+ IMG_SYS_PHYADDR ** ppPhysAddr);
+
+ void BCFreeDiscontigMemory (unsigned long ulSize,
+ BCE_HANDLE unref__ hMemHandle,
+ IMG_CPU_VIRTADDR LinAddr,
+ IMG_SYS_PHYADDR * pPhysAddr);
+
+ IMG_SYS_PHYADDR CpuPAddrToSysPAddrBC (IMG_CPU_PHYADDR cpu_paddr);
+ IMG_CPU_PHYADDR SysPAddrToCpuPAddrBC (IMG_SYS_PHYADDR sys_paddr);
+
+ void *MapPhysAddr (IMG_SYS_PHYADDR sSysAddr, unsigned long ulSize);
+ void UnMapPhysAddr (void *pvAddr, unsigned long ulSize);
+
+ BCE_ERROR BCGetLibFuncAddr (BCE_HANDLE hExtDrv, char *szFunctionName,
+ PFN_BC_GET_PVRJTABLE * ppfnFuncTable);
+ BC_VIDEO_DEVINFO *GetAnchorPtr (int id);
+ int GetBufferCount (unsigned int *puiBufferCount, int id);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/drivers/staging/mrst/bc_video/bufferclass_video_linux.c b/drivers/staging/mrst/bc_video/bufferclass_video_linux.c
new file mode 100644
index 0000000..b591366
--- /dev/null
+++ b/drivers/staging/mrst/bc_video/bufferclass_video_linux.c
@@ -0,0 +1,891 @@
+/****************************************************************************
+ *
+ * Copyright © 2010 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.
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#if defined(LMA)
+#include <linux/pci.h>
+#else
+#include <linux/dma-mapping.h>
+#endif
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include "psb_drv.h"
+#include "ttm/ttm_bo_api.h"
+#include "ttm/ttm_placement.h"
+#include "ttm/ttm_object.h"
+
+#include "bufferclass_video.h"
+#include "bufferclass_video_linux.h"
+#include "pvrmodule.h"
+#include "sys_pvr_drm_export.h"
+
+#define DEVNAME "bc_video"
+#define DRVNAME DEVNAME
+
+#if defined(BCE_USE_SET_MEMORY)
+#undef BCE_USE_SET_MEMORY
+#endif
+
+#if defined(__i386__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) && defined(SUPPORT_LINUX_X86_PAT) && defined(SUPPORT_LINUX_X86_WRITECOMBINE)
+#include <asm/cacheflush.h>
+#define BCE_USE_SET_MEMORY
+#endif
+
+static int width_align;
+unsigned int bc_video_id_usage[BC_VIDEO_DEVICE_MAX_ID];
+
+MODULE_SUPPORTED_DEVICE (DEVNAME);
+
+int FillBuffer (unsigned int uiBufferIndex);
+
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+static struct class *psPvrClass;
+#endif
+
+static int AssignedMajorNumber;
+
+#define unref__ __attribute__ ((unused))
+
+#if defined(LMA)
+#define PVR_BUFFERCLASS_MEMOFFSET (220 * 1024 * 1024)
+#define PVR_BUFFERCLASS_MEMSIZE (4 * 1024 * 1024)
+
+unsigned long g_ulMemBase = 0;
+unsigned long g_ulMemCurrent = 0;
+
+#define VENDOR_ID_PVR 0x1010
+#define DEVICE_ID_PVR 0x1CF1
+
+#define PVR_MEM_PCI_BASENUM 2
+#endif
+
+#define file_to_id(file) (iminor(file->f_path.dentry->d_inode))
+
+int
+BC_Video_ModInit (void)
+{
+ int i, j;
+ /*LDM_PCI is defined, while LDM_PLATFORM and LMA are not defined.*/
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+ struct device *psDev;
+#endif
+
+#if defined(LMA)
+ struct pci_dev *psPCIDev;
+ int error;
+#endif
+
+ /* video width is 4 byte aligned */
+ width_align = 4;
+
+#if defined(LMA)
+ psPCIDev = pci_get_device (VENDOR_ID_PVR, DEVICE_ID_PVR, NULL);
+ if (psPCIDev == NULL)
+ {
+ printk (KERN_ERR DRVNAME
+ ": BC_Video_ModInit: pci_get_device failed\n");
+ goto ExitError;
+ }
+
+ if ((error = pci_enable_device (psPCIDev)) != 0)
+ {
+ printk (KERN_ERR DRVNAME
+ ": BC_Video_ModInit: pci_enable_device failed (%d)\n", error);
+ goto ExitError;
+ }
+#endif
+
+#if defined(DEBUG)
+ printk (KERN_ERR DRVNAME ": BC_Video_ModInit: major device %d\n",
+ AssignedMajorNumber);
+#endif
+
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+ psPvrClass = class_create (THIS_MODULE, "bc_video");
+ if (IS_ERR (psPvrClass))
+ {
+ printk (KERN_ERR DRVNAME
+ ": BC_Video_ModInit: unable to create class (%ld)",
+ PTR_ERR (psPvrClass));
+ goto ExitUnregister;
+ }
+
+ psDev = device_create (psPvrClass, NULL, MKDEV (AssignedMajorNumber, 0),
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
+ NULL,
+#endif
+ DEVNAME);
+ if (IS_ERR (psDev))
+ {
+ printk (KERN_ERR DRVNAME
+ ": BC_Video_ModInit: unable to create device (%ld)",
+ PTR_ERR (psDev));
+ goto ExitDestroyClass;
+ }
+#endif
+
+#if defined(LMA)
+ g_ulMemBase =
+ pci_resource_start (psPCIDev,
+ PVR_MEM_PCI_BASENUM) + PVR_BUFFERCLASS_MEMOFFSET;
+#endif
+
+ for (i = 0; i < BC_VIDEO_DEVICE_MAX_ID; i++)
+ {
+ bc_video_id_usage[i] = 0;
+ if (BC_Video_Init (i) != BCE_OK)
+ {
+ printk (KERN_ERR DRVNAME
+ ": BC_Video_ModInit: can't init video bc device %d.\n", i);
+ for (j = i; j >= 0; j--)
+ {
+ BC_Video_Deinit (j);
+ }
+ goto ExitUnregister;
+ }
+ }
+
+ if (BC_Video_Init (BC_CAMERA_DEVICEID) != BCE_OK)
+ {
+ for (i = BC_VIDEO_DEVICE_MAX_ID - 1; i >= 0; i--)
+ {
+ BC_Video_Deinit (i);
+ }
+ BC_Video_Deinit (BC_CAMERA_DEVICEID);
+ printk (KERN_ERR DRVNAME ": BC_Camera_ModInit: can't init device\n");
+ goto ExitUnregister;
+ }
+
+#if defined(LMA)
+ pci_disable_device (psPCIDev);
+#endif
+
+ return 0;
+
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+ExitDestroyClass:
+ class_destroy (psPvrClass);
+#endif
+ExitUnregister:
+ unregister_chrdev (AssignedMajorNumber, DEVNAME);
+ //ExitDisable:
+#if defined(LMA)
+ pci_disable_device (psPCIDev);
+ExitError:
+#endif
+ return -EBUSY;
+}
+
+int
+BC_Video_ModCleanup (void)
+{
+ int i;
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+ device_destroy (psPvrClass, MKDEV (AssignedMajorNumber, 0));
+ class_destroy (psPvrClass);
+#endif
+
+ for (i = 0; i < BC_VIDEO_DEVICE_MAX_ID; i++)
+ {
+ if (BC_Video_Deinit (i) != BCE_OK)
+ {
+ printk (KERN_ERR DRVNAME
+ ": BC_Video_ModCleanup: can't deinit video device %d.\n",
+ i);
+ return -1;
+ }
+ }
+
+ if (BC_Video_Deinit (BC_CAMERA_DEVICEID) != BCE_OK)
+ {
+ printk (KERN_ERR DRVNAME
+ ": BC_Camera_ModCleanup: can't deinit device\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+ void *
+BCAllocKernelMem (unsigned long ulSize)
+{
+ return kmalloc (ulSize, GFP_KERNEL);
+}
+
+void
+BCFreeKernelMem (void *pvMem)
+{
+ kfree (pvMem);
+}
+
+#define RANGE_TO_PAGES(range) (((range) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)
+#define VMALLOC_TO_PAGE_PHYS(vAddr) page_to_phys(vmalloc_to_page(vAddr))
+
+BCE_ERROR
+BCAllocDiscontigMemory (unsigned long ulSize,
+ BCE_HANDLE unref__ * phMemHandle,
+ IMG_CPU_VIRTADDR * pLinAddr,
+ IMG_SYS_PHYADDR ** ppPhysAddr)
+{
+ unsigned long ulPages = RANGE_TO_PAGES (ulSize);
+ IMG_SYS_PHYADDR *pPhysAddr;
+ unsigned long ulPage;
+ IMG_CPU_VIRTADDR LinAddr;
+
+ LinAddr =
+ __vmalloc (ulSize, GFP_KERNEL | __GFP_HIGHMEM,
+ pgprot_noncached (PAGE_KERNEL));
+ if (!LinAddr)
+ {
+ return BCE_ERROR_OUT_OF_MEMORY;
+ }
+
+ pPhysAddr = kmalloc (ulPages * sizeof (IMG_SYS_PHYADDR), GFP_KERNEL);
+ if (!pPhysAddr)
+ {
+ vfree (LinAddr);
+ return BCE_ERROR_OUT_OF_MEMORY;
+ }
+
+ *pLinAddr = LinAddr;
+
+ for (ulPage = 0; ulPage < ulPages; ulPage++)
+ {
+ pPhysAddr[ulPage].uiAddr = VMALLOC_TO_PAGE_PHYS (LinAddr);
+
+ LinAddr += PAGE_SIZE;
+ }
+
+ *ppPhysAddr = pPhysAddr;
+
+ return BCE_OK;
+}
+
+void
+BCFreeDiscontigMemory (unsigned long ulSize,
+ BCE_HANDLE unref__ hMemHandle,
+ IMG_CPU_VIRTADDR LinAddr, IMG_SYS_PHYADDR * pPhysAddr)
+{
+ kfree (pPhysAddr);
+
+ vfree (LinAddr);
+}
+
+ BCE_ERROR
+BCAllocContigMemory (unsigned long ulSize,
+ BCE_HANDLE unref__ * phMemHandle,
+ IMG_CPU_VIRTADDR * pLinAddr, IMG_CPU_PHYADDR * pPhysAddr)
+{
+#if defined(LMA)
+ void *pvLinAddr;
+
+
+ if (g_ulMemCurrent + ulSize >= PVR_BUFFERCLASS_MEMSIZE)
+ {
+ return (BCE_ERROR_OUT_OF_MEMORY);
+ }
+
+ pvLinAddr = ioremap (g_ulMemBase + g_ulMemCurrent, ulSize);
+
+ if (pvLinAddr)
+ {
+ pPhysAddr->uiAddr = g_ulMemBase + g_ulMemCurrent;
+ *pLinAddr = pvLinAddr;
+
+ g_ulMemCurrent += ulSize;
+ return (BCE_OK);
+ }
+ return (BCE_ERROR_OUT_OF_MEMORY);
+#else
+#if defined(BCE_USE_SET_MEMORY)
+ void *pvLinAddr;
+ unsigned long ulAlignedSize = PAGE_ALIGN (ulSize);
+ int iPages = (int) (ulAlignedSize >> PAGE_SHIFT);
+ int iError;
+
+ pvLinAddr = kmalloc (ulAlignedSize, GFP_KERNEL);
+ BUG_ON (((unsigned long) pvLinAddr) & ~PAGE_MASK);
+
+ iError = set_memory_wc ((unsigned long) pvLinAddr, iPages);
+ if (iError != 0)
+ {
+ printk (KERN_ERR DRVNAME
+ ": BCAllocContigMemory: set_memory_wc failed (%d)\n", iError);
+ return (BCE_ERROR_OUT_OF_MEMORY);
+ }
+
+ pPhysAddr->uiAddr = virt_to_phys (pvLinAddr);
+ *pLinAddr = pvLinAddr;
+
+ return (BCE_OK);
+#else
+ dma_addr_t dma;
+ void *pvLinAddr;
+
+ pvLinAddr = dma_alloc_coherent (NULL, ulSize, &dma, GFP_KERNEL);
+ if (pvLinAddr == NULL)
+ {
+ return (BCE_ERROR_OUT_OF_MEMORY);
+ }
+
+ pPhysAddr->uiAddr = dma;
+ *pLinAddr = pvLinAddr;
+
+ return (BCE_OK);
+#endif
+#endif
+}
+
+void
+BCFreeContigMemory (unsigned long ulSize,
+ BCE_HANDLE unref__ hMemHandle,
+ IMG_CPU_VIRTADDR LinAddr, IMG_CPU_PHYADDR PhysAddr)
+{
+#if defined(LMA)
+ g_ulMemCurrent -= ulSize;
+ iounmap (LinAddr);
+#else
+#if defined(BCE_USE_SET_MEMORY)
+ unsigned long ulAlignedSize = PAGE_ALIGN (ulSize);
+ int iError;
+ int iPages = (int) (ulAlignedSize >> PAGE_SHIFT);
+
+ iError = set_memory_wb ((unsigned long) LinAddr, iPages);
+ if (iError != 0)
+ {
+ printk (KERN_ERR DRVNAME
+ ": BCFreeContigMemory: set_memory_wb failed (%d)\n", iError);
+ }
+ kfree (LinAddr);
+#else
+ dma_free_coherent (NULL, ulSize, LinAddr, (dma_addr_t) PhysAddr.uiAddr);
+#endif
+#endif
+}
+
+ IMG_SYS_PHYADDR
+CpuPAddrToSysPAddrBC (IMG_CPU_PHYADDR cpu_paddr)
+{
+ IMG_SYS_PHYADDR sys_paddr;
+ sys_paddr.uiAddr = cpu_paddr.uiAddr;
+ return sys_paddr;
+}
+
+ IMG_CPU_PHYADDR
+SysPAddrToCpuPAddrBC (IMG_SYS_PHYADDR sys_paddr)
+{
+ IMG_CPU_PHYADDR cpu_paddr;
+ cpu_paddr.uiAddr = sys_paddr.uiAddr;
+ return cpu_paddr;
+}
+
+BCE_ERROR
+BCOpenPVRServices (BCE_HANDLE * phPVRServices)
+{
+ *phPVRServices = 0;
+ return (BCE_OK);
+}
+
+
+BCE_ERROR
+BCClosePVRServices (BCE_HANDLE unref__ hPVRServices)
+{
+ return (BCE_OK);
+}
+
+BCE_ERROR
+BCGetLibFuncAddr (BCE_HANDLE unref__ hExtDrv, char *szFunctionName,
+ PFN_BC_GET_PVRJTABLE * ppfnFuncTable)
+{
+ if (strcmp ("PVRGetBufferClassJTable", szFunctionName) != 0)
+ {
+ return (BCE_ERROR_INVALID_PARAMS);
+ }
+
+ *ppfnFuncTable = PVRGetBufferClassJTable;
+
+ return (BCE_OK);
+}
+
+int
+BC_CreateBuffers (int id, bc_buf_params_t * p, IMG_BOOL is_conti_addr)
+{
+ BC_VIDEO_DEVINFO *psDevInfo;
+ IMG_UINT32 i, stride, size;
+ PVRSRV_PIXEL_FORMAT pixel_fmt;
+
+ if (p->count <= 0)
+ return -EINVAL;
+
+ if (p->width <= 1 || p->width % width_align || p->height <= 1)
+ return -EINVAL;
+
+ switch (p->fourcc)
+ {
+ case BC_PIX_FMT_NV12:
+ pixel_fmt = PVRSRV_PIXEL_FORMAT_NV12;
+ break;
+ case BC_PIX_FMT_UYVY:
+ pixel_fmt = PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY;
+ break;
+ case BC_PIX_FMT_RGB565:
+ pixel_fmt = PVRSRV_PIXEL_FORMAT_RGB565;
+ p->stride = p->stride << 1; /* stride for RGB from user space is uncorrect */
+ break;
+ case BC_PIX_FMT_YUYV:
+ pixel_fmt = PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ stride = p->stride;
+
+ if (p->type != BC_MEMORY_MMAP && p->type != BC_MEMORY_USERPTR)
+ return -EINVAL;
+
+ if ((psDevInfo = GetAnchorPtr (id)) == IMG_NULL)
+ return -ENODEV;
+
+ if (psDevInfo->ulNumBuffers)
+ BC_DestroyBuffers (id);
+
+ psDevInfo->buf_type = p->type;
+ psDevInfo->psSystemBuffer =
+ BCAllocKernelMem (sizeof (BC_VIDEO_BUFFER) * p->count);
+
+ if (!psDevInfo->psSystemBuffer)
+ return -ENOMEM;
+
+ memset (psDevInfo->psSystemBuffer, 0, sizeof (BC_VIDEO_BUFFER) * p->count);
+ size = p->height * stride;
+ if (pixel_fmt == PVRSRV_PIXEL_FORMAT_NV12)
+ size += (stride >> 1) * (p->height >> 1) << 1;
+
+ for (i = 0; i < p->count; i++)
+ {
+ IMG_SYS_PHYADDR *pPhysAddr;
+ psDevInfo->ulNumBuffers++;
+ psDevInfo->psSystemBuffer[i].ulSize = size;
+ psDevInfo->psSystemBuffer[i].psSyncData = IMG_NULL;
+
+ /*for discontig buffers, allocate memory for pPhysAddr */
+ psDevInfo->psSystemBuffer[i].is_conti_addr = is_conti_addr;
+ if (is_conti_addr)
+ {
+ pPhysAddr = BCAllocKernelMem (1 * sizeof (IMG_SYS_PHYADDR));
+ if (!pPhysAddr)
+ {
+ return BCE_ERROR_OUT_OF_MEMORY;
+ }
+ memset (pPhysAddr, 0, 1 * sizeof (IMG_SYS_PHYADDR));
+ }
+ else
+ {
+ unsigned long ulPages = RANGE_TO_PAGES (size);
+ pPhysAddr = BCAllocKernelMem (ulPages * sizeof (IMG_SYS_PHYADDR));
+ if (!pPhysAddr)
+ {
+ return BCE_ERROR_OUT_OF_MEMORY;
+ }
+ memset (pPhysAddr, 0, ulPages * sizeof (IMG_SYS_PHYADDR));
+ }
+ psDevInfo->psSystemBuffer[i].psSysAddr = pPhysAddr;
+ }
+ p->count = psDevInfo->ulNumBuffers;
+
+ psDevInfo->sBufferInfo.ui32BufferCount = psDevInfo->ulNumBuffers;
+ psDevInfo->sBufferInfo.pixelformat = pixel_fmt;
+ psDevInfo->sBufferInfo.ui32Width = p->width;
+ psDevInfo->sBufferInfo.ui32Height = p->height;
+ psDevInfo->sBufferInfo.ui32ByteStride = stride;
+ psDevInfo->sBufferInfo.ui32BufferDeviceID = id;
+ psDevInfo->sBufferInfo.ui32Flags = PVRSRV_BC_FLAGS_YUVCSC_FULL_RANGE |
+ PVRSRV_BC_FLAGS_YUVCSC_BT601;
+ return 0;
+}
+
+int
+BC_DestroyBuffers (int id)
+{
+ BC_VIDEO_DEVINFO *psDevInfo;
+ IMG_UINT32 i;
+ if ((psDevInfo = GetAnchorPtr (id)) == IMG_NULL)
+ return -ENODEV;
+
+ if (!psDevInfo->ulNumBuffers)
+ return 0;
+
+ for (i = 0; i < psDevInfo->ulNumBuffers; i++)
+ BCFreeKernelMem (psDevInfo->psSystemBuffer[i].psSysAddr);
+
+ BCFreeKernelMem (psDevInfo->psSystemBuffer);
+
+ 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 = psDevInfo->ulNumBuffers;
+
+ return 0;
+}
+
+int
+GetBufferCount (unsigned int *puiBufferCount, int id)
+{
+ BC_VIDEO_DEVINFO *psDevInfo = GetAnchorPtr (id);
+
+ if (psDevInfo == IMG_NULL)
+ {
+ return -1;
+ }
+
+ *puiBufferCount = (unsigned int) psDevInfo->sBufferInfo.ui32BufferCount;
+
+ return 0;
+}
+
+int
+BC_Video_Bridge (struct drm_device *dev, IMG_VOID * arg,
+ struct drm_file *file_priv)
+{
+ int err = -EFAULT;
+
+ BC_VIDEO_DEVINFO *devinfo;
+ int i;
+ BC_Video_ioctl_package *psBridge = (BC_Video_ioctl_package *) arg;
+ int command = psBridge->ioctl_cmd;
+ int id = 0;
+
+ if (command == BC_Video_ioctl_request_buffers)
+ {
+ for (i = 0; i < BC_VIDEO_DEVICE_MAX_ID; i++)
+ {
+ if (bc_video_id_usage[i] == 0)
+ {
+ bc_video_id_usage[i] = 1;
+ id = i;
+ break;
+ }
+ }
+ if (i == BC_VIDEO_DEVICE_MAX_ID)
+ {
+ printk (KERN_ERR DRVNAME
+ " : Does you really need to run more than 5 video simulateously.\n");
+ return -1;
+ }
+ }
+ else
+ id = psBridge->device_id;
+
+ if ((devinfo = GetAnchorPtr (id)) == IMG_NULL)
+ return -ENODEV;
+
+ switch (command)
+ {
+ case BC_Video_ioctl_get_buffer_count:
+ {
+ if (GetBufferCount (&psBridge->outputparam, id) == -1)
+ {
+ printk (KERN_ERR DRVNAME
+ " : GetBufferCount error in BC_Video_Bridge.\n");
+ return err;
+ }
+ return 0;
+ break;
+ }
+ case BC_Video_ioctl_get_buffer_index:
+ {
+ int idx;
+ BC_VIDEO_BUFFER *buffer;
+
+ for (idx = 0; idx < devinfo->ulNumBuffers; idx++)
+ {
+ buffer = &devinfo->psSystemBuffer[idx];
+
+ if (psBridge->inputparam == buffer->sBufferHandle)
+ {
+ psBridge->outputparam = idx;
+ return 0;
+ }
+ }
+ printk (KERN_ERR DRVNAME ": BCIOGET_BUFFERIDX- buffer not found\n");
+ return -EINVAL;
+ break;
+ }
+ case BC_Video_ioctl_request_buffers:
+ {
+ bc_buf_params_t p;
+ if (copy_from_user
+ (&p, (void __user *) (psBridge->inputparam), sizeof (p)))
+ {
+ printk (KERN_ERR " : failed to copy inputparam to kernel.\n");
+ return -EFAULT;
+ }
+ psBridge->outputparam = id;
+ return BC_CreateBuffers (id, &p, IMG_FALSE);
+ break;
+ }
+ case BC_Video_ioctl_set_buffer_phyaddr:
+ {
+ bc_buf_ptr_t p;
+ struct ttm_buffer_object *bo = NULL;
+ struct ttm_tt *ttm = NULL;
+ struct ttm_object_file *tfile = psb_fpriv (file_priv)->tfile;
+
+ if (copy_from_user
+ (&p, (void __user *) (psBridge->inputparam), sizeof (p)))
+ {
+ printk (KERN_ERR DRVNAME
+ " : failed to copy inputparam to kernel.\n");
+ return -EFAULT;
+ }
+
+ if (p.index >= devinfo->ulNumBuffers || !p.handle)
+ {
+ printk (KERN_ERR DRVNAME
+ " : index big than NumBuffers or p.handle is NULL.\n");
+ return -EINVAL;
+ }
+
+ bo = ttm_buffer_object_lookup (tfile, p.handle);
+ if (unlikely (bo == NULL))
+ {
+ printk (KERN_ERR DRVNAME
+ " : Could not find buffer object for setstatus.\n");
+ return -EINVAL;
+ }
+ ttm = bo->ttm;
+
+ devinfo->psSystemBuffer[p.index].sCPUVAddr = NULL;
+ devinfo->psSystemBuffer[p.index].sBufferHandle = p.handle;
+ for (i = 0; i < ttm->num_pages; i++)
+ {
+ if (ttm->pages[i] == NULL)
+ {
+ printk (KERN_ERR " : Debug: the page is NULL.\n");
+ return -EINVAL;
+ }
+ devinfo->psSystemBuffer[p.index].psSysAddr[i].uiAddr =
+ page_to_pfn (ttm->pages[i]) << PAGE_SHIFT;
+ }
+ if (bo)
+ ttm_bo_unref (&bo);
+ return 0;
+ break;
+ }
+ case BC_Video_ioctl_release_buffer_device:
+ {
+ bc_video_id_usage[id] = 0;
+
+ BC_DestroyBuffers (id);
+ return 0;
+ break;
+ }
+ case BC_Video_ioctl_alloc_buffer:
+ {
+ bc_buf_ptr_t p;
+ IMG_VOID *pvBuf;
+ IMG_UINT32 ui32Size;
+ IMG_UINT32 ulPagesNumber;
+ IMG_UINT32 ulCounter;
+ BUFFER_INFO *bufferInfo;
+
+ if (copy_from_user
+ (&p, (void __user *) (psBridge->inputparam), sizeof (p)))
+ {
+ printk (KERN_ERR DRVNAME
+ " : failed to copy inputparam to kernel.\n");
+ return -EFAULT;
+ }
+
+ if (p.index >= devinfo->ulNumBuffers)
+ {
+ printk (KERN_ERR DRVNAME " : index big than NumBuffers.\n");
+ return -EINVAL;
+ }
+
+ bufferInfo = &(devinfo->sBufferInfo);
+ if (bufferInfo->pixelformat != PVRSRV_PIXEL_FORMAT_NV12)
+ {
+ printk (KERN_ERR DRVNAME
+ " : BC_Video_ioctl_alloc_buffer only support NV12 format.\n");
+ return -EINVAL;
+ }
+ ui32Size = bufferInfo->ui32Height * bufferInfo->ui32ByteStride;
+ ui32Size +=
+ (bufferInfo->ui32ByteStride >> 1) *
+ (bufferInfo->ui32Height >> 1) << 1;
+
+ pvBuf =
+ __vmalloc (ui32Size, GFP_KERNEL | __GFP_HIGHMEM,
+ __pgprot ((pgprot_val (PAGE_KERNEL) & ~_PAGE_CACHE_MASK)
+ | _PAGE_CACHE_WC));
+ if (pvBuf == NULL)
+ {
+ printk (KERN_ERR DRVNAME
+ " : Failed to allocate %d bytes buffer.\n", ui32Size);
+ return -EINVAL;
+ }
+ devinfo->psSystemBuffer[p.index].sCPUVAddr = pvBuf;
+ devinfo->psSystemBuffer[p.index].sBufferHandle = 0;
+
+ ulPagesNumber = (ui32Size + PAGE_SIZE - 1) / PAGE_SIZE;
+ i = 0;
+
+ for (ulCounter = 0; ulCounter < ui32Size; ulCounter += PAGE_SIZE)
+ {
+ devinfo->psSystemBuffer[p.index].psSysAddr[i++].uiAddr =
+ vmalloc_to_pfn (pvBuf + ulCounter) << PAGE_SHIFT;
+ }
+
+ if (p.handle)
+ {
+ printk (KERN_ERR DRVNAME
+ " : fill data %d bytes from user space 0x%x.\n", ui32Size,
+ (int) p.handle);
+ if (copy_from_user (pvBuf, (void __user *) p.handle, ui32Size))
+ {
+ printk (KERN_ERR DRVNAME
+ " : failed to copy inputparam to kernel.\n");
+ return -EFAULT;
+ }
+
+ }
+ psBridge->outputparam = (int) pvBuf;
+
+ return 0;
+ break;
+ }
+ case BC_Video_ioctl_free_buffer:
+ {
+ bc_buf_ptr_t p;
+
+ if (copy_from_user
+ (&p, (void __user *) (psBridge->inputparam), sizeof (p)))
+ {
+ printk (KERN_ERR DRVNAME
+ " : failed to copy inputparam to kernel.\n");
+ return -EFAULT;
+ }
+
+ vfree (devinfo->psSystemBuffer[p.index].sCPUVAddr);
+ return 0;
+ break;
+ }
+ default:
+ return err;
+ }
+
+ return 0;
+}
+
+int
+BC_Camera_Bridge (BC_Video_ioctl_package * psBridge, unsigned long pAddr)
+{
+ int err = -EFAULT;
+
+ BC_VIDEO_DEVINFO *devinfo;
+ int id = BC_CAMERA_DEVICEID;
+ int command = psBridge->ioctl_cmd;
+
+ if ((devinfo = GetAnchorPtr (BC_CAMERA_DEVICEID)) == IMG_NULL)
+ return -ENODEV;
+
+ switch (command)
+ {
+ case BC_Video_ioctl_get_buffer_count:
+ {
+ if (GetBufferCount (&psBridge->outputparam, id) == -1)
+ {
+ printk (KERN_ERR DRVNAME
+ " : GetBufferCount error in BC_Video_Bridge.\n");
+ return err;
+ }
+ return 0;
+ break;
+ }
+ case BC_Video_ioctl_get_buffer_index:
+ {
+ int idx;
+ BC_VIDEO_BUFFER *buffer;
+
+ for (idx = 0; idx < devinfo->ulNumBuffers; idx++)
+ {
+ buffer = &devinfo->psSystemBuffer[idx];
+
+ if (psBridge->inputparam == buffer->sBufferHandle)
+ {
+ psBridge->outputparam = idx;
+ return 0;
+ }
+ }
+ printk (KERN_ERR DRVNAME ": BCIOGET_BUFFERIDX- buffer not found\n");
+ return -EINVAL;
+ break;
+ }
+ case BC_Video_ioctl_request_buffers:
+ {
+ bc_buf_params_t p;
+ memcpy (&p, (void *) (psBridge->inputparam), sizeof (p));
+ return BC_CreateBuffers (id, &p, IMG_TRUE);
+ break;
+ }
+ case BC_Video_ioctl_set_buffer_phyaddr:
+ {
+ bc_buf_ptr_t p;
+
+ memcpy (&p, (void *) (psBridge->inputparam), sizeof (p));
+ if (p.index >= devinfo->ulNumBuffers)
+ {
+ printk (KERN_ERR DRVNAME " : index big than NumBuffers\n");
+ return -EINVAL;
+ }
+
+ /* Get the physical address of each frame */
+ devinfo->psSystemBuffer[p.index].psSysAddr[0].uiAddr =
+ pAddr +
+ p.index * PAGE_ALIGN (devinfo->psSystemBuffer[p.index].ulSize);
+
+ return 0;
+ break;
+ }
+ default:
+ return err;
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/mrst/bc_video/bufferclass_video_linux.h b/drivers/staging/mrst/bc_video/bufferclass_video_linux.h
new file mode 100644
index 0000000..f350577
--- /dev/null
+++ b/drivers/staging/mrst/bc_video/bufferclass_video_linux.h
@@ -0,0 +1,67 @@
+/*****************************************************************************
+ *
+ * Copyright © 2010 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.
+ *
+ ******************************************************************************/
+
+#ifndef __BC_VIDEO_LINUX_H__
+#define __BC_VIDEO_LINUX_H__
+
+#include <linux/ioctl.h>
+
+#define BC_FOURCC(a,b,c,d) \
+ ((unsigned long) ((a) | (b)<<8 | (c)<<16 | (d)<<24))
+
+#define BC_PIX_FMT_NV12 BC_FOURCC('N', 'V', '1', '2') /*YUV 4:2:0 */
+#define BC_PIX_FMT_UYVY BC_FOURCC('U', 'Y', 'V', 'Y') /*YUV 4:2:2 */
+#define BC_PIX_FMT_YUYV BC_FOURCC('Y', 'U', 'Y', 'V') /*YUV 4:2:2 */
+#define BC_PIX_FMT_RGB565 BC_FOURCC('R', 'G', 'B', 'P') /*RGB 5:6:5 */
+
+typedef struct BC_Video_ioctl_package_TAG
+{
+ int ioctl_cmd;
+ int device_id;
+ int inputparam;
+ int outputparam;
+} BC_Video_ioctl_package;
+
+typedef struct bc_buf_ptr
+{
+ unsigned int index;
+ int size;
+ unsigned long pa;
+ unsigned long handle;
+} bc_buf_ptr_t;
+
+#define BC_Video_ioctl_fill_buffer 0
+#define BC_Video_ioctl_get_buffer_count 1
+#define BC_Video_ioctl_get_buffer_phyaddr 2 /*get physical address by index */
+#define BC_Video_ioctl_get_buffer_index 3 /*get index by physical address */
+#define BC_Video_ioctl_request_buffers 4
+#define BC_Video_ioctl_set_buffer_phyaddr 5
+#define BC_Video_ioctl_release_buffer_device 6
+
+#define BC_Video_ioctl_alloc_buffer 7
+#define BC_Video_ioctl_free_buffer 8
+
+int BC_DestroyBuffers (int id);
+#endif
diff --git a/drivers/staging/mrst/drv/psb_drv.c b/drivers/staging/mrst/drv/psb_drv.c
index c106aec..f76920f 100644
--- a/drivers/staging/mrst/drv/psb_drv.c
+++ b/drivers/staging/mrst/drv/psb_drv.c
@@ -62,6 +62,8 @@
#include "pvr_bridge.h"
#include "linkage.h"
+#include "bufferclass_video_linux.h"
+
int drm_psb_debug;
/*EXPORT_SYMBOL(drm_psb_debug); */
static int drm_psb_trap_pagefaults;
@@ -289,6 +291,9 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
/* PSB video extension */
#define DRM_LNC_VIDEO_GETPARAM (DRM_PSB_FLIP + 1)
+/*BC_VIDEO ioctl*/
+#define DRM_BUFFER_CLASS_VIDEO (DRM_LNC_VIDEO_GETPARAM + 1) /*0x32*/
+
#define DRM_IOCTL_PSB_TTM_PL_CREATE \
DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_CREATE,\
union ttm_pl_create_arg)
@@ -326,6 +331,11 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
DRM_IOWR(DRM_COMMAND_BASE + DRM_LNC_VIDEO_GETPARAM, \
struct drm_lnc_video_getparam_arg)
+/*bc_video ioctl*/
+#define DRM_IOCTL_BUFFER_CLASS_VIDEO \
+ DRM_IOWR(DRM_COMMAND_BASE + DRM_BUFFER_CLASS_VIDEO, \
+ BC_Video_ioctl_package)
+
static int psb_vt_leave_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
static int psb_vt_enter_ioctl(struct drm_device *dev, void *data,
@@ -452,6 +462,8 @@ static struct drm_ioctl_desc psb_ioctls[] = {
/*PSB_IOCTL_DEF(DRM_IOCTL_PSB_FLIP, psb_page_flip, DRM_AUTH),*/
PSB_IOCTL_DEF(DRM_IOCTL_LNC_VIDEO_GETPARAM,
lnc_video_getparam, DRM_AUTH),
+ PSB_IOCTL_DEF(DRM_IOCTL_BUFFER_CLASS_VIDEO,
+ BC_Video_Bridge, DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCRL_PSB_DPU_QUERY, psb_dpu_query_ioctl,
DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCRL_PSB_DPU_DSR_ON, psb_dpu_dsr_on_ioctl,
@@ -2844,10 +2856,17 @@ static int __init psb_init(void)
}
ret = drm_init(&driver);
- if (ret != 0)
- {
- return ret;
- }
+ if (ret != 0)
+ {
+ return ret;
+ }
+
+ /*init for bc_video*/
+ ret = BC_Video_ModInit();
+ if (ret != 0)
+ {
+ return ret;
+ }
#ifdef CONFIG_MDFD_HDMI
msic_regsiter_driver();
@@ -2858,6 +2877,13 @@ static int __init psb_init(void)
static void __exit psb_exit(void)
{
+ int ret;
+ /*cleanup for bc_video*/
+ ret = BC_Video_ModCleanup();
+ if (ret != 0)
+ {
+ return;
+ }
#ifdef CONFIG_MDFD_HDMI
msic_unregister_driver();
#endif
diff --git a/drivers/staging/mrst/medfield/Makefile b/drivers/staging/mrst/medfield/Makefile
index 99a4573..14ab4a5 100644
--- a/drivers/staging/mrst/medfield/Makefile
+++ b/drivers/staging/mrst/medfield/Makefile
@@ -16,6 +16,7 @@ include_dirs := \
-I$(INCDIR)/pvr/services4/srvkm/devices/sgx \
-I$(INCDIR)/ \
-I$(INCDIR)/drv \
+ -I$(INCDIR)/bc_video \
-I$(INCDIR)/imgv \
-Iinclude/linux \
-Iinclude/drm
@@ -73,7 +74,7 @@ ccflags-$(RES_MAN_EXTEND) += -DRES_MAN_EXTEND
ccflags-$(PVRSRV_OS_MEM_INFO) += -DPVRSRV_OS_MEM_INFO
ccflags-$(CONFIG_DRM_MID_RELEASE) += -DBUILD="\"release\"" -DPVR_BUILD_TYPE="\"release\"" -DRELEASE
-ccflags-$(CONFIG_DRM_MID_DEBUG) += -DBUILD="\"debug\"" -DPVR_BUILD_TYPE="\"debug\"" -DDEBUG
+ccflags-$(CONFIG_DRM_MID_DEBUG) += -DBUILD="\"debug\"" -DPVR_BUILD_TYPE="\"debug\"" -DDEBUG -DDEBUG_LINUX_MEM_AREAS -DDEBUG_LINUX_MEMORY_ALLOCATIONS -DDEBUG_LINUX_MMAP_AREAS -DDEBUG_BRIDGE_KM
ccflags-$(CONFIG_PCI_MSI) += -DCONFIG_PCI_MSI
@@ -85,6 +86,7 @@ FBDEVDIR = ../pvr/services4/3rdparty/linux_framebuffer_mrst
DRMDRVDIR = ../drv
SYSCONFIGDIR = ../pvr/services4/system/unified
IMGVDIR = ../imgv
+BUFFER_CLASS_DIR = ../bc_video
%.medfield.c: %.c
cp $< $@
@@ -199,5 +201,8 @@ medfield_gfx-$(CONFIG_MDFD_GL3) += $(DRMDRVDIR)/mdfld_gl3.medfield.o
medfield_gfx-y += $(DRMDRVDIR)/psb_powermgmt.medfield.o $(DRMDRVDIR)/psb_irq.medfield.o
+medfield_gfx-y += $(BUFFER_CLASS_DIR)/bufferclass_video.o \
+ $(BUFFER_CLASS_DIR)/bufferclass_video_linux.o
+
obj-$(CONFIG_DRM_MDFLD) += medfield_gfx.o
diff --git a/drivers/staging/mrst/moorestown/Makefile b/drivers/staging/mrst/moorestown/Makefile
index ca6ffaa..781fe42 100644
--- a/drivers/staging/mrst/moorestown/Makefile
+++ b/drivers/staging/mrst/moorestown/Makefile
@@ -16,6 +16,7 @@ include_dirs := \
-I$(INCDIR)/pvr/services4/srvkm/devices/sgx \
-I$(INCDIR)/ \
-I$(INCDIR)/drv \
+ -I$(INCDIR)/bc_video \
-I$(INCDIR)/imgv \
-Iinclude/linux \
-Iinclude/drm
@@ -85,6 +86,7 @@ FBDEVDIR = ../pvr/services4/3rdparty/linux_framebuffer_mrst
DRMDRVDIR = ../drv
SYSCONFIGDIR = ../pvr/services4/system/moorestown
IMGVDIR = ../imgv
+BUFFER_CLASS_DIR = ../bc_video
%.mrst.c: %.c
cp $< $@
@@ -198,5 +200,8 @@ mrst_gfx-$(CONFIG_MDFLD_DSI_DPU) += $(DRMDRVDIR)/mdfld_dsi_dbi_dpu.mrst.o
mrst_gfx-y += $(DRMDRVDIR)/psb_powermgmt.mrst.o $(DRMDRVDIR)/psb_irq.mrst.o
+mrst_gfx-y += $(BUFFER_CLASS_DIR)/bufferclass_video.o \
+ $(BUFFER_CLASS_DIR)/bufferclass_video_linux.o
+
obj-$(CONFIG_DRM_MRST) += mrst_gfx.o
diff --git a/drivers/staging/mrst/pvr/services4/system/moorestown/sys_pvr_drm_export.h b/drivers/staging/mrst/pvr/services4/system/moorestown/sys_pvr_drm_export.h
index 2b9bfdd..3a87972 100644
--- a/drivers/staging/mrst/pvr/services4/system/moorestown/sys_pvr_drm_export.h
+++ b/drivers/staging/mrst/pvr/services4/system/moorestown/sys_pvr_drm_export.h
@@ -87,6 +87,10 @@ int SYSPVRPreSuspend(struct drm_device *dev);
int SYSPVRPostSuspend(struct drm_device *dev);
int SYSPVRResume(struct drm_device *dev);
+int BC_Video_ModInit(void);
+int BC_Video_ModCleanup(void);
+int BC_Video_Bridge(struct drm_device *dev, IMG_VOID *arg, struct drm_file *file_priv);
+
#endif
#endif
diff --git a/drivers/staging/mrst/pvr/services4/system/moorestown/sysinfo.h b/drivers/staging/mrst/pvr/services4/system/moorestown/sysinfo.h
index 97d02dd..6e113c9 100644
--- a/drivers/staging/mrst/pvr/services4/system/moorestown/sysinfo.h
+++ b/drivers/staging/mrst/pvr/services4/system/moorestown/sysinfo.h
@@ -38,6 +38,6 @@ typedef enum _SYS_DEVICE_TYPE_
} SYS_DEVICE_TYPE;
-#define SYS_DEVICE_COUNT 4
+#define SYS_DEVICE_COUNT 10
#endif
diff --git a/drivers/staging/mrst/pvr/services4/system/unified/sys_pvr_drm_export.h b/drivers/staging/mrst/pvr/services4/system/unified/sys_pvr_drm_export.h
index 2b9bfdd..3a87972 100644
--- a/drivers/staging/mrst/pvr/services4/system/unified/sys_pvr_drm_export.h
+++ b/drivers/staging/mrst/pvr/services4/system/unified/sys_pvr_drm_export.h
@@ -87,6 +87,10 @@ int SYSPVRPreSuspend(struct drm_device *dev);
int SYSPVRPostSuspend(struct drm_device *dev);
int SYSPVRResume(struct drm_device *dev);
+int BC_Video_ModInit(void);
+int BC_Video_ModCleanup(void);
+int BC_Video_Bridge(struct drm_device *dev, IMG_VOID *arg, struct drm_file *file_priv);
+
#endif
#endif
diff --git a/drivers/staging/mrst/pvr/services4/system/unified/sysinfo.h b/drivers/staging/mrst/pvr/services4/system/unified/sysinfo.h
index 97d02dd..6e113c9 100644
--- a/drivers/staging/mrst/pvr/services4/system/unified/sysinfo.h
+++ b/drivers/staging/mrst/pvr/services4/system/unified/sysinfo.h
@@ -38,6 +38,6 @@ typedef enum _SYS_DEVICE_TYPE_
} SYS_DEVICE_TYPE;
-#define SYS_DEVICE_COUNT 4
+#define SYS_DEVICE_COUNT 10
#endif
--
1.7.1
More information about the MeeGo-kernel
mailing list