From: Randy Xu <[email protected]>

Add buffer clas video driver to support future Texture
streaming feature.

Signed-off-by: Randy Xu <[email protected]>
Signed-off-by: Hitesh K. Patel <[email protected]>
---
 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

_______________________________________________
MeeGo-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to