diff options
17 files changed, 492 insertions, 50 deletions
diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c index 541975b93e08..9cc7f0ea31d8 100644 --- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c +++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c @@ -6559,6 +6559,17 @@ gckHARDWARE_DumpGPUState( dmaAddress1 = dmaAddress2 = dmaLow = dmaHigh = 0; + gckOS_Delay(gcvNULL, gcdPOWEROFF_TIMEOUT); + + if (Hardware->chipPowerState != gcvPOWER_ON + && Hardware->chipPowerState != gcvPOWER_IDLE + ) + { + gcmkPRINT("[galcore]: Can't dump when GPU is power off or clock off."); + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + } + /* Verify whether DMA is running. */ gcmkONERROR(_VerifyDMA( os, core, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2 diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c index abcea2fe5398..63ed89e00d27 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c @@ -300,7 +300,7 @@ gckKERNEL_Construct( #endif /* Construct a video memory mutex. */ - gcmkONERROR(gckOS_CreateMutex(Os, &kernel->vidmemMutex)); + gcmkONERROR(gckOS_GetVideoMemoryMutex(Os, &kernel->vidmemMutex)); /* Return pointer to the gckKERNEL object. */ *Kernel = kernel; @@ -523,8 +523,6 @@ gckKERNEL_Destroy( gcmkVERIFY_OK(gckOS_DestroySyncTimeline(Kernel->os, Kernel->timeline)); #endif - gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->vidmemMutex)); - /* Mark the gckKERNEL object as unknown. */ Kernel->object.type = gcvOBJ_UNKNOWN; @@ -775,7 +773,7 @@ _AllocateMemory_Retry: if((physAddr & 0x80000000) || ((physAddr + Bytes) & 0x80000000)) { - gckOS_Print("gpu virtual memory 0x%x cannot be allocated for external use !\n", physAddr); + gckOS_Print("gpu virtual memory 0x%x cannot be allocated in force contiguous request!\n", physAddr); gcmkONERROR(gckVIDMEM_Free(Kernel, node)); @@ -872,7 +870,15 @@ _AllocateMemory_Retry: #ifdef CONFIG_GPU_LOW_MEMORY_KILLER if(forceContiguous == gcvTRUE) { - if(force_contiguous_lowmem_shrink(Kernel) == 0) + int ret; + /* Acquire the mutex. */ + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->vidmemMutex, gcvINFINITE)); + + ret = force_contiguous_lowmem_shrink(Kernel); + + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex)); + + if(ret == 0) { /* Sleep 1 millisecond. */ gckOS_Delay(gcvNULL, 1); @@ -1186,7 +1192,7 @@ gckKERNEL_Dispatch( break; case gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY: - type = Interface->u.AllocateLinearVideoMemory.type; + type = Interface->u.AllocateLinearVideoMemory.type & 0xFF; /* Allocate memory. */ gcmkONERROR( @@ -1194,7 +1200,7 @@ gckKERNEL_Dispatch( &Interface->u.AllocateLinearVideoMemory.pool, Interface->u.AllocateLinearVideoMemory.bytes, Interface->u.AllocateLinearVideoMemory.alignment, - Interface->u.AllocateLinearVideoMemory.type, + type, &node)); if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) @@ -1260,14 +1266,6 @@ gckKERNEL_Dispatch( node->VidMem.logical = gcvNULL; } #endif - /* Free video memory. */ - gcmkONERROR( - gckVIDMEM_Free(Kernel, node)); - - gcmkONERROR( - gckKERNEL_RemoveProcessDB(Kernel, - processID, gcvDB_VIDEO_MEMORY, - node)); if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) { @@ -1291,6 +1289,15 @@ gckKERNEL_Dispatch( node)); } + /* Free video memory. */ + gcmkONERROR( + gckVIDMEM_Free(Kernel, node)); + + gcmkONERROR( + gckKERNEL_RemoveProcessDB(Kernel, + processID, gcvDB_VIDEO_MEMORY, + node)); + break; case gcvHAL_LOCK_VIDEO_MEMORY: diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c index 5af3355d15bd..ae12dffba3e6 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c @@ -3431,10 +3431,10 @@ gckVGCOMMAND_Commit( break; } - gcmkERR_BREAK(_FlushMMU(Command)); - do { + gcmkERR_BREAK(_FlushMMU(Command)); + /* Assign a context ID if not yet assigned. */ if (Context->id == 0) { diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c index 56bed68c6822..6a0f8e0e2856 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c @@ -1177,6 +1177,9 @@ gckKERNEL_DestroyProcessDB( /* Next next record. */ next = record->next; + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex)); + acquired = gcvFALSE; + /* Dispatch on record type. */ switch (record->type) { @@ -1347,6 +1350,10 @@ gckKERNEL_DestroyProcessDB( break; } + gcmkONERROR( + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE)); + acquired = gcvTRUE; + /* Delete the record. */ gcmkONERROR(gckKERNEL_DeleteRecord(Kernel, database, diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c index ae3211ee3b8f..c1f37172d069 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c @@ -305,6 +305,8 @@ gckKERNEL_AllocateLinearMemory( if (status == gcvSTATUS_OK) { + if(*Pool == gcvPOOL_SYSTEM) + Type |= gcvSURF_VG; /* Allocate memory. */ status = gckVIDMEM_AllocateLinear(Kernel, videoMemory, diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c index 7b83d57237a1..9d6aacbf022b 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c @@ -509,6 +509,10 @@ gckVIDMEM_Construct( node->VidMem.locked = 0; +#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG + node->VidMem.kernelVirtual = gcvNULL; +#endif + gcmkONERROR(gckOS_ZeroMemory(&node->VidMem.sharedInfo, gcmSIZEOF(gcsVIDMEM_NODE_SHARED_INFO))); #ifdef __QNXNTO__ @@ -971,10 +975,14 @@ gckVIDMEM_AllocateLinear( gctUINT32 alignment; gctINT bank, i; gctBOOL acquired = gcvFALSE; +#if gcdSMALL_BLOCK_SIZE + gctBOOL force_allocate = (Type == gcvSURF_TILE_STATUS) || (Type & gcvSURF_VG); +#endif - gcmkHEADER_ARG("Memory=0x%x Bytes=%lu Alignment=%u Type=%d", + gcmkHEADER_ARG("Memory=0x%x Bytes=%lu Alignment=%u Type=%d", Memory, Bytes, Alignment, Type); + Type &= ~gcvSURF_VG; /* Verify the arguments. */ gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM); gcmkVERIFY_ARGUMENT(Bytes > 0); @@ -996,7 +1004,7 @@ gckVIDMEM_AllocateLinear( #endif #if gcdSMALL_BLOCK_SIZE - if ((Memory->freeBytes < (Memory->bytes/gcdRATIO_FOR_SMALL_MEMORY)) + if ((!force_allocate) && (Memory->freeBytes < (Memory->bytes/gcdRATIO_FOR_SMALL_MEMORY)) && (Bytes >= gcdSMALL_BLOCK_SIZE) ) { @@ -2145,34 +2153,40 @@ gckVIDMEM_Unlock( /* No flush required. */ flush = (gceKERNEL_FLUSH) 0; } - - gcmkONERROR( - gckHARDWARE_Flush(hardware, flush, gcvNULL, &requested)); - - if (requested != 0) + if(hardware) { - /* Acquire the command queue. */ - gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE)); - commitEntered = gcvTRUE; + gcmkONERROR( + gckHARDWARE_Flush(hardware, flush, gcvNULL, &requested)); - gcmkONERROR(gckCOMMAND_Reserve( - command, requested, &buffer, &bufferSize - )); + if (requested != 0) + { + /* Acquire the command queue. */ + gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE)); + commitEntered = gcvTRUE; - gcmkONERROR(gckHARDWARE_Flush( - hardware, flush, buffer, &bufferSize - )); + gcmkONERROR(gckCOMMAND_Reserve( + command, requested, &buffer, &bufferSize + )); + + gcmkONERROR(gckHARDWARE_Flush( + hardware, flush, buffer, &bufferSize + )); - /* Mark node as pending. */ + /* Mark node as pending. */ #ifdef __QNXNTO__ - Node->Virtual.unlockPendings[Kernel->core] = gcvTRUE; + Node->Virtual.unlockPendings[Kernel->core] = gcvTRUE; #endif - gcmkONERROR(gckCOMMAND_Execute(command, requested)); + gcmkONERROR(gckCOMMAND_Execute(command, requested)); - /* Release the command queue. */ - gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE)); - commitEntered = gcvFALSE; + /* Release the command queue. */ + gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE)); + commitEntered = gcvFALSE; + } + } + else + { + gckOS_Print("Hardware already is freed.\n"); } } diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h index 71321d6ba164..6445a41e7810 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h @@ -1497,6 +1497,13 @@ gckOS_StopTimer( IN gctPOINTER Timer ); +/* Get the global video memory mutex. */ +gceSTATUS +gckOS_GetVideoMemoryMutex( + IN gckOS Os, + OUT gctPOINTER *Mutex + ); + /******************************************************************************\ ********************************* gckHEAP Object ******************************** \******************************************************************************/ diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h index 375a8f5b03d1..800d1bce6a2c 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h @@ -2127,6 +2127,15 @@ gcoSURF_SetAlignment( IN gctUINT Height ); +/* Set width/height alignment and stride of the surface directly. This is only for dri backend now. Please be careful before use. */ +gceSTATUS +gcoSURF_SetAlignmentEx( + IN gcoSURF Surface, + IN gctUINT Width, + IN gctUINT Height, + IN gctUINT Stride + ); + /* Increase reference count of the surface. */ gceSTATUS gcoSURF_ReferenceSurface( diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h index f8413700031a..2c744012e02a 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h @@ -455,6 +455,7 @@ typedef struct _gcsKERNEL_FUNCTION * gcKERNEL_FUNCTION; typedef struct _gcsHINT * gcsHINT_PTR; typedef struct _gcSHADER_PROFILER * gcSHADER_PROFILER; typedef struct _gcVARIABLE * gcVARIABLE; +typedef struct _gcSHADER_LIST * gcSHADER_LIST; struct _gcsHINT { @@ -523,6 +524,11 @@ struct _gcsHINT #if TEMP_SHADER_PATCH gctUINT32 pachedShaderIdentifier; #endif + +#if gcdUSE_WCLIP_PATCH + /* Strict WClip match. */ + gctBOOL strictWClipMatch; +#endif }; #if TEMP_SHADER_PATCH @@ -3230,6 +3236,12 @@ gcATTRIBUTE_IsEnabled( OUT gctBOOL * Enabled ); +gceSTATUS +gcATTRIBUTE_GetIndex( + IN gcATTRIBUTE Attribute, + OUT gctUINT16 * Index + ); + /******************************************************************************* ** gcUNIFORM_GetType ******************************************************************************** @@ -3392,6 +3404,12 @@ gcUNIFORM_GetSampler( OUT gctUINT32 * Sampler ); +gceSTATUS +gcUNIFORM_GetIndex( + IN gcUNIFORM Uniform, + OUT gctUINT16 * Index + ); + /******************************************************************************* ** gcUNIFORM_GetFormat ** @@ -4290,6 +4308,46 @@ gcSHADER_PatchZBiasForMachineCodeVS( IN OUT gcsHINT_PTR pHints /* User needs copy original hints to this one, then passed this one in */ ); +gceSTATUS +gcSHADER_InsertList( + IN gcSHADER Shader, + IN gcSHADER_LIST * Root, + IN gctINT Index, + IN gctINT Data0, + IN gctINT Data1 + ); + +gceSTATUS +gcSHADER_UpdateList( + IN gcSHADER Shader, + IN gcSHADER_LIST Root, + IN gctINT Index, + IN gctINT NewIndex + ); + +gceSTATUS +gcSHADER_DeleteList( + IN gcSHADER Shader, + IN gcSHADER_LIST * Root, + IN gctINT Index + ); + +gceSTATUS +gcSHADER_FindList( + IN gcSHADER Shader, + IN gcSHADER_LIST Root, + IN gctINT Index, + IN gcSHADER_LIST * List + ); + +gceSTATUS +gcSHADER_InsertWClipList( + IN gcSHADER Shader, + IN gctINT Index, + IN gctINT Data0, + IN gctINT Data1 + ); + #ifdef __cplusplus } #endif diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h index c4347e1e0bbc..7a62d3fec89c 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h @@ -55,18 +55,21 @@ typedef struct _DFBPixmap * HALNativePixmapType; #include "wayland-server.h" #include <wayland-egl.h> -#define WL_EGL_NUM_BACKBUFFERS 2 +#define WL_EGL_NUM_BACKBUFFERS 3 typedef struct _gcsWL_VIV_BUFFER { - struct wl_buffer wl_buffer; + struct wl_resource *wl_buffer; gcoSURF surface; + gctINT32 width, height; } gcsWL_VIV_BUFFER; typedef struct _gcsWL_EGL_DISPLAY { struct wl_display* wl_display; struct wl_viv* wl_viv; + struct wl_registry *registry; + struct wl_event_queue *wl_queue; } gcsWL_EGL_DISPLAY; typedef struct _gcsWL_EGL_BUFFER_INFO @@ -79,6 +82,9 @@ typedef struct _gcsWL_EGL_BUFFER_INFO gcePOOL pool; gctUINT bytes; gcoSURF surface; + gcoSURF attached_surface; + gctINT32 invalidate; + gctBOOL locked; } gcsWL_EGL_BUFFER_INFO; typedef struct _gcsWL_EGL_BUFFER @@ -89,19 +95,24 @@ typedef struct _gcsWL_EGL_BUFFER typedef struct _gcsWL_EGL_WINDOW_INFO { + gctINT32 dx; + gctINT32 dy; gctUINT width; gctUINT height; + gctINT32 attached_width; + gctINT32 attached_height; gceSURF_FORMAT format; gctUINT bpp; } gcsWL_EGL_WINDOW_INFO; struct wl_egl_window { + gcsWL_EGL_DISPLAY* display; gcsWL_EGL_BUFFER backbuffers[WL_EGL_NUM_BACKBUFFERS]; gcsWL_EGL_WINDOW_INFO info; gctUINT current; struct wl_surface* surface; - struct wl_callback* pending; + struct wl_callback* frame_callback; }; typedef void* HALNativeDisplayType; diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h index 522253779182..d8141e09ec74 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h @@ -224,6 +224,7 @@ typedef enum _gceSURF_TYPE gcvSURF_TILE_STATUS_DIRTY = 0x1000, /* Init tile status to all dirty */ gcvSURF_LINEAR = 0x2000, + gcvSURF_VG = 0x4000, gcvSURF_TEXTURE_LINEAR = gcvSURF_TEXTURE | gcvSURF_LINEAR, diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h index f79d3ef1392c..4c1dc3ef8119 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h @@ -726,7 +726,7 @@ Support swap with a specific rectangle. - Set the rectangle with eglSetSwapRectangleVIV api. + Set the rectangle with eglSetSwapRectangleANDROID api. */ #ifndef gcdSUPPORT_SWAP_RECTANGLE # define gcdSUPPORT_SWAP_RECTANGLE 0 diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h index b44652944c92..d33e8c280aa0 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h @@ -18,7 +18,6 @@ * *****************************************************************************/ - #ifndef __gc_hal_types_h_ #define __gc_hal_types_h_ @@ -1015,6 +1014,7 @@ typedef enum _gcePATCH_ID gcePATCH_RTESTVA, gcePATCH_BMX, gcePATCH_BMGUI, + gcePATCH_ANDROID_CTS_MEDIA_PRESENTATIONTIME, /* Game list */ gcePATCH_NBA2013, @@ -1048,7 +1048,16 @@ typedef enum _gcePATCH_ID gcePATCH_DUOKANTV, gcePATCH_TESTAPP, gcePATCH_GOOGLEEARTH, - + gcePATCH_SF4, + gcePATCH_SPEEDRACE, + gcePATCH_AIRNAVY, + gcePATCH_F18NEW, + gcePATCH_F18, + gcePATCH_WISTONESG, + gcvPATCH_VECUNIT_RED, + gcvPATCH_NAMESGAS, + gcvPATCH_AFTERBURNER, + gcvPATCH_UIMARK, /* Count enum*/ gcePATCH_COUNT, } 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 4c04efa308e3..b15399271f8d 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 @@ -214,6 +214,8 @@ struct _gckOS int gpu_clk_on[3]; struct mutex gpu_clk_mutex; + + gctPOINTER vidmemMutex; }; typedef struct _gcsSIGNAL * gcsSIGNAL_PTR; @@ -1116,6 +1118,8 @@ gckOS_Construct( mutex_init(&os->gpu_clk_mutex); + gcmkONERROR(gckOS_CreateMutex(os, &os->vidmemMutex)); + /* Return pointer to the gckOS object. */ *Os = os; @@ -1239,6 +1243,9 @@ gckOS_Destroy( /* Destroy debug lock mutex. */ gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->debugLock)); + /* Destroy video memory mutex. */ + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->vidmemMutex)); + /* Wait for all works done. */ flush_workqueue(Os->workqueue); @@ -2024,6 +2031,21 @@ gckOS_AllocateNonPagedMemory( &mdl->dmaHandle, GFP_KERNEL | gcdNOWARN); } +#if gcdUSE_NON_PAGED_MEMORY_CACHE + if(addr == gcvNULL) + { + MEMORY_UNLOCK(Os); + locked = gcvFALSE; + /*Free all cache and try again*/ + _FreeAllNonPagedMemoryCache(Os); + MEMORY_LOCK(Os); + locked = gcvTRUE; + addr = dma_alloc_coherent(gcvNULL, + mdl->numPages * PAGE_SIZE, + &mdl->dmaHandle, + GFP_KERNEL | gcdNOWARN); + } +#endif #else size = mdl->numPages * PAGE_SIZE; order = get_order(size); @@ -3992,6 +4014,9 @@ gckOS_AllocatePagedMemoryEx( gctSIZE_T bytes; gctBOOL locked = gcvFALSE; gceSTATUS status; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) + gctPOINTER addr = gcvNULL; +#endif gcmkHEADER_ARG("Os=0x%X Contiguous=%d Bytes=%lu", Os, Contiguous, Bytes); @@ -4022,14 +4047,27 @@ gckOS_AllocatePagedMemoryEx( gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) + addr = + alloc_pages_exact(numPages * PAGE_SIZE, GFP_KERNEL | gcdNOWARN | __GFP_NORETRY); + + mdl->u.contiguousPages = addr + ? virt_to_page(addr) + : gcvNULL; + + mdl->exact = gcvTRUE; +#else mdl->u.contiguousPages = alloc_pages(GFP_KERNEL | gcdNOWARN | __GFP_NORETRY, order); - +#endif if (mdl->u.contiguousPages == gcvNULL) { mdl->u.contiguousPages = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN, order); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) + mdl->exact = gcvFALSE; +#endif } } else @@ -4174,7 +4212,16 @@ gckOS_FreePagedMemory( if (mdl->contiguous) { - __free_pages(mdl->u.contiguousPages, GetOrder(mdl->numPages)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) + if (mdl->exact == gcvTRUE) + { + free_pages_exact(page_address(mdl->u.contiguousPages), mdl->numPages * PAGE_SIZE); + } + else +#endif + { + __free_pages(mdl->u.contiguousPages, GetOrder(mdl->numPages)); + } } else { @@ -6987,14 +7034,12 @@ gckOS_SetGPUPower( if((Power == gcvTRUE) && (oldPowerState == gcvFALSE)) { #if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - mutex_lock(&set_cpufreq_lock); if(!IS_ERR(Os->device->gpu_regulator)) { ret = regulator_enable(Os->device->gpu_regulator); if (ret != 0) gckOS_Print("%s(%d): fail to enable pu regulator %d!\n", __FUNCTION__, __LINE__, ret); } - mutex_unlock(&set_cpufreq_lock); #else imx_gpc_power_up_pu(true); #endif @@ -7122,7 +7167,6 @@ gckOS_SetGPUPower( #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - mutex_lock(&set_cpufreq_lock); if(!IS_ERR(Os->device->gpu_regulator)) regulator_disable(Os->device->gpu_regulator); #else @@ -8696,6 +8740,20 @@ gckOS_GetProcessNameByPid( return gcvSTATUS_OK; } +gceSTATUS +gckOS_GetVideoMemoryMutex( + IN gckOS Os, + OUT gctPOINTER *Mutex + ) +{ + gcmkHEADER_ARG("Mutex=x%X", Mutex); + + *Mutex = Os->vidmemMutex; + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} + #if gcdANDROID_NATIVE_FENCE_SYNC gceSTATUS 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 ad2dac0b540a..b22081740fdb 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 @@ -55,6 +55,9 @@ typedef struct _LINUX_MDL gctINT numPages; gctINT pagedMem; gctBOOL contiguous; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) + gctBOOL exact; +#endif dma_addr_t dmaHandle; PLINUX_MDL_MAP maps; struct _LINUX_MDL * prev; diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c new file mode 100644 index 000000000000..7efae1c74bbe --- /dev/null +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c @@ -0,0 +1,174 @@ +/**************************************************************************** +* +* Copyright (C) 2005 - 2013 by Vivante Corp. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the license, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but 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., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + + +#include <linux/kernel.h> +#include <linux/file.h> +#include <linux/fs.h> +#include <linux/miscdevice.h> +#include <linux/module.h> +#include <linux/syscalls.h> +#include <linux/uaccess.h> + +#include "gc_hal_kernel_sync.h" + +#if gcdANDROID_NATIVE_FENCE_SYNC + +static struct sync_pt * +viv_sync_pt_dup( + struct sync_pt * sync_pt + ) +{ + gceSTATUS status; + struct viv_sync_pt *pt; + struct viv_sync_pt *src; + struct viv_sync_timeline *obj; + + src = (struct viv_sync_pt *) sync_pt; + obj = (struct viv_sync_timeline *) sync_pt->parent; + + /* Create the new sync_pt. */ + pt = (struct viv_sync_pt *) + sync_pt_create(&obj->obj, sizeof(struct viv_sync_pt)); + + pt->stamp = src->stamp; + pt->sync = src->sync; + + /* Reference sync point. */ + status = gckOS_ReferenceSyncPoint(obj->os, pt->sync); + + if (gcmIS_ERROR(status)) + { + sync_pt_free((struct sync_pt *)pt); + return NULL; + } + + return (struct sync_pt *)pt; +} + +static int +viv_sync_pt_has_signaled( + struct sync_pt * sync_pt + ) +{ + gceSTATUS status; + gctBOOL state; + struct viv_sync_pt * pt; + struct viv_sync_timeline * obj; + + pt = (struct viv_sync_pt *)sync_pt; + obj = (struct viv_sync_timeline *)sync_pt->parent; + + status = gckOS_QuerySyncPoint(obj->os, pt->sync, &state); + + if (gcmIS_ERROR(status)) + { + /* Error. */ + return -1; + } + + return state; +} + +static int +viv_sync_pt_compare( + struct sync_pt * a, + struct sync_pt * b + ) +{ + int ret; + struct viv_sync_pt * pt1 = (struct viv_sync_pt *) a; + struct viv_sync_pt * pt2 = (struct viv_sync_pt *) b; + + ret = (pt1->stamp < pt2->stamp) ? -1 + : (pt1->stamp == pt2->stamp) ? 0 + : 1; + + return ret; +} + +static void +viv_sync_pt_free( + struct sync_pt * sync_pt + ) +{ + struct viv_sync_pt * pt; + struct viv_sync_timeline * obj; + + pt = (struct viv_sync_pt *) sync_pt; + obj = (struct viv_sync_timeline *) sync_pt->parent; + + gckOS_DestroySyncPoint(obj->os, pt->sync); +} + +static struct sync_timeline_ops viv_timeline_ops = +{ + .driver_name = "viv_sync", + .dup = viv_sync_pt_dup, + .has_signaled = viv_sync_pt_has_signaled, + .compare = viv_sync_pt_compare, + .free_pt = viv_sync_pt_free, +}; + +struct viv_sync_timeline * +viv_sync_timeline_create( + const char * name, + gckOS os + ) +{ + struct viv_sync_timeline * obj; + + obj = (struct viv_sync_timeline *) + sync_timeline_create(&viv_timeline_ops, sizeof(struct viv_sync_timeline), name); + + obj->os = os; + obj->stamp = 0; + + return obj; +} + +struct sync_pt * +viv_sync_pt_create( + struct viv_sync_timeline * obj, + gctSYNC_POINT SyncPoint + ) +{ + gceSTATUS status; + struct viv_sync_pt * pt; + + pt = (struct viv_sync_pt *) + sync_pt_create(&obj->obj, sizeof(struct viv_sync_pt)); + + pt->stamp = obj->stamp++; + pt->sync = SyncPoint; + + /* Dup signal. */ + status = gckOS_ReferenceSyncPoint(obj->os, SyncPoint); + + if (gcmIS_ERROR(status)) + { + sync_pt_free((struct sync_pt *)pt); + return NULL; + } + + return (struct sync_pt *) pt; +} + +#endif diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h new file mode 100644 index 000000000000..6fc12e5d0832 --- /dev/null +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h @@ -0,0 +1,71 @@ +/**************************************************************************** +* +* Copyright (C) 2005 - 2013 by Vivante Corp. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the license, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but 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., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + + +#ifndef __gc_hal_kernel_sync_h_ +#define __gc_hal_kernel_sync_h_ + +#include <linux/types.h> + +#include <linux/sync.h> + +#include <gc_hal.h> +#include <gc_hal_base.h> + +struct viv_sync_timeline +{ + /* Parent object. */ + struct sync_timeline obj; + + /* Timestamp when sync_pt is created. */ + gctUINT stamp; + + /* Pointer to os struct. */ + gckOS os; +}; + + +struct viv_sync_pt +{ + /* Parent object. */ + struct sync_pt pt; + + /* Reference sync point*/ + gctSYNC_POINT sync; + + /* Timestamp when sync_pt is created. */ + gctUINT stamp; +}; + +/* Create viv_sync_timeline object. */ +struct viv_sync_timeline * +viv_sync_timeline_create( + const char * Name, + gckOS Os + ); + +/* Create viv_sync_pt object. */ +struct sync_pt * +viv_sync_pt_create( + struct viv_sync_timeline * Obj, + gctSYNC_POINT SyncPoint + ); + +#endif /* __gc_hal_kernel_sync_h_ */ |