本系列文章将分析linux对于omap的电源管理功能,以am33xx作为实例(目前的硬件平台先主要关注am335xstarterkit开发板),在必要时穿插其他相关内容。
在linux-3.8.1/arch/arm/mach-omap2/board-generic.c中有如下定义(分析某个开发板的内核,自然从board file的machine desc开始):
其中与比较关键的电源管理相关的代码是am33xx_init_early()函数。该函数在linux-3.8.1/arch/arm/mach-omap2/io.c中。
下面我们从am33xx_voltagedomains_init(),am33xx_powerdomains_init(),am33xx_clockdomains_init()等几个函数分析。
下面的文档定义了什么是voltage domain【参考ti的prcm文档sprufa5】。
根据这个定义,我们可以得出voltage domain的功能包括下面几项:
一个voltage domain由一个voltage regulator供电
有一个独立的可控开关
不同voltage domain可以有不同电压
voltage domain的电压可以scale ,可以基于普通dvfs,或者opp,当然也可固定
当选定某个电压后,还可用类似smartreflex的技术微调(软件透明,也可不透明)
可以完全关闭
可以支持唤醒(wake-up)
一个voltage domain可以有多个power domain
因此,如果要自己设计一个voltage domain的结构,可以考虑在其中支持一个voltage_control()的接口,参数可以是0到最大opp电压,而全范围的opp可以作为该结构的附加数据提供。不过我们还是先来看linux的实现如何。
首先是am33xx_voltagedomains_init()的voltage domain初始化,在内核的linux-3.8.1/arch/arm/mach-omap2/voltagedomains33xx_data.c。
这里将mpu和core分成单独的voltage domain。但是实际上,根据《am335x arm® cortex™-a8 microprocessors (mpus)》文档在power-up sequencing一节中描述,应该可以合并这两个voltage domain。
{
when using the zcz package option, vdd_mpu and vdd_core power inputs may be powered from the same source if the application only uses operating performance points (opps) that define a common power supply voltage for vdd_mpu and vdd_core. the zce package option has the vdd_mpu domain merged with the vdd_core domain.
}
每个voltage domain由一个struct voltagedomain来表示。
注意,尽管tps65910的文档上说明了该pmic支持8个可编程的ldo,且在am335xstarterkit开发板上的确通过am335x_i2c0链接了这个pmic的i2c,但是由于这些ldo连接的都是些常规i/o,限定了要求的电压范围(不可使用dvfs这样的方式来类似调整voltage domain的电压一样来调整输出电压),因此这里不把这些ldo看做独立的voltage domain。但是,实际上如果这些对应的模块不需要的话,应该还是可以在初始化时将其ldo电源关掉。
再注意到,tps65910的文档上说明了该pmic支持通过smartreflex接口(实际上是独立的i2c接口)来控制processor core的power。但是实际的am335xstarterkit开发板上却没有连接这个smartreflex接口。有一点需要注意,tps65910实现的是smartreflex class-3,而am335x实现的是smartreflex class-2b。下面的文字来自tps65910文档。
关于smartreflex的支持,可以参考这个github的patch,但是这是针对am335x evm或者beaglebone开发板的。在am3359 - tmdxidk3359开发板中,smartreflex的i2c接口是接上的。
https://github.com/angstrom-distribution/meta-ti/blob/master/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am33xx-add-smartreflex-support.patch
实际上,在tps65910的文档中还说明了这个pmic的smartreflex寄存器是可以通过control i2c和smartreflex i2c访问的,但是需要通过control i2c先配置其devctrl_reg寄存器的sr_ctl_i2c_sel位来选择。
下面简单分析对struct voltagedomain的管理。
首先是平台初始化代码通过voltdm_init()来把自己支持的voltage domain注册到系统中,实际上这是通过调用_voltdm_register()来实现的,并且是将这个struct voltagedomain加入到一个全局的voltdm_list中。从而,也就可以对这个voltdm_list进行查找,所以又有voltdm_lookup()函数。
另外,为了方便起见,还提供一个voltdm_for_each()函数,通过扫描这个voltdm_list,每当发现一个voltage domain,就调用指定的函数指针,从而可以实现对所有的voltage domain都执行某种操作的功能。由于每个voltage domain可以有多个power domain,因此voltdm_add_pwrdm()就被用来向一个voltage domain添加一个power domain(将这些power domain连接到这个voltage domain的pwrdm_list中)。类似的,还提供了一个voltdm_for_each_pwrdm()来对一个voltage domain的所有power domain执行指定的操作函数。
对于每个voltage domain,由于可以有不同的scale的方法(比如可以使用voltage controller,也可以用voltage processor来实现),因此提供omap_change_voltscale_method()来改变相应的scale方法。其实这一点,如果为了通用起见,应该让平台代码直接实现scale方法就行了,也就是可以直接用xxx_set_scale_method()就可以。
omap_voltage_register_pmic()被用来设置struct voltagedomain的pmic字段。omap_voltage_get_voltdata()用来返回对应电压的相关数据(这里使用voltage table实现),即opp数据。omap_voltage_get_volttable()就是用来返回这个voltage table的。voltdm_reset()将这个voltage domain的电压设置为当前opp,实际调用的是voltdm_scale()实现的。voltdm_scale()就是用来实现voltage scale功能的,根据参数指定电压,在该voltage domain自己的voltage table中找到一项恰好大于该指定电压的标称电压,用来设置对应的regulator。voltdm_get_voltage()用来获得该voltage domain的当前标称电压nominal_volt。
荣耀9什么时候上市?荣耀9最新消息:荣耀9工信部谍照曝光,售价比小米6还便宜!
这四个技术载体,是企业能否演化成功的决定因素
区块链如何提升游戏生态的价值
收集一下深圳的新能源汽车数据
本是同根生,华为荣耀V9和华为Mate9怎么选?我选华为P10
以AM33XX为实例的OMAP的电源管理功能
华为荣耀8青春版对比vivoX9,我的颜值担当对比我的颜值你选谁?
ups蓄电池维护方法
iPhone 8发布会:早在10年前,母上大人就答应给买iPhone 8了!
国产高性能32位M0内核MCU单片机DP32G003介绍
国星光电宣布两项省重点领域研发计划项目获批立项
铅酸蓄电池生产工艺详细介绍
国星半导体开展2023年质量审核工作 为公司高质量发展保驾护航
频率步进雷达系统的仿真与测试
线束测试仪在无人机线束测试中的应用说明
紫光集团拟用14亿美元将展讯囊入麾下?
华为Mate20Pro玩游戏到底怎么样
区块链和物联网融合:这正在发生吗?
工厂智能照明系统解决方案应用优势
边缘计算盒子护航企业安全生产,边缘设备提高安全生产监管效率