summaryrefslogtreecommitdiff
path: root/drivers/mxc/gpu-viv/hal/os/linux/kernel
diff options
context:
space:
mode:
authorLoren Huang <b02279@freescale.com>2012-04-24 12:21:24 +0800
committerJason Liu <r64343@freescale.com>2012-07-20 13:36:32 +0800
commit2978a182258f896d950194aff970a7131829594c (patch)
tree6c6d7d10be22c6c455137635a34ed2ff338dcbd8 /drivers/mxc/gpu-viv/hal/os/linux/kernel
parent1c81be6a539289ba20c2ab8225c4e98253aff91f (diff)
ENGR00180624 Merge vivante 4.6.7p1 kernel part code
Merge vivante 4.6.7p1 kernel part code Signed-off-by: Loren Huang <b02279@freescale.com> Acked-by: Lily Zhang
Diffstat (limited to 'drivers/mxc/gpu-viv/hal/os/linux/kernel')
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c117
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h4
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c62
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c504
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h7
5 files changed, 372 insertions, 322 deletions
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
index efdaef8931d9..df75a8b3c65c 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
@@ -140,7 +140,7 @@ static int threadRoutine(void *ctxt)
static int down;
down = down_interruptible(&device->semas[gcvCORE_MAJOR]);
- if (down); /* To make gcc4.6 happy */
+ if (down); /*To make gcc 4.6 happye*/
device->dataReadys[gcvCORE_MAJOR] = gcvFALSE;
if (device->killThread == gcvTRUE)
@@ -193,7 +193,7 @@ static int threadRoutine2D(void *ctxt)
static int down;
down = down_interruptible(&device->semas[gcvCORE_2D]);
- if (down); /* To make gcc4.6 happy */
+ if (down); /*To make gcc 4.6 happye*/
device->dataReadys[gcvCORE_2D] = gcvFALSE;
if (device->killThread == gcvTRUE)
@@ -244,7 +244,7 @@ static int threadRoutineVG(void *ctxt)
static int down;
down = down_interruptible(&device->semas[gcvCORE_VG]);
- if (down); /* To make gcc4.6 happy */
+ if (down); /*To make gcc 4.6 happye*/
device->dataReadys[gcvCORE_VG] = gcvFALSE;
if (device->killThread == gcvTRUE)
@@ -262,65 +262,6 @@ static int threadRoutineVG(void *ctxt)
}
}
-#if gcdPOWEROFF_TIMEOUT
-/*
-** PM Thread Routine
-**/
-static int _threadRoutinePM(gckGALDEVICE Device, gckHARDWARE Hardware)
-{
- gceCHIPPOWERSTATE state;
-
- for(;;)
- {
- /* wait for idle */
- gcmkVERIFY_OK(
- gckOS_WaitSignal(Device->os, Hardware->powerOffSignal, gcvINFINITE));
-
- /* We try to power off every 200 ms, until GPU is not idle */
- do
- {
- if (Device->killThread == gcvTRUE)
- {
- /* The daemon exits. */
- while (!kthread_should_stop())
- {
- gckOS_Delay(Device->os, 1);
- }
- return 0;
- }
-
- gcmkVERIFY_OK(
- gckHARDWARE_SetPowerManagementState(
- Hardware,
- gcvPOWER_OFF_TIMEOUT));
-
- /* relax cpu 200 ms before retry */
- gckOS_Delay(Device->os, 200);
-
- gcmkVERIFY_OK(
- gckHARDWARE_QueryPowerManagementState(Hardware, &state));
- }
- while (state == gcvPOWER_IDLE);
- }
-}
-
-static int threadRoutinePM(void *ctxt)
-{
- gckGALDEVICE device = (gckGALDEVICE) ctxt;
- gckHARDWARE hardware = device->kernels[gcvCORE_MAJOR]->hardware;
-
- return _threadRoutinePM(device, hardware);
-}
-
-static int threadRoutinePM_2D(void *ctxt)
-{
- gckGALDEVICE device = (gckGALDEVICE) ctxt;
- gckHARDWARE hardware = device->kernels[gcvCORE_2D]->hardware;
-
- return _threadRoutinePM(device, hardware);
-}
-#endif
-
/******************************************************************************\
******************************* gckGALDEVICE Code ******************************
\******************************************************************************/
@@ -1398,25 +1339,6 @@ gckGALDEVICE_Start_Threads(
Device->threadCtxts[gcvCORE_MAJOR] = task;
Device->threadInitializeds[gcvCORE_MAJOR] = gcvTRUE;
-
-#if gcdPOWEROFF_TIMEOUT
- /* Start the kernel thread. */
- task = kthread_run(threadRoutinePM, Device, "galcore pm thread");
-
- if (IS_ERR(task))
- {
- gcmkTRACE_ZONE(
- gcvLEVEL_ERROR, gcvZONE_DRIVER,
- "%s(%d): Could not start the kernel thread.\n",
- __FUNCTION__, __LINE__
- );
-
- gcmkONERROR(gcvSTATUS_GENERIC_IO);
- }
-
- Device->pmThreadCtxts[gcvCORE_MAJOR] = task;
- Device->pmThreadInitializeds[gcvCORE_MAJOR] = gcvTRUE;
-#endif
}
if (Device->kernels[gcvCORE_2D] != gcvNULL)
@@ -1437,25 +1359,6 @@ gckGALDEVICE_Start_Threads(
Device->threadCtxts[gcvCORE_2D] = task;
Device->threadInitializeds[gcvCORE_2D] = gcvTRUE;
-
-#if gcdPOWEROFF_TIMEOUT
- /* Start the kernel thread. */
- task = kthread_run(threadRoutinePM_2D, Device, "galcore pm 2d thread");
-
- if (IS_ERR(task))
- {
- gcmkTRACE_ZONE(
- gcvLEVEL_ERROR, gcvZONE_DRIVER,
- "%s(%d): Could not start the kernel thread.\n",
- __FUNCTION__, __LINE__
- );
-
- gcmkONERROR(gcvSTATUS_GENERIC_IO);
- }
-
- Device->pmThreadCtxts[gcvCORE_2D] = task;
- Device->pmThreadInitializeds[gcvCORE_2D] = gcvTRUE;
-#endif
}
else
{
@@ -1537,20 +1440,6 @@ gckGALDEVICE_Stop_Threads(
Device->threadCtxts[i] = gcvNULL;
Device->threadInitializeds[i] = gcvFALSE;
}
-
-#if gcdPOWEROFF_TIMEOUT
- /* Stop the kernel threads. */
- if (Device->pmThreadInitializeds[i])
- {
- gckHARDWARE hardware = Device->kernels[i]->hardware;
- Device->killThread = gcvTRUE;
- gckOS_Signal(Device->os, hardware->powerOffSignal, gcvTRUE);
-
- kthread_stop(Device->pmThreadCtxts[i]);
- Device->pmThreadCtxts[i] = gcvNULL;
- Device->pmThreadInitializeds[i] = gcvFALSE;
- }
-#endif
}
gcmkFOOTER_NO();
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
index 5bbbd662c0d3..69c985c90ff3 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
@@ -92,10 +92,6 @@ typedef struct _gckGALDEVICE
struct clk *clk_2d_axi;
struct clk *clk_vg_axi;
-#if gcdPOWEROFF_TIMEOUT
- struct task_struct *pmThreadCtxts[gcdCORE_COUNT];
- gctBOOL pmThreadInitializeds[gcdCORE_COUNT];
-#endif
}
* gckGALDEVICE;
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
index 4d544ea0aa6c..7d1314882dde 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
@@ -49,44 +49,44 @@ static struct class* gpuClass;
static gckGALDEVICE galDevice;
-static int major = 199;
-module_param(major, int, 0644);
+static uint major = 199;
+module_param(major, uint, 0644);
static int irqLine = -1;
module_param(irqLine, int, 0644);
-static long registerMemBase = 0x80000000;
-module_param(registerMemBase, long, 0644);
+static ulong registerMemBase = 0x80000000;
+module_param(registerMemBase, ulong, 0644);
-static ulong registerMemSize = 256 << 10;
+static ulong registerMemSize = 2 << 10;
module_param(registerMemSize, ulong, 0644);
static int irqLine2D = -1;
module_param(irqLine2D, int, 0644);
-static long registerMemBase2D = 0x00000000;
-module_param(registerMemBase2D, long, 0644);
+static ulong registerMemBase2D = 0x00000000;
+module_param(registerMemBase2D, ulong, 0644);
-static ulong registerMemSize2D = 256 << 10;
+static ulong registerMemSize2D = 2 << 10;
module_param(registerMemSize2D, ulong, 0644);
static int irqLineVG = -1;
module_param(irqLineVG, int, 0644);
-static long registerMemBaseVG = 0x00000000;
-module_param(registerMemBaseVG, long, 0644);
+static ulong registerMemBaseVG = 0x00000000;
+module_param(registerMemBaseVG, ulong, 0644);
-static ulong registerMemSizeVG = 256 << 10;
+static ulong registerMemSizeVG = 2 << 10;
module_param(registerMemSizeVG, ulong, 0644);
-static long contiguousSize = 4 << 20;
-module_param(contiguousSize, long, 0644);
+static ulong contiguousSize = 4 << 20;
+module_param(contiguousSize, ulong, 0644);
static ulong contiguousBase = 0;
module_param(contiguousBase, ulong, 0644);
-static long bankSize = 32 << 20;
-module_param(bankSize, long, 0644);
+static ulong bankSize = 32 << 20;
+module_param(bankSize, ulong, 0644);
static int fastClear = -1;
module_param(fastClear, int, 0644);
@@ -199,20 +199,6 @@ int drv_open(
galDevice->contiguousSize,
&data->contiguousLogical
));
-
- for (i = 0; i < gcdCORE_COUNT; i++)
- {
- if (galDevice->kernels[i] != gcvNULL)
- {
- gcmkVERIFY_OK(gckKERNEL_AddProcessDB(
- galDevice->kernels[i],
- data->pidOpen,
- gcvDB_MAP_MEMORY,
- data->contiguousLogical,
- galDevice->contiguousPhysical,
- galDevice->contiguousSize));
- }
- }
}
filp->private_data = data;
@@ -261,8 +247,6 @@ int drv_release(
gcsHAL_PRIVATE_DATA_PTR data;
gckGALDEVICE device;
gctINT i;
- gctUINT32 processID;
-
gcmkHEADER_ARG("inode=0x%08X filp=0x%08X", inode, filp);
@@ -307,7 +291,6 @@ int drv_release(
{
if (data->contiguousLogical != gcvNULL)
{
- gcmkVERIFY_OK(gckOS_GetProcessID(&processID));
gcmkONERROR(gckOS_UnmapMemoryEx(
galDevice->os,
galDevice->contiguousPhysical,
@@ -316,25 +299,10 @@ int drv_release(
data->pidOpen
));
- for (i = 0; i < gcdCORE_COUNT; i++)
- {
- if (galDevice->kernels[i] != gcvNULL)
- {
- gcmkVERIFY_OK(
- gckKERNEL_RemoveProcessDB(galDevice->kernels[i],
- processID, gcvDB_MAP_MEMORY,
- data->contiguousLogical));
- }
- }
-
data->contiguousLogical = gcvNULL;
}
}
- /* Clean user signals if exit unnormally. */
- gcmkVERIFY_OK(gckOS_GetProcessID(&processID));
- gcmkVERIFY_OK(gckOS_CleanProcessSignal(galDevice->os, (gctHANDLE)processID));
-
/* A process gets detached. */
for (i = 0; i < gcdCORE_COUNT; i++)
{
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
index c763d0f84a55..510b0300e3c4 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
@@ -33,6 +33,7 @@
#include <linux/slab.h>
#include <linux/idr.h>
#include <mach/hardware.h>
+#include <linux/workqueue.h>
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
#include <linux/math64.h>
#endif
@@ -174,6 +175,9 @@ struct _gckOS
gcsNonPagedMemoryCache * cacheHead;
gcsNonPagedMemoryCache * cacheTail;
#endif
+
+ /* workqueue for os timer. */
+ struct workqueue_struct * workqueue;
};
typedef struct _gcsSIGNAL * gcsSIGNAL_PTR;
@@ -217,6 +221,13 @@ typedef struct _gcsiDEBUG_REGISTERS
}
gcsiDEBUG_REGISTERS;
+typedef struct _gcsOSTIMER * gcsOSTIMER_PTR;
+typedef struct _gcsOSTIMER
+{
+ struct delayed_work work;
+ gctTIMERFUNCTION function;
+ gctPOINTER data;
+} gcsOSTIMER;
/******************************************************************************\
******************************* Private Functions ******************************
@@ -1223,6 +1234,15 @@ gckOS_Construct(
os->cacheTail = gcvNULL;
#endif
+ /* Create a workqueue for os timer. */
+ os->workqueue = create_singlethread_workqueue("galcore workqueue");
+
+ if (os->workqueue == gcvNULL)
+ {
+ /* Out of memory. */
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
/* Return pointer to the gckOS object. */
*Os = os;
@@ -1261,6 +1281,11 @@ OnError:
gckOS_DeleteMutex(os, os->debugLock));
}
+ if (os->workqueue != gcvNULL)
+ {
+ destroy_workqueue(os->workqueue);
+ }
+
kfree(os);
/* Return the error. */
@@ -1324,6 +1349,12 @@ gckOS_Destroy(
/* Destroy debug lock mutex. */
gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->debugLock));
+ /* Wait for all works done. */
+ flush_workqueue(Os->workqueue);
+
+ /* Destory work queue. */
+ destroy_workqueue(Os->workqueue);
+
/* Flush the debug cache. */
gcmkDEBUGFLUSH(~0U);
@@ -3033,27 +3064,28 @@ gckOS_CreateMutex(
OUT gctPOINTER * Mutex
)
{
+ gceSTATUS status;
+
gcmkHEADER_ARG("Os=0x%X", Os);
/* Validate the arguments. */
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
- /* Allocate a FAST_MUTEX structure. */
- *Mutex = (gctPOINTER)kmalloc(sizeof(struct semaphore), GFP_KERNEL | __GFP_NOWARN);
+ /* Allocate the mutex structure. */
+ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(struct mutex), Mutex));
- if (*Mutex == gcvNULL)
- {
- gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_MEMORY);
- return gcvSTATUS_OUT_OF_MEMORY;
- }
-
- /* Initialize the semaphore.. Come up in unlocked state. */
- sema_init(*Mutex, 1);
+ /* Initialize the mutex. */
+ mutex_init(*Mutex);
/* Return status. */
gcmkFOOTER_ARG("*Mutex=0x%X", *Mutex);
return gcvSTATUS_OK;
+
+OnError:
+ /* Return status. */
+ gcmkFOOTER();
+ return status;
}
/*******************************************************************************
@@ -3080,17 +3112,27 @@ gckOS_DeleteMutex(
IN gctPOINTER Mutex
)
{
+ gceSTATUS status;
+
gcmkHEADER_ARG("Os=0x%X Mutex=0x%X", Os, Mutex);
/* Validate the arguments. */
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
- /* Delete the fast mutex. */
- kfree(Mutex);
+ /* Destroy the mutex. */
+ mutex_destroy(Mutex);
+
+ /* Free the mutex structure. */
+ gcmkONERROR(gckOS_Free(Os, Mutex));
gcmkFOOTER_NO();
return gcvSTATUS_OK;
+
+OnError:
+ /* Return status. */
+ gcmkFOOTER();
+ return status;
}
/*******************************************************************************
@@ -3139,7 +3181,7 @@ gckOS_AcquireMutex(
for (;;)
{
/* Try to acquire the mutex. */
- if (!down_trylock((struct semaphore *) Mutex))
+ if (mutex_trylock(Mutex))
{
/* Success. */
gcmkFOOTER_NO();
@@ -3203,7 +3245,8 @@ gckOS_AcquireMutex(
#else
if (Timeout == gcvINFINITE)
{
- down((struct semaphore *) Mutex);
+ /* Lock the mutex. */
+ mutex_lock(Mutex);
/* Success. */
gcmkFOOTER_NO();
@@ -3213,7 +3256,7 @@ gckOS_AcquireMutex(
for (;;)
{
/* Try to acquire the mutex. */
- if (!down_trylock((struct semaphore *) Mutex))
+ if (mutex_trylock(Mutex))
{
/* Success. */
gcmkFOOTER_NO();
@@ -3265,8 +3308,8 @@ gckOS_ReleaseMutex(
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
- /* Release the fast mutex. */
- up((struct semaphore *) Mutex);
+ /* Release the mutex. */
+ mutex_unlock(Mutex);
/* Success. */
gcmkFOOTER_NO();
@@ -3762,7 +3805,7 @@ gckOS_GetTicks(
{
gcmkHEADER();
- *Time = jiffies * 1000 / HZ;
+ *Time = jiffies_to_msecs(jiffies);
gcmkFOOTER_NO();
return gcvSTATUS_OK;
@@ -5327,20 +5370,9 @@ OnError:
gceSTATUS
gckOS_MapUserMemory(
IN gckOS Os,
- IN gctPOINTER Memory,
- IN gctSIZE_T Size,
- OUT gctPOINTER * Info,
- OUT gctUINT32_PTR Address
- )
-{
- return gckOS_MapUserMemoryEx(Os, gcvCORE_MAJOR, Memory, Size, Info, Address);
-}
-
-gceSTATUS
-gckOS_MapUserMemoryEx(
- IN gckOS Os,
IN gceCORE Core,
IN gctPOINTER Memory,
+ IN gctUINT32 Physical,
IN gctSIZE_T Size,
OUT gctPOINTER * Info,
OUT gctUINT32_PTR Address
@@ -5364,7 +5396,8 @@ OnError:
gctSIZE_T pageCount, i, j;
gctUINT32_PTR pageTable;
gctUINT32 address = 0, physical = ~0U;
- gctUINT32 start, end, memory;
+ gctUINT32 memory;
+ gctUINT32 offset;
gctINT result = 0;
gcsPageInfo_PTR info = gcvNULL;
@@ -5372,7 +5405,7 @@ OnError:
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
- gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Memory != gcvNULL || Physical != ~0U);
gcmkVERIFY_ARGUMENT(Size > 0);
gcmkVERIFY_ARGUMENT(Info != gcvNULL);
gcmkVERIFY_ARGUMENT(Address != gcvNULL);
@@ -5381,10 +5414,7 @@ OnError:
{
memory = (gctUINT32) Memory;
- /* Get the number of required pages. */
- end = (memory + Size + PAGE_SIZE - 1) >> PAGE_SHIFT;
- start = memory >> PAGE_SHIFT;
- pageCount = end - start;
+ pageCount = GetPageCount(Size, 0);
gcmkTRACE_ZONE(
gcvLEVEL_INFO, gcvZONE_OS,
@@ -5393,13 +5423,6 @@ OnError:
pageCount
);
- /* Invalid argument. */
- if (pageCount == 0)
- {
- gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
- return gcvSTATUS_INVALID_ARGUMENT;
- }
-
/* Overflow. */
if ((memory + Size) < memory)
{
@@ -5427,9 +5450,19 @@ OnError:
break;
}
- /* Get the user pages. */
- down_read(&current->mm->mmap_sem);
- result = get_user_pages(current,
+ if (Physical != ~0U)
+ {
+ for (i = 0; i < pageCount; i++)
+ {
+ pages[i] = pfn_to_page((Physical >> PAGE_SHIFT) + i);
+ get_page(pages[i]);
+ }
+ }
+ else
+ {
+ /* Get the user pages. */
+ down_read(&current->mm->mmap_sem);
+ result = get_user_pages(current,
current->mm,
memory & PAGE_MASK,
pageCount,
@@ -5438,87 +5471,84 @@ OnError:
pages,
gcvNULL
);
- up_read(&current->mm->mmap_sem);
-
- if (result <=0 || result < pageCount)
- {
- struct vm_area_struct *vma;
+ up_read(&current->mm->mmap_sem);
- /* Free the page table. */
- if (pages != gcvNULL)
+ if (result <=0 || result < pageCount)
{
- /* Release the pages if any. */
- if (result > 0)
+ struct vm_area_struct *vma;
+
+ /* Free the page table. */
+ if (pages != gcvNULL)
{
- for (i = 0; i < result; i++)
+ /* Release the pages if any. */
+ if (result > 0)
{
- if (pages[i] == gcvNULL)
+ for (i = 0; i < result; i++)
{
- break;
- }
+ if (pages[i] == gcvNULL)
+ {
+ break;
+ }
- page_cache_release(pages[i]);
+ page_cache_release(pages[i]);
+ }
}
- }
- kfree(pages);
- pages = gcvNULL;
- }
+ kfree(pages);
+ pages = gcvNULL;
+ }
- vma = find_vma(current->mm, memory);
+ vma = find_vma(current->mm, memory);
- if (vma && (vma->vm_flags & VM_PFNMAP) )
- {
- pte_t * pte;
- spinlock_t * ptl;
- unsigned long pfn;
-
- pgd_t * pgd = pgd_offset(current->mm, memory);
- pud_t * pud = pud_offset(pgd, memory);
- if (pud)
+ if (vma && (vma->vm_flags & VM_PFNMAP) )
{
- pmd_t * pmd = pmd_offset(pud, memory);
- pte = pte_offset_map_lock(current->mm, pmd, memory, &ptl);
- if (!pte)
+ pte_t * pte;
+ spinlock_t * ptl;
+ unsigned long pfn;
+
+ pgd_t * pgd = pgd_offset(current->mm, memory);
+ pud_t * pud = pud_offset(pgd, memory);
+ if (pud)
+ {
+ pmd_t * pmd = pmd_offset(pud, memory);
+ pte = pte_offset_map_lock(current->mm, pmd, memory, &ptl);
+ if (!pte)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+ }
+ else
{
gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
}
- }
- else
- {
- gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
- }
- pfn = pte_pfn(*pte);
+ pfn = pte_pfn(*pte);
- physical = (pfn << PAGE_SHIFT) | (memory & ~PAGE_MASK);
+ physical = (pfn << PAGE_SHIFT) | (memory & ~PAGE_MASK);
- pte_unmap_unlock(pte, ptl);
+ pte_unmap_unlock(pte, ptl);
- if ((Os->device->kernels[Core]->hardware->mmuVersion == 0)
- && !((physical - Os->device->baseAddress) & 0x80000000))
- {
- /* Release page info struct. */
- if (info != gcvNULL)
+ if ((Os->device->kernels[Core]->hardware->mmuVersion == 0)
+ && !((physical - Os->device->baseAddress) & 0x80000000))
{
- /* Free the page info struct. */
- kfree(info);
- }
+ info->pages = gcvNULL;
+ info->pageTable = gcvNULL;
- MEMORY_MAP_UNLOCK(Os);
+ MEMORY_MAP_UNLOCK(Os);
- *Address = physical - Os->device->baseAddress;
- *Info = gcvNULL;
+ *Address = physical - Os->device->baseAddress;
+ *Info = info;
- gcmkFOOTER_ARG("*Info=0x%X *Address=0x%08x",
- *Info, *Address);
+ gcmkFOOTER_ARG("*Info=0x%X *Address=0x%08x",
+ *Info, *Address);
- return gcvSTATUS_OK;
+ return gcvSTATUS_OK;
+ }
+ }
+ else
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
}
- }
- else
- {
- gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
}
}
@@ -5540,7 +5570,6 @@ OnError:
(gctPOINTER)(physical & PAGE_MASK),
(gctPOINTER)(memory & PAGE_MASK),
PAGE_SIZE * pageCount));
-
}
#if gcdENABLE_VG
@@ -5629,8 +5658,12 @@ OnError:
info
);
+ offset = (Physical != ~0U)
+ ? (Physical & ~PAGE_MASK)
+ : (memory & ~PAGE_MASK);
+
/* Return address. */
- *Address = address + (memory & ~PAGE_MASK);
+ *Address = address + offset;
gcmkTRACE_ZONE(
gcvLEVEL_INFO, gcvZONE_OS,
@@ -5747,18 +5780,6 @@ OnError:
gceSTATUS
gckOS_UnmapUserMemory(
IN gckOS Os,
- IN gctPOINTER Memory,
- IN gctSIZE_T Size,
- IN gctPOINTER Info,
- IN gctUINT32 Address
- )
-{
- return gckOS_UnmapUserMemoryEx(Os, gcvCORE_MAJOR, Memory, Size, Info, Address);
-}
-
-gceSTATUS
-gckOS_UnmapUserMemoryEx(
- IN gckOS Os,
IN gceCORE Core,
IN gctPOINTER Memory,
IN gctSIZE_T Size,
@@ -5782,7 +5803,7 @@ OnError:
return status;
#else
{
- gctUINT32 memory, start, end;
+ gctUINT32 memory;
gcsPageInfo_PTR info;
gctSIZE_T pageCount, i;
struct page **pages;
@@ -5795,8 +5816,6 @@ OnError:
do
{
- /*gctUINT32 physical = ~0U;*/
-
info = (gcsPageInfo_PTR) Info;
pages = info->pages;
@@ -5809,25 +5828,16 @@ OnError:
);
/* Invalid page array. */
- if (pages == gcvNULL)
+ if (pages == gcvNULL && info->pageTable == gcvNULL)
{
- if (info->pageTable == gcvNULL)
- {
- kfree(info);
+ kfree(info);
- gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
- return gcvSTATUS_INVALID_ARGUMENT;
- }
- else
- {
- /*physical = (*info->pageTable) & PAGE_MASK;*/
- }
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
}
memory = (gctUINT32) Memory;
- end = (memory + Size + PAGE_SIZE - 1) >> PAGE_SHIFT;
- start = memory >> PAGE_SHIFT;
- pageCount = end - start;
+ pageCount = GetPageCount(Size, 0);
/* Overflow. */
if ((memory + Size) < memory)
@@ -5836,13 +5846,6 @@ OnError:
return gcvSTATUS_INVALID_ARGUMENT;
}
- /* Invalid argument. */
- if (pageCount == 0)
- {
- gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
- return gcvSTATUS_INVALID_ARGUMENT;
- }
-
gcmkTRACE_ZONE(
gcvLEVEL_INFO, gcvZONE_OS,
"%s(%d): memory: 0x%X, pageCount: %d, pageTable: 0x%X.",
@@ -5852,6 +5855,8 @@ OnError:
MEMORY_MAP_LOCK(Os);
+ gcmkASSERT(info->pageTable != gcvNULL);
+
#if gcdENABLE_VG
if (Core == gcvCORE_VG)
{
@@ -6476,7 +6481,11 @@ gckOS_Broadcast(
/* Put GPU IDLE. */
gcmkONERROR(
gckHARDWARE_SetPowerManagementState(Hardware,
+#if gcdPOWER_SUSNPEND_WHEN_IDLE
+ gcvPOWER_SUSPEND_BROADCAST));
+#else
gcvPOWER_IDLE_BROADCAST));
+#endif
/* Add idle process DB. */
gcmkONERROR(gckKERNEL_AddProcessDB(Hardware->kernel,
@@ -7753,15 +7762,6 @@ gckOS_SignalUserSignal(
return gckOS_Signal(Os, (gctSIGNAL)SignalID, State);
}
-gceSTATUS
-gckOS_CleanProcessSignal(
- gckOS Os,
- gctHANDLE Process
- )
-{
- return gcvSTATUS_OK;
-}
-
#if gcdENABLE_VG
gceSTATUS
gckOS_CreateSemaphoreVG(
@@ -8060,3 +8060,207 @@ gckOS_DumpGPUState(
/* Success. */
return gcvSTATUS_OK;
}
+
+/******************************************************************************\
+******************************** Software Timer ********************************
+\******************************************************************************/
+
+void
+_TimerFunction(
+ struct work_struct * work
+ )
+{
+ gcsOSTIMER_PTR timer = (gcsOSTIMER_PTR)work;
+
+ gctTIMERFUNCTION function = timer->function;
+
+ function(timer->data);
+}
+
+/*******************************************************************************
+**
+** gckOS_CreateTimer
+**
+** Create a software timer.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to the gckOS object.
+**
+** gctTIMERFUNCTION Function.
+** Pointer to a call back function which will be called when timer is
+** expired.
+**
+** gctPOINTER Data.
+** Private data which will be passed to call back function.
+**
+** OUTPUT:
+**
+** gctPOINTER * Timer
+** Pointer to a variable receiving the created timer.
+*/
+gceSTATUS
+gckOS_CreateTimer(
+ IN gckOS Os,
+ IN gctTIMERFUNCTION Function,
+ IN gctPOINTER Data,
+ OUT gctPOINTER * Timer
+ )
+{
+ gceSTATUS status;
+ gcsOSTIMER_PTR pointer;
+ gcmkHEADER_ARG("Os=0x%X Function=0x%X Data=0x%X", Os, Function, Data);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
+
+ gcmkONERROR(gckOS_Allocate(Os, sizeof(gcsOSTIMER), (gctPOINTER)&pointer));
+
+ pointer->function = Function;
+ pointer->data = Data;
+
+ INIT_DELAYED_WORK(&pointer->work, _TimerFunction);
+
+ *Timer = pointer;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckOS_DestoryTimer
+**
+** Destory a software timer.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to the gckOS object.
+**
+** gctPOINTER Timer
+** Pointer to the timer to be destoryed.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_DestoryTimer(
+ IN gckOS Os,
+ IN gctPOINTER Timer
+ )
+{
+ gcsOSTIMER_PTR timer;
+ gcmkHEADER_ARG("Os=0x%X Timer=0x%X", Os, Timer);
+
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
+
+ timer = (gcsOSTIMER_PTR)Timer;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+ cancel_delayed_work_sync(&timer->work);
+#else
+ cancel_delayed_work(&timer->work);
+ flush_workqueue(Os->workqueue);
+#endif
+
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, Timer));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_StartTimer
+**
+** Schedule a software timer.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to the gckOS object.
+**
+** gctPOINTER Timer
+** Pointer to the timer to be scheduled.
+**
+** gctUINT32 Delay
+** Delay in milliseconds.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_StartTimer(
+ IN gckOS Os,
+ IN gctPOINTER Timer,
+ IN gctUINT32 Delay
+ )
+{
+ gcsOSTIMER_PTR timer;
+
+ gcmkHEADER_ARG("Os=0x%X Timer=0x%X Delay=%u", Os, Timer, Delay);
+
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Delay != 0);
+
+ timer = (gcsOSTIMER_PTR)Timer;
+
+ if (unlikely(delayed_work_pending(&timer->work)))
+ {
+ cancel_delayed_work(&timer->work);
+ }
+
+ queue_delayed_work(Os->workqueue, &timer->work, msecs_to_jiffies(Delay));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_StopTimer
+**
+** Cancel a unscheduled timer.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to the gckOS object.
+**
+** gctPOINTER Timer
+** Pointer to the timer to be cancel.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_StopTimer(
+ IN gckOS Os,
+ IN gctPOINTER Timer
+ )
+{
+ gcsOSTIMER_PTR timer;
+ gcmkHEADER_ARG("Os=0x%X Timer=0x%X", Os, Timer);
+
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
+
+ timer = (gcsOSTIMER_PTR)Timer;
+
+ cancel_delayed_work(&timer->work);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h
index 021e77f6d75b..577fb388c178 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h
@@ -78,11 +78,4 @@ typedef struct _DRIVER_ARGS
}
DRIVER_ARGS;
-/* Cleanup the signal table. */
-gceSTATUS
-gckOS_CleanProcessSignal(
- gckOS Os,
- gctHANDLE Process
- );
-
#endif /* __gc_hal_kernel_os_h_ */