summaryrefslogtreecommitdiffstats
path: root/pvr-source/services4/3rdparty/dc_nohw/dc_nohw_linux.c
diff options
context:
space:
mode:
Diffstat (limited to 'pvr-source/services4/3rdparty/dc_nohw/dc_nohw_linux.c')
-rw-r--r--pvr-source/services4/3rdparty/dc_nohw/dc_nohw_linux.c376
1 files changed, 376 insertions, 0 deletions
diff --git a/pvr-source/services4/3rdparty/dc_nohw/dc_nohw_linux.c b/pvr-source/services4/3rdparty/dc_nohw/dc_nohw_linux.c
new file mode 100644
index 0000000..2f603ea
--- /dev/null
+++ b/pvr-source/services4/3rdparty/dc_nohw/dc_nohw_linux.c
@@ -0,0 +1,376 @@
+/*************************************************************************/ /*!
+@Title Dummy 3rd party driver linux specific declarations.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+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 shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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.
+*/ /**************************************************************************/
+
+/**************************************************************************
+ The 3rd party driver is a specification of an API to integrate the
+ IMG PowerVR Services driver with 3rd Party display hardware.
+ It is NOT a specification for a display controller driver, rather a
+ specification to extend the API for a pre-existing driver for the display hardware.
+
+ The 3rd party driver interface provides IMG PowerVR client drivers (e.g. PVR2D)
+ with an API abstraction of the system's underlying display hardware, allowing
+ the client drivers to indirectly control the display hardware and access its
+ associated memory.
+
+ Functions of the API include
+
+ - query primary surface attributes (width, height, stride, pixel format,
+ CPU physical and virtual address)
+ - swap/flip chain creation and subsequent query of surface attributes
+ - asynchronous display surface flipping, taking account of asynchronous
+ read (flip) and write (render) operations to the display surface
+
+ Note: having queried surface attributes the client drivers are able to map
+ the display memory to any IMG PowerVR Services device by calling
+ PVRSRVMapDeviceClassMemory with the display surface handle.
+
+ This code is intended to be an example of how a pre-existing display driver
+ may be extended to support the 3rd Party Display interface to
+ PowerVR Services - IMG is not providing a display driver implementation
+ **************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+
+#if defined(SUPPORT_DRI_DRM)
+#include <drm/drmP.h>
+#endif
+
+#if defined(DC_NOHW_DISCONTIG_BUFFERS)
+#include <linux/vmalloc.h>
+#include <asm/page.h>
+#else
+#include <asm/dma-mapping.h>
+#endif
+
+#include "img_defs.h"
+#include "servicesext.h"
+#include "kerneldisplay.h"
+#include "dc_nohw.h"
+#include "pvrmodule.h"
+
+#if defined(SUPPORT_DRI_DRM)
+#include "pvr_drm.h"
+#endif
+
+#if defined(DC_USE_SET_MEMORY)
+ #undef DC_USE_SET_MEMORY
+#endif
+
+#if !defined(DC_NOHW_DISCONTIG_BUFFERS)
+ #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 DC_USE_SET_MEMORY
+ #endif
+#endif /* defined(DC_NOHW_DISCONTIG_BUFFERS) */
+
+#define DRVNAME "dcnohw"
+
+#if !defined(SUPPORT_DRI_DRM)
+MODULE_SUPPORTED_DEVICE(DRVNAME);
+#endif
+
+#define unref__ __attribute__ ((unused))
+
+#if defined(DC_NOHW_GET_BUFFER_DIMENSIONS)
+static unsigned long width = DC_NOHW_BUFFER_WIDTH;
+static unsigned long height = DC_NOHW_BUFFER_HEIGHT;
+static unsigned long depth = DC_NOHW_BUFFER_BIT_DEPTH;
+
+module_param(width, ulong, S_IRUGO);
+module_param(height, ulong, S_IRUGO);
+module_param(depth, ulong, S_IRUGO);
+
+IMG_BOOL GetBufferDimensions(IMG_UINT32 *pui32Width, IMG_UINT32 *pui32Height, PVRSRV_PIXEL_FORMAT *pePixelFormat, IMG_UINT32 *pui32Stride)
+{
+ if (width == 0 || height == 0 || depth == 0 ||
+ depth != dc_nohw_roundup_bit_depth(depth))
+ {
+ printk(KERN_WARNING DRVNAME ": Illegal module parameters (width %lu, height %lu, depth %lu)\n", width, height, depth);
+ return IMG_FALSE;
+ }
+
+ *pui32Width = (IMG_UINT32)width;
+ *pui32Height = (IMG_UINT32)height;
+
+ switch(depth)
+ {
+ case 32:
+ *pePixelFormat = PVRSRV_PIXEL_FORMAT_ARGB8888;
+ break;
+ case 16:
+ *pePixelFormat = PVRSRV_PIXEL_FORMAT_RGB565;
+ break;
+ default:
+ printk(KERN_WARNING DRVNAME ": Display depth %lu not supported\n", depth);
+ *pePixelFormat = PVRSRV_PIXEL_FORMAT_UNKNOWN;
+ return IMG_FALSE;
+ }
+
+ *pui32Stride = dc_nohw_byte_stride(width, depth);
+
+#if defined(DEBUG)
+ printk(KERN_INFO DRVNAME " Width: %lu\n", (unsigned long)*pui32Width);
+ printk(KERN_INFO DRVNAME " Height: %lu\n", (unsigned long)*pui32Height);
+ printk(KERN_INFO DRVNAME " Depth: %lu bits\n", depth);
+ printk(KERN_INFO DRVNAME " Stride: %lu bytes\n", (unsigned long)*pui32Stride);
+#endif /* defined(DEBUG) */
+
+ return IMG_TRUE;
+}
+#endif /* defined(DC_NOHW_GET_BUFFER_DIMENSIONS) */
+
+/*****************************************************************************
+ Function Name: DC_NOHW_Init
+ Description : Insert the driver into the kernel.
+
+ __init places the function in a special memory section that
+ the kernel frees once the function has been run. Refer also
+ to module_init() macro call below.
+
+*****************************************************************************/
+#if defined(SUPPORT_DRI_DRM)
+int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(struct drm_device unref__ *dev)
+#else
+static int __init DC_NOHW_Init(void)
+#endif
+{
+ if(Init() != DC_OK)
+ {
+ return -ENODEV;
+ }
+
+ return 0;
+} /*DC_NOHW_Init*/
+
+/*****************************************************************************
+ Function Name: DC_NOHW_Cleanup
+ Description : Remove the driver from the kernel.
+
+ __exit places the function in a special memory section that
+ the kernel frees once the function has been run. Refer also
+ to module_exit() macro call below.
+
+*****************************************************************************/
+#if defined(SUPPORT_DRI_DRM)
+void PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Cleanup)(struct drm_device unref__ *dev)
+#else
+static void __exit DC_NOHW_Cleanup(void)
+#endif
+{
+ if(Deinit() != DC_OK)
+ {
+ printk (KERN_INFO DRVNAME ": DC_NOHW_Cleanup: can't deinit device\n");
+ }
+} /*DC_NOHW_Cleanup*/
+
+
+void *AllocKernelMem(unsigned long ulSize)
+{
+ return kmalloc(ulSize, GFP_KERNEL);
+}
+
+void FreeKernelMem(void *pvMem)
+{
+ kfree(pvMem);
+}
+
+#if defined(DC_NOHW_DISCONTIG_BUFFERS)
+
+#define RANGE_TO_PAGES(range) (((range) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)
+#define VMALLOC_TO_PAGE_PHYS(vAddr) page_to_phys(vmalloc_to_page(vAddr))
+
+DC_ERROR AllocDiscontigMemory(unsigned long ulSize,
+ DC_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 DC_ERROR_OUT_OF_MEMORY;
+ }
+
+ pPhysAddr = kmalloc(ulPages * sizeof(IMG_SYS_PHYADDR), GFP_KERNEL);
+ if (!pPhysAddr)
+ {
+ vfree(LinAddr);
+ return DC_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 DC_OK;
+}
+
+void FreeDiscontigMemory(unsigned long ulSize,
+ DC_HANDLE unref__ hMemHandle,
+ IMG_CPU_VIRTADDR LinAddr,
+ IMG_SYS_PHYADDR *pPhysAddr)
+{
+ kfree(pPhysAddr);
+
+ vfree(LinAddr);
+}
+#else /* defined(DC_NOHW_DISCONTIG_BUFFERS) */
+DC_ERROR AllocContigMemory(unsigned long ulSize,
+ DC_HANDLE unref__ *phMemHandle,
+ IMG_CPU_VIRTADDR *pLinAddr,
+ IMG_CPU_PHYADDR *pPhysAddr)
+{
+#if defined(DC_USE_SET_MEMORY)
+ void *pvLinAddr;
+ unsigned long ulAlignedSize = PAGE_ALIGN(ulSize);
+ int iPages = (int)(ulAlignedSize >> PAGE_SHIFT);
+ int iError;
+
+ pvLinAddr = kmalloc(ulAlignedSize, GFP_KERNEL);
+ iError = set_memory_wc((unsigned long)pvLinAddr, iPages);
+ if (iError != 0)
+ {
+ printk(KERN_ERR DRVNAME ": AllocContigMemory: set_memory_wc failed (%d)\n", iError);
+
+ return DC_ERROR_OUT_OF_MEMORY;
+ }
+
+ pPhysAddr->uiAddr = virt_to_phys(pvLinAddr);
+ *pLinAddr = pvLinAddr;
+
+ return DC_OK;
+#else /* DC_USE_SET_MEMORY */
+ dma_addr_t dma;
+ IMG_VOID *pvLinAddr;
+
+ pvLinAddr = dma_alloc_coherent(NULL, ulSize, &dma, GFP_KERNEL);
+
+ if (pvLinAddr == NULL)
+ {
+ return DC_ERROR_OUT_OF_MEMORY;
+ }
+
+ pPhysAddr->uiAddr = dma;
+ *pLinAddr = pvLinAddr;
+
+ return DC_OK;
+#endif /* DC_USE_SET_MEMORY */
+}
+
+void FreeContigMemory(unsigned long ulSize,
+ DC_HANDLE unref__ hMemHandle,
+ IMG_CPU_VIRTADDR LinAddr,
+ IMG_CPU_PHYADDR PhysAddr)
+{
+#if defined(DC_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 ": FreeContigMemory: set_memory_wb failed (%d)\n", iError);
+ }
+ kfree(LinAddr);
+#else /* DC_USE_SET_MEMORY */
+ dma_free_coherent(NULL, ulSize, LinAddr, (dma_addr_t)PhysAddr.uiAddr);
+#endif /* DC_USE_SET_MEMORY */
+}
+#endif /* defined(DC_NOHW_DISCONTIG_BUFFERS) */
+
+DC_ERROR OpenPVRServices (DC_HANDLE *phPVRServices)
+{
+ /* Nothing to do - we have already checked services module insertion */
+ *phPVRServices = 0;
+ return DC_OK;
+}
+
+DC_ERROR ClosePVRServices (DC_HANDLE unref__ hPVRServices)
+{
+ /* Nothing to do */
+ return DC_OK;
+}
+
+DC_ERROR GetLibFuncAddr (DC_HANDLE unref__ hExtDrv, char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable)
+{
+ if(strcmp("PVRGetDisplayClassJTable", szFunctionName) != 0)
+ {
+ return DC_ERROR_INVALID_PARAMS;
+ }
+
+ /* Nothing to do - should be exported from pvrsrv.ko */
+ *ppfnFuncTable = PVRGetDisplayClassJTable;
+
+ return DC_OK;
+}
+
+#if !defined(SUPPORT_DRI_DRM)
+/*
+ These macro calls define the initialisation and removal functions of the
+ driver. Although they are prefixed `module_', they apply when compiling
+ statically as well; in both cases they define the function the kernel will
+ run to start/stop the driver.
+*/
+module_init(DC_NOHW_Init);
+module_exit(DC_NOHW_Cleanup);
+#endif