gpu: add support of enter power off while gpu in idle for a long time
author杜坤明 <dkm@rockchip.com>
Wed, 4 May 2011 06:16:44 +0000 (14:16 +0800)
committer杜坤明 <dkm@rockchip.com>
Wed, 4 May 2011 06:16:44 +0000 (14:16 +0800)
drivers/staging/rk29/vivante/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
drivers/staging/rk29/vivante/hal/inc/gc_hal_options.h
drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_device.c
drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c

index ab1f0cfba511b5a69bcfd7b17cfac826a4f6c58c..5f086e2133afacc39de9e141d4bba30b899a18bc 100755 (executable)
@@ -93,6 +93,24 @@ inline void cal_run_idle(gceCHIPPOWERSTATE State)
 
 #endif
 
+#if gcdENABLE_LONG_IDLE_POWEROFF
+#include <linux/workqueue.h>
+struct delayed_work poweroff_work;
+static gckHARDWARE gHardware = gcvNULL;
+void time_to_poweroff(struct work_struct *work)
+{
+    gceSTATUS status;
+    if(NULL==gHardware)     return;
+
+    status = gckHARDWARE_SetPowerManagementState(gHardware, gcvPOWER_OFF_BROADCAST);
+    if (gcmIS_ERROR(status))
+    {
+        printk("%s fail!\n", __func__);
+        return;
+    }
+}
+#endif
+
 /******************************************************************************\
 ********************************* Support Code *********************************
 \******************************************************************************/
