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
