aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/pvr/display/omap_sgx_displayclass.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/pvr/display/omap_sgx_displayclass.c')
-rw-r--r--drivers/gpu/pvr/display/omap_sgx_displayclass.c1620
1 files changed, 0 insertions, 1620 deletions
diff --git a/drivers/gpu/pvr/display/omap_sgx_displayclass.c b/drivers/gpu/pvr/display/omap_sgx_displayclass.c
deleted file mode 100644
index 7ae2420..0000000
--- a/drivers/gpu/pvr/display/omap_sgx_displayclass.c
+++ /dev/null
@@ -1,1620 +0,0 @@
-/*************************************************************************
- *
- * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful but, except
- * as otherwise stated in writing, without any warranty; without even the
- * implied warranty of merchantability or fitness for a particular purpose.
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * The full GNU General Public License is included in this distribution in
- * the file called "COPYING".
- *
- * Contact Information:
- * Imagination Technologies Ltd. <gpl-support@imgtec.com>
- * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
- *
- *************************************************************************/
-
-#include <linux/slab.h>
-#include <linux/version.h>
-#include <linux/kernel.h>
-#include <linux/console.h>
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/notifier.h>
-
-#if defined(LDM_PLATFORM)
-#include <linux/platform_device.h>
-#if defined(SGX_EARLYSUSPEND)
-#include <linux/earlysuspend.h>
-#endif
-#endif
-
-#include "img_defs.h"
-#include "servicesext.h"
-#include "kerneldisplay.h"
-#include "omap_sgx_displayclass.h"
-#include "omap_display.h"
-
-/* XXX: Expect 2 framebuffers for virtual display */
-#if (CONFIG_FB_OMAP2_NUM_FBS < 2)
-#error "Virtual display is supported only with 2 or more framebuffers, \
-CONFIG_FB_OMAP2_NUM_FBS must be equal or greater than 2 \
-see CONFIG_FB_OMAP2_NUM_FBS for details in the kernel config"
-#endif
-
-#define OMAP_DC_CMD_COUNT 1
-#define MAX_BUFFERS_FLIPPING 4
-
-/* Pointer Display->Services */
-static PFN_DC_GET_PVRJTABLE pfnGetPVRJTable = NULL;
-
-/* Pointer to the display devices */
-static struct OMAP_DISP_DEVINFO *pDisplayDevices = NULL;
-static int display_devices_count = 0;
-
-static void display_sync_handler(struct work_struct *work);
-static enum OMAP_ERROR get_pvr_dc_jtable (char *szFunctionName,
- PFN_DC_GET_PVRJTABLE *ppfnFuncTable);
-
-
-/*
- * Swap to display buffer. This buffer refers to one inside the
- * framebuffer memory.
- * in: hDevice, hBuffer, ui32SwapInterval, hPrivateTag, ui32ClipRectCount,
- * psClipRect
- */
-static PVRSRV_ERROR SwapToDCBuffer(IMG_HANDLE hDevice,
- IMG_HANDLE hBuffer,
- IMG_UINT32 ui32SwapInterval,
- IMG_HANDLE hPrivateTag,
- IMG_UINT32 ui32ClipRectCount,
- IMG_RECT *psClipRect)
-{
- /* Nothing to do */
- return PVRSRV_OK;
-}
-
-/*
- * Set display destination rectangle.
- * in: hDevice, hSwapChain, psRect
- */
-static PVRSRV_ERROR SetDCDstRect(IMG_HANDLE hDevice,
- IMG_HANDLE hSwapChain,
- IMG_RECT *psRect)
-{
- /* Nothing to do */
- return PVRSRV_ERROR_NOT_SUPPORTED;
-}
-
-/*
- * Set display source rectangle.
- * in: hDevice, hSwapChain, psRect
- */
-static PVRSRV_ERROR SetDCSrcRect(IMG_HANDLE hDevice,
- IMG_HANDLE hSwapChain,
- IMG_RECT *psRect)
-{
- /* Nothing to do */
- return PVRSRV_ERROR_NOT_SUPPORTED;
-}
-
-/*
- * Set display destination colour key.
- * in: hDevice, hSwapChain, ui32CKColour
- */
-static PVRSRV_ERROR SetDCDstColourKey(IMG_HANDLE hDevice,
- IMG_HANDLE hSwapChain,
- IMG_UINT32 ui32CKColour)
-{
- /* Nothing to do */
- return PVRSRV_ERROR_NOT_SUPPORTED;
-}
-
-/*
- * Set display source colour key.
- * in: hDevice, hSwapChain, ui32CKColour
- */
-static PVRSRV_ERROR SetDCSrcColourKey(IMG_HANDLE hDevice,
- IMG_HANDLE hSwapChain,
- IMG_UINT32 ui32CKColour)
-{
- /* Nothing to do */
- return PVRSRV_ERROR_NOT_SUPPORTED;
-}
-
-/*
- * Closes the display.
- * in: hDevice
- */
-static PVRSRV_ERROR CloseDCDevice(IMG_HANDLE hDevice)
-{
- struct OMAP_DISP_DEVINFO *psDevInfo =
- (struct OMAP_DISP_DEVINFO*) hDevice;
- struct omap_display_device *display = psDevInfo->display;
-
- if(display->close(display))
- WARNING_PRINTK("Unable to close properly display '%s'",
- display->name);
-
- return PVRSRV_OK;
-}
-
-/*
- * Flushes the sync queue present in the specified swap chain.
- * in: psSwapChain
- */
-static void FlushInternalSyncQueue(struct OMAP_DISP_SWAPCHAIN *psSwapChain)
-{
- struct OMAP_DISP_DEVINFO *psDevInfo =
- (struct OMAP_DISP_DEVINFO*) psSwapChain->pvDevInfo;
- struct OMAP_DISP_FLIP_ITEM *psFlipItem;
- struct omap_display_device *display = psDevInfo->display;
- unsigned long ulMaxIndex;
- unsigned long i;
-
- psFlipItem = &psSwapChain->psFlipItems[psSwapChain->ulRemoveIndex];
- ulMaxIndex = psSwapChain->ulBufferCount - 1;
-
- DEBUG_PRINTK("Flushing sync queue on display %lu",
- psDevInfo->ulDeviceID);
- for(i = 0; i < psSwapChain->ulBufferCount; i++)
- {
- if (psFlipItem->bValid == OMAP_FALSE)
- continue;
-
- DEBUG_PRINTK("Flushing swap buffer index %lu",
- psSwapChain->ulRemoveIndex);
-
- /* Flip the buffer if it hasn't been flipped */
- if(psFlipItem->bFlipped == OMAP_FALSE)
- {
- display->present_buffer(psFlipItem->display_buffer);
- }
-
- /* If the command didn't complete, assume it did */
- if(psFlipItem->bCmdCompleted == OMAP_FALSE)
- {
- DEBUG_PRINTK("Calling command complete for swap "
- "buffer index %lu",
- psSwapChain->ulRemoveIndex);
- psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(
- (IMG_HANDLE)psFlipItem->hCmdComplete,
- IMG_TRUE);
- }
-
- psSwapChain->ulRemoveIndex++;
- if(psSwapChain->ulRemoveIndex > ulMaxIndex)
- psSwapChain->ulRemoveIndex = 0;
-
- /* Put the state of the buffer to be used again later */
- psFlipItem->bFlipped = OMAP_FALSE;
- psFlipItem->bCmdCompleted = OMAP_FALSE;
- psFlipItem->bValid = OMAP_FALSE;
- psFlipItem =
- &psSwapChain->psFlipItems[psSwapChain->ulRemoveIndex];
- }
-
- psSwapChain->ulInsertIndex = 0;
- psSwapChain->ulRemoveIndex = 0;
-}
-
-/*
- * Sets the flush state of the specified display device
- * at the swap chain level without blocking the call.
- * in: psDevInfo, bFlushState
- */
-static void SetFlushStateInternalNoLock(struct OMAP_DISP_DEVINFO* psDevInfo,
- enum OMAP_BOOL bFlushState)
-{
- struct OMAP_DISP_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain;
-
- /* Nothing to do if there is no swap chain */
- if (psSwapChain == NULL){
- DEBUG_PRINTK("Swap chain is null, nothing to do for"
- " display %lu", psDevInfo->ulDeviceID);
- return;
- }
-
- if (bFlushState)
- {
- DEBUG_PRINTK("Desired flushState is true for display %lu",
- psDevInfo->ulDeviceID);
- if (psSwapChain->ulSetFlushStateRefCount == 0)
- {
- psSwapChain->bFlushCommands = OMAP_TRUE;
- FlushInternalSyncQueue(psSwapChain);
- }
- psSwapChain->ulSetFlushStateRefCount++;
- }
- else
- {
- DEBUG_PRINTK("Desired flushState is false for display %lu",
- psDevInfo->ulDeviceID);
- if (psSwapChain->ulSetFlushStateRefCount != 0)
- {
- psSwapChain->ulSetFlushStateRefCount--;
- if (psSwapChain->ulSetFlushStateRefCount == 0)
- {
- psSwapChain->bFlushCommands = OMAP_FALSE;
- }
- }
- }
-}
-
-/*
- * Sets the flush state of the specified display device
- * at device level blocking the call if needed.
- * in: psDevInfo, bFlushState
- */
-static void SetFlushStateExternal(struct OMAP_DISP_DEVINFO* psDevInfo,
- enum OMAP_BOOL bFlushState)
-{
- DEBUG_PRINTK("Executing for display %lu",
- psDevInfo->ulDeviceID);
- mutex_lock(&psDevInfo->sSwapChainLockMutex);
- if (psDevInfo->bFlushCommands != bFlushState)
- {
- psDevInfo->bFlushCommands = bFlushState;
- SetFlushStateInternalNoLock(psDevInfo, bFlushState);
- }
- mutex_unlock(&psDevInfo->sSwapChainLockMutex);
-}
-
-/*
- * Opens the display.
- * in: ui32DeviceID, phDevice
- * out: psSystemBufferSyncData
- */
-static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 ui32DeviceID,
- IMG_HANDLE *phDevice,
- PVRSRV_SYNC_DATA* psSystemBufferSyncData)
-{
- struct OMAP_DISP_DEVINFO *psDevInfo;
- struct omap_display_device *display;
- int i;
-
- psDevInfo = 0;
- for(i = 0; i < display_devices_count; i++)
- {
- if(ui32DeviceID == (&pDisplayDevices[i])->ulDeviceID)
- {
- psDevInfo = &pDisplayDevices[i];
- break;
- }
- }
-
- if(!psDevInfo)
- {
- WARNING_PRINTK("Unable to identify display device with id %i",
- (int)ui32DeviceID);
- return OMAP_ERROR_INVALID_DEVICE;
- }
-
- psDevInfo->sSystemBuffer.psSyncData = psSystemBufferSyncData;
- display = psDevInfo->display;
-
- DEBUG_PRINTK("Opening display %lu '%s'",psDevInfo->ulDeviceID,
- display->name);
-
- /* TODO: Explain here why ORIENTATION_VERTICAL is used*/
- if(display->open(display, ORIENTATION_VERTICAL | ORIENTATION_INVERT))
- ERROR_PRINTK("Unable to open properly display '%s'",
- psDevInfo->display->name);
-
- display->present_buffer(display->main_buffer);
-
- /* TODO: Turn on display here? */
-
- *phDevice = (IMG_HANDLE)psDevInfo;
-
- return PVRSRV_OK;
-}
-
-/*
- * Gets the available formats for the display.
- * in: hDevice
- * out: pui32NumFormats, psFormat
- */
-static PVRSRV_ERROR EnumDCFormats(IMG_HANDLE hDevice,
- IMG_UINT32 *pui32NumFormats,
- DISPLAY_FORMAT *psFormat)
-{
- struct OMAP_DISP_DEVINFO *psDevInfo;
- if(!hDevice || !pui32NumFormats)
- {
- ERROR_PRINTK("Invalid parameters");
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
- *pui32NumFormats = 1;
-
- if(psFormat)
- psFormat[0] = psDevInfo->sDisplayFormat;
- else
- WARNING_PRINTK("Display format is null for"
- " display %lu", psDevInfo->ulDeviceID);
-
- return PVRSRV_OK;
-}
-
-/*
- * Gets the available dimensions for the display.
- * in: hDevice, psFormat
- * out: pui32NumDims, psDim
- */
-static PVRSRV_ERROR EnumDCDims(IMG_HANDLE hDevice,
- DISPLAY_FORMAT *psFormat,
- IMG_UINT32 *pui32NumDims,
- DISPLAY_DIMS *psDim)
-{
- struct OMAP_DISP_DEVINFO *psDevInfo;
- if(!hDevice || !psFormat || !pui32NumDims)
- {
- ERROR_PRINTK("Invalid parameters");
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
- *pui32NumDims = 1;
-
- if(psDim)
- psDim[0] = psDevInfo->sDisplayDim;
- else
- WARNING_PRINTK("Display dimensions are null for"
- " display %lu", psDevInfo->ulDeviceID);
-
- return PVRSRV_OK;
-}
-
-/*
- * Gets the display framebuffer physical address.
- * in: hDevice
- * out: phBuffer
- */
-static PVRSRV_ERROR GetDCSystemBuffer(IMG_HANDLE hDevice, IMG_HANDLE *phBuffer)
-{
- struct OMAP_DISP_DEVINFO *psDevInfo;
-
- if(!hDevice || !phBuffer)
- {
- ERROR_PRINTK("Invalid parameters");
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
- *phBuffer = (IMG_HANDLE)&psDevInfo->sSystemBuffer;
-
- return PVRSRV_OK;
-}
-
-/*
- * Gets the display general information.
- * in: hDevice
- * out: psDCInfo
- */
-static PVRSRV_ERROR GetDCInfo(IMG_HANDLE hDevice, DISPLAY_INFO *psDCInfo)
-{
- struct OMAP_DISP_DEVINFO *psDevInfo;
-
- if(!hDevice || !psDCInfo)
- {
- ERROR_PRINTK("Invalid parameters");
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
- *psDCInfo = psDevInfo->sDisplayInfo;
-
- return PVRSRV_OK;
-}
-
-/*
- * Gets the display framebuffer virtual address.
- * in: hDevice
- * out: ppsSysAddr, pui32ByteSize, ppvCpuVAddr, phOSMapInfo, pbIsContiguous
- */
-static PVRSRV_ERROR GetDCBufferAddr(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)
-{
- struct OMAP_DISP_DEVINFO *psDevInfo;
- struct OMAP_DISP_BUFFER *psSystemBuffer;
-
- if(!hDevice || !hBuffer || !ppsSysAddr || !pui32ByteSize )
- {
- ERROR_PRINTK("Invalid parameters");
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
- psSystemBuffer = (struct OMAP_DISP_BUFFER *)hBuffer;
- *ppsSysAddr = &psSystemBuffer->sSysAddr;
- *pui32ByteSize = (IMG_UINT32)psDevInfo->sSystemBuffer.ulBufferSize;
-
- if (ppvCpuVAddr)
- *ppvCpuVAddr = psSystemBuffer->sCPUVAddr;
-
- if (phOSMapInfo)
- *phOSMapInfo = (IMG_HANDLE)0;
-
- if (pbIsContiguous)
- *pbIsContiguous = IMG_TRUE;
-
- return PVRSRV_OK;
-}
-
-/*
- * Creates a swap chain. Called when a 3D application begins.
- * in: hDevice, ui32Flags, ui32BufferCount, psDstSurfAttrib, psSrcSurfAttrib
- * ui32OEMFlags
- * out: phSwapChain, ppsSyncData, pui32SwapChainID
- */
-static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice,
- IMG_UINT32 ui32Flags,
- DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
- DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
- IMG_UINT32 ui32BufferCount,
- PVRSRV_SYNC_DATA **ppsSyncData,
- IMG_UINT32 ui32OEMFlags,
- IMG_HANDLE *phSwapChain,
- IMG_UINT32 *pui32SwapChainID)
-{
- struct OMAP_DISP_DEVINFO *psDevInfo;
- struct OMAP_DISP_SWAPCHAIN *psSwapChain;
- struct OMAP_DISP_BUFFER *psBuffer;
- struct OMAP_DISP_FLIP_ITEM *psFlipItems;
- IMG_UINT32 i;
- PVRSRV_ERROR eError;
- IMG_UINT32 ui32BuffersToSkip;
- struct omap_display_device *display;
- int err;
-
- if(!hDevice || !psDstSurfAttrib || !psSrcSurfAttrib ||
- !ppsSyncData || !phSwapChain)
- {
- ERROR_PRINTK("Invalid parameters");
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
- psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
-
- if (psDevInfo->sDisplayInfo.ui32MaxSwapChains == 0)
- {
- ERROR_PRINTK("Unable to operate with 0 MaxSwapChains for"
- " display %lu", psDevInfo->ulDeviceID);
- return PVRSRV_ERROR_NOT_SUPPORTED;
- }
-
- if(psDevInfo->psSwapChain != NULL)
- {
- ERROR_PRINTK("Swap chain already exists for"
- " display %lu", psDevInfo->ulDeviceID);
- return PVRSRV_ERROR_FLIP_CHAIN_EXISTS;
- }
-
- if(ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers)
- {
- ERROR_PRINTK("Too many buffers. Trying to use %u buffers while"
- " there is only %u available for display %lu",
- (unsigned int)ui32BufferCount,
- (unsigned int)psDevInfo->
- sDisplayInfo.ui32MaxSwapChainBuffers,
- psDevInfo->ulDeviceID);
- return PVRSRV_ERROR_TOOMANYBUFFERS;
- }
-
- ui32BuffersToSkip = psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers -
- ui32BufferCount;
-
- if((psDstSurfAttrib->pixelformat !=
- psDevInfo->sDisplayFormat.pixelformat) ||
- (psDstSurfAttrib->sDims.ui32ByteStride !=
- psDevInfo->sDisplayDim.ui32ByteStride) ||
- (psDstSurfAttrib->sDims.ui32Width !=
- psDevInfo->sDisplayDim.ui32Width) ||
- (psDstSurfAttrib->sDims.ui32Height !=
- psDevInfo->sDisplayDim.ui32Height))
- {
- ERROR_PRINTK("Destination surface attributes differ from the"
- " current framebuffer for display %lu",
- psDevInfo->ulDeviceID);
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- if((psDstSurfAttrib->pixelformat !=
- psSrcSurfAttrib->pixelformat) ||
- (psDstSurfAttrib->sDims.ui32ByteStride !=
- psSrcSurfAttrib->sDims.ui32ByteStride) ||
- (psDstSurfAttrib->sDims.ui32Width !=
- psSrcSurfAttrib->sDims.ui32Width) ||
- (psDstSurfAttrib->sDims.ui32Height !=
- psSrcSurfAttrib->sDims.ui32Height))
- {
- ERROR_PRINTK("Destination surface attributes differ from the"
- " target destination surface for display %lu",
- psDevInfo->ulDeviceID);
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- /* Create the flip chain in display side */
- display = psDevInfo->display;
- /* TODO: What about TILER buffers? */
- /*
- * Creating the flip chain with the maximum number of buffers
- * we will decide which ones will be used later
- */
- err = display->create_flip_chain(
- display, psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers);
- if(err)
- {
- ERROR_PRINTK("Unable to create the flip chain for '%s' display"
- " id %lu", display->name, psDevInfo->ulDeviceID);
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- /* Allocate memory needed for the swap chain */
- psSwapChain = (struct OMAP_DISP_SWAPCHAIN*) kmalloc(
- sizeof(struct OMAP_DISP_SWAPCHAIN), GFP_KERNEL);
- if(!psSwapChain)
- {
- ERROR_PRINTK("Out of memory to allocate swap chain for"
- " display %lu", psDevInfo->ulDeviceID);
- return PVRSRV_ERROR_OUT_OF_MEMORY;
- }
-
- DEBUG_PRINTK("Creating swap chain for display %lu",
- psDevInfo->ulDeviceID );
-
- /* Allocate memory for the buffer abstraction structures */
- psBuffer = (struct OMAP_DISP_BUFFER*) kmalloc(
- sizeof(struct OMAP_DISP_BUFFER) * ui32BufferCount, GFP_KERNEL);
- if(!psBuffer)
- {
- ERROR_PRINTK("Out of memory to allocate the buffer"
- " abstraction structures for display %lu",
- psDevInfo->ulDeviceID);
- eError = PVRSRV_ERROR_OUT_OF_MEMORY;
- goto ErrorFreeSwapChain;
- }
-
- /* Allocate memory for the flip item abstraction structures */
- psFlipItems = (struct OMAP_DISP_FLIP_ITEM *) kmalloc (
- sizeof(struct OMAP_DISP_FLIP_ITEM) * ui32BufferCount,
- GFP_KERNEL);
- if (!psFlipItems)
- {
- ERROR_PRINTK("Out of memory to allocate the flip item"
- " abstraction structures for display %lu",
- psDevInfo->ulDeviceID);
- eError = PVRSRV_ERROR_OUT_OF_MEMORY;
- goto ErrorFreeBuffers;
- }
-
- /* Assign to the swap chain structure the initial data */
- psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount;
- psSwapChain->psBuffer = psBuffer;
- psSwapChain->psFlipItems = psFlipItems;
- psSwapChain->ulInsertIndex = 0;
- psSwapChain->ulRemoveIndex = 0;
- psSwapChain->psPVRJTable = &psDevInfo->sPVRJTable;
- psSwapChain->pvDevInfo = (void*)psDevInfo;
-
- /*
- * Init the workqueue (single thread, freezable and real time)
- * and its own work for this display
- */
- INIT_WORK(&psDevInfo->sync_display_work, display_sync_handler);
- psDevInfo->sync_display_wq =
- __create_workqueue("pvr_display_sync_wq", 1, 1, 1);
-
- DEBUG_PRINTK("Swap chain will have %u buffers for display %lu",
- (unsigned int)ui32BufferCount, psDevInfo->ulDeviceID);
- /* Link the buffers available like a circular list */
- for(i=0; i<ui32BufferCount-1; i++)
- {
- psBuffer[i].psNext = &psBuffer[i+1];
- }
- psBuffer[i].psNext = &psBuffer[0];
-
- /* Initialize each buffer abstraction structure */
- for(i=0; i<ui32BufferCount; i++)
- {
- /* Get the needed buffers from the display flip chain */
- IMG_UINT32 ui32SwapBuffer = i + ui32BuffersToSkip;
- struct omap_display_buffer * flip_buffer =
- display->flip_chain->buffers[ui32SwapBuffer];
- psBuffer[i].display_buffer = flip_buffer;
- psBuffer[i].psSyncData = ppsSyncData[i];
- psBuffer[i].sSysAddr.uiAddr = flip_buffer->physical_addr;
- psBuffer[i].sCPUVAddr =
- (IMG_CPU_VIRTADDR) flip_buffer->virtual_addr;
- DEBUG_PRINTK("Display %lu buffer index %u has physical "
- "address 0x%x",
- psDevInfo->ulDeviceID,
- (unsigned int)i,
- (unsigned int)psBuffer[i].sSysAddr.uiAddr);
- }
-
- /* Initialize each flip item abstraction structure */
- for(i=0; i<ui32BufferCount; i++)
- {
- psFlipItems[i].bValid = OMAP_FALSE;
- psFlipItems[i].bFlipped = OMAP_FALSE;
- psFlipItems[i].bCmdCompleted = OMAP_FALSE;
- psFlipItems[i].display_buffer = 0;
- }
-
- mutex_lock(&psDevInfo->sSwapChainLockMutex);
-
- psDevInfo->psSwapChain = psSwapChain;
- psSwapChain->bFlushCommands = psDevInfo->bFlushCommands;
- if (psSwapChain->bFlushCommands)
- psSwapChain->ulSetFlushStateRefCount = 1;
- else
- psSwapChain->ulSetFlushStateRefCount = 0;
-
- mutex_unlock(&psDevInfo->sSwapChainLockMutex);
-
- *phSwapChain = (IMG_HANDLE)psSwapChain;
-
- return PVRSRV_OK;
-
-ErrorFreeBuffers:
- kfree(psBuffer);
-ErrorFreeSwapChain:
- kfree(psSwapChain);
-
- return eError;
-}
-
-/*
- * Destroy a swap chain. Called when a 3D application ends.
- * in: hDevice, hSwapChain
- */
-static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice,
- IMG_HANDLE hSwapChain)
-{
- struct OMAP_DISP_DEVINFO *psDevInfo;
- struct OMAP_DISP_SWAPCHAIN *psSwapChain;
- struct omap_display_device *display;
- int err;
-
- if(!hDevice || !hSwapChain)
- {
- ERROR_PRINTK("Invalid parameters");
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
- psSwapChain = (struct OMAP_DISP_SWAPCHAIN*)hSwapChain;
- display = psDevInfo->display;
-
- if (psSwapChain != psDevInfo->psSwapChain)
- {
- ERROR_PRINTK("Swap chain handler differs from the one "
- "present in the display device pointer");
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- DEBUG_PRINTK("Destroying swap chain for display %lu",
- psDevInfo->ulDeviceID);
-
- mutex_lock(&psDevInfo->sSwapChainLockMutex);
-
- FlushInternalSyncQueue(psSwapChain);
- psDevInfo->psSwapChain = NULL;
-
- /*
- * Present the buffer which is at the base of address of
- * the framebuffer
- */
- display->present_buffer(display->main_buffer);
-
- /* Destroy the flip chain in display side */
- err = display->destroy_flip_chain(display);
- if(err)
- {
- ERROR_PRINTK("Unable to destroy the flip chain for '%s' "
- "display id %lu", display->name,
- psDevInfo->ulDeviceID);
- }
-
- mutex_unlock(&psDevInfo->sSwapChainLockMutex);
-
- /* Destroy the workqueue */
- flush_workqueue(psDevInfo->sync_display_wq);
- destroy_workqueue(psDevInfo->sync_display_wq);
-
- kfree(psSwapChain->psFlipItems);
- kfree(psSwapChain->psBuffer);
- kfree(psSwapChain);
-
- return PVRSRV_OK;
-}
-
-
-/*
- * Get display buffers. These are the buffers that can be allocated
- * inside the framebuffer memory.
- * in: hDevice, hSwapChain
- * out: pui32BufferCount, phBuffer
- */
-static PVRSRV_ERROR GetDCBuffers(IMG_HANDLE hDevice,
- IMG_HANDLE hSwapChain,
- IMG_UINT32 *pui32BufferCount,
- IMG_HANDLE *phBuffer)
-{
- struct OMAP_DISP_DEVINFO *psDevInfo;
- struct OMAP_DISP_SWAPCHAIN *psSwapChain;
- unsigned long i;
-
- if(!hDevice || !hSwapChain || !pui32BufferCount || !phBuffer)
- {
- ERROR_PRINTK("Invalid parameters");
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
- psSwapChain = (struct OMAP_DISP_SWAPCHAIN*)hSwapChain;
- if (psSwapChain != psDevInfo->psSwapChain)
- {
- ERROR_PRINTK("Swap chain handler differs from the one "
- "present in the display device %lu pointer",
- psDevInfo->ulDeviceID);
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
- *pui32BufferCount = (IMG_UINT32)psSwapChain->ulBufferCount;
-
- for(i=0; i<psSwapChain->ulBufferCount; i++)
- phBuffer[i] = (IMG_HANDLE)&psSwapChain->psBuffer[i];
-
- return PVRSRV_OK;
-}
-
-/*
- * Sets the display state.
- * in: ui32State, hDevice
- */
-static IMG_VOID SetDCState(IMG_HANDLE hDevice, IMG_UINT32 ui32State)
-{
- struct OMAP_DISP_DEVINFO *psDevInfo =
- (struct OMAP_DISP_DEVINFO*) hDevice;
-
- switch (ui32State)
- {
- case DC_STATE_FLUSH_COMMANDS:
- DEBUG_PRINTK("Setting state to flush commands for"
- " display %lu", psDevInfo->ulDeviceID);
- SetFlushStateExternal(psDevInfo, OMAP_TRUE);
- break;
- case DC_STATE_NO_FLUSH_COMMANDS:
- DEBUG_PRINTK("Setting state to not flush commands for"
- " display %lu", psDevInfo->ulDeviceID);
- SetFlushStateExternal(psDevInfo, OMAP_FALSE);
- break;
- default:
- WARNING_PRINTK("Unknown command state %u for display"
- " %lu", (unsigned int)ui32State,
- psDevInfo->ulDeviceID);
- break;
- }
-}
-
-/*
- * Swap to display system buffer. This buffer refers to the one which
- * is that fits in the framebuffer memory.
- * in: hDevice, hSwapChain
- */
-static PVRSRV_ERROR SwapToDCSystem(IMG_HANDLE hDevice,
- IMG_HANDLE hSwapChain)
-{
- struct OMAP_DISP_DEVINFO *psDevInfo;
- struct OMAP_DISP_SWAPCHAIN *psSwapChain;
- struct omap_display_device *display;
-
- if(!hDevice || !hSwapChain)
- {
- ERROR_PRINTK("Invalid parameters");
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
- psSwapChain = (struct OMAP_DISP_SWAPCHAIN*)hSwapChain;
- display = psDevInfo->display;
-
- DEBUG_PRINTK("Executing for display %lu",
- psDevInfo->ulDeviceID);
-
- if (psSwapChain != psDevInfo->psSwapChain)
- {
- ERROR_PRINTK("Swap chain handler differs from the one "
- "present in the display device %lu pointer",
- psDevInfo->ulDeviceID);
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- mutex_lock(&psDevInfo->sSwapChainLockMutex);
-
- FlushInternalSyncQueue(psSwapChain);
- display->present_buffer(display->main_buffer);
-
- mutex_unlock(&psDevInfo->sSwapChainLockMutex);
-
- return PVRSRV_OK;
-}
-
-/*
- * Handles the synchronization with the display
- * in: work
- */
-
-static void display_sync_handler(struct work_struct *work)
-{
- /*
- * TODO: Since present_buffer_sync waits and then present, this
- * algorithm can be simplified further
- */
- struct OMAP_DISP_DEVINFO *psDevInfo = container_of(work,
- struct OMAP_DISP_DEVINFO, sync_display_work);
- struct omap_display_device *display = psDevInfo->display;
- struct OMAP_DISP_FLIP_ITEM *psFlipItem;
- struct OMAP_DISP_SWAPCHAIN *psSwapChain;
- unsigned long ulMaxIndex;
-
- mutex_lock(&psDevInfo->sSwapChainLockMutex);
-
- psSwapChain = psDevInfo->psSwapChain;
- if (!psSwapChain || psSwapChain->bFlushCommands)
- goto ExitUnlock;
-
- psFlipItem = &psSwapChain->psFlipItems[psSwapChain->ulRemoveIndex];
- ulMaxIndex = psSwapChain->ulBufferCount - 1;
-
- /* Iterate through the flip items and flip them if necessary */
- while (psFlipItem->bValid) {
- /* Update display */
- display->present_buffer_sync(psFlipItem->display_buffer);
-
- psFlipItem->ulSwapInterval--;
- psFlipItem->bFlipped = OMAP_TRUE;
-
- if (psFlipItem->ulSwapInterval == 0) {
-
- /* Mark the flip item as completed to reuse it */
- psSwapChain->ulRemoveIndex++;
- if (psSwapChain->ulRemoveIndex > ulMaxIndex)
- psSwapChain->ulRemoveIndex = 0;
- psFlipItem->bCmdCompleted = OMAP_FALSE;
- psFlipItem->bFlipped = OMAP_FALSE;
- psFlipItem->bValid = OMAP_FALSE;
-
- psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(
- (IMG_HANDLE)psFlipItem->hCmdComplete,
- IMG_TRUE);
- psFlipItem->bCmdCompleted = OMAP_TRUE;
- } else {
- /*
- * Here the swap interval is not zero yet
- * we need to schedule another work until
- * it reaches zero
- */
- queue_work(psDevInfo->sync_display_wq,
- &psDevInfo->sync_display_work);
- break;
- }
-
- psFlipItem =
- &psSwapChain->psFlipItems[psSwapChain->ulRemoveIndex];
- }
-
-ExitUnlock:
- mutex_unlock(&psDevInfo->sSwapChainLockMutex);
-}
-
-/*
- * Performs a flip. This function takes the necessary steps to present
- * the buffer to be flipped in the display.
- * in: hCmdCookie, ui32DataSize, pvData
- */
-static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie,
- IMG_UINT32 ui32DataSize,
- IMG_VOID *pvData)
-{
- DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
- struct OMAP_DISP_DEVINFO *psDevInfo;
- struct OMAP_DISP_BUFFER *psBuffer;
- struct OMAP_DISP_SWAPCHAIN *psSwapChain;
- struct omap_display_device *display;
-#if defined(SYS_USING_INTERRUPTS)
- struct OMAP_DISP_FLIP_ITEM* psFlipItem;
-#endif
-
- if(!hCmdCookie || !pvData)
- {
- WARNING_PRINTK("Ignoring call with NULL parameters");
- return IMG_FALSE;
- }
-
- psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData;
-
- if (psFlipCmd == IMG_NULL ||
- sizeof(DISPLAYCLASS_FLIP_COMMAND) != ui32DataSize)
- {
- WARNING_PRINTK("NULL command or command data size is wrong");
- return IMG_FALSE;
- }
-
- psDevInfo = (struct OMAP_DISP_DEVINFO*)psFlipCmd->hExtDevice;
- psBuffer = (struct OMAP_DISP_BUFFER*)psFlipCmd->hExtBuffer;
- psSwapChain = (struct OMAP_DISP_SWAPCHAIN*) psFlipCmd->hExtSwapChain;
- display = psDevInfo->display;
-
- mutex_lock(&psDevInfo->sSwapChainLockMutex);
-
- if (psDevInfo->bDeviceSuspended)
- {
- /* If is suspended then assume the commands are completed */
- psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(
- hCmdCookie, IMG_TRUE);
- goto ExitTrueUnlock;
- }
-
-#if defined(SYS_USING_INTERRUPTS)
-
- if( psFlipCmd->ui32SwapInterval == 0 ||
- psSwapChain->bFlushCommands == OMAP_TRUE)
- {
-#endif
- display->present_buffer(psBuffer->display_buffer);
- psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(
- hCmdCookie, IMG_TRUE);
-
-#if defined(SYS_USING_INTERRUPTS)
- goto ExitTrueUnlock;
- }
-
- psFlipItem = &psSwapChain->psFlipItems[psSwapChain->ulInsertIndex];
-
- if(psFlipItem->bValid == OMAP_FALSE)
- {
- unsigned long ulMaxIndex = psSwapChain->ulBufferCount - 1;
-
- psFlipItem->bFlipped = OMAP_FALSE;
-
- /*
- * The buffer is queued here, must be consumed by the workqueue
- */
- psFlipItem->hCmdComplete = (OMAP_HANDLE)hCmdCookie;
- psFlipItem->ulSwapInterval =
- (unsigned long)psFlipCmd->ui32SwapInterval;
- psFlipItem->sSysAddr = &psBuffer->sSysAddr;
- psFlipItem->bValid = OMAP_TRUE;
- psFlipItem->display_buffer = psBuffer->display_buffer;
-
- psSwapChain->ulInsertIndex++;
- if(psSwapChain->ulInsertIndex > ulMaxIndex)
- psSwapChain->ulInsertIndex = 0;
-
- /* Give work to the workqueue to sync with the display */
- queue_work(psDevInfo->sync_display_wq,
- &psDevInfo->sync_display_work);
-
- goto ExitTrueUnlock;
- }
-
- mutex_unlock(&psDevInfo->sSwapChainLockMutex);
- return IMG_FALSE;
-#endif
-
-ExitTrueUnlock:
- mutex_unlock(&psDevInfo->sSwapChainLockMutex);
- return IMG_TRUE;
-}
-
-#if defined(LDM_PLATFORM)
-
-/*
- * Function called when the driver must suspend
- */
-static void DriverSuspend(void)
-{
- struct OMAP_DISP_DEVINFO *psDevInfo;
- int i;
-
- if(!pDisplayDevices)
- return;
-
- for(i = 0; i < display_devices_count; i++)
- {
- psDevInfo = &pDisplayDevices[i];
-
- mutex_lock(&psDevInfo->sSwapChainLockMutex);
-
- if (psDevInfo->bDeviceSuspended)
- {
- mutex_unlock(&psDevInfo->sSwapChainLockMutex);
- continue;
- }
-
- psDevInfo->bDeviceSuspended = OMAP_TRUE;
- SetFlushStateInternalNoLock(psDevInfo, OMAP_TRUE);
-
- mutex_unlock(&psDevInfo->sSwapChainLockMutex);
- }
-}
-
-/*
- * Function called when the driver must resume
- */
-static void DriverResume(void)
-{
- struct OMAP_DISP_DEVINFO *psDevInfo;
- int i;
-
- if(!pDisplayDevices)
- return;
-
- for(i = 0; i < display_devices_count; i++)
- {
- psDevInfo = &pDisplayDevices[i];
-
- mutex_lock(&psDevInfo->sSwapChainLockMutex);
-
- if (!psDevInfo->bDeviceSuspended)
- {
- mutex_unlock(&psDevInfo->sSwapChainLockMutex);
- continue;
- }
-
- SetFlushStateInternalNoLock(psDevInfo, OMAP_FALSE);
- psDevInfo->bDeviceSuspended = OMAP_FALSE;
-
- mutex_unlock(&psDevInfo->sSwapChainLockMutex);
- }
-}
-#endif /* defined(LDM_PLATFORM) */
-
-/*
- * Frees the kernel framebuffer
- * in: psDevInfo
- */
-static void deinit_display_device(struct OMAP_DISP_DEVINFO *psDevInfo)
-{
- /* TODO: Are we sure there is nothing to do here? */
-}
-
-/*
- * Deinitialization routine for the 3rd party display driver
- */
-static enum OMAP_ERROR destroy_display_devices(void)
-{
- struct OMAP_DISP_DEVINFO *psDevInfo;
- PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable;
- int i;
-
- DEBUG_PRINTK("Deinitializing 3rd party display driver");
-
- if(!pDisplayDevices)
- return OMAP_OK;
-
- for(i = 0; i < display_devices_count; i++)
- {
- psDevInfo = &pDisplayDevices[i];
- if(!psDevInfo->display)
- continue;
-
- /* Remove the ProcessFlip command callback */
- psJTable = &psDevInfo->sPVRJTable;
-
- if(!psJTable)
- continue;
-
- if (psDevInfo->sPVRJTable.pfnPVRSRVRemoveCmdProcList(
- psDevInfo->ulDeviceID,
- OMAP_DC_CMD_COUNT) != PVRSRV_OK)
- {
- ERROR_PRINTK("Unable to remove callback for "
- "ProcessFlip command for display %lu",
- psDevInfo->ulDeviceID);
- return OMAP_ERROR_GENERIC;
- }
-
- /* Remove the display device from services */
- if (psJTable->pfnPVRSRVRemoveDCDevice(
- psDevInfo->ulDeviceID) != PVRSRV_OK)
- {
- ERROR_PRINTK("Unable to remove the display %lu "
- "from services", psDevInfo->ulDeviceID);
- return OMAP_ERROR_GENERIC;
- }
-
- deinit_display_device(psDevInfo);
- }
-
- kfree(pDisplayDevices);
-
- return OMAP_OK;
-}
-
-/*
- * Extracts the framebuffer data from the kernel driver
- * in: psDevInfo
- */
-static enum OMAP_ERROR init_display_device(struct OMAP_DISP_DEVINFO *psDevInfo,
- struct omap_display_device *display)
-{
- int buffers_available = display->buffers_available;
-
- /* Extract the needed data from the display struct */
- DEBUG_PRINTK("Display '%s' id %i information:", display->name,
- display->id);
- DEBUG_PRINTK("*Width, height: %u,%u", display->width,
- display->height);
- DEBUG_PRINTK("*Rotation: %u", display->rotation);
- DEBUG_PRINTK("*Stride: %u bytes", display->byte_stride);
- DEBUG_PRINTK("*Buffers available: %u", buffers_available);
- DEBUG_PRINTK("*Bytes per pixel: %u (%u bpp)",
- display->bytes_per_pixel, display->bits_per_pixel);
-
- if(display->bits_per_pixel == 16)
- {
- if(display->pixel_format == RGB_565)
- {
- DEBUG_PRINTK("*Format: RGB565");
- psDevInfo->sDisplayFormat.pixelformat =
- PVRSRV_PIXEL_FORMAT_RGB565;
- }
- else
- WARNING_PRINTK("*Format: Unknown framebuffer"
- "format");
- }
- else if(display->bits_per_pixel == 24 ||
- display->bits_per_pixel == 32)
- {
- if(display->pixel_format == ARGB_8888)
- {
- DEBUG_PRINTK("*Format: ARGB8888");
- psDevInfo->sDisplayFormat.pixelformat =
- PVRSRV_PIXEL_FORMAT_ARGB8888;
-
- }
- else
- WARNING_PRINTK("*Format: Unknown framebuffer"
- "format");
- }
- else
- WARNING_PRINTK("*Format: Unknown framebuffer format");
-
- if(display->main_buffer)
- {
- DEBUG_PRINTK("*Bytes per buffer: %lu",
- display->main_buffer->size);
- DEBUG_PRINTK("*Main buffer physical address: 0x%lx",
- display->main_buffer->physical_addr);
- DEBUG_PRINTK("*Main buffer virtual address: 0x%lx",
- display->main_buffer->virtual_addr);
- DEBUG_PRINTK("*Main buffer size: %lu bytes",
- display->main_buffer->size);
- }
- else
- {
- psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = 0;
- ERROR_PRINTK("*No main buffer found for display '%s'",
- display->name);
- return OMAP_ERROR_INIT_FAILURE;
- }
-
- psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = buffers_available;
- mutex_init(&psDevInfo->sSwapChainLockMutex);
- psDevInfo->psSwapChain = 0;
- psDevInfo->bFlushCommands = OMAP_FALSE;
- psDevInfo->bDeviceSuspended = OMAP_FALSE;
-
- if(psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers > 1)
- {
- if(MAX_BUFFERS_FLIPPING == 1)
- {
- DEBUG_PRINTK("Flipping support is possible"
- " but you decided not to use it");
- }
-
- DEBUG_PRINTK("*Flipping support");
- if(psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers >
- MAX_BUFFERS_FLIPPING)
- psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers =
- MAX_BUFFERS_FLIPPING;
- }
- else
- {
- DEBUG_PRINTK("*Flipping not supported");
- }
-
- if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers == 0)
- {
- psDevInfo->sDisplayInfo.ui32MaxSwapChains = 0;
- psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 0;
- }
- else
- {
- psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1;
- psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 3;
- }
- psDevInfo->sDisplayInfo.ui32MinSwapInterval = 0;
-
- /* Get the display and framebuffer needed info */
- strncpy(psDevInfo->sDisplayInfo.szDisplayName,
- DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE);
-
- psDevInfo->sDisplayDim.ui32Width = display->width;
- psDevInfo->sDisplayDim.ui32Height = display->height;
- psDevInfo->sDisplayDim.ui32ByteStride = display->byte_stride;
- psDevInfo->sSystemBuffer.sSysAddr.uiAddr =
- display->main_buffer->physical_addr;
- psDevInfo->sSystemBuffer.sCPUVAddr =
- (IMG_CPU_VIRTADDR) display->main_buffer->virtual_addr;
- psDevInfo->sSystemBuffer.ulBufferSize = display->main_buffer->size;
- psDevInfo->sSystemBuffer.display_buffer = display->main_buffer;
- psDevInfo->display = display;
-
- return OMAP_OK;
-}
-
-/*
- * Initialization routine for the 3rd party display driver
- */
-static enum OMAP_ERROR create_display_devices(void)
-{
- PFN_CMD_PROC pfnCmdProcList[OMAP_DC_CMD_COUNT];
- IMG_UINT32 aui32SyncCountList[OMAP_DC_CMD_COUNT][2];
- int i;
- unsigned int bytes_to_alloc;
-
- DEBUG_PRINTK("Initializing 3rd party display driver");
-
- /* Init display abstraction layer */
- omap_display_initialize();
-
- /* Ask for the number of displays available */
- /* TODO: allow more displays */
- display_devices_count = 1; // omap_display_count();
-
- DEBUG_PRINTK("Found %i displays", display_devices_count);
-
- /*
- * Obtain the function pointer for the jump table from kernel
- * services to fill it with the function pointers that we want
- */
- if(get_pvr_dc_jtable ("PVRGetDisplayClassJTable",
- &pfnGetPVRJTable) != OMAP_OK)
- {
- ERROR_PRINTK("Unable to get the function to get the"
- " jump table display->services");
- return OMAP_ERROR_INIT_FAILURE;
- }
-
- /*
- * Allocate the display device structures, one per display available
- */
- bytes_to_alloc =
- sizeof(struct OMAP_DISP_DEVINFO) * display_devices_count;
- pDisplayDevices = (struct OMAP_DISP_DEVINFO *) kmalloc(
- bytes_to_alloc, GFP_KERNEL);
- if(!pDisplayDevices)
- {
- pDisplayDevices = NULL;
- ERROR_PRINTK("Out of memory");
- return OMAP_ERROR_OUT_OF_MEMORY;
- }
- memset(pDisplayDevices, 0, bytes_to_alloc);
-
- /*
- * Initialize each display device
- */
- for(i = 0; i < display_devices_count; i++)
- {
- struct omap_display_device *display;
- struct OMAP_DISP_DEVINFO * psDevInfo;
- enum omap_display_id id;
-
- psDevInfo = &pDisplayDevices[i];
- psDevInfo->display = 0;
-
- id = OMAP_DISPID_VIRTUAL;
-
- /*
- * TODO: Modify this to allow primary, secondary,
- * not only virtual
- */
-#if 0
- switch(i)
- {
- case 0:
- id = OMAP_DISPID_PRIMARY;
- break;
- case 1:
- id = OMAP_DISPID_SECONDARY;
- break;
- case 2:
- id = OMAP_DISPID_TERTIARY;
- break;
- case 3:
- id = OMAP_DISPID_VIRTUAL;
- break;
- default:
- ERROR_PRINTK("Invalid display type %i", i);
- BUG();
- }
-
-#endif
-
- display = omap_display_get(id);
- if(!display)
- continue;
-
- if(init_display_device(psDevInfo, display) != OMAP_OK)
- {
- ERROR_PRINTK("Unable to initialize display '%s' type"
- " %u", display->name, display->id);
- continue;
-#if 0
- kfree(pDisplayDevices);
- pDisplayDevices = NULL;
- return OMAP_ERROR_INIT_FAILURE;
-#endif
- }
-
- /*
- * Populate each display device structure
- */
- if(!(*pfnGetPVRJTable)(&psDevInfo->sPVRJTable))
- {
- ERROR_PRINTK("Unable to get the jump table"
- " display->services for display '%s'",
- display->name);
- return OMAP_ERROR_INIT_FAILURE;
- }
-
- /* Populate the function table that services will use */
- psDevInfo->sDCJTable.ui32TableSize =
- sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE);
- psDevInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice;
- psDevInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice;
- psDevInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats;
- psDevInfo->sDCJTable.pfnEnumDCDims = EnumDCDims;
- psDevInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer;
- psDevInfo->sDCJTable.pfnGetDCInfo = GetDCInfo;
- psDevInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr;
- psDevInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain;
- psDevInfo->sDCJTable.pfnDestroyDCSwapChain =
- DestroyDCSwapChain;
- psDevInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect;
- psDevInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect;
- psDevInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey;
- psDevInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey;
- psDevInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers;
- psDevInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer;
- psDevInfo->sDCJTable.pfnSwapToDCSystem = SwapToDCSystem;
- psDevInfo->sDCJTable.pfnSetDCState = SetDCState;
-
- /* Register the display device */
- if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice(
- &psDevInfo->sDCJTable,
- (IMG_UINT32*) &psDevInfo->ulDeviceID) != PVRSRV_OK)
- {
- ERROR_PRINTK("Unable to register the jump table"
- " services->display");
- return OMAP_ERROR_DEVICE_REGISTER_FAILED;
- }
-
- DEBUG_PRINTK("Display '%s' registered with the GPU with"
- " id %lu", display->name, psDevInfo->ulDeviceID);
-
- /*
- * Register the ProcessFlip function to notify when a frame is
- * ready to be flipped
- */
- pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip;
- aui32SyncCountList[DC_FLIP_COMMAND][0] = 0;
- aui32SyncCountList[DC_FLIP_COMMAND][1] = 2;
- if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList(
- psDevInfo->ulDeviceID, &pfnCmdProcList[0],
- aui32SyncCountList, OMAP_DC_CMD_COUNT) != PVRSRV_OK)
- {
- ERROR_PRINTK("Unable to register callback for "
- "ProcessFlip command");
- return OMAP_ERROR_CANT_REGISTER_CALLBACK;
- }
-
- }
- return OMAP_OK;
-}
-
-/*
- * Here we get the function pointer to get jump table from
- * services using an external function.
- * in: szFunctionName
- * out: ppfnFuncTable
- */
-static enum OMAP_ERROR get_pvr_dc_jtable (char *szFunctionName,
- PFN_DC_GET_PVRJTABLE *ppfnFuncTable)
-{
- if(strcmp("PVRGetDisplayClassJTable", szFunctionName) != 0)
- {
- ERROR_PRINTK("Unable to get function pointer for %s"
- " from services", szFunctionName);
- return OMAP_ERROR_INVALID_PARAMS;
- }
- *ppfnFuncTable = PVRGetDisplayClassJTable;
-
- return OMAP_OK;
-}
-
-#if defined(LDM_PLATFORM)
-
-static volatile enum OMAP_BOOL bDeviceSuspended;
-
-/*
- * Common suspend driver function
- * in: psSwapChain, aPhyAddr
- */
-static void CommonSuspend(void)
-{
- if (bDeviceSuspended)
- {
- DEBUG_PRINTK("Driver is already suspended");
- return;
- }
-
- DriverSuspend();
- bDeviceSuspended = OMAP_TRUE;
-}
-
-#if defined(SGX_EARLYSUSPEND)
-
-static struct early_suspend driver_early_suspend;
-
-/*
- * Android specific, driver is requested to be suspended
- * in: ea_event
- */
-static void DriverSuspend_Entry(struct early_suspend *ea_event)
-{
- DEBUG_PRINTK("Requested driver suspend");
- CommonSuspend();
-}
-
-/*
- * Android specific, driver is requested to be suspended
- * in: ea_event
- */
-static void DriverResume_Entry(struct early_suspend *ea_event)
-{
- DEBUG_PRINTK("Requested driver resume");
- DriverResume();
- bDeviceSuspended = OMAP_FALSE;
-}
-
-static struct platform_driver omap_sgx_dc_driver = {
- .driver = {
- .name = DRVNAME,
- }
-};
-
-#else /* defined(SGX_EARLYSUSPEND) */
-
-/*
- * Function called when the driver is requested to be suspended
- * in: pDevice, state
- */
-static int DriverSuspend_Entry(struct platform_device unref__ *pDevice,
- pm_message_t unref__ state)
-{
- DEBUG_PRINTK("Requested driver suspend");
- CommonSuspend();
- return 0;
-}
-
-/*
- * Function called when the driver is requested to resume
- * in: pDevice
- */
-static int DriverResume_Entry(struct platform_device unref__ *pDevice)
-{
- DEBUG_PRINTK("Requested driver resume");
- DriverResume();
- bDeviceSuspended = OMAP_FALSE;
- return 0;
-}
-
-/*
- * Function called when the driver is requested to shutdown
- * in: pDevice
- */
-static IMG_VOID DriverShutdown_Entry(
- struct platform_device unref__ *pDevice)
-{
- DEBUG_PRINTK("Requested driver shutdown");
- CommonSuspend();
-}
-
-static struct platform_driver omap_sgx_dc_driver = {
- .driver = {
- .name = DRVNAME,
- },
- .suspend = DriverSuspend_Entry,
- .resume = DriverResume_Entry,
- .shutdown = DriverShutdown_Entry,
-};
-
-#endif /* defined(SGX_EARLYSUSPEND) */
-
-#endif /* defined(LDM_PLATFORM) */
-
-/*
- * Driver init function
- */
-static int __init omap_sgx_dc_init(void)
-{
- if(create_display_devices() != OMAP_OK)
- {
- WARNING_PRINTK("Driver init failed");
- return -ENODEV;
- }
-
-#if defined(LDM_PLATFORM)
- DEBUG_PRINTK("Registering platform driver");
- if (platform_driver_register(&omap_sgx_dc_driver))
- {
- WARNING_PRINTK("Unable to register platform driver");
- if(destroy_display_devices() != OMAP_OK)
- WARNING_PRINTK("Driver cleanup failed\n");
- return -ENODEV;
- }
-
-#if defined(SGX_EARLYSUSPEND)
- driver_early_suspend.suspend = DriverSuspend_Entry;
- driver_early_suspend.resume = DriverResume_Entry;
- driver_early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
- register_early_suspend(&driver_early_suspend);
- DEBUG_PRINTK("Registered early suspend support");
-#endif
-
-#endif
- return 0;
-}
-
-/*
- * Driver exit function
- */
-static IMG_VOID __exit omap_sgx_dc_deinit(IMG_VOID)
-{
-#if defined(LDM_PLATFORM)
- DEBUG_PRINTK("Removing platform driver");
- platform_driver_unregister(&omap_sgx_dc_driver);
-#if defined(SGX_EARLYSUSPEND)
- unregister_early_suspend(&driver_early_suspend);
-#endif
-#endif
- if(destroy_display_devices() != OMAP_OK)
- WARNING_PRINTK("Driver cleanup failed");
-}
-
-MODULE_SUPPORTED_DEVICE(DEVNAME);
-late_initcall(omap_sgx_dc_init);
-module_exit(omap_sgx_dc_deinit);