本文轉載自:http://www.javashuo.com/content/p-6398007.html
調試環境
RK3288
Android5.1
硬件原理
pmic 電路原理
電源分為兩種:
DCDC:輸入輸出壓差大時,效率高,但是有紋波問題,成本高,所以大壓差,大電流時使用。
LDO:輸入輸出壓差大時,效率低,成本低。
為了提高 LDO 的轉換效率,系統上會進行相關優化如:
LDO 輸出電壓為 1.1V,為了提高效率,其輸入電壓可以從 VCCIO_3.3V 的 DCDC 給出。
所以電路上如果允許盡量將 LDO 接到 DCDC 輸出回路,但是要注意上電時序。
DCDC 一般有兩種工作模式:
PWM–紋波瞬態響應好,效率低;
PFM:效率高,但是負載能力差。
平台概述
RICO619(5路DCDC)
RK808
ACT8846
各模塊需要供電:
ARM 1.0V
GPU 1.0V
DDR 1.2V
VCCIO 3.3V
LOGIC 1.0V(分立 PWM)
Logic 需要動態調壓,如果采用分立DCDC(PWM),調節精度、輸出電壓一致性不能保證。
雙電池 ACT8846 + SYR82X
單電池 RK808 或者 RICOH619 + SYR82X
RK808
(本方案采用的 RK808)
| Resource | VCC1 | VCC2 | VCC3 | VCC4 | LDO1 | LDO2 | LDO3 |
|---|---|---|---|---|---|---|---|
| VOL | 1.0V | 1.0V | 1.2V | 3.3V | 3.3V | 3.3V | 1.0V |
| TimeSlot | 2 | 2 | 4 | 2 | 1 | OFF | 2 |
| Resource | LDO4 | LDO5 | LDO6 | LDO7 | LDO8 | VSWOUT1 | VSWOUT2 |
|---|---|---|---|---|---|---|---|
| VOL | 1.8V | 3.3V | 1.2V | 1.8V | 3.3V | 3.0V | 3.0V |
| TimeSlot | OFF | 5 | OFF | 3 | OFF | OFF | OFF |
開機流程:
當有接適配器時。
VDC 電壓 升高; VSYS 上電; PMIC 上電並輸出。
當只接電池時,按開機鍵。
PWRON 拉高; PMIC 上電並輸出。PMIC 啟動,實現 EPROM 中的默認設置,各路上電完成后,發送 reset 信號,芯片上電,系統啟動,PMIC 設備掛載,通過I2C 重新配置 PMIC。
PWM 介紹
PWM 即通過占空比設置電壓。
計算占空比:
利用 pwm_regulator_set_voltage 將設置的電壓轉換成占空比
pwm_value = (max - vol)/coefficient/10 //計算占空比,max 及 coefficient 由板級傳參
設置占空比:
在rockchip-pwm-regulator.c中pwm_set_rate()
RATE為0時設置PWM為GPIO口輸出低,控制LOGIC電壓最高(1.4V)。
RATE為100時設置PWM為GPIO口輸出高,控制LOGIC電壓最低(0.9V)。
RATE在0~100之間:
根據當前PWM的CLK計算高電平和低電平的值,然后寫到PWM控制寄存器中即可
其驅動方面需要按特定流程,先將 PWM 控制器 disable 並且 RESET,然后設置,最后 enable。
驅動分析
dts
先看 rk808.dtsi
rk808_dcdc1_reg: regulator@0 {
reg = <0>; regulator-compatible = "rk_dcdc1"; regulator-min-microvolt = <700000>; //min 和 max 相同時,初始化會設置電壓。不一樣則表示范圍。 regulator-max-microvolt = <1500000>; regulator-initial-mode = <0x2>; //工作模式,類別參考手冊 regulator-initial-state = <3>; //suspend 模式下的設置 regulator-state-mem { //休眠模式下的工作模式 regulator-state-mode = <0x2>; regulator-state-disabled;//disabled //休眠下的使能狀態 regulator-state-uv = <900000>; //休眠下的電壓 }; };
再看 rk3288-tb_8846.dts
/include/ "rk808.dtsi" &rk808 { gpios =<&gpio0 GPIO_A4 GPIO_ACTIVE_HIGH>,<&gpio0 GPIO_B3 GPIO_ACTIVE_LOW>; rk808,system-power-controller; regulators { rk808_dcdc1_reg: regulator@0{ regulator-name= "vdd_arm"; //驅動根據這個name 設置 PMU 電壓、工作模式、使能。不可重名。 regulator-always-on; //表示常開 regulator-boot-on; }; ... };
驅動流程
PMIC
regulator_ops 注冊,完成 PMU 驅動與 regulator 之間鏈接:
kernel/drivers/regulator/
完成 regulator_ops 的注冊后,可以使用 regulator 的接口了。(regulator_set_voltage)
PWM
用 PWM 調整外掛 DCDC 電壓,注冊 PWM 驅動
pwm_regulator {
compatible = "rockchip_pwm_regulator"; pwms = <&pwm1 0 2000>; rockchip,pwm_id= <1>; rockchip,pwm_voltage_map= <925000 950000 975000 1000000 1025000 1050000 1075000 1100000 1125000 1150000 1175000 1200000 1225000 1250000 1275000 1300000 1325000 1350000 1375000 1400000>; rockchip,pwm_voltage= <1000000>; rockchip,pwm_min_voltage= <925000>; rockchip,pwm_max_voltage= <1400000>; rockchip,pwm_suspend_voltage= <950000>; rockchip,pwm_coefficient= <475>; regulators { #address-cells = <1>; #size-cells = <0>; pwm_reg0: regulator@0 { regulator-compatible = "pwm_dcdc1"; regulator-name= "vdd_logic"; regulator-min-microvolt = <925000>; regulator-max-microvolt = <1400000>; regulator-always-on; regulator-boot-on; }; }; };
並且打開 PWM 口
&pwm1 {
status = "okay";
};
配置相關
menuconfig
/rk808
相關的兩個宏打開
修改各路 DCDC 和 LDO
方法一,修改dts
通過設置 dts 里面的
regulator-min-microvolt = < 3300000>; regulator-max-microvolt = <3300000>;
pwm_regulator { rockchip,pwm_voltage= <1000000>; };
來設置默認電壓。
方法二,運行中動態設置
Struct regulator *dcdc;
dcdc =regulator_get(NULL, "name");
regulator_set_voltage(dcdc, min_uv, max_uv); regulator_enable(dcdc); regulator_put(dcdc);
設置 DCDC 工作模式接口
DCDC 有兩種模式(PWM、PFM)。
有一種 Auto 模式會自動調整 PWM、PFM。
所以我們常說的兩種模式是 PWM 和 AUTO(PWM+PFM)。
AUTO 模式 效率高、紋波瞬態響應差。
現在一般都 PWM 模式。
方法一,初始化設置
regulator-initial-mode< 0x2 >
方法二,運行下切換
dcdc = regulator_get(NULL, "name"); regulator_set_mode(dcdc, REGULATOR_MODE_STANDBY); //pwm:REGULATOR_MODE_NORMAL pfm: REGULATOR_MODE_STANDBY
ldo =regulator_get(NULL, "act_ldo1"); regulator_enable(ldo); //開啟 ldo1 //regulator_disable(ldo); //關閉 ldo1
調試流程與碰到的問題
- 開機打印 PMU 注冊失敗,提示 i2c 通信失敗,或者直接跑飛
1)測試 i2c 的 CLK 和 data 數據線是否被拉低;
2)核對 i2c 有沒有注冊錯,使用的 i2c 是否跟平台
上一致;
3)i2c 上是否還有其他設備;
4)測試 PMIC 的各路默認的上電電壓是否正確;
5)測試Power_hold 是否為高;
6)測試 PMIC 默認上電完成后 reset 信號是否發送;
7)PMIC 外圍部件是
否焊接錯誤,例如晶振有沒有焊反,電感、電容等有沒有焊錯。 - 系統運行中死機
1)測試死機時各路的電壓,是否有電壓異常;
2)測試 DVFS 調整是否正常;
3)測試 arm、logic、DDR、VCCIO 的電壓的紋波等,看下在系統異常時是否有明顯的電壓塌陷。
3 、待機喚醒死機
1)測試 PMU_sleep 腳已經恢復成低;
2)測試各路電壓已經從待機電壓恢復回來;
3)用示波器測試喚醒時各路電壓的的變化波形,有無異常;4)sleep 狀態不去關閉電源。不降低電壓;
Reset 后無法開機或者某些設備異常 - Reset
如果出現此問題,請參考本文第三章 pmic 的關機及復位。
Reset 按下時,芯片復位,各個 io 口恢復成默認值,如果 PMU 沒有復位功能或者沒有完成硬復位,
則 PMU 不會被復位,則無法完成 PMU 的斷電並重新上電,這樣可能會導致部分設備重啟后工作
不正常。(部分項目上發現有些設備在復位時必須要掉電,否則會工作異常)
RTC 無法正常寫入 - RTC
1)如果 PMU 是 act8846(不帶 RTC)此時要看下 RTC 設備是否掛載正常;2)PMU 設備的 i2c
通信是否正常 - 運行時部分 LDO 沒有輸出
1)確認此 LDO 在其他地方沒有被關閉,通過搜索此 LDO 的 name (使用此接口 regulator_disable());
2)測試 PMIC_SLEEP 腳是不是為高,如果為高,PMU 已經進入休眠模式,部分 LDO 會被關閉。
PMIC_SLEEP 腳的配置應該是不對的,需要配置此 io 口:見本文檔 1.2 章(注意:硬件上此 io 口,
最好沒有復用功能,而且是應該是默認內部下拉口) - 關機后隨機性的自動開機或者關機失敗
關機失敗:device_shutdown()中會通過 i2c 寫關機命令,i2c 通信失敗,無法寫關機命令。如果遇到此問題。加一些保護鎖,如果一直寫失敗,直接重啟。
關機后自動開機:因為 RTC 鬧鈴具有開機的功能,在關機后如果 RTC 鬧鈴產生,即會觸發開機條
件而開機。目前已經解決過了,在關機函數中先關閉 RTC 鬧鈴的中斷,在開機時再打開中斷。 - 待機時隨機性被喚醒
如果喚醒中斷是 PMIC_INT,那么應該是 PMU 的 RTC 鬧鈴在喚醒系統。除了用戶設置的鬧鈴外,
還有一些谷歌的應用會產生 RTC 鬧鈴,需要移除相應的應用。查看方法如下:
請客戶在命令行中敲入 dumpsys alarm 來查看當前系統的 alarm 申請情況。
android 總共有4種類型 alarm,其中只有2種 alarm 會在休眠喚醒系統,請在相關信息中查找對應的
第三方軟件。
這兩種分別是 ELAPSED_WAKEUP 和 RTC_WAKEUP。
我們觀察到,凡是帶了谷歌相關的 apk 就會申請相關 alarm,如下:
RTC_WAKEUP #5: Alarm{413418b8 type 0 com.google.android.gsf}
type=0 when=+5d17h1m54s609ms repeatInterval=566316000 count=0
operation=PendingIntent{41294818: PendingIntentRecord{413ce158
com.google.android.gsf broadcastIntent}}
注意:此喚醒動作只在二級待機,不會到一級待機喚醒,點亮屏,如果點亮了屏,應該是屏那邊沒有進
休眠。
RICOH619 - RICOH619
RICOH619無法開機或者開機后電量顯示異常
確認電池包上 TS 端是否有10K 電阻,如果沒有,請確認板子上 TS 端對地有10K 電阻。如果沒有10K
電阻,PMIC 默認電池是不存在的。 - RICOH619
RICOH619充電異常,充電電流多小,或者充電充不滿
充電電流過小:
我們上電有默認的充電電流,USB:500MA , ADP :1A,開機后 USB 根據枚舉結果通過 I2C
重新設置充電電流,最大可設置 3A(一般推薦到 2A),ADP 電流開機后就會修改,最大 3A。
實際往電池充的電流跟設置電流會有一些不一樣,有充電效率的關系。詳細見下:
ILIM_USB/ILIM_ADP 的設置值 限制 USB/ADP 輸入時 VSYS 系統輸出的電流極限最大
限流。 ( 實際限制的輸出值 大約在 設置值 的 90% 左右 )
因為 工作方式是 DCDC 的關系, 實際的輸入電流會小於輸出電流。
( 功率轉換:理想情況下 輸入 5V x 1A
5V = VADP, 1A = I_ADP,
4V = VSYS,
=4V * 1.25A )
Ex.
ILIM_ADP = 1.25A.
另外,限制電流的偵測方式是 由 ILM, ILP 間的 Sense 電阻 壓降而得到。
( ILM , ILP 端口需要直接采集 電阻( 20mohm ) 上的 壓降,需要注意版圖畫法)
關於流入電池的電流 可以 查看一下 ICM , ICP 之間的 Sense 電阻的壓降來判斷。
當然,也需要小心制版時, PMU 的 ICM, ICP 是否取到的直接時 電阻兩端的電壓。 - 1.5A 設置 輸入限流, 實際輸出限制 大約 1.3A 以上。
( 可通過 檢測 ILM /
ILP 間 電阻壓降 ) - 由於是 DCDC 工作的方式, IUSB= VSYS * I_SYS V_USB * I_USB * 效率 = VSYS * I_SYS / (V_USB * 效率 ) = 4.0 * 1.3 / ( 5 * 0.9 ) = 1.1A ( 約 ) 充電充不滿: 充電有充電時間的限制,一般是充電 5 小時就會關閉充電,所以存在一邊使用一邊充電時電池充 不滿,這個問題我們后期會使用軟件解決。
