diff options
author | Liu Ying <Ying.Liu@freescale.com> | 2012-02-27 15:14:53 +0800 |
---|---|---|
committer | Liu Ying <Ying.Liu@freescale.com> | 2012-02-27 16:30:35 +0800 |
commit | efa2d1e00b84a7395389483c9283c0e1ffbb4818 (patch) | |
tree | bf7182288ab82df171952d9276234c5f7ea202c8 | |
parent | f027d501ddce904c9d06152defe70728e84b3861 (diff) |
ENGR00175459 VIV GPU:Support 2D core clock gating
This patch supports Vivante 2D GPU core clock
gating feature.
Signed-off-by: Liu Ying <Ying.Liu@freescale.com>
Acked-by: Lily Zhang <r58066@freescale.com>
-rw-r--r-- | drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c | 80 | ||||
-rw-r--r-- | drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h | 4 |
2 files changed, 60 insertions, 24 deletions
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c index 8b25b9fdc533..314f27a9724a 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c @@ -262,45 +262,59 @@ static int threadRoutineVG(void *ctxt) /* ** PM Thread Routine **/ -static int threadRoutinePM(void *ctxt) +static int _threadRoutinePM(gckGALDEVICE Device, gckHARDWARE Hardware) { - gckGALDEVICE device = (gckGALDEVICE) ctxt; - gckHARDWARE hardware = device->kernels[gcvCORE_MAJOR]->hardware; gceCHIPPOWERSTATE state; for(;;) { /* wait for idle */ gcmkVERIFY_OK( - gckOS_WaitSignal(device->os, hardware->powerOffSignal, gcvINFINITE)); + gckOS_WaitSignal(Device->os, Hardware->powerOffSignal, gcvINFINITE)); /* We try to power off every 200 ms, until GPU is not idle */ do { - if (device->killThread == gcvTRUE) + if (Device->killThread == gcvTRUE) { /* The daemon exits. */ while (!kthread_should_stop()) { - gckOS_Delay(device->os, 1); + gckOS_Delay(Device->os, 1); } return 0; } gcmkVERIFY_OK( gckHARDWARE_SetPowerManagementState( - hardware, + Hardware, gcvPOWER_OFF_TIMEOUT)); /* relax cpu 200 ms before retry */ - gckOS_Delay(device->os, 200); + gckOS_Delay(Device->os, 200); gcmkVERIFY_OK( - gckHARDWARE_QueryPowerManagementState(hardware, &state)); + gckHARDWARE_QueryPowerManagementState(Hardware, &state)); } while (state == gcvPOWER_IDLE); } } + +static int threadRoutinePM(void *ctxt) +{ + gckGALDEVICE device = (gckGALDEVICE) ctxt; + gckHARDWARE hardware = device->kernels[gcvCORE_MAJOR]->hardware; + + return _threadRoutinePM(device, hardware); +} + +static int threadRoutinePM_2D(void *ctxt) +{ + gckGALDEVICE device = (gckGALDEVICE) ctxt; + gckHARDWARE hardware = device->kernels[gcvCORE_2D]->hardware; + + return _threadRoutinePM(device, hardware); +} #endif /******************************************************************************\ @@ -1375,8 +1389,8 @@ gckGALDEVICE_Start_Threads( gcmkONERROR(gcvSTATUS_GENERIC_IO); } - Device->pmThreadCtxts = task; - Device->pmThreadInitializeds = gcvTRUE; + Device->pmThreadCtxts[gcvCORE_MAJOR] = task; + Device->pmThreadInitializeds[gcvCORE_MAJOR] = gcvTRUE; #endif } @@ -1398,10 +1412,32 @@ gckGALDEVICE_Start_Threads( Device->threadCtxts[gcvCORE_2D] = task; Device->threadInitializeds[gcvCORE_2D] = gcvTRUE; + +#if gcdPOWEROFF_TIMEOUT + /* Start the kernel thread. */ + task = kthread_run(threadRoutinePM_2D, Device, "galcore pm thread"); + + if (IS_ERR(task)) + { + gcmkTRACE_ZONE( + gcvLEVEL_ERROR, gcvZONE_DRIVER, + "%s(%d): Could not start the kernel thread.\n", + __FUNCTION__, __LINE__ + ); + + gcmkONERROR(gcvSTATUS_GENERIC_IO); + } + + Device->pmThreadCtxts[gcvCORE_2D] = task; + Device->pmThreadInitializeds[gcvCORE_2D] = gcvTRUE; +#endif } else { Device->threadInitializeds[gcvCORE_2D] = gcvFALSE; +#if gcdPOWEROFF_TIMEOUT + Device->pmThreadInitializeds[gcvCORE_2D] = gcvFALSE; +#endif } if (Device->kernels[gcvCORE_VG] != gcvNULL) @@ -1479,21 +1515,21 @@ gckGALDEVICE_Stop_Threads( Device->threadCtxts[i] = gcvNULL; Device->threadInitializeds[i] = gcvFALSE; } - } #if gcdPOWEROFF_TIMEOUT - /* Stop the kernel threads. */ - if (Device->pmThreadInitializeds) - { - gckHARDWARE hardware = Device->kernels[gcvCORE_MAJOR]->hardware; - Device->killThread = gcvTRUE; - gckOS_Signal(Device->os, hardware->powerOffSignal, gcvTRUE); + /* Stop the kernel threads. */ + if (Device->pmThreadInitializeds[i]) + { + gckHARDWARE hardware = Device->kernels[i]->hardware; + Device->killThread = gcvTRUE; + gckOS_Signal(Device->os, hardware->powerOffSignal, gcvTRUE); - kthread_stop(Device->pmThreadCtxts); - Device->pmThreadCtxts = gcvNULL; - Device->pmThreadInitializeds = gcvFALSE; - } + kthread_stop(Device->pmThreadCtxts[i]); + Device->pmThreadCtxts[i] = gcvNULL; + Device->pmThreadInitializeds[i] = gcvFALSE; + } #endif + } gcmkFOOTER_NO(); return gcvSTATUS_OK; diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h index 86333ba34732..563bf673bf5c 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h @@ -89,8 +89,8 @@ typedef struct _gckGALDEVICE gctBOOL clk_flag[gcdCORE_COUNT]; #if gcdPOWEROFF_TIMEOUT - struct task_struct *pmThreadCtxts; - gctBOOL pmThreadInitializeds; + struct task_struct *pmThreadCtxts[gcdCORE_COUNT]; + gctBOOL pmThreadInitializeds[gcdCORE_COUNT]; #endif } * gckGALDEVICE; |