diff options
author | Shawn Xiao <b49994@freescale.com> | 2015-05-14 20:13:13 +0800 |
---|---|---|
committer | Prabhu Sundararaj <prabhu.sundararaj@freescale.com> | 2015-05-15 11:18:16 -0500 |
commit | a49e3c68582c8b19b02ef42d48d18116628fc072 (patch) | |
tree | c418bc754bc083815bb189952344e0dd8ca48683 /drivers/mxc/gpu-viv | |
parent | 6edd31c921efb7d77c29ec3bb6911c39537d9c8e (diff) |
MGS-722 [#ccc] Dump kernel command, event queue and DB status when GPU hang
To make it easy to debug GPU hang issue in 4.x driver, add the function
to dump kernel command buffer, event queue and DB status when GPU hang.
This logic only work when GPU hang, and have no side effect when GPU
run
well.
Date May 6, 2015
Signed-off-by: Shawn Xiao <b49994@freescale.com>
Diffstat (limited to 'drivers/mxc/gpu-viv')
5 files changed, 60 insertions, 4 deletions
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 ea69d81d5e67..31da41598527 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c @@ -228,6 +228,10 @@ gckKERNEL_Construct( gckOS_CreateMutex(Os, (gctPOINTER)&kernel->virtualBufferLock)); #endif + /* Contrust GPU status Dump mutex */ + gcmkONERROR( + gckOS_CreateMutex(Os, (gctPOINTER)&kernel->dumpMutex)); + /* Construct atom holding number of clients. */ kernel->atomClients = gcvNULL; gcmkONERROR(gckOS_AtomConstruct(Os, &kernel->atomClients)); @@ -374,6 +378,12 @@ OnError: } #endif + if (kernel->dumpMutex != gcvNULL) + { + /* Destroy the GPU Status Dump mutex. */ + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, kernel->dumpMutex)); + } + #if gcdDVFS if (kernel->dvfs) { @@ -511,6 +521,8 @@ gckKERNEL_Destroy( gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->virtualBufferLock)); #endif + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->dumpMutex)); + #if gcdDVFS if (Kernel->dvfs) { diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h index 769479843436..1f534a0c7c10 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h @@ -455,6 +455,9 @@ struct _gckKERNEL #endif gctPOINTER vidmemMutex; + + /* GPU Status Dump mutex. */ + gctPOINTER dumpMutex; }; struct _FrequencyHistory diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c index 7c2d6a395288..fa3d839542a9 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c @@ -346,7 +346,6 @@ OnError: return status; } -#if gcdVIRTUAL_COMMAND_BUFFER static void _DumpBuffer( IN gctPOINTER Buffer, @@ -424,7 +423,6 @@ _DumpKernelCommandBuffer( _DumpBuffer(entry, physical, Command->pageSize); } } -#endif /******************************************************************************\ ****************************** gckCOMMAND API Code ****************************** @@ -3049,4 +3047,44 @@ OnError: return gcvSTATUS_OK; #endif } +#else +gceSTATUS +gckCOMMAND_DumpExecutingBuffer( + IN gckCOMMAND Command + ) +{ + gctUINT32 gpuAddress; + gctSIZE_T bytes; + gctPOINTER entry; + gckOS os = Command->os; + gckKERNEL kernel = Command->kernel; + gctPOINTER entryDump; + + gcmkPRINT("**************************\n"); + gcmkPRINT("**** KERNEL COMMAND BUF DUMP ****\n"); + gcmkPRINT("**************************\n"); + + _DumpKernelCommandBuffer(Command); + + gcmkPRINT("**************************\n"); + gcmkPRINT("**** COMMAND BUF DUMP(Current DMA Address) ****\n"); + gcmkPRINT("**************************\n"); + + gcmkVERIFY_OK(gckOS_ReadRegisterEx(os, kernel->core, 0x664, &gpuAddress)); + gcmkPRINT("DMA Address 0x%08X", gpuAddress); + + /* Without link queue information, we don't know the entry of last command + * ** buffer, just dump the page where GPU stuck. */ + + gcmkVERIFY_OK(gckOS_MapPhysical(os, gpuAddress, 4096, &entry)); + /* Align to page start. */ + entryDump = (gctPOINTER)((gctUINTPTR_T)entry & ~0xFFF); + gpuAddress = gpuAddress & ~0xFFF; + bytes = 4096; + gcmkPRINT("User Command Buffer:\n"); + _DumpBuffer(entryDump, gpuAddress, bytes); + gcmkVERIFY_OK(gckOS_UnmapPhysical(os, entry, 4096)); + + return gcvSTATUS_OK; +} #endif 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 6445a41e7810..ec770ad69f24 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h @@ -2528,12 +2528,10 @@ gckCOMMAND_Detach( IN gckCONTEXT Context ); -#if gcdVIRTUAL_COMMAND_BUFFER gceSTATUS gckCOMMAND_DumpExecutingBuffer( IN gckCOMMAND Command ); -#endif /******************************************************************************\ ********************************* gckMMU Object ******************************** 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 b15399271f8d..418b8417122f 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 @@ -6577,7 +6577,12 @@ gckOS_Broadcast( case gcvBROADCAST_GPU_STUCK: gcmkTRACE_N(gcvLEVEL_ERROR, 0, "gcvBROADCAST_GPU_STUCK\n"); #if !gcdENABLE_RECOVERY + gcmkVERIFY_OK(gckOS_AcquireMutex(Hardware->kernel->os, Hardware->kernel->dumpMutex, gcvINFINITE)); gcmkONERROR(gckHARDWARE_DumpGPUState(Hardware)); + gcmkONERROR(gckCOMMAND_DumpExecutingBuffer(Hardware->kernel->command)); + gcmkONERROR(gckEVENT_Dump(Hardware->kernel->eventObj)); + gcmkONERROR(gckKERNEL_DumpProcessDB(Hardware->kernel)); + gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->kernel->os, Hardware->kernel->dumpMutex)); #endif gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel)); break; |