高通8916 PMIC休眠关闭LDO调试记录
2016-11-24 16:26
1046 查看
转自:http://blog.csdn.net/eliot_shao/article/details/53262360
案例:在调试qcom msm8916 + PM8916平台的时候,遇到一个bug,LCM休眠时候,vdd引脚电压没有拉低,电压还是2.85V,造成1920X1200nt51021b 京东方8寸LCM调试的时候经常因为系统休眠或者不断重启,LCM 极化,造成闪屏,或者不能正常显示的问题。
调试经过:
通过查看原理图发现,vdd使用了LDO17作为电源,LDO17在系统休眠的时候没有关闭。
在/sys文件系统下面留有两个调试接口:
[html] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
/sys/kernel/debug/regulator/pm8917_l17
/sys/class/regulator/regulator.27/
我们使用/sys/kernel/debug/regulator/pm8917_l17
![](https://oscdn.geek-share.com/Uploads/Images/Content/202008/06/00de86a956335b02933e8dde7b7c5610)
可以看到,一共有两个设备用了l17。其实通过echo 0 >enable两次也可以实现关闭l17,但是就很奇怪为什么要两次才起作用,不禁联想到,ldo被其他设备占用了,而休眠的时候没有关闭。
第一个就是lcm用到的vdd: 1a94000.qcom,mdss_dsi_ctrl0-vdd
在LA.BR.1.2.4-05310-8x16.0\kernel\arch\arm\boot\dts\qcom\msm8916-mdss.dtsi
中配置的vdd
[cpp] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
mdss_dsi0:qcom,mdss_dsi@1a98000 {
compatible= "qcom,mdss-dsi-ctrl";
label= "MDSS DSI CTRL->0";
cell-index= <0>;
reg= <0x1a98000 0x25c>,
<0x1a98500 0x2b0>,
<0x193e000 0x30>;
reg-names= "dsi_ctrl", "dsi_phy", "mmss_misc_phys";
qcom,mdss-fb-map= <&mdss_fb0>;
qcom,mdss-mdp= <&mdss_mdp>;
gdsc-supply= <&gdsc_mdss>;
vdda-supply= <&pm8916_l2>;
vdd-supply = <&pm8916_l17>;
vddio-supply= <&pm8916_l6>;
Mdss_mdp.c (drivers\video\msm\mdss)中解析vdd(注意devm_regulator_get函数会将vdd补全为vdd-supply):
[cpp] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
mdata->fs = devm_regulator_get(&mdata->pdev->dev, "vdd");
在Mdss_mdp.c中提供了一个对mdata->fs LDO的控制方法:
[cpp] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on)
在休眠函数里,定义了关闭LDO17的方法:
[cpp] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
static inline intmdss_mdp_suspend_sub(struct mdss_data_type *mdata)
{
mdata->suspend_fs_ena= mdata->fs_ena;
mdss_mdp_footswitch_ctrl(mdata, false);
pr_debug("suspenddone fs=%d\n", mdata->suspend_fs_ena);
return0;
}
所以,LDO17没有正常关闭很有可能是另外一个驱动中申请使用后,suspend函数没有关闭造成的!下面分析一下3-005d-vdd。
地址为0x5d的是在
\kernel\arch\arm\boot\dts\qcom\msm8916-qrd-skui-slm755-public.dts
中定义的
[cpp] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
i2c@78b9000{ /* BLSP1 QUP5 */
goodix@5d {
compatible = "goodix,gt9xx";
reg = <0x5d>;
interrupt-parent = <&msm_gpio>;
interrupts = <13 0x2008>;
reset-gpios = <&msm_gpio 12 0x00>;
interrupt-gpios = <&msm_gpio 13 0x00>;
vdd-supply = <&pm8916_l17>;
vcc-i2c-supply = <&pm8916_l6>;
……
};
在驱动中:kernel/drivers/input/touchscreen/gt9xx/gt928.c
static int goodix_ts_suspend(struct device*dev)函数里面并没有出现关闭LDO的操作,所以我们在里面加入一行代码:
[cpp] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
regulator_disable(ts->vdd);
当然,也需要在resume中打开ldo17
在函数static int goodix_ts_resume(struct device *dev)加入:
[cpp] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
ret= regulator_enable(ts->vdd);
if(ret) {
printk(KERN_ERR"eliot regulator_enable err...\n");
}
重新编译,打包下载实验。LDO17在lcm休眠的时候关闭了!!!
除了上述在使用ldo17驱动的suspend函数中关闭ldo的做法外,还有休眠的时候统一关闭LDO17的方法,qcom回复如下:
Dear customer
Try :
rpm_proc/core/systemdrivers/pmic/config/msm8916/pm_config_target.c
#if 1
sleep_register_type sleep_enter_info[] =
{
{1,0x5046,0x00}, //disable LDO17
{0, 0xFFFF, 0x00}, //invalid setting, used to check the end of the array.
};
sleep_register_type sleep_exit_info[] =
{
{1,0x15046,0x80},
{0, 0xFFFF, 0x00},
};
#endif
因为是modem部分的代码,没有权限访问,所以就没有实验这种方法是否可行了。
总结:休眠关闭电源是驱动应该要做的,也是平台功耗问题应该尽量避免的。高通建议使用第一种方法,谁使用谁关闭的做法,如果一组LDO被多个驱动所使用,还是应该在驱动的suspend中加入regulator_disable操作。
案例:在调试qcom msm8916 + PM8916平台的时候,遇到一个bug,LCM休眠时候,vdd引脚电压没有拉低,电压还是2.85V,造成1920X1200nt51021b 京东方8寸LCM调试的时候经常因为系统休眠或者不断重启,LCM 极化,造成闪屏,或者不能正常显示的问题。
调试经过:
通过查看原理图发现,vdd使用了LDO17作为电源,LDO17在系统休眠的时候没有关闭。
在/sys文件系统下面留有两个调试接口:
[html] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
/sys/kernel/debug/regulator/pm8917_l17
/sys/class/regulator/regulator.27/
我们使用/sys/kernel/debug/regulator/pm8917_l17
可以看到,一共有两个设备用了l17。其实通过echo 0 >enable两次也可以实现关闭l17,但是就很奇怪为什么要两次才起作用,不禁联想到,ldo被其他设备占用了,而休眠的时候没有关闭。
第一个就是lcm用到的vdd: 1a94000.qcom,mdss_dsi_ctrl0-vdd
在LA.BR.1.2.4-05310-8x16.0\kernel\arch\arm\boot\dts\qcom\msm8916-mdss.dtsi
中配置的vdd
[cpp] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
mdss_dsi0:qcom,mdss_dsi@1a98000 {
compatible= "qcom,mdss-dsi-ctrl";
label= "MDSS DSI CTRL->0";
cell-index= <0>;
reg= <0x1a98000 0x25c>,
<0x1a98500 0x2b0>,
<0x193e000 0x30>;
reg-names= "dsi_ctrl", "dsi_phy", "mmss_misc_phys";
qcom,mdss-fb-map= <&mdss_fb0>;
qcom,mdss-mdp= <&mdss_mdp>;
gdsc-supply= <&gdsc_mdss>;
vdda-supply= <&pm8916_l2>;
vdd-supply = <&pm8916_l17>;
vddio-supply= <&pm8916_l6>;
Mdss_mdp.c (drivers\video\msm\mdss)中解析vdd(注意devm_regulator_get函数会将vdd补全为vdd-supply):
[cpp] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
mdata->fs = devm_regulator_get(&mdata->pdev->dev, "vdd");
在Mdss_mdp.c中提供了一个对mdata->fs LDO的控制方法:
[cpp] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on)
在休眠函数里,定义了关闭LDO17的方法:
[cpp] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
static inline intmdss_mdp_suspend_sub(struct mdss_data_type *mdata)
{
mdata->suspend_fs_ena= mdata->fs_ena;
mdss_mdp_footswitch_ctrl(mdata, false);
pr_debug("suspenddone fs=%d\n", mdata->suspend_fs_ena);
return0;
}
所以,LDO17没有正常关闭很有可能是另外一个驱动中申请使用后,suspend函数没有关闭造成的!下面分析一下3-005d-vdd。
地址为0x5d的是在
\kernel\arch\arm\boot\dts\qcom\msm8916-qrd-skui-slm755-public.dts
中定义的
[cpp] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
i2c@78b9000{ /* BLSP1 QUP5 */
goodix@5d {
compatible = "goodix,gt9xx";
reg = <0x5d>;
interrupt-parent = <&msm_gpio>;
interrupts = <13 0x2008>;
reset-gpios = <&msm_gpio 12 0x00>;
interrupt-gpios = <&msm_gpio 13 0x00>;
vdd-supply = <&pm8916_l17>;
vcc-i2c-supply = <&pm8916_l6>;
……
};
在驱动中:kernel/drivers/input/touchscreen/gt9xx/gt928.c
static int goodix_ts_suspend(struct device*dev)函数里面并没有出现关闭LDO的操作,所以我们在里面加入一行代码:
[cpp] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
regulator_disable(ts->vdd);
当然,也需要在resume中打开ldo17
在函数static int goodix_ts_resume(struct device *dev)加入:
[cpp] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
ret= regulator_enable(ts->vdd);
if(ret) {
printk(KERN_ERR"eliot regulator_enable err...\n");
}
重新编译,打包下载实验。LDO17在lcm休眠的时候关闭了!!!
除了上述在使用ldo17驱动的suspend函数中关闭ldo的做法外,还有休眠的时候统一关闭LDO17的方法,qcom回复如下:
Dear customer
Try :
rpm_proc/core/systemdrivers/pmic/config/msm8916/pm_config_target.c
#if 1
sleep_register_type sleep_enter_info[] =
{
{1,0x5046,0x00}, //disable LDO17
{0, 0xFFFF, 0x00}, //invalid setting, used to check the end of the array.
};
sleep_register_type sleep_exit_info[] =
{
{1,0x15046,0x80},
{0, 0xFFFF, 0x00},
};
#endif
因为是modem部分的代码,没有权限访问,所以就没有实验这种方法是否可行了。
总结:休眠关闭电源是驱动应该要做的,也是平台功耗问题应该尽量避免的。高通建议使用第一种方法,谁使用谁关闭的做法,如果一组LDO被多个驱动所使用,还是应该在驱动的suspend中加入regulator_disable操作。
相关文章推荐
- 高通8916 PMIC休眠关闭LDO 解决LCM极化问题
- LCM休眠唤醒闪白屏问题调试记录
- 高通Secure Boot调试流程记录
- 超低压差LDO-TPS7333调试记录
- 高通Secure Boot调试流程记录
- 嵌入式编程中调试问题全记录
- JavaSctipt更新记录后关闭子窗口并刷新父窗口的
- c++--SDI的启动和关闭的调试跟踪的过程摘抄
- WinDbg 调试命令记录一
- 无法在Web服务器上启动调试。基础连接已经关闭:接收时发生错误--解决
- c++--SDI的启动和关闭的调试跟踪的过程摘抄
- WinDbg 调试命令记录二 (基础CLR查看)
- 记录一个PL/SQL调试语句
- 修复VS2005(Visual Studio2005)调试自动关闭问题[成功方法!]
- WinDbg 调试命令记录二 (基础CLR查看)
- c++--SDI的启动和关闭的调试跟踪的过程摘抄
- 更新记录后关闭子窗口并刷新父窗口的Javascript
- WinDbg 调试命令记录一
- c++--SDI的启动和关闭的调试跟踪的过程摘抄
- [原创]修复VS2005(Visual Studio2005)调试自动关闭问题[成功方法!]