@@ -433,6 +451,11 @@ gckHARDWARE_Construct(
     /* Return pointer to the gckHARDWARE object. */
     *Hardware = hardware;
 
+#if gcdENABLE_LONG_IDLE_POWEROFF
+    INIT_DELAYED_WORK(&poweroff_work, time_to_poweroff);
+    gHardware = hardware;
+#endif
+
     /* Success. */
     gcmkFOOTER_ARG("*Hardware=0x%x", *Hardware);
     return gcvSTATUS_OK;
@@ -2963,6 +2986,17 @@ gckHARDWARE_SetPowerManagementState(
     os = Hardware->os;
     gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
 
+#if gcdENABLE_LONG_IDLE_POWEROFF
+    if(gcvPOWER_IDLE_BROADCAST==State) {
+        cancel_delayed_work_sync(&poweroff_work);
+        schedule_delayed_work(&poweroff_work, 5*HZ);
+    } else if(gcvPOWER_OFF_BROADCAST==State) {
+        // NULL
+    } else {
+        cancel_delayed_work_sync(&poweroff_work);
+    }
+#endif
+
     /* Convert the broadcast power state. */
     switch (State)
     {
@@ -3068,6 +3102,12 @@ gckHARDWARE_SetPowerManagementState(
 
     if ((flag == 0) || (Hardware->settingPowerState))
     {
+#if gcdENABLE_LONG_IDLE_POWEROFF
+        if( (gcvPOWER_OFF==Hardware->chipPowerState) && (gcvPOWER_OFF==State) && (gcvFALSE==broadcast) )
+        {
+            Hardware->broadcast = gcvFALSE;
+        }
+#endif
         /* Release the power mutex. */
         Hardware->powerProcess = 0;
         Hardware->powerThread = 0;
index f4158b80905ca7860f988facc7e80925eaac96b5..eb3debc7513388817141f57031e2cf9aa251694b 100755 (executable)
 */
 #define gcdENABLE_MEM_CACHE                 2
 
+
 /*
     gcdENABLE_DELAY_EARLY_SUSPEND
 
     ÔÚgpu_early_suspendÖÐʹÓÃÑÓʱ¹¤×÷¶ÓÁÐÀ´Ö´ÐÐsuspend,
     ±ÜÃâgpu_early_suspend¹ýÔçÖ´Ðе¼ÖÂÓû§Ï̵߳ÄÊÂÇ黹´¦Àí¸É¾»
+    0: Ê¹ÓÃÕý³£µÄearly_suspend¹¦ÄÜ
+    1: Ê¹ÓÃdelayµÄearly_suspend¹¦ÄÜ
+    2: ¹Ø±Õearly_suspend¹¦ÄÜ
+*/
+#define gcdENABLE_DELAY_EARLY_SUSPEND       2
+
+
+/*
+    gcdENABLE_LONG_IDLE_POWEROFF
+
+    ³¤Ê±¼äIDLEºó½øÈëPowerOff, ¸Ã¹¦ÄÜ¿ªÆôºóÐèÒª°ÑEarlySuspend¹¦Äܹصô
+    ÕâÑù¿ÉÒÔʹijЩ²»Ê¹ÓÃGPUµÄ³¡¾°µÄ¹¦ºÄ½øÒ»²½½µµÍ£¬ÈçÊÓƵ²¥·Åʱ£¬Ò»¼¶´ý»úʱ£¬
+    »ò³¤Ê±¼ä²»²Ù×÷½çÃ浫»¹Î´½øÈëÒ»¼¶´ý»ú
 */
-#define gcdENABLE_DELAY_EARLY_SUSPEND       0
+#define gcdENABLE_LONG_IDLE_POWEROFF        1
 
 #endif /* __gc_hal_options_h_ */
 
index bf3e657489b1b967536e312688e7e110141898a3..6efee265b58ee1672cfc5d5ab020262ced4d4905 100755 (executable)
@@ -488,7 +488,7 @@ gckGALDEVICE_Construct(
         device->registerBase = (gctPOINTER) ioremap_nocache(RegisterMemBase,
                                                         RegisterMemSize);
         if (!device->registerBase)
-    {
+        {
             gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
                       "[galcore] gckGALDEVICE_Construct: Unable to map location->0x%lX for size->%ld",
               RegisterMemBase,
@@ -496,6 +496,7 @@ gckGALDEVICE_Construct(
 
             return gcvSTATUS_OUT_OF_RESOURCES;
         }
+        printk("---- gpu regbase: 0x%08x ---- \n", (unsigned int)device->registerBase);
 
         physical += RegisterMemSize;
 
index 142b96c177ae058bf49bf318847ac388626a4c70..29fb592e7db485b35bb810c2fd5cb87cea223731 100755 (executable)
@@ -151,7 +151,7 @@ void gputimer_callback(unsigned long arg)
 }
 #endif
 
-#if gcdENABLE_DELAY_EARLY_SUSPEND
+#if (1==gcdENABLE_DELAY_EARLY_SUSPEND)
 struct delayed_work suspend_work;
 void real_suspend(struct work_struct *work)
 {
@@ -770,11 +770,10 @@ module_exit(drv_exit);
 #if CONFIG_HAS_EARLYSUSPEND
 static void gpu_early_suspend(struct early_suspend *h)
 {
-#if gcdENABLE_DELAY_EARLY_SUSPEND
+#if (1==gcdENABLE_DELAY_EARLY_SUSPEND)
     schedule_delayed_work(&suspend_work, 5*HZ);
 #else
        gceSTATUS status;
-
        status = gckHARDWARE_SetPowerManagementState(galDevice->kernel->hardware, gcvPOWER_OFF);
 
        if (gcmIS_ERROR(status))
@@ -789,7 +788,7 @@ static void gpu_early_resume(struct early_suspend *h)
 {
        gceSTATUS status;
 
-#if gcdENABLE_DELAY_EARLY_SUSPEND
+#if (1==gcdENABLE_DELAY_EARLY_SUSPEND)
     cancel_delayed_work_sync(&suspend_work);
 #endif
        status = gckHARDWARE_SetPowerManagementState(galDevice->kernel->hardware, gcvPOWER_ON);
@@ -843,10 +842,12 @@ static int __devinit gpu_probe(struct platform_device *pdev)
 #endif
 
 #if CONFIG_HAS_EARLYSUSPEND
-    //register_early_suspend(&gpu_early_suspend_info);
+#if (2!=gcdENABLE_DELAY_EARLY_SUSPEND)
+    register_early_suspend(&gpu_early_suspend_info);
+#endif
 #endif
 
-#if gcdENABLE_DELAY_EARLY_SUSPEND
+#if (1==gcdENABLE_DELAY_EARLY_SUSPEND)
     INIT_DELAYED_WORK(&suspend_work, real_suspend);
 #endif
 
@@ -863,7 +864,7 @@ gpu_probe_fail:
 
 static int __devinit gpu_remove(struct platform_device *pdev)
 {
-#if gcdENABLE_DELAY_EARLY_SUSPEND
+#if (1==gcdENABLE_DELAY_EARLY_SUSPEND)
     cancel_delayed_work_sync(&suspend_work);
 #endif
        drv_exit();
@@ -875,7 +876,7 @@ static int __devinit gpu_suspend(struct platform_device *dev, pm_message_t state
        gceSTATUS status;
        gckGALDEVICE device;
     
-#if gcdENABLE_DELAY_EARLY_SUSPEND
+#if (1==gcdENABLE_DELAY_EARLY_SUSPEND)
     cancel_delayed_work_sync(&suspend_work);
 #endif
        device = platform_get_drvdata(dev);
@@ -911,7 +912,7 @@ static int __devinit gpu_resume(struct platform_device *dev)
 
 static void __devinit gpu_shutdown(struct platform_device *dev)
 {
-#if gcdENABLE_DELAY_EARLY_SUSPEND
+#if (1==gcdENABLE_DELAY_EARLY_SUSPEND)
     cancel_delayed_work_sync(&suspend_work);
 #endif
     drv_exit();