summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Xiao <b49994@freescale.com>2015-05-14 19:59:51 +0800
committerPrabhu Sundararaj <prabhu.sundararaj@freescale.com>2015-05-15 11:18:15 -0500
commit4b1f045aece41a599d212136f523a011b130cf08 (patch)
treeaba3e8c5959b0cb4190aefabe20bf9630a2c0346
parente96509c59cd50831b649f2c293d11db85f098073 (diff)
MGS-213 [#1469] detect VG state in power management
this patch is provided by Vivante to enhance VG power up. comparing to 2D/3D power management, there is no state detection in VG power up, that will cause that VG core hang due to the abnormal GPU power up. Date: Dec 01, 2014 Signed-off-by: Xianzhong <b07117@freescale.com>
-rw-r--r--drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c98
1 files changed, 96 insertions, 2 deletions
diff --git a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c
index a17d2fdb7747..6d1f44a5ebaa 100644
--- a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c
+++ b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c
@@ -338,7 +338,6 @@ gckVGHARDWARE_Construct(
gcmkVERIFY_OK(gckVGHARDWARE_SetFastClear(hardware, -1));
gcmkERR_BREAK(gckOS_CreateMutex(Os, &hardware->powerMutex));
-
/* Enable power management by default. */
hardware->powerManagement = gcvTRUE;
@@ -1447,6 +1446,64 @@ static gceSTATUS _CommandStall(
return status;
}
+static gceSTATUS
+_IsGPUPresent(
+ IN gckVGHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gceCHIPMODEL chipModel;
+ gctUINT32 chipRev, chipFeatures, chipMinorFeatures, chipMinorFeatures2;
+ /*gcsHAL_QUERY_CHIP_IDENTITY identity;*/
+ gctUINT32 control;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ gcvCORE_VG,
+ 0x00000,
+ &control));
+
+ control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ gcvCORE_VG,
+ 0x00000,
+ control));
+
+ /* Identify the hardware. */
+ gcmkONERROR(_IdentifyHardware(Hardware->os,
+ &chipModel, &chipRev,
+ &chipFeatures,
+ &chipMinorFeatures,
+ &chipMinorFeatures2
+ ));
+ /* Check if these are the same values as saved before. */
+ if ((Hardware->chipModel != chipModel)
+ || (Hardware->chipRevision != chipRev)
+ || (Hardware->chipFeatures != chipFeatures)
+ || (Hardware->chipMinorFeatures != chipMinorFeatures)
+ || (Hardware->chipMinorFeatures2 != chipMinorFeatures2)
+ )
+ {
+ gcmkPRINT("[galcore]: VG is not present.");
+ gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the error. */
+ gcmkFOOTER();
+ return status;
+}
+
+
/*******************************************************************************
**
** gckHARDWARE_SetPowerManagementState
@@ -1570,7 +1627,6 @@ gckVGHARDWARE_SetPowerManagementState(
gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
command = Hardware->kernel->command;
gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
-
if (Hardware->powerManagement == gcvFALSE)
{
gcmkFOOTER_NO();
@@ -1770,6 +1826,44 @@ gckVGHARDWARE_SetPowerManagementState(
/* Mark clock and power as enabled. */
Hardware->clockState = gcvTRUE;
Hardware->powerState = gcvTRUE;
+
+ for (;;)
+ {
+ /* Check if GPU is present and awake. */
+ status = _IsGPUPresent(Hardware);
+
+ /* Check if the GPU is not responding. */
+ if (status == gcvSTATUS_GPU_NOT_RESPONDING)
+ {
+ /* Turn off the power and clock. */
+ gcmkONERROR(gckOS_SetGPUPower(os, gcvCORE_VG, gcvFALSE, gcvFALSE));
+
+ Hardware->clockState = gcvFALSE;
+ Hardware->powerState = gcvFALSE;
+
+ /* Wait a little. */
+ gckOS_Delay(os, 1);
+
+ /* Turn on the power and clock. */
+ gcmkONERROR(gckOS_SetGPUPower(os, gcvCORE_VG, gcvTRUE, gcvTRUE));
+
+ Hardware->clockState = gcvTRUE;
+ Hardware->powerState = gcvTRUE;
+
+ /* We need to initialize the hardware and start the command
+ * processor. */
+ flag |= gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_START;
+ }
+ else
+ {
+ /* Test for error. */
+ gcmkONERROR(status);
+
+ /* Break out of loop. */
+ break;
+ }
+ }
+
}
/* Get time until powered on. */