-Correct gc355 initial power state to poweroff.
-Separate clock gating operation in function gckOS_SetGPUPower().
-Turn on clock while suspend GPU cores.
-Remove clock switch in drv_open().
Signed-off-by: Loren Huang <b02279@freescale.com>
Acked-by: Lily Zhang
hardware->powerMutex = gcvNULL;
hardware->idleSemaphore = gcvNULL;
- hardware->chipPowerState = gcvPOWER_ON;
+ hardware->chipPowerState = gcvPOWER_OFF;
hardware->chipPowerStateGlobal = gcvPOWER_ON;
hardware->clockState = gcvTRUE;
hardware->powerState = gcvTRUE;
if (flag & (gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_CLOCK_ON))
{
/* Turn on the power. */
- gcmkONERROR(gckOS_SetGPUPower(os, gcvTRUE, gcvTRUE));
+ gcmkONERROR(gckOS_SetGPUPower(os, gcvCORE_VG , gcvTRUE, gcvTRUE));
/* Mark clock and power as enabled. */
Hardware->clockState = gcvTRUE;
/* Turn off the GPU power. */
gcmkONERROR(
gckOS_SetGPUPower(os,
+ gcvCORE_VG,
(flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
: gcvTRUE,
(flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
/* Enable the GPU. */
- gcmkONERROR(gckOS_SetGPUPower(Os, gcvTRUE, gcvTRUE));
+ gcmkONERROR(gckOS_SetGPUPower(Os, Core, gcvTRUE, gcvTRUE));
gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00000, 0));
status = _ResetGPU(Os, Core);
if (hardware != gcvNULL)
{
/* Turn off the power. */
- gcmkVERIFY_OK(gckOS_SetGPUPower(Os, gcvFALSE, gcvFALSE));
+ gcmkVERIFY_OK(gckOS_SetGPUPower(Os, hardware->core, gcvFALSE, gcvFALSE));
if (hardware->globalSemaphore != gcvNULL)
{
gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
/* Turn off the power. */
- gcmkVERIFY_OK(gckOS_SetGPUPower(Hardware->os, gcvFALSE, gcvFALSE));
+ gcmkVERIFY_OK(gckOS_SetGPUPower(Hardware->os, Hardware->core, gcvFALSE, gcvFALSE));
/* Destroy the power semaphore. */
gcmkVERIFY_OK(gckOS_DestroySemaphore(Hardware->os,
if (flag & (gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_CLOCK_ON))
{
/* Turn on the power. */
- gcmkONERROR(gckOS_SetGPUPower(os, gcvTRUE, gcvTRUE));
+ gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvTRUE, gcvTRUE));
/* Mark clock and power as enabled. */
Hardware->clockState = gcvTRUE;
/* Turn off the GPU power. */
gcmkONERROR(
gckOS_SetGPUPower(os,
+ Hardware->core,
(flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
: gcvTRUE,
(flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
** gckOS Os
** Pointer to a gckOS object.ß
**
+** gceCORE Core
+** Core type.
+**
** gctBOOL Clock
** gcvTRUE to turn on the clock, or gcvFALSE to turn off the clock.
**
gceSTATUS
gckOS_SetGPUPower(
IN gckOS Os,
+ IN gceCORE Core,
IN gctBOOL Clock,
IN gctBOOL Power
);
memset(device, 0, sizeof(struct _gckGALDEVICE));
+ /*Initialize the clock structure*/
+ if (IrqLine != -1) {
+ device->clk_3d_core = clk_get(NULL, "gpu3d_clk");
+ if (!IS_ERR(device->clk_3d_core)) {
+ device->clk_3d_shader = clk_get(NULL, "gpu3d_shader_clk");
+ if (IS_ERR(device->clk_3d_shader)) {
+ IrqLine = -1;
+ clk_put(device->clk_3d_core);
+ device->clk_3d_core = NULL;
+ device->clk_3d_shader = NULL;
+ gckOS_Print("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n");
+ }
+ } else {
+ IrqLine = -1;
+ device->clk_3d_core = NULL;
+ gckOS_Print("galcore: clk_get gpu3d_clk failed, disable 3d!\n");
+ }
+ }
+ if ((IrqLine2D != -1) || (IrqLineVG != -1)) {
+ device->clk_2d_core = clk_get(NULL, "gpu2d_clk");
+ if (IS_ERR(device->clk_2d_core)) {
+ IrqLine2D = -1;
+ IrqLineVG = -1;
+ device->clk_2d_core = NULL;
+ gckOS_Print("galcore: clk_get 2d clock failed, disable 2d/vg!\n");
+ }
+ }
+
if (IrqLine != -1)
{
device->requestedRegisterMemBases[gcvCORE_MAJOR] = RegisterMemBase;
}
}
+ /*Disable clock*/
+ if (Device->clk_3d_core) {
+ clk_disable(Device->clk_3d_core);
+ clk_put(Device->clk_3d_core);
+ Device->clk_3d_core = NULL;
+ }
+ if (Device->clk_3d_shader) {
+ clk_disable(Device->clk_3d_shader);
+ clk_put(Device->clk_3d_shader);
+ Device->clk_3d_shader = NULL;
+ }
+ if (Device->clk_2d_core) {
+ clk_disable(Device->clk_2d_core);
+ clk_put(Device->clk_2d_core);
+ Device->clk_2d_core = NULL;
+ }
+
/* Destroy the gckOS object. */
if (Device->os != gcvNULL)
{
/* Core mapping */
gceCORE coreMapping[8];
+ /* Clock management.*/
+ struct clk *clk_3d_core;
+ struct clk *clk_3d_shader;
+ struct clk *clk_2d_core;
+ gctBOOL clk_flag[gcdCORE_COUNT];
+
#if gcdPOWEROFF_TIMEOUT
struct task_struct *pmThreadCtxts;
gctBOOL pmThreadInitializeds;
module_param(coreClock, ulong, 0644);
#endif
-static struct clk * clk_3d_core;
-static struct clk * clk_3d_shader;
-static struct clk * clk_2d_core;
-
static int drv_open(
struct inode* inode,
struct file* filp
#if defined(CONFIG_PXA_DVFM) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
gc_pwr(1);
# endif
-# else
- if (irqLine != -1) {
- clk_3d_core = clk_get(NULL, "gpu3d_clk");
- if (!IS_ERR(clk_3d_core)) {
- clk_3d_shader = clk_get(NULL, "gpu3d_shader_clk");
- if (!IS_ERR(clk_3d_shader)) {
- clk_enable(clk_3d_core);
- clk_enable(clk_3d_shader);
- } else {
- irqLine = -1;
- clk_put(clk_3d_core);
- clk_3d_core = NULL;
- clk_3d_shader = NULL;
- printk(KERN_ERR "galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n");
- }
- } else {
- irqLine = -1;
- clk_3d_core = NULL;
- printk(KERN_ERR "galcore: clk_get gpu3d_clk failed, disable 3d!\n");
- }
- }
- if ((irqLine2D != -1) || (irqLineVG != -1)) {
- clk_2d_core = clk_get(NULL, "gpu2d_clk");
- if (IS_ERR(clk_2d_core)) {
- irqLine2D = -1;
- irqLineVG = -1;
- clk_2d_core = NULL;
- printk(KERN_ERR "galcore: clk_get 2d clock failed, disable 2d/vg!\n");
- } else {
- clk_enable(clk_2d_core);
- }
- }
# endif
}
#endif
#endif
clk = clk_get(NULL, "GCCLK");
clk_disable(clk);
-# else
- if (clk_3d_core) {
- clk_disable(clk_3d_core);
- clk_put(clk_3d_core);
- clk_3d_core = NULL;
- }
- if (clk_3d_shader) {
- clk_disable(clk_3d_shader);
- clk_put(clk_3d_shader);
- clk_3d_shader = NULL;
- }
- if (clk_2d_core) {
- clk_disable(clk_2d_core);
- clk_put(clk_2d_core);
- clk_2d_core = NULL;
- }
# endif
}
#endif
{
status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_OFF);
}
-
+ /*gpu clock must be turned on before power down*/
+ gckOS_SetGPUPower(device->os, i, gcvTRUE, gcvFALSE);
if (gcmIS_ERROR(status))
{
return -1;
** gckOS Os
** Pointer to a gckOS object.
**
+** gceCORE Core
+** Core type.
+**
** gctBOOL Clock
** gcvTRUE to turn on the clock, or gcvFALSE to turn off the clock.
**
gceSTATUS
gckOS_SetGPUPower(
IN gckOS Os,
+ IN gceCORE Core,
IN gctBOOL Clock,
IN gctBOOL Power
)
{
- gcmkHEADER_ARG("Os=0x%X Clock=%d Power=%d", Os, Clock, Power);
-
+ struct clk *clk_3dcore = Os->device->clk_3d_core;
+ struct clk *clk_3dshader = Os->device->clk_3d_shader;
+ struct clk *clk_2dcore = Os->device->clk_2d_core;
+
+ gcmkHEADER_ARG("Os=0x%X Core=%d Clock=%d Power=%d", Os, Core, Clock, Power);
+ if (Clock == gcvTRUE) {
+ switch (Core) {
+ case gcvCORE_MAJOR:
+ if (!Os->device->clk_flag[gcvCORE_MAJOR]) {
+ clk_enable(clk_3dcore);
+ clk_enable(clk_3dshader);
+ }
+ Os->device->clk_flag[gcvCORE_MAJOR] = gcvTRUE;
+ break;
+ case gcvCORE_2D:
+ if (!(Os->device->clk_flag[gcvCORE_2D] || Os->device->clk_flag[gcvCORE_VG])) {
+ clk_enable(clk_2dcore);
+ }
+ Os->device->clk_flag[gcvCORE_2D] = gcvTRUE;
+ break;
+ case gcvCORE_VG:
+ if (!(Os->device->clk_flag[gcvCORE_2D] || Os->device->clk_flag[gcvCORE_VG])) {
+ clk_enable(clk_2dcore);
+ }
+ Os->device->clk_flag[gcvCORE_VG] = gcvTRUE;
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (Core) {
+ case gcvCORE_MAJOR:
+ if (Os->device->clk_flag[gcvCORE_MAJOR]) {
+ clk_disable(clk_3dshader);
+ clk_disable(clk_3dcore);
+ }
+ Os->device->clk_flag[gcvCORE_MAJOR] = gcvFALSE;
+ break;
+ case gcvCORE_2D:
+ if (Os->device->clk_flag[gcvCORE_2D] && (!Os->device->clk_flag[gcvCORE_VG])) {
+ clk_disable(clk_2dcore);
+ }
+ Os->device->clk_flag[gcvCORE_2D] = gcvFALSE;
+ break;
+ case gcvCORE_VG:
+ if ((!Os->device->clk_flag[gcvCORE_2D]) && Os->device->clk_flag[gcvCORE_VG]) {
+ clk_disable(clk_2dcore);
+ }
+ Os->device->clk_flag[gcvCORE_VG] = gcvFALSE;
+ break;
+ default:
+ break;
+ }
+ }
/* TODO: Put your code here. */
gcmkFOOTER_NO();