UFS Power Management 介绍
一 . UFS Power Management Overview
1. UFS Power Management 管理UFS Power相关资源,
在收到访问请求的时候唤醒UFS工作,切换为工作模式,在完成请求后让UFS进行睡眠,切换为睡眠模式,能够节省功耗,提高续航。
主要是分为UFS Runtime Power Management和UFS System Power Management。
2. UFS Runtime Power Management:
UFS模块运行时睡眠唤醒机制,只需要UFS模块空闲,即可进入睡眠状态,不受其他模块的睡眠唤醒状态影响,通俗点讲就是个人自扫门前雪。
3. UFS System Power Management:
UFS系统睡眠唤醒机制,和系统的睡眠唤醒状态有关,需要系统所有的模块都睡眠下去,UFS 模块才会睡眠下去,当只有存在系统一个模块是唤醒状态/或者系统存在唤醒源导致睡眠部下去,UFS模块也是不能成功睡眠下去,通俗点讲就是有福同享,有难同当,不放弃任何一个民众。
二 . UFS Power Management Detail
1. UFS Runtime Power Management :
(1) UFS Runtime Power Management是在Linux Kernel RPM Framework下进行管理的,在没有访问请求/UFS空闲的时候,将UFS置为睡眠状态,当UFS有访问请求/不是空闲状态时,将UFS置为唤醒状态。
(2) UFS Driver RPM Power Management 主要是管理UFS Device Power Mode State和MPHY Link State。
UFS PM Level State划分为六个等级,默认rpm_lvl 是3,也就是UFS_SLEEP_PWR_MODE, UIC_LINK_ACTIVE_STATE。
UFS_SLEEP_PWR_MODE:指的是UFS Device PowerMode为Sleep Mode, 需要发送SSU命令切换UFS Power Mode。
UIC_LINK_ACTIVE_STATE:指的是将UFS MPHY Link设置为Hibernate状态,需要发送DME_HIBERNATE_ENTER命令切换Link Status.
struct ufs_pm_lvl_states ufs_pm_lvl_states[] = {{UFS_ACTIVE_PWR_MODE, UIC_LINK_ACTIVE_STATE},{UFS_ACTIVE_PWR_MODE, UIC_LINK_HIBERN8_STATE},{UFS_SLEEP_PWR_MODE, UIC_LINK_ACTIVE_STATE},{UFS_SLEEP_PWR_MODE, UIC_LINK_HIBERN8_STATE},{UFS_POWERDOWN_PWR_MODE, UIC_LINK_HIBERN8_STATE},{UFS_POWERDOWN_PWR_MODE, UIC_LINK_OFF_STATE},
};
(3) UFS RPM 相关Sysfs节点:
UFS RPM Sysfs节点目录: /sys/device/platform/soc/1d84.ufshci/powerUFS RPM 相关节点:1. control: Report/change current runtime PM setting of the device
** Runtime power management of a device can be blocked with the help of* this attribute. All devices have one of the following two values for* the power/control file:* + "auto\n" to allow the device to be power managed at run time;* + "on\n" to prevent the device from being power managed at run time;2. autosuspend_delay_ms - Report/change a device's autosuspend_delay value** Some drivers don't want to carry out a runtime suspend as soon as a* device becomes idle; they want it always to remain idle for some period* of time before suspending it. This period is the autosuspend_delay* value (expressed in milliseconds) and it can be controlled by the user.* If the value is negative then the device will never be runtime* suspended.3. runtime_active_time: report runtime active status totol time.4. runtime_suspended_time: report runtime suspended status totol time.5. runtime_status: report runtime status.
(4) UFS 设备Runtime Power Management状态:
/** Device run-time power management status.** These status labels are used internally by the PM core to indicate the* current status of a device with respect to the PM core operations. They do* not reflect the actual power state of the device or its status as seen by the* driver.** RPM_ACTIVE Device is fully operational. Indicates that the device* bus type's ->runtime_resume() callback has completed* successfully.** RPM_SUSPENDED Device bus type's ->runtime_suspend() callback has* completed successfully. The device is regarded as* suspended.** RPM_RESUMING Device bus type's ->runtime_resume() callback is being* executed.** RPM_SUSPENDING Device bus type's ->runtime_suspend() callback is being* executed.*/enum rpm_status {RPM_ACTIVE = 0,RPM_RESUMING,RPM_SUSPENDED,RPM_SUSPENDING,
};
(5) UFS 驱动常用Runtime PM使用接口和使用场景
在访问UFS 设备之前,为了防止UFS 进入Suspend , 我们需要调用以下两个接口增加设备使用计数,然后唤醒UFS 设备(Resume)为Active状态,这里UFS设备指的是UFS Host Controller,
Note:不管是UFS驱动还是USB驱动还是其他驱动,在访问设备之前都应该遵循以上流程,唤醒设备为Active状态,保证设备正常工作,否则如果设备进入了Suspend状态去访问会出现未知的错误。
pm_runtime_get_sync
pm_runtime_get
访问UFS设备之后,就可以让UFS 设备进入Suspend, 我们需要调用以下两个接口减少设备使用技术,然后使得UFS设备进入睡眠状态(Suspended), 这里UFS设备指的是UFS Host Controller.
pm_runtime_put
pm_runtime_put_sync
下面是一个具体的使用场景:
在对UFS Host Controller做访问之前,调用pm,_runtime_get_sync增加设备引用计数,唤醒设备,然后对设备进行访问操作,访问完成后调用pm_runtimr_put_sync减少设备引用计数,让设备睡眠。
int ufshcd_clk_scaling_enable(struct ufs_hba *hba, int value)
{int err;value = !!value;mutex_lock(&ufshcd_clkscale_lock);if (value == hba->clk_scaling.is_allowed)goto out;// 获取UFS PM Runtime 资源,增加PM Usage Count, 让UFS Host处于Active Statuspm_runtime_get_sync(hba->dev); ufshcd_hold(hba, false);cancel_work_sync(&hba->clk_scaling.suspend_work);cancel_work_sync(&hba->clk_scaling.resume_work);hba->clk_scaling.is_allowed = value;if (value) {ufshcd_resume_clkscaling(hba);} else {ufshcd_suspend_clkscaling(hba);err = ufshcd_devfreq_scale(hba, true);if (err)dev_err(hba->dev, "%s: failed to scale clocks up %d\n",__func__, err);}ufshcd_release(hba, false);// 释放UFS PM Runtime资源,减少PM Usage Count, 让UFS Host处于Suspend Statuspm_runtime_put_sync(hba->dev);
out:mutex_unlock(&ufshcd_clkscale_lock);return 0;
}
阻塞UFS设备在Linux RPM Power Management 管理运行时进入Suspend.
增加设备引用计数和清除设备power.runtime_auto标志
除非调用pm_runtime_allow,否则UFS设备不会在运行的时候进入Suspend状态
pm_runtime_forbid
UFS设备在Linux RPM Power Management 管理运行时允许挂起(进入Suspended)
减少设备引用计数和设置设备power.runtime_auto标志
pm_runtime_allow
下面是一个具体的使用场景:
static const char ctrl_auto[] = "auto";
static const char ctrl_on[] = "on";static ssize_t control_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
return sprintf(buf, "%s\n",
dev->power.runtime_auto ? ctrl_auto : ctrl_on);
}static ssize_t control_store(struct device * dev, struct device_attribute *attr,
const char * buf, size_t n)
{
device_lock(dev);
if (sysfs_streq(buf, ctrl_auto))
pm_runtime_allow(dev);
else if (sysfs_streq(buf, ctrl_on))
pm_runtime_forbid(dev);
else
n = -EINVAL;
device_unlock(dev);
return n;
}
2. UFS System Power Management:
(1)UFS System Power Management是受整个内核系统影响的,需要内核系统所有模块都睡眠 了或者内核系统没有唤醒事件,UFS设备才会进入UFS System Suspend。
UFS手机功耗续航测试就是在整个系统进入System Suspend(包括UFS System Suspend)后进行 测试的,相关开发同事需要对整个系统的System Suspend/Resume 机制非常了解,才能清晰的 定位到某个模块影响了系统进入System Suspend,导致功耗问题。
(2) UFS Driver RPM Power Management 主要是管理UFS Device Power Mode State和 MPHY Link State 还有UFS Device的供电VCC。
UFS PM Level State划分为六个等级,默认spm_lvl 是3,也就是UFS_SLEEP_PWR_MODE, UIC_LINK_ACTIVE_STATE。
UFS_SLEEP_PWR_MODE:指的是UFS Device PowerMode为Sleep Mode, 需要发送SSU命 令切换UFS Power Mode。
UIC_LINK_ACTIVE_STATE:指的是将UFS MPHY Link设置为Hibernate状态,需要发送 DME_HIBERNATE_ENTER命令切换Link Status.
VCC: UFS Device进入System Suspend的时候,会将VCC电压关闭节省耗电,减少功耗。
(3) UFS System Suspend相关Sysfs节点:
系统PM节点目录: /sys/power/*
wake_lock: 系统唤醒锁,如果有进程持有wake_lock, 整个系统就不会进入System Suspend, 当然UFS 设备也不能进入system suspend.
wake_unlock: 释放系统唤醒锁,让整个系统可以进入System Suspend, 当然UFS 设备也 能进入system suspend.
(4) UFS 设备相关System PM状态:
系统System PM 相关状态:
#define PM_SUSPEND_ON ((__force suspend_state_t) 0)
#define PM_SUSPEND_TO_IDLE ((__force suspend_state_t) 1)
#define PM_SUSPEND_STANDBY ((__force suspend_state_t) 2)
#define PM_SUSPEND_MEM ((__force suspend_state_t) 3)
#define PM_SUSPEND_MIN PM_SUSPEND_TO_IDLE
#define PM_SUSPEND_MAX ((__force suspend_state_t) 4)
kernel/power/main.c
static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t n)
{
suspend_state_t state;
int error;error = pm_autosleep_lock();
if (error)
return error;if (pm_autosleep_state() > PM_SUSPEND_ON) {
error = -EBUSY;
goto out;
}state = decode_state(buf, n);
if (state < PM_SUSPEND_MAX) {
if (state == PM_SUSPEND_MEM)
state = mem_sleep_current;error = pm_suspend(state);
} else if (state == PM_SUSPEND_MAX) {
error = hibernate();
} else {
error = -EINVAL;
}out:
pm_autosleep_unlock();
return error ? error : n;
}
UFS System PM相关状态:
/* Used to differentiate the power management options */
enum ufs_pm_op {
UFS_RUNTIME_PM,
UFS_SYSTEM_PM,
UFS_SHUTDOWN_PM,
};
/**
* ufshcd_system_suspend - system suspend routine
* @hba: per adapter instance
*
* Check the description of ufshcd_suspend() function for more details.
*
* Returns 0 for success and non-zero for failure
*/
int ufshcd_system_suspend(struct ufs_hba *hba)
{
int ret = 0;
ktime_t start = ktime_get();if (!hba || !hba->is_powered)
return 0;if ((ufs_get_pm_lvl_to_dev_pwr_mode(hba->spm_lvl) ==
hba->curr_dev_pwr_mode) &&
(ufs_get_pm_lvl_to_link_pwr_state(hba->spm_lvl) ==
hba->uic_link_state))
goto out;if (pm_runtime_suspended(hba->dev)) {
/*
* UFS device and/or UFS link low power states during runtime
* suspend seems to be different than what is expected during
* system suspend. Hence runtime resume the devic & link and
* let the system suspend low power states to take effect.
* TODO: If resume takes longer time, we might have optimize
* it in future by not resuming everything if possible.
*/
ret = ufshcd_runtime_resume(hba);
if (ret)
goto out;
}ret = ufshcd_suspend(hba, UFS_SYSTEM_PM);
out:
trace_ufshcd_system_suspend(dev_name(hba->dev), ret,
ktime_to_us(ktime_sub(ktime_get(), start)),
hba->curr_dev_pwr_mode, hba->uic_link_state);
if (!ret)
hba->is_sys_suspended = true;
return ret;
}
EXPORT_SYMBOL(ufshcd_system_suspend);
(6)UFS 驱动常用System PM使用接口和使用场景:
系统开始进入System Suspend的时候,会循环遍历每个设备都进入System Suspend状态,包 括UFS设备,UFS驱动没有显性调用System PM的接口,主要是受系统Suspend机制管理,当系 统开始进入Suspend流程的时候,UFS设备也是空闲的状态的时候,此时UFS设备就会进入System Suspend的状态,UFS驱动发送SSU命令让UFS Device进入SLEEP Mode, 发送DME_HIBER_ENTER让MPHY Link 进入Hibernate状态,并且UFS Device的VCC供电也会关闭,节省功耗。
三. 参考资料
1. Kernel System Power Management Source Code
2 . Kernel Runtime Power Management Source Code
3. Kernel UFS Power Management Source Code
UFS Power Management 介绍相关推荐
- 【知识点】AT91SAM9260的Power Management Controller (PMC)寄存器介绍
AT91SAM9260的Power Management Controller(PMC)寄存器 1.寄存器映射: 2.寄存器的详细介绍 2.1 PMC_SCER (系统时钟启用寄存器) 2.2 PMC ...
- Zephyr Power Management Subsystem详细介绍
目录 简介 前景补充 SOC Interface IDLE Thread * Tickless Idle Power Gating Power State Device Runtime Power M ...
- PCI Express学习篇---Power Management(二)
声明:此文章为原创,转载请注明 转自https://blog.csdn.net/weixin_48180416/article/details/115576691 此篇介绍L1低功耗状态.下一篇介绍L ...
- SATA系列专题之五:Link Power Management解析
一.故事前传 在之前的文章中, 我们已经针对SATA的主要结构进行了较为详细的解析,详见前期文章: 1,浅析SATA Physical Layer物理层OOB信号: 2,SATA Link Layer ...
- [笔记分享] [Power] MSM8x60 Power Management study report
1 Overview 本文主要介绍MSM8x60平台的电源管理部分,平台通过PM8058和PM8901两个IC来管理电源部分,另外,RPM中的MPM用来提供MSM的sleep mode功能来使系统最小 ...
- PCI Express学习篇:Power Management(二)
原文链接:https://blog.csdn.net/weixin_48180416/article/details/115576691 一. 前言 此篇介绍L1低功耗状态.下一篇介绍L1 Subst ...
- PCI Express学习篇---Power Management(一)
声明:此文章为原创,转载请注明 转自https://blog.csdn.net/weixin_48180416/article/details/115576240 此篇为Power Managemen ...
- <Linux> Linux Power Management Overview
Overview Generic PM 传统意义上的Power Management,如Power On/Off, Restart, Suspend to RAM/Disk等. Clock Frame ...
- PCI Express学习篇:Power Management(一)
https://blog.csdn.net/weixin_48180416/article/details/115576240 前言 此篇为Power Management概述.下一篇介绍L1低功耗状 ...
- 【转】POWER MANAGEMENT IN IEEE 802.11
港澳台同胞的BLOG,看着有点困难.FROM: http://sky.csie.org/sky/archives/000040.html 一些關於Power management In IEEE 80 ...
最新文章
- 微信小程序万里目_微信小程序学习用推荐:破音万里:音频播放,音乐列表
- POJ 3449 Geometric Shapes
- WCF第一个Demo
- 用一句SQL取出第 m 条到第 n 条记录的方法
- 【Android】解析Json数据
- python数据分析笔记——数据加载与整理
- java ftp获取文件夹大小,java 用FTPClient 下载文件时不显示总大小?解决方案
- 缔造完美运维 共谱双赢新篇
- 计算机专业性特有的道德要求,什么是通信科学技术人员职业道德的双重性?
- 使用conda创建环境以及出现包找不到解决方案
- 【一起学爬虫】爬虫实战:爬取京东零食
- 诛仙2怎样修改服务器时间同步,《诛仙2》2月22日更新公告
- 关于文件的MIME类型
- Flink POJO类状态使用注意事项
- win7电脑蓝屏没有修复计算机,Win7旗舰版系统电脑老是出现蓝屏的修复教程
- linux远程主机拒绝连接,linux – Telnet [无法连接到远程主机:拒绝连接]
- 程序员做前端好还是做后台好?
- golang 获取当天0点时间_golang 获取当天是周几(两种方法)
- Jetbrains系列产品
- Red_Hat_Linux忘记root密码解决办法
热门文章
- Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
- 闰月算法c语言,公历转农历算法-C语言
- 2018年系统架构设计师案例分析真题及详细答案解析
- 台式计算机如何联络无线网,台式电脑怎么无线上网
- 【Python】bar柱状(条形)图(带均值和标准差)
- 20190729杭电多校第三场
- bada 2D游戏编程——开篇说明
- Atitit 软件开发中 瓦哈比派的核心含义以及修行方法以及对我们生活与工作中的指导意义...
- SpringCLoud+redis+es高并发项目《九》(Spring Security Oauth2 JWT)
- 点击自定义按钮弹出百度商桥对话框