summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c37
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