diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c | 37 |
1 files changed, 37 insertions, 0 deletions
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 45c42a4908ea..79ca3e3b17ff 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 @@ -211,6 +211,9 @@ struct _gckOS /* workqueue for os timer. */ struct workqueue_struct * workqueue; + + int gpu_clk_on[3]; + struct mutex gpu_clk_mutex; }; typedef struct _gcsSIGNAL * gcsSIGNAL_PTR; @@ -1111,6 +1114,8 @@ gckOS_Construct( gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); } + mutex_init(&os->gpu_clk_mutex); + /* Return pointer to the gckOS object. */ *Os = os; @@ -2425,7 +2430,17 @@ gckOS_ReadRegisterEx( gcmkVERIFY_ARGUMENT(Address < Os->device->requestedRegisterMemSizes[Core]); gcmkVERIFY_ARGUMENT(Data != gcvNULL); + if(Address != 0x10) mutex_lock(&Os->gpu_clk_mutex); + BUG_ON(!Os->gpu_clk_on[Core]); + + if(Address) + { + gctUINT32 AQHiClockControl = readl((gctUINT8 *)Os->device->registerBases[Core]); + BUG_ON((AQHiClockControl & 0x3) == 0x3); + } + *Data = readl((gctUINT8 *)Os->device->registerBases[Core] + Address); + if(Address != 0x10) mutex_unlock(&Os->gpu_clk_mutex); /* Success. */ gcmkFOOTER_ARG("*Data=0x%08x", *Data); @@ -2475,7 +2490,17 @@ gckOS_WriteRegisterEx( gcmkVERIFY_ARGUMENT(Address < Os->device->requestedRegisterMemSizes[Core]); + mutex_lock(&Os->gpu_clk_mutex); + BUG_ON(!Os->gpu_clk_on[Core]); + + if(Address) + { + gctUINT32 AQHiClockControl = readl((gctUINT8 *)Os->device->registerBases[Core]); + BUG_ON((AQHiClockControl & 0x3) == 0x3); + } + writel(Data, (gctUINT8 *)Os->device->registerBases[Core] + Address); + mutex_unlock(&Os->gpu_clk_mutex); /* Success. */ gcmkFOOTER_NO(); @@ -7020,6 +7045,7 @@ gckOS_SetGPUPower( #if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) if (Clock == gcvTRUE) { if (oldClockState == gcvFALSE) { + mutex_lock(&Os->gpu_clk_mutex); switch (Core) { case gcvCORE_MAJOR: clk_enable(clk_3dcore); @@ -7037,9 +7063,12 @@ gckOS_SetGPUPower( default: break; } + Os->gpu_clk_on[Core] = 1; + mutex_unlock(&Os->gpu_clk_mutex); } } else { if (oldClockState == gcvTRUE) { + mutex_lock(&Os->gpu_clk_mutex); switch (Core) { case gcvCORE_MAJOR: if (cpu_is_mx6q()) @@ -7057,11 +7086,14 @@ gckOS_SetGPUPower( default: break; } + Os->gpu_clk_on[Core] = 0; + mutex_unlock(&Os->gpu_clk_mutex); } } #else if (Clock == gcvTRUE) { if (oldClockState == gcvFALSE) { + mutex_lock(&Os->gpu_clk_mutex); switch (Core) { case gcvCORE_MAJOR: clk_prepare(clk_3dcore); @@ -7086,9 +7118,12 @@ gckOS_SetGPUPower( default: break; } + Os->gpu_clk_on[Core] = 1; + mutex_unlock(&Os->gpu_clk_mutex); } } else { if (oldClockState == gcvTRUE) { + mutex_lock(&Os->gpu_clk_mutex); switch (Core) { case gcvCORE_MAJOR: clk_disable(clk_3dshader); @@ -7113,6 +7148,8 @@ gckOS_SetGPUPower( default: break; } + Os->gpu_clk_on[Core] = 0; + mutex_unlock(&Os->gpu_clk_mutex); } } #endif |