diff options
author | Loren Huang <b02279@freescale.com> | 2012-04-24 12:21:24 +0800 |
---|---|---|
committer | Jason Liu <r64343@freescale.com> | 2012-07-20 13:36:32 +0800 |
commit | 2978a182258f896d950194aff970a7131829594c (patch) | |
tree | 6c6d7d10be22c6c455137635a34ed2ff338dcbd8 /drivers/mxc/gpu-viv/hal/os/linux/kernel | |
parent | 1c81be6a539289ba20c2ab8225c4e98253aff91f (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')
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(¤t->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(¤t->mm->mmap_sem); + result = get_user_pages(current, current->mm, memory & PAGE_MASK, pageCount, @@ -5438,87 +5471,84 @@ OnError: pages, gcvNULL ); - up_read(¤t->mm->mmap_sem); - - if (result <=0 || result < pageCount) - { - struct vm_area_struct *vma; + up_read(¤t->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_ */ |