From b25fc8f5f69e4ae457f1679c01eb9d45eaa1dd04 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E6=9D=9C=E5=9D=A4=E6=98=8E?= Date: Thu, 15 Dec 2011 10:57:09 +0800 Subject: [PATCH] gpu : repair gckVIDMEM_Unlock's event problem; add gcvFLUSH_2D at gckVIDMEM_Unlock to avoid gpu hang. --- .../XAQ2/hal/kernel/gc_hal_kernel_hardware.c | 5 +- .../hal/kernel/gc_hal_kernel_video_memory.c | 154 +++++++++--------- .../os/linux/kernel/gc_hal_kernel_driver.c | 12 +- 3 files changed, 89 insertions(+), 82 deletions(-) diff --git a/drivers/staging/rk29/vivante/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/drivers/staging/rk29/vivante/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c index 552ab0893a9b..08540815e6f4 100755 --- a/drivers/staging/rk29/vivante/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c +++ b/drivers/staging/rk29/vivante/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c @@ -26,8 +26,7 @@ #define _GC_OBJ_ZONE gcvZONE_HARDWARE -static uint gpu_state = 0; -module_param(gpu_state, uint, 0644); +extern uint gpuState; // dkm: gcdENABLE_AUTO_FREQ #if (1==gcdENABLE_AUTO_FREQ) @@ -3370,7 +3369,7 @@ gckHARDWARE_SetPowerManagementState( /* Release the power mutex. */ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex)); - gpu_state = State; + gpuState = State; /* Success. */ gcmkFOOTER_NO(); diff --git a/drivers/staging/rk29/vivante/hal/kernel/gc_hal_kernel_video_memory.c b/drivers/staging/rk29/vivante/hal/kernel/gc_hal_kernel_video_memory.c index 927a57bd4e1c..2b0617a41a46 100755 --- a/drivers/staging/rk29/vivante/hal/kernel/gc_hal_kernel_video_memory.c +++ b/drivers/staging/rk29/vivante/hal/kernel/gc_hal_kernel_video_memory.c @@ -822,7 +822,7 @@ gckVIDMEM_AllocateLinear( acquired = gcvTRUE; -#if 1 +#if 0 // dkm: ¶ÔÓÚ»¨ÆÁËÀ»úµÄÎÊÌ⣬¸Ð¾õVVÕâô×öÖ»Êǹæ±Ü£¬»¹ÊÇûÓÐÕÒµ½ÎÊÌâµÄÔ­Òò if (Type == gcvSURF_TILE_STATUS && (Bytes + (1 << 20) > Memory->freeBytes)) @@ -1519,7 +1519,6 @@ gckVIDMEM_Unlock( gckOS os = gcvNULL; gctBOOL acquired = gcvFALSE; gctBOOL needRelease = gcvFALSE; - gctBOOL pendingUnlock = gcvFALSE; gcmkHEADER_ARG("Node=0x%x Type=%d *Asynchroneous=%d", Node, Type, gcmOPT_VALUE(Asynchroneous)); @@ -1569,6 +1568,18 @@ gckVIDMEM_Unlock( command = Node->Virtual.kernel->command; gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND); + + /* Get the gckOS object pointer. */ + os = kernel->os; + gcmkVERIFY_OBJECT(os, gcvOBJ_OS); + + /* Grab the mutex. */ + gcmkONERROR( + gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE)); + + acquired = gcvTRUE; + + if (Asynchroneous == gcvNULL) { gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, @@ -1576,14 +1587,60 @@ gckVIDMEM_Unlock( Node, Node->Virtual.locked); - /* Get the gckOS object pointer. */ - os = kernel->os; - gcmkVERIFY_OBJECT(os, gcvOBJ_OS); + if (Node->Virtual.locked == 0) + { + status = gcvSTATUS_MEMORY_UNLOCKED; + goto OnError; + } - /* Grab the mutex. */ - gcmkONERROR( - gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE)); + /* Decrement lock count. */ + -- Node->Virtual.locked; + /* See if we can unlock the resources. */ + if (Node->Virtual.locked == 0) + { + /* Unlock the pages. */ +#ifdef __QNXNTO__ + gcmkONERROR( + gckOS_UnlockPages(os, + Node->Virtual.physical, + Node->Virtual.userPID, + Node->Virtual.bytes, + Node->Virtual.logical)); +#else + gcmkONERROR( + gckOS_UnlockPages(os, + Node->Virtual.physical, + Node->Virtual.bytes, + Node->Virtual.logical)); +#endif + + /* Free the page table. */ + if (Node->Virtual.pageTable != gcvNULL) + { + gcmkONERROR( + gckMMU_FreePages(Node->Virtual.kernel->mmu, + Node->Virtual.pageTable, + Node->Virtual.pageCount)); + + /* Mark page table as freed. */ + Node->Virtual.pageTable = gcvNULL; + } + + /* Mark node as unlocked. */ +#ifdef __QNXTO + Node->Virtual.unlockPending = gcvFALSE; +#else + Node->Virtual.pending = gcvFALSE; +#endif + } + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, + "Unmapped virtual node 0x%x from 0x%08X", + Node, Node->Virtual.address); + } + else + { /* If we need to unlock a node from virtual memory we have to be ** very carefull. If the node is still inside the caches we ** might get a bus error later if the cache line needs to be @@ -1619,12 +1676,18 @@ gckVIDMEM_Unlock( /* Flush depth cache. */ flush = gcvFLUSH_DEPTH; } + else if (Type == gcvSURF_TEXTURE) // dkm : add + { + flush = gcvFLUSH_TEXTURE; + } else { /* No flush required. */ flush = (gceKERNEL_FLUSH) 0; } + flush = flush | gcvFLUSH_2D; // dkm : add to avoid the gpu hang + gcmkONERROR( gckHARDWARE_Flush(hardware, flush, gcvNULL, &requested)); @@ -1643,12 +1706,6 @@ gckVIDMEM_Unlock( buffer, &bufferSize)); - gcmkONERROR( - gckEVENT_Unlock(Node->Virtual.kernel->event, - gcvKERNEL_PIXEL, - Node, - Type)); - /* Mark node as pending. */ #ifdef __QNXNTO__ Node->Virtual.unlockPending = gcvTRUE; @@ -1656,75 +1713,12 @@ gckVIDMEM_Unlock( Node->Virtual.pending = gcvTRUE; #endif - needRelease = gcvFALSE; - gcmkONERROR(gckCOMMAND_Execute(command, requested)); - pendingUnlock = gcvTRUE; - } - } - - if (!pendingUnlock) - { - if (Node->Virtual.locked == 0) - { - status = gcvSTATUS_MEMORY_UNLOCKED; - goto OnError; - } - - /* Decrement lock count. */ - -- Node->Virtual.locked; - - /* See if we can unlock the resources. */ - if (Node->Virtual.locked == 0) - { - /* Unlock the pages. */ -#ifdef __QNXNTO__ - gcmkONERROR( - gckOS_UnlockPages(os, - Node->Virtual.physical, - Node->Virtual.userPID, - Node->Virtual.bytes, - Node->Virtual.logical)); -#else - gcmkONERROR( - gckOS_UnlockPages(os, - Node->Virtual.physical, - Node->Virtual.bytes, - Node->Virtual.logical)); -#endif - - /* Free the page table. */ - if (Node->Virtual.pageTable != gcvNULL) - { - gcmkONERROR( - gckMMU_FreePages(Node->Virtual.kernel->mmu, - Node->Virtual.pageTable, - Node->Virtual.pageCount)); - - /* Mark page table as freed. */ - Node->Virtual.pageTable = gcvNULL; - } - - /* Mark node as unlocked. */ -#ifdef __QNXTO - Node->Virtual.unlockPending = gcvFALSE; -#else - Node->Virtual.pending = gcvFALSE; -#endif + needRelease = gcvFALSE; } - - gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, - "Unmapped virtual node 0x%x from 0x%08X", - Node, Node->Virtual.address); } - /* Release the mutex. */ - gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex)); - } - - else - { gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, "Scheduled unlock for virtual node 0x%x", Node); @@ -1732,6 +1726,10 @@ gckVIDMEM_Unlock( /* Schedule the surface to be unlocked. */ *Asynchroneous = gcvTRUE; } + + /* Release the mutex. */ + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex)); + acquired = gcvFALSE; } /* Success. */ diff --git a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c index 240340c2b8fc..cdcdcd712640 100755 --- a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c +++ b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c @@ -94,7 +94,8 @@ module_param(coreClock, ulong, 0644); uint gpu_dmask = D_ERROR; module_param(gpu_dmask, uint, 0644); -unsigned int regAddress = 0; +uint gpuState = 0; +uint regAddress = 0; // gcdkREPORT_VIDMEM_USAGE add by vv #if gcdkREPORT_VIDMEM_USAGE @@ -1413,6 +1414,15 @@ struct RegDefine reg_def[] = static int proc_gpu_show(struct seq_file *s, void *v) { int i = 0; + + switch(gpuState) { + case gcvPOWER_ON: seq_printf(s, "gpu state: POWER_ON\n"); break; + case gcvPOWER_OFF: seq_printf(s, "gpu state: POWER_OFF\n"); break; + case gcvPOWER_IDLE: seq_printf(s, "gpu state: POWER_IDLE\n"); break; + case gcvPOWER_SUSPEND: seq_printf(s, "gpu state: POWER_SUSPEND\n"); break; + default: seq_printf(s, "gpu state: %d\n", gpuState); break; + } + seq_printf(s, "gpu regs:\n"); for(i=0; i