Linux Runtime PM介绍

一、Runtime PM引言

1. 背景

(1)display的需求

(2)系统整机动态功耗优化的需求

(3)upstream


2. 解决方案

(1)引入debounce

(2)使用统一的workqueue来管理任务

(3)实时地关闭不需要工作的device

(4)当device作为parent时,所有的child不工作时,关闭该device

(5)引入pm_rutime


3. 性能指标

(1)快速开关屏场景,亮屏速度提升

(2)动态功耗,更为稳定;唤醒而不亮屏的场景,功耗更低

(3)有助于降低系统整机动态功耗


二、Runtime PM框架

1. Runtime PM层次结构

技术分享


2. Runtime PM状态

技术分享


3. Runtime PM控制流程

    每个设备或者子系统都会向Runtime PM core注册3个callback。

    在struct dev_pm_ops结构体中,定义了这三个callback:
          struct dev_pm_ops {
    ...
    int (*runtime_suspend)(struct device *dev);
    int (*runtime_resume)(struct device *dev);
    int (*runtime_idle)(struct device *dev);
    .suspend
    .resume
          };
     注:引入runtime之后,suspend 接口需和runtime接口放在同一个数据结构内;


4. rpm_status(include\linux\pm.h)

        enum rpm_status {
            RPM_ACTIVE = 0, /* 表示runtime_resume()被成功执行 */
            RPM_RESUMING, /* 表示runtime_resume()正在被执行 */
            RPM_SUSPENDED, /* 表示runtime_suspend()被成功执行 */
            RPM_SUSPENDING, /* 表示runtime_suspend()正在被执行 */
        };


5. rpm_request(include\linux\pm.h)

        enum rpm_request {
            RPM_REQ_NONE = 0,RPM_REQ_IDLE, 
/* 执行runtime_idle() */

            RPM_REQ_SUSPEND, /* 执行runtime_suspend () */
            RPM_REQ_AUTOSUSPEND,  /* 延迟autosuspend_delay后执行runtime_suspend() */
            RPM_REQ_RESUME,  /* 执行runtime_resume() */
        };
       请求的类型(设置request_pending才有效)。


6. Idle Reference API

        pm_runtime_put_noidle: only put
        pm_runtime_idle
        pm_request_idle:async
        pm_runtime_put: put + async
        pm_runtime_put_sync


7. Suspend Reference API

        pm_schedule_suspend
        pm_runtime_suspend: 
        pm_runtime_put_sync_suspend: put
        pm_runtime_autosuspend: auto
        pm_request_autosuspend:async + auto
        pm_runtime_put_autosuspend: put + async + auto
        pm_runtime_put_sync_autosuspend: put + auto


8. Resume Reference API

        pm_runtime_get_noresume
        pm_runtime_resume
        pm_request_resume: async
        pm_runtime_get: get + async
        pm_runtime_get_sync: get


9. Device Runtime suspend 流程

    触发:
        pm_schedule_suspend
        pm_runtime_suspend: 
        pm_runtime_put_sync_suspend: put
        pm_runtime_autosuspend: auto
        pm_request_autosuspend:async + auto
        pm_runtime_put_autosuspend: put + async + auto
        pm_runtime_put_sync_autosuspend: put + auto
    suspend的条件:
        usage_cnt= 0; 
        disable_depth = 0; 
        runtime_status = RPM_ACTIVE

技术分享


10. Device Runtime PM idle流程

      idle的触发:
        pm_runtime_put_noidle: only put
        pm_runtime_idle
        pm_request_idle:async
        pm_runtime_put: put + async
        pm_runtime_put_sync
      idle的条件:
        usage_cnt= 0; 
        disable_depth = 0; 
        runtime_status = RPM_ACTIVE

技术分享


11. Device Runtime PM resume流程

      触发:
          pm_runtime_get_noresume
          pm_runtime_resume
          pm_request_resume: async
          pm_runtime_get: get + async
          pm_runtime_get_sync: get
      条件:
          disable_depth = 0
          runtime_status != RPM_ACTIVE

技术分享


三、Runtime PM和设备模型

1. Device Runtime PM 初始化

技术分享

(1)设备模型完成pm_runtime 的初始化;

(2)对pm_runtime 状态的改变,需在device_register 之后实现;

(3)设备模型,在调用drv probe, remove, shutdown 等接口时,

          可以保证pm_runtime 处于disable 状态,或其他约定状态;

技术分享

        void pm_runtime_init(struct device *dev)
        {
            dev->power.runtime_status = RPM_SUSPENDED;
            dev->power.idle_notification = false;
            dev->power.disable_depth = 1;
            atomic_set(&dev->power.usage_count, 0);
            dev->power.runtime_error = 0;
            atomic_set(&dev->power.child_count, 0);
            pm_suspend_ignore_children(dev, false);
            dev->power.runtime_auto = true;
            dev->power.request_pending = false;
            dev->power.request = RPM_REQ_NONE;
            dev->power.deferred_resume = false;
            dev->power.accounting_timestamp = jiffies;
            INIT_WORK(&dev->power.work, pm_runtime_work);
            dev->power.timer_expires = 0;
            setup_timer(&dev->power.suspend_timer, pm_suspend_timer_fn, (unsigned long)dev);
            init_waitqueue_head(&dev->power.wait_queue);
        }


        platform_device_register(&platform_disp_device);
        pm_runtime_set_active(&platform_disp_device.dev);
        pm_runtime_get_noresume(&platform_disp_device.dev);
        pm_runtime_enable(&platform_disp_device.dev);
        pm_runtime_set_autosuspend_delay(&platform_disp_device.dev, 5000);
        pm_runtime_use_autosuspend(&platform_disp_device.dev);
        platform_driver_register(&disp_driver);


2. Device Runtime PM remove流程

技术分享


3. Device Runtime PM shutdown流程

技术分享


四、Runtime PM和电源管理

1. system sleep flow

技术分享

技术分享

2. system sleep flow: resume

技术分享

3. system sleep flow: suspend

技术分享


五、Runtime PM实例分析

技术分享

技术分享

技术分享



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。