mirror of
https://github.com/torvalds/linux.git
synced 2026-06-12 00:23:01 +02:00
gpu: add support of enter power off while gpu in idle for a long time
This commit is contained in:
parent
3901afba10
commit
40acaf7488
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -274,13 +274,27 @@
|
|||
*/
|
||||
#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 0
|
||||
#define gcdENABLE_DELAY_EARLY_SUSPEND 2
|
||||
|
||||
|
||||
/*
|
||||
gcdENABLE_LONG_IDLE_POWEROFF
|
||||
|
||||
长时间IDLE后进入PowerOff, 该功能开启后需要把EarlySuspend功能关掉
|
||||
这样可以使某些不使用GPU的场景的功耗进一步降低,如视频播放时,一级待机时,
|
||||
或长时间不操作界面但还未进入一级待机
|
||||
*/
|
||||
#define gcdENABLE_LONG_IDLE_POWEROFF 1
|
||||
|
||||
#endif /* __gc_hal_options_h_ */
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 @@ static int __devinit gpu_probe(struct platform_device *pdev)
|
|||
|
||||
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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user