diff options
author | Loren Huang <b02279@freescale.com> | 2012-03-16 15:29:06 +0800 |
---|---|---|
committer | Jason Liu <r64343@freescale.com> | 2012-07-20 13:24:15 +0800 |
commit | 217856f4c04b3ea8e964cf591414d561c50fb0dd (patch) | |
tree | 7b7b2c70808839658524cfc2170ef2be708ff3cf /drivers/mxc/gpu-viv/hal/os | |
parent | b6cd59a82130ec0c7e1ac56deec1b60e02114612 (diff) |
ENGR00177048 Merge vivante 4.6.6 kernel part code
Merge vivante 4.6.6 kernel part code
Signed-off-by: Loren Huang <b02279@freescale.com>
Acked-by: Lily Zhang
Diffstat (limited to 'drivers/mxc/gpu-viv/hal/os')
4 files changed, 147 insertions, 112 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 afac3fcb9e81..ae6062d7a859 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 @@ -22,7 +22,7 @@ #include "gc_hal_kernel_linux.h" -/*#include <linux/pagemap.h>*/ +#include <linux/pagemap.h> #include <linux/seq_file.h> #include <linux/mm.h> #include <linux/mman.h> @@ -137,9 +137,10 @@ static int threadRoutine(void *ctxt) for (;;) { - int down; + static int down; + down = down_interruptible(&device->semas[gcvCORE_MAJOR]); - if (down); + if (down); /*To make gcc4.6 happy*/ device->dataReadys[gcvCORE_MAJOR] = gcvFALSE; if (device->killThread == gcvTRUE) @@ -189,10 +190,10 @@ static int threadRoutine2D(void *ctxt) for (;;) { - int down; + static int down; down = down_interruptible(&device->semas[gcvCORE_2D]); - if (down); + if (down); /*To make gcc4.6 happy*/ device->dataReadys[gcvCORE_2D] = gcvFALSE; if (device->killThread == gcvTRUE) @@ -240,10 +241,10 @@ static int threadRoutineVG(void *ctxt) for (;;) { - int down; + static int down; down = down_interruptible(&device->semas[gcvCORE_VG]); - if (down); + if (down); /*To make gcc4.6 happy*/ device->dataReadys[gcvCORE_VG] = gcvFALSE; if (device->killThread == gcvTRUE) @@ -265,45 +266,59 @@ static int threadRoutineVG(void *ctxt) /* ** PM Thread Routine **/ -static int threadRoutinePM(void *ctxt) +static int _threadRoutinePM(gckGALDEVICE Device, gckHARDWARE Hardware) { - gckGALDEVICE device = (gckGALDEVICE) ctxt; - gckHARDWARE hardware = device->kernels[gcvCORE_MAJOR]->hardware; gceCHIPPOWERSTATE state; for(;;) { /* wait for idle */ gcmkVERIFY_OK( - gckOS_WaitSignal(device->os, hardware->powerOffSignal, gcvINFINITE)); + 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) + if (Device->killThread == gcvTRUE) { /* The daemon exits. */ while (!kthread_should_stop()) { - gckOS_Delay(device->os, 1); + gckOS_Delay(Device->os, 1); } return 0; } gcmkVERIFY_OK( gckHARDWARE_SetPowerManagementState( - hardware, + Hardware, gcvPOWER_OFF_TIMEOUT)); /* relax cpu 200 ms before retry */ - gckOS_Delay(device->os, 200); + gckOS_Delay(Device->os, 200); gcmkVERIFY_OK( - gckHARDWARE_QueryPowerManagementState(hardware, &state)); + 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 /******************************************************************************\ @@ -1399,8 +1414,8 @@ gckGALDEVICE_Start_Threads( gcmkONERROR(gcvSTATUS_GENERIC_IO); } - Device->pmThreadCtxts = task; - Device->pmThreadInitializeds = gcvTRUE; + Device->pmThreadCtxts[gcvCORE_MAJOR] = task; + Device->pmThreadInitializeds[gcvCORE_MAJOR] = gcvTRUE; #endif } @@ -1422,6 +1437,25 @@ 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 { @@ -1503,21 +1537,21 @@ gckGALDEVICE_Stop_Threads( Device->threadCtxts[i] = gcvNULL; Device->threadInitializeds[i] = gcvFALSE; } - } #if gcdPOWEROFF_TIMEOUT - /* Stop the kernel threads. */ - if (Device->pmThreadInitializeds) - { - gckHARDWARE hardware = Device->kernels[gcvCORE_MAJOR]->hardware; - Device->killThread = gcvTRUE; - gckOS_Signal(Device->os, hardware->powerOffSignal, gcvTRUE); + /* 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); - Device->pmThreadCtxts = gcvNULL; - Device->pmThreadInitializeds = gcvFALSE; - } + kthread_stop(Device->pmThreadCtxts[i]); + Device->pmThreadCtxts[i] = gcvNULL; + Device->pmThreadInitializeds[i] = gcvFALSE; + } #endif + } gcmkFOOTER_NO(); return gcvSTATUS_OK; 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 f0b806fbc94d..5bbbd662c0d3 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 @@ -93,8 +93,8 @@ typedef struct _gckGALDEVICE struct clk *clk_vg_axi; #if gcdPOWEROFF_TIMEOUT - struct task_struct *pmThreadCtxts; - gctBOOL pmThreadInitializeds; + 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 496082e6547f..30e6a304783c 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 @@ -199,6 +199,20 @@ 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; @@ -247,6 +261,8 @@ int drv_release( gcsHAL_PRIVATE_DATA_PTR data; gckGALDEVICE device; gctINT i; + gctUINT32 processID; + gcmkHEADER_ARG("inode=0x%08X filp=0x%08X", inode, filp); @@ -291,7 +307,6 @@ int drv_release( { if (data->contiguousLogical != gcvNULL) { - gctUINT32 processID; gcmkVERIFY_OK(gckOS_GetProcessID(&processID)); gcmkONERROR(gckOS_UnmapMemoryEx( galDevice->os, @@ -316,6 +331,10 @@ int drv_release( } } + /* 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++) { @@ -479,20 +498,6 @@ long drv_ioctl( } else { - if (iface.command == gcvHAL_CACHE) - { - if (device->contiguousMapped - && iface.u.Cache.node->VidMem.memory->object.type == gcvOBJ_VIDMEM) - { - iface.u.Cache.physical = (gctPOINTER)device->contiguousVidMem->baseAddress - + (iface.u.Cache.logical - data->mappedMemory); - } - else - { - iface.u.Cache.physical = 0; - } - } - if (iface.hardwareType < 0 || iface.hardwareType > 7) { gcmkTRACE_ZONE( @@ -620,7 +625,7 @@ static int drv_mmap( } #if !gcdPAGED_MEMORY_CACHEABLE - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND; #endif vma->vm_pgoff = 0; 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 53489ffaa2c4..467f4f3b2820 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 @@ -68,7 +68,7 @@ const char * _PLATFORM = "\n\0$PLATFORM$Linux$\n"; gcmkVERIFY_OK(gckOS_ReleaseMutex((os), (os)->memoryMapLock)) /* Protection bit when mapping memroy to user sapce */ -#define gcmkPAGED_MEMROY_PROT(x) pgprot_noncached(x) +#define gcmkPAGED_MEMROY_PROT(x) pgprot_writecombine(x) #if gcdNONPAGED_MEMORY_BUFFERABLE #define gcmkIOREMAP ioremap_wc @@ -321,7 +321,8 @@ OnError: static gceSTATUS _DumpGPUState( - IN gckOS Os + IN gckOS Os, + IN gceCORE Core ) { static gctCONST_STRING _cmdState[] = @@ -391,7 +392,7 @@ _DumpGPUState( gctUINT32 dmaReqState, calState, veReqState; gctUINT i; - gcmkHEADER_ARG("Os=0x%X", Os); + gcmkHEADER_ARG("Os=0x%X, Core=%d", Os, Core); gcmkONERROR(gckOS_AcquireMutex(Os, Os->debugLock, gcvINFINITE)); acquired = gcvTRUE; @@ -400,9 +401,14 @@ _DumpGPUState( device = (gckGALDEVICE) Os->device; /* TODO: Kernel shortcut. */ - kernel = device->kernels[gcvCORE_MAJOR]; + kernel = device->kernels[Core]; + gcmkPRINT_N(4, "Core = 0x%d\n",Core); - if (kernel == gcvNULL) return gcvSTATUS_OK; + if (kernel == gcvNULL) + { + gcmkFOOTER(); + return gcvSTATUS_OK; + } /* Reset register values. */ idle = axi = @@ -686,6 +692,7 @@ FindMdlMap( gcmkHEADER_ARG("Mdl=0x%X ProcessID=%d", Mdl, ProcessID); if(Mdl == gcvNULL) { + gcmkFOOTER_NO(); return gcvNULL; } mdlMap = Mdl->maps; @@ -765,6 +772,16 @@ _NonContiguousAlloc( gcmkHEADER_ARG("NumPages=%lu", NumPages); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) + if (NumPages > totalram_pages) +#else + if (NumPages > num_physpages) +#endif + { + gcmkFOOTER_NO(); + return gcvNULL; + } + size = NumPages * sizeof(struct page *); pages = kmalloc(size, GFP_KERNEL | __GFP_NOWARN); @@ -776,7 +793,7 @@ _NonContiguousAlloc( if (!pages) { gcmkFOOTER_NO(); - return 0; + return gcvNULL; } } @@ -788,7 +805,7 @@ _NonContiguousAlloc( { _NonContiguousFree(pages, i); gcmkFOOTER_NO(); - return 0; + return gcvNULL; } pages[i] = p; @@ -1992,12 +2009,6 @@ gckOS_AllocateNonPagedMemory( mdl->addr = addr; - /* - * We will not do any mapping from here. - * Mapping will happen from mmap method. - * mdl structure will be used. - */ - /* Return allocated memory. */ *Bytes = bytes; *Physical = (gctPHYS_ADDR) mdl; @@ -3103,7 +3114,7 @@ gckOS_AcquireMutex( ) # endif { - gcmkVERIFY_OK(_DumpGPUState(Os)); + gcmkVERIFY_OK(_DumpGPUState(Os, gcvCORE_MAJOR)); gcmkPRINT( "%s(%d): mutex 0x%X; forced message flush.", @@ -4830,6 +4841,7 @@ gckOS_GetKernelLogicalEx( default: /* Invalid memory pool. */ + gcmkFOOTER(); return gcvSTATUS_INVALID_ARGUMENT; } @@ -5528,10 +5540,6 @@ OnError: pageTable[i * (PAGE_SIZE/4096) + j] = pageTable[i * (PAGE_SIZE/4096)] + 4096 * j; } -#if gcdSHARED_PAGETABLE - gcmkONERROR(gckMMU_FlushAllMmuCache()); -#endif - gcmkTRACE_ZONE( gcvLEVEL_INFO, gcvZONE_OS, "%s(%d): pageTable[%d]: 0x%X 0x%X.", @@ -5539,6 +5547,13 @@ OnError: i, phys, pageTable[i]); } +#if gcdENABLE_VG + if (Core != gcvCORE_VG) +#endif + { + gcmkONERROR(gckMMU_Flush(Os->device->kernels[Core]->mmu)); + } + /* Save pointer to page table. */ info->pageTable = pageTable; info->pages = pages; @@ -6426,13 +6441,13 @@ gckOS_Broadcast( case gcvBROADCAST_GPU_STUCK: gcmkTRACE_N(gcvLEVEL_ERROR, 0, "gcvBROADCAST_GPU_STUCK\n"); - gcmkONERROR(_DumpGPUState(Os)); + gcmkONERROR(_DumpGPUState(Os, gcvCORE_MAJOR)); gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel)); break; case gcvBROADCAST_AXI_BUS_ERROR: gcmkTRACE_N(gcvLEVEL_ERROR, 0, "gcvBROADCAST_AXI_BUS_ERROR\n"); - gcmkONERROR(_DumpGPUState(Os)); + gcmkONERROR(_DumpGPUState(Os, gcvCORE_MAJOR)); gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel)); break; } @@ -7374,7 +7389,7 @@ gckOS_WaitSignal( /* Increment complain count. */ complained += 1; - gcmkVERIFY_OK(_DumpGPUState(Os)); + gcmkVERIFY_OK(_DumpGPUState(Os, gcvCORE_MAJOR)); gcmkPRINT( "%s(%d): signal 0x%X; forced message flush (%d).", @@ -8318,58 +8333,39 @@ gckOS_VerifyThread( /* Success. */ return gcvSTATUS_OK; } +#endif -#if gcdDYNAMIC_MAP_RESERVED_MEMORY +/******************************************************************************* +** +** gckOS_DumpGPUState +** +** Dump GPU state. +** +** INPUT: +** +** gckOS Os +** Pointer to the gckOS object. +** +** gceCORE Core +** The core type of kernel. +** +** OUTPUT: +** +** Nothing. +*/ gceSTATUS -gckOS_MapReservedMemoryToKernel( +gckOS_DumpGPUState( IN gckOS Os, - IN gctUINT32 Physical, - IN gctINT Bytes, - IN OUT gctPOINTER *Virtual + IN gceCORE Core ) { - gceSTATUS status; - gckGALDEVICE device; - - gcmkHEADER_ARG("Os=0x%X Physical=0x%x Bytes=0x%d", Os, Physical, Bytes); - + gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core); + /* Verify the arguments. */ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); - gcmkVERIFY_ARGUMENT(Physical != 0); - gcmkVERIFY_ARGUMENT(Bytes != 0); - gcmkVERIFY_ARGUMENT(Virtual != gcvNULL); - - device = (gckGALDEVICE) Os->device; - /* Reserved memory should not be mapped yet. */ - gcmkASSERT(device->contiguousBase == gcvNULL); - - *Virtual = ioremap_nocache(Physical, Bytes); - - if(*Virtual == gcvNULL) - { - gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); - } - - gcmkFOOTER_NO(); - return gcvSTATUS_OK; - -OnError: - gcmkFOOTER(); - return status; -} - -gceSTATUS -gckOS_UnmapReservedMemoryFromKernel( - IN gctPOINTER Virtual - ) -{ - gcmkHEADER_ARG("Virtual=0x%X", Virtual); - - iounmap((void *)Virtual); + _DumpGPUState(Os, Core); gcmkFOOTER_NO(); + /* Success. */ return gcvSTATUS_OK; } -#endif -#endif - |