summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2019-10-26 07:50:45 -0400
committerTom Rini <trini@konsulko.com>2019-10-26 07:50:45 -0400
commitd1882290e5c08255ef34611af6ad0b7b0b82b1e1 (patch)
tree6422bea37619549c10c84a1667cb8ef11a897b9a
parentffc379b42c85466e1dd4c8fee8268801f26d2ab8 (diff)
parenta8a09d078d5e17873754b33dc5d15858d2cb2605 (diff)
downloadu-boot-WIP/26Oct2019.tar.gz
Merge tag 'u-boot-rockchip-20191026' of https://gitlab.denx.de/u-boot/custodians/u-boot-rockchipWIP/26Oct2019
- Add support for rockchip pmic rk805,rk809, rk816, rk817 - Add rk3399 board Leez support - Fix bug in rk3328 ram driver - Adapt SPL to support ATF bl31 with entry at 0x40000
-rw-r--r--arch/arm/dts/Makefile1
-rw-r--r--arch/arm/dts/rk3328-rock64-u-boot.dtsi5
-rw-r--r--arch/arm/dts/rk3399-leez-p710-u-boot.dtsi13
-rw-r--r--arch/arm/dts/rk3399-leez-p710.dts645
-rw-r--r--arch/arm/include/asm/arch-rockchip/cru_rk3328.h3
-rwxr-xr-xarch/arm/mach-rockchip/make_fit_atf.py52
-rw-r--r--arch/arm/mach-rockchip/rk3188/rk3188.c4
-rw-r--r--arch/arm/mach-rockchip/rk322x/rk322x.c4
-rw-r--r--arch/arm/mach-rockchip/rk3288/Kconfig1
-rw-r--r--arch/arm/mach-rockchip/rk3288/rk3288.c4
-rw-r--r--arch/arm/mach-rockchip/rk3328/rk3328.c4
-rw-r--r--arch/arm/mach-rockchip/rk3368/rk3368.c4
-rw-r--r--arch/arm/mach-rockchip/rk3399/Kconfig3
-rw-r--r--board/rockchip/evb_rk3399/MAINTAINERS6
-rw-r--r--common/spl/spl_atf.c49
-rw-r--r--configs/chromebook_bob_defconfig1
-rw-r--r--configs/evb-px5_defconfig1
-rw-r--r--configs/evb-rk3328_defconfig1
-rw-r--r--configs/evb-rk3399_defconfig2
-rw-r--r--configs/ficus-rk3399_defconfig1
-rw-r--r--configs/firefly-rk3288_defconfig5
-rw-r--r--configs/firefly-rk3399_defconfig2
-rw-r--r--configs/khadas-edge-captain-rk3399_defconfig2
-rw-r--r--configs/khadas-edge-rk3399_defconfig2
-rw-r--r--configs/khadas-edge-v-rk3399_defconfig2
-rw-r--r--configs/leez-rk3399_defconfig56
-rw-r--r--configs/nanopc-t4-rk3399_defconfig2
-rw-r--r--configs/nanopi-m4-rk3399_defconfig2
-rw-r--r--configs/nanopi-neo4-rk3399_defconfig2
-rw-r--r--configs/orangepi-rk3399_defconfig2
-rw-r--r--configs/puma-rk3399_defconfig1
-rw-r--r--configs/roc-rk3399-pc_defconfig2
-rw-r--r--configs/rock-pi-4-rk3399_defconfig2
-rw-r--r--configs/rock64-rk3328_defconfig1
-rw-r--r--configs/rock960-rk3399_defconfig1
-rw-r--r--configs/rockpro64-rk3399_defconfig2
-rw-r--r--doc/device-tree-bindings/regulator/regulator.txt27
-rw-r--r--drivers/clk/rockchip/clk_rk3328.c2
-rw-r--r--drivers/power/pmic/rk8xx.c89
-rw-r--r--drivers/power/regulator/regulator-uclass.c70
-rw-r--r--drivers/power/regulator/rk8xx.c939
-rw-r--r--drivers/ram/rockchip/sdram_rk3328.c6
-rw-r--r--include/configs/rk3328_common.h2
-rw-r--r--include/configs/rk3368_common.h2
-rw-r--r--include/configs/rk3399_common.h2
-rw-r--r--include/power/regulator.h64
-rw-r--r--include/power/rk8xx_pmic.h42
-rw-r--r--test/dm/regulator.c57
48 files changed, 2034 insertions, 158 deletions
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 6a7dbb6309..2b14c29b73 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -111,6 +111,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3399) += \
rk3399-khadas-edge.dtb \
rk3399-khadas-edge-captain.dtb \
rk3399-khadas-edge-v.dtb \
+ rk3399-leez-p710.dtb \
rk3399-nanopc-t4.dtb \
rk3399-nanopi-m4.dtb \
rk3399-nanopi-neo4.dtb \
diff --git a/arch/arm/dts/rk3328-rock64-u-boot.dtsi b/arch/arm/dts/rk3328-rock64-u-boot.dtsi
index 1d441f7124..e5946d2d2d 100644
--- a/arch/arm/dts/rk3328-rock64-u-boot.dtsi
+++ b/arch/arm/dts/rk3328-rock64-u-boot.dtsi
@@ -5,6 +5,11 @@
#include "rk3328-u-boot.dtsi"
#include "rk3328-sdram-lpddr3-1600.dtsi"
+/ {
+ chosen {
+ u-boot,spl-boot-order = "same-as-spl", &sdmmc, &emmc;
+ };
+};
&usb_host0_xhci {
status = "okay";
diff --git a/arch/arm/dts/rk3399-leez-p710-u-boot.dtsi b/arch/arm/dts/rk3399-leez-p710-u-boot.dtsi
new file mode 100644
index 0000000000..f8b2a1d56e
--- /dev/null
+++ b/arch/arm/dts/rk3399-leez-p710-u-boot.dtsi
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 Andy Yan <andy.yan@gmail.com>
+ */
+
+#include "rk3399-u-boot.dtsi"
+#include "rk3399-sdram-lpddr4-100.dtsi"
+
+/ {
+ chosen {
+ u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc;
+ };
+};
diff --git a/arch/arm/dts/rk3399-leez-p710.dts b/arch/arm/dts/rk3399-leez-p710.dts
new file mode 100644
index 0000000000..32baa57b94
--- /dev/null
+++ b/arch/arm/dts/rk3399-leez-p710.dts
@@ -0,0 +1,645 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Andy Yan <andy.yan@gmail.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "rk3399.dtsi"
+#include "rk3399-opp.dtsi"
+
+/ {
+ model = "Leez RK3399 P710";
+ compatible = "leez,p710", "rockchip,rk3399";
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ clkin_gmac: external-gmac-clock {
+ compatible = "fixed-clock";
+ clock-frequency = <125000000>;
+ clock-output-names = "clkin_gmac";
+ #clock-cells = <0>;
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rk808 1>;
+ clock-names = "ext_clock";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_reg_on_h>;
+ reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
+ };
+
+ dc5v_adp: dc5v-adp {
+ compatible = "regulator-fixed";
+ regulator-name = "dc5v_adapter";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vcc5v0_sys: vcc5v0-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&dc5v_adp>;
+ };
+
+ vcc3v3_sys: vcc3v3-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_host0: vcc5v0_host1: vcc5v0-host {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_host";
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-min-microvolt = <5500000>;
+ regulator-max-microvolt = <5500000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_host3: vcc5v0-host3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_host3";
+ enable-active-high;
+ gpio = <&gpio2 RK_PA2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_host3_en>;
+ regulator-always-on;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_lan: vcc3v3-lan {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_lan";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vim-supply = <&vcc3v3_sys>;
+ };
+
+ vdd_log: vdd-log {
+ compatible = "pwm-regulator";
+ pwms = <&pwm2 0 25000 1>;
+ regulator-name = "vdd_log";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l1 {
+ cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l2 {
+ cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l3 {
+ cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu_b>;
+};
+
+&cpu_b1 {
+ cpu-supply = <&vdd_cpu_b>;
+};
+
+&emmc_phy {
+ status = "okay";
+};
+
+&gmac {
+ assigned-clocks = <&cru SCLK_RMII_SRC>;
+ assigned-clock-parents = <&clkin_gmac>;
+ clock_in_out = "input";
+ phy-supply = <&vcc3v3_lan>;
+ phy-mode = "rgmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins>;
+ snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 50000>;
+ tx_delay = <0x28>;
+ rx_delay = <0x11>;
+ status = "okay";
+};
+
+&gpu {
+ mali-supply = <&vdd_gpu>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_cec>;
+ status = "okay";
+};
+
+&hdmi_sound {
+ status = "okay";
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+ i2c-scl-rising-time-ns = <168>;
+ i2c-scl-falling-time-ns = <4>;
+ status = "okay";
+
+ rk808: pmic@1b {
+ compatible = "rockchip,rk808";
+ reg = <0x1b>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
+ #clock-cells = <1>;
+ clock-output-names = "xin32k", "rk808-clkout2";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int_l>;
+ rockchip,system-power-controller;
+ wakeup-source;
+
+ vcc1-supply = <&vcc5v0_sys>;
+ vcc2-supply = <&vcc5v0_sys>;
+ vcc3-supply = <&vcc5v0_sys>;
+ vcc4-supply = <&vcc5v0_sys>;
+ vcc6-supply = <&vcc5v0_sys>;
+ vcc7-supply = <&vcc5v0_sys>;
+ vcc8-supply = <&vcc3v3_sys>;
+ vcc9-supply = <&vcc5v0_sys>;
+ vcc10-supply = <&vcc5v0_sys>;
+ vcc11-supply = <&vcc5v0_sys>;
+ vcc12-supply = <&vcc3v3_sys>;
+ vddio-supply = <&vcc_1v8>;
+
+ regulators {
+ vdd_center: DCDC_REG1 {
+ regulator-name = "vdd_center";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_l: DCDC_REG2 {
+ regulator-name = "vdd_cpu_l";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-name = "vcc_ddr";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_1v8: DCDC_REG4 {
+ regulator-name = "vcc_1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vcc1v8_dvp: LDO_REG1 {
+ regulator-name = "vcc1v8_dvp";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc1v8_hdmi: LDO_REG2 {
+ regulator-name = "vcc1v8_hdmi";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcca_1v8: LDO_REG3 {
+ regulator-name = "vcca_1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vccio_sd: LDO_REG4 {
+ regulator-name = "vccio_sd";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3000000>;
+ };
+ };
+
+ vcca3v0_codec: LDO_REG5 {
+ regulator-name = "vcca3v0_codec";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v5: LDO_REG6 {
+ regulator-name = "vcc_1v5";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1500000>;
+ };
+ };
+
+ vcc0v9_hdmi: LDO_REG7 {
+ regulator-name = "vcc0v9_hdmi";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v0: LDO_REG8 {
+ regulator-name = "vcc_3v0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3000000>;
+ };
+ };
+ };
+ };
+
+ vdd_cpu_b: regulator@40 {
+ compatible = "silergy,syr827";
+ reg = <0x40>;
+ fcs,suspend-voltage-selector = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vsel1_gpio>;
+ regulator-name = "vdd_cpu_b";
+ regulator-min-microvolt = <712500>;
+ regulator-max-microvolt = <1500000>;
+ regulator-ramp-delay = <1000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_gpu: regulator@41 {
+ compatible = "silergy,syr828";
+ reg = <0x41>;
+ fcs,suspend-voltage-selector = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vsel2_gpio>;
+ regulator-name = "vdd_gpu";
+ regulator-min-microvolt = <712500>;
+ regulator-max-microvolt = <1500000>;
+ regulator-ramp-delay = <1000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c1 {
+ i2c-scl-rising-time-ns = <300>;
+ i2c-scl-falling-time-ns = <15>;
+ status = "okay";
+};
+
+&i2c3 {
+ i2c-scl-rising-time-ns = <450>;
+ i2c-scl-falling-time-ns = <15>;
+ status = "okay";
+};
+
+&i2c4 {
+ i2c-scl-rising-time-ns = <600>;
+ i2c-scl-falling-time-ns = <20>;
+ status = "okay";
+};
+
+&i2c7 {
+ status = "okay";
+};
+
+&i2s0 {
+ rockchip,playback-channels = <8>;
+ rockchip,capture-channels = <8>;
+ status = "okay";
+};
+
+&i2s1 {
+ rockchip,playback-channels = <2>;
+ rockchip,capture-channels = <2>;
+ status = "okay";
+};
+
+&i2s2 {
+ status = "okay";
+};
+
+&io_domains {
+ status = "okay";
+
+ bt656-supply = <&vcc1v8_dvp>;
+ audio-supply = <&vcc_1v8>;
+ sdmmc-supply = <&vccio_sd>;
+ gpio1830-supply = <&vcc_3v0>;
+};
+
+&pmu_io_domains {
+ status = "okay";
+ pmu1830-supply = <&vcc_3v0>;
+};
+
+&pinctrl {
+ bt {
+ bt_reg_on_h: bt-reg-on-h {
+ rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_host_wake_l: bt-host-wake-l {
+ rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_wake_l: bt-wake-l {
+ rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ pmic_int_l: pmic-int-l {
+ rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ vsel1_gpio: vsel1-gpio {
+ rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+
+ vsel2_gpio: vsel2-gpio {
+ rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+
+ usb2 {
+ vcc5v0_host3_en: vcc5v0-host3-en {
+ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ wifi {
+ wifi_reg_on_h: wifi-reg-on-h {
+ rockchip,pins =
+ <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ wifi_host_wake_l: wifi-host-wake-l {
+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pwm2 {
+ status = "okay";
+};
+
+&saradc {
+ status = "okay";
+
+ vref-supply = <&vcc_1v8>;
+};
+
+&sdio0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ bus-width = <4>;
+ clock-frequency = <50000000>;
+ cap-sdio-irq;
+ cap-sd-highspeed;
+ keep-power-in-suspend;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
+ sd-uhs-sdr104;
+ status = "okay";
+
+ brcmf: wifi@1 {
+ compatible = "brcm,bcm4329-fmac";
+ reg = <1>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA3 GPIO_ACTIVE_HIGH>;
+ interrupt-names = "host-wake";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_host_wake_l>;
+ };
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ max-frequency = <150000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_clk &sdmmc_cd &sdmmc_cmd &sdmmc_bus4>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ non-removable;
+ status = "okay";
+};
+
+&tcphy0 {
+ status = "okay";
+};
+
+&tcphy1 {
+ status = "okay";
+};
+
+&tsadc {
+ status = "okay";
+
+ /* tshut mode 0:CRU 1:GPIO */
+ rockchip,hw-tshut-mode = <1>;
+ /* tshut polarity 0:LOW 1:HIGH */
+ rockchip,hw-tshut-polarity = <1>;
+};
+
+&u2phy0 {
+ status = "okay";
+
+ u2phy0_otg: otg-port {
+ status = "okay";
+ };
+
+ u2phy0_host: host-port {
+ phy-supply = <&vcc5v0_host0>;
+ status = "okay";
+ };
+};
+
+&u2phy1 {
+ status = "okay";
+
+ u2phy1_otg: otg-port {
+ status = "okay";
+ };
+
+ u2phy1_host: host-port {
+ phy-supply = <&vcc5v0_host1>;
+ status = "okay";
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+ status = "okay";
+
+ bluetooth {
+ compatible = "brcm,bcm43438-bt";
+ clocks = <&rk808 1>;
+ clock-names = "ext_clock";
+ device-wakeup-gpios = <&gpio2 RK_PD2 GPIO_ACTIVE_HIGH>;
+ host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>;
+ shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_reg_on_h>;
+ };
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
+
+&usbdrd3_0 {
+ status = "okay";
+};
+
+&usbdrd_dwc3_0 {
+ status = "okay";
+ dr_mode = "otg";
+};
+
+&usbdrd3_1 {
+ status = "okay";
+};
+
+&usbdrd_dwc3_1 {
+ status = "okay";
+ dr_mode = "host";
+};
+
+&vopb {
+ status = "okay";
+};
+
+&vopb_mmu {
+ status = "okay";
+};
+
+&vopl {
+ status = "okay";
+};
+
+&vopl_mmu {
+ status = "okay";
+};
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3328.h b/arch/arm/include/asm/arch-rockchip/cru_rk3328.h
index 15b9788d9c..4bf69dbe08 100644
--- a/arch/arm/include/asm/arch-rockchip/cru_rk3328.h
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3328.h
@@ -66,4 +66,7 @@ enum apll_frequencies {
APLL_600_MHZ,
};
+void rk3328_configure_cpu(struct rk3328_cru *cru,
+ enum apll_frequencies apll_freq);
+
#endif /* __ASM_ARCH_CRU_RK3328_H_ */
diff --git a/arch/arm/mach-rockchip/make_fit_atf.py b/arch/arm/mach-rockchip/make_fit_atf.py
index 585edcf9d5..3c045a5e17 100755
--- a/arch/arm/mach-rockchip/make_fit_atf.py
+++ b/arch/arm/mach-rockchip/make_fit_atf.py
@@ -63,6 +63,21 @@ def append_bl31_node(file, atf_index, phy_addr, elf_entry):
file.write('\t\t};\n')
file.write('\n')
+def append_tee_node(file, atf_index, phy_addr, elf_entry):
+ # Append TEE DT node to input FIT dts file.
+ data = 'tee_0x%08x.bin' % phy_addr
+ file.write('\t\tatf_%d {\n' % atf_index)
+ file.write('\t\t\tdescription = \"TEE\";\n')
+ file.write('\t\t\tdata = /incbin/("%s");\n' % data)
+ file.write('\t\t\ttype = "tee";\n')
+ file.write('\t\t\tarch = "arm64";\n')
+ file.write('\t\t\tos = "tee";\n')
+ file.write('\t\t\tcompression = "none";\n')
+ file.write('\t\t\tload = <0x%08x>;\n' % phy_addr)
+ file.write('\t\t\tentry = <0x%08x>;\n' % elf_entry)
+ file.write('\t\t};\n')
+ file.write('\n')
+
def append_fdt_node(file, dtbs):
# Append FDT nodes.
cnt = 1
@@ -115,15 +130,23 @@ def generate_atf_fit_dts_uboot(fit_file, uboot_file_name):
index, entry, p_paddr, data = segments[0]
fit_file.write(DT_UBOOT % p_paddr)
-def generate_atf_fit_dts_bl31(fit_file, bl31_file_name, dtbs_file_name):
+def generate_atf_fit_dts_bl31(fit_file, bl31_file_name, tee_file_name, dtbs_file_name):
segments = unpack_elf(bl31_file_name)
for index, entry, paddr, data in segments:
append_bl31_node(fit_file, index + 1, paddr, entry)
+ num_segments = len(segments)
+
+ if tee_file_name:
+ tee_segments = unpack_elf(tee_file_name)
+ for index, entry, paddr, data in tee_segments:
+ append_tee_node(fit_file, num_segments + index + 1, paddr, entry)
+ num_segments = num_segments + len(tee_segments)
+
append_fdt_node(fit_file, dtbs_file_name)
fit_file.write(DT_IMAGES_NODE_END)
- append_conf_node(fit_file, dtbs_file_name, len(segments))
+ append_conf_node(fit_file, dtbs_file_name, num_segments)
-def generate_atf_fit_dts(fit_file_name, bl31_file_name, uboot_file_name, dtbs_file_name):
+def generate_atf_fit_dts(fit_file_name, bl31_file_name, tee_file_name, uboot_file_name, dtbs_file_name):
# Generate FIT script for ATF image.
if fit_file_name != sys.stdout:
fit_file = open(fit_file_name, "wb")
@@ -132,7 +155,7 @@ def generate_atf_fit_dts(fit_file_name, bl31_file_name, uboot_file_name, dtbs_fi
fit_file.write(DT_HEADER)
generate_atf_fit_dts_uboot(fit_file, uboot_file_name)
- generate_atf_fit_dts_bl31(fit_file, bl31_file_name, dtbs_file_name)
+ generate_atf_fit_dts_bl31(fit_file, bl31_file_name, tee_file_name, dtbs_file_name)
fit_file.write(DT_END)
if fit_file_name != sys.stdout:
@@ -144,6 +167,13 @@ def generate_atf_binary(bl31_file_name):
with open(file_name, "wb") as atf:
atf.write(data)
+def generate_tee_binary(tee_file_name):
+ if tee_file_name:
+ for index, entry, paddr, data in unpack_elf(tee_file_name):
+ file_name = 'tee_0x%08x.bin' % paddr
+ with open(file_name, "wb") as atf:
+ atf.write(data)
+
def unpack_elf(filename):
with open(filename, 'rb') as file:
elf = file.read()
@@ -178,7 +208,14 @@ def main():
logging.warning(' BL31 file bl31.elf NOT found, resulting binary is non-functional')
logging.warning(' Please read Building section in doc/README.rockchip')
- opts, args = getopt.getopt(sys.argv[1:], "o:u:b:h")
+ if "TEE" in os.environ:
+ tee_elf = os.getenv("TEE")
+ elif os.path.isfile("./tee.elf"):
+ tee_elf = "./tee.elf"
+ else:
+ tee_elf = ""
+
+ opts, args = getopt.getopt(sys.argv[1:], "o:u:b:t:h")
for opt, val in opts:
if opt == "-o":
fit_its = val
@@ -186,14 +223,17 @@ def main():
uboot_elf = val
elif opt == "-b":
bl31_elf = val
+ elif opt == "-t":
+ tee_elf = val
elif opt == "-h":
print(__doc__)
sys.exit(2)
dtbs = args
- generate_atf_fit_dts(fit_its, bl31_elf, uboot_elf, dtbs)
+ generate_atf_fit_dts(fit_its, bl31_elf, tee_elf, uboot_elf, dtbs)
generate_atf_binary(bl31_elf)
+ generate_tee_binary(tee_elf)
if __name__ == "__main__":
main()
diff --git a/arch/arm/mach-rockchip/rk3188/rk3188.c b/arch/arm/mach-rockchip/rk3188/rk3188.c
index 95f0e3ccbe..1b012f7f67 100644
--- a/arch/arm/mach-rockchip/rk3188/rk3188.c
+++ b/arch/arm/mach-rockchip/rk3188/rk3188.c
@@ -14,8 +14,8 @@
#define GRF_BASE 0x20008000
const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
- [BROM_BOOTSOURCE_EMMC] = "dwmmc@1021c000",
- [BROM_BOOTSOURCE_SD] = "dwmmc@10214000",
+ [BROM_BOOTSOURCE_EMMC] = "/dwmmc@1021c000",
+ [BROM_BOOTSOURCE_SD] = "/dwmmc@10214000",
};
#ifdef CONFIG_DEBUG_UART_BOARD_INIT
diff --git a/arch/arm/mach-rockchip/rk322x/rk322x.c b/arch/arm/mach-rockchip/rk322x/rk322x.c
index cd0bf8a70c..562117e6c1 100644
--- a/arch/arm/mach-rockchip/rk322x/rk322x.c
+++ b/arch/arm/mach-rockchip/rk322x/rk322x.c
@@ -8,8 +8,8 @@
#include <asm/arch-rockchip/hardware.h>
const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
- [BROM_BOOTSOURCE_EMMC] = "dwmmc@30020000",
- [BROM_BOOTSOURCE_SD] = "dwmmc@30000000",
+ [BROM_BOOTSOURCE_EMMC] = "/dwmmc@30020000",
+ [BROM_BOOTSOURCE_SD] = "/dwmmc@30000000",
};
#ifdef CONFIG_DEBUG_UART_BOARD_INIT
diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig
index 4ebc0792d5..afb62fca78 100644
--- a/arch/arm/mach-rockchip/rk3288/Kconfig
+++ b/arch/arm/mach-rockchip/rk3288/Kconfig
@@ -67,6 +67,7 @@ config TARGET_FIREFLY_RK3288
bool "Firefly-RK3288"
select BOARD_LATE_INIT
select SPL_BOARD_INIT if SPL
+ select TPL
help
Firefly is a RK3288-based development board with 2 USB ports,
HDMI, VGA, micro-SD card, audio, WiFi and Gigabit Ethernet, It
diff --git a/arch/arm/mach-rockchip/rk3288/rk3288.c b/arch/arm/mach-rockchip/rk3288/rk3288.c
index 057ce92080..987b4e0d58 100644
--- a/arch/arm/mach-rockchip/rk3288/rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/rk3288.c
@@ -22,8 +22,8 @@ DECLARE_GLOBAL_DATA_PTR;
#define GRF_BASE 0xff770000
const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
- [BROM_BOOTSOURCE_EMMC] = "dwmmc@ff0f0000",
- [BROM_BOOTSOURCE_SD] = "dwmmc@ff0c0000",
+ [BROM_BOOTSOURCE_EMMC] = "/dwmmc@ff0f0000",
+ [BROM_BOOTSOURCE_SD] = "/dwmmc@ff0c0000",
};
#ifdef CONFIG_SPL_BUILD
diff --git a/arch/arm/mach-rockchip/rk3328/rk3328.c b/arch/arm/mach-rockchip/rk3328/rk3328.c
index c2448d7273..8c81242e5d 100644
--- a/arch/arm/mach-rockchip/rk3328/rk3328.c
+++ b/arch/arm/mach-rockchip/rk3328/rk3328.c
@@ -19,8 +19,8 @@ DECLARE_GLOBAL_DATA_PTR;
#define FW_DDR_CON_REG 0xFF7C0040
const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
- [BROM_BOOTSOURCE_EMMC] = "rksdmmc@ff520000",
- [BROM_BOOTSOURCE_SD] = "rksdmmc@ff500000",
+ [BROM_BOOTSOURCE_EMMC] = "/rksdmmc@ff520000",
+ [BROM_BOOTSOURCE_SD] = "/rksdmmc@ff500000",
};
static struct mm_region rk3328_mem_map[] = {
diff --git a/arch/arm/mach-rockchip/rk3368/rk3368.c b/arch/arm/mach-rockchip/rk3368/rk3368.c
index 7ccd417a18..20ae797794 100644
--- a/arch/arm/mach-rockchip/rk3368/rk3368.c
+++ b/arch/arm/mach-rockchip/rk3368/rk3368.c
@@ -54,8 +54,8 @@ static struct mm_region rk3368_mem_map[] = {
struct mm_region *mem_map = rk3368_mem_map;
const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
- [BROM_BOOTSOURCE_EMMC] = "dwmmc@ff0f0000",
- [BROM_BOOTSOURCE_SD] = "dwmmc@ff0c0000",
+ [BROM_BOOTSOURCE_EMMC] = "/dwmmc@ff0f0000",
+ [BROM_BOOTSOURCE_SD] = "/dwmmc@ff0c0000",
};
#ifdef CONFIG_ARCH_EARLY_INIT_R
diff --git a/arch/arm/mach-rockchip/rk3399/Kconfig b/arch/arm/mach-rockchip/rk3399/Kconfig
index 6660d05349..f781eacd16 100644
--- a/arch/arm/mach-rockchip/rk3399/Kconfig
+++ b/arch/arm/mach-rockchip/rk3399/Kconfig
@@ -91,6 +91,9 @@ config TPL_STACK
config TPL_TEXT_BASE
default 0xff8c2000
+config SPL_STACK_R_ADDR
+ default 0x04000000
+
source "board/rockchip/evb_rk3399/Kconfig"
source "board/theobroma-systems/puma_rk3399/Kconfig"
source "board/vamrs/rock960_rk3399/Kconfig"
diff --git a/board/rockchip/evb_rk3399/MAINTAINERS b/board/rockchip/evb_rk3399/MAINTAINERS
index f8299d9460..139791795e 100644
--- a/board/rockchip/evb_rk3399/MAINTAINERS
+++ b/board/rockchip/evb_rk3399/MAINTAINERS
@@ -24,6 +24,12 @@ S: Maintained
F: configs/khadas-edge-v-rk3399_defconfig
F: arch/arm/dts/rk3399-khadas-edge-v-u-boot.dtsi
+LEEZ-P710
+M: Andy Yan <andy.yan@rock-chips.com>
+S: Maintained
+F: arch/arm/dts/rk3399-leez-p710-u-boot.dtsi
+F: configs/leez-rk3399_defconfig
+
NANOPC-T4
M: Jagan Teki <jagan@amarulasolutions.com>
S: Maintained
diff --git a/common/spl/spl_atf.c b/common/spl/spl_atf.c
index 4715f9d371..7a46ed6e6d 100644
--- a/common/spl/spl_atf.c
+++ b/common/spl/spl_atf.c
@@ -30,8 +30,11 @@ static struct bl31_params *bl2_to_bl31_params;
*
* @return bl31 params structure pointer
*/
-static struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl33_entry)
+static struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl32_entry,
+ uintptr_t bl33_entry,
+ uintptr_t fdt_addr)
{
+ struct entry_point_info *bl32_ep_info;
struct entry_point_info *bl33_ep_info;
/*
@@ -49,16 +52,22 @@ static struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl33_entry)
SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info,
ATF_PARAM_IMAGE_BINARY, ATF_VERSION_1, 0);
- /* Fill BL32 related information if it exists */
+
+ /* Fill BL32 related information */
bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
- SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, ATF_PARAM_EP,
- ATF_VERSION_1, 0);
+ bl32_ep_info = &bl31_params_mem.bl32_ep_info;
+ SET_PARAM_HEAD(bl32_ep_info, ATF_PARAM_EP, ATF_VERSION_1,
+ ATF_EP_SECURE);
+
+ /* secure payload is optional, so set pc to 0 if absent */
+ bl32_ep_info->args.arg3 = fdt_addr;
+ bl32_ep_info->pc = bl32_entry ? bl32_entry : 0;
+ bl32_ep_info->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
+ DISABLE_ALL_EXECPTIONS);
+
bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info,
ATF_PARAM_IMAGE_BINARY, ATF_VERSION_1, 0);
-#ifndef BL32_BASE
- bl2_to_bl31_params->bl32_ep_info->pc = 0;
-#endif /* BL32_BASE */
/* Fill BL33 related information */
bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
@@ -86,13 +95,14 @@ static inline void raw_write_daif(unsigned int daif)
typedef void (*atf_entry_t)(struct bl31_params *params, void *plat_params);
-static void bl31_entry(uintptr_t bl31_entry, uintptr_t bl33_entry,
- uintptr_t fdt_addr)
+static void bl31_entry(uintptr_t bl31_entry, uintptr_t bl32_entry,
+ uintptr_t bl33_entry, uintptr_t fdt_addr)
{
struct bl31_params *bl31_params;
atf_entry_t atf_entry = (atf_entry_t)bl31_entry;
- bl31_params = bl2_plat_get_bl31_params(bl33_entry);
+ bl31_params = bl2_plat_get_bl31_params(bl32_entry, bl33_entry,
+ fdt_addr);
raw_write_daif(SPSR_EXCEPTION_MASK);
dcache_disable();
@@ -100,7 +110,7 @@ static void bl31_entry(uintptr_t bl31_entry, uintptr_t bl33_entry,
atf_entry((void *)bl31_params, (void *)fdt_addr);
}
-static int spl_fit_images_find_uboot(void *blob)
+static int spl_fit_images_find(void *blob, int os)
{
int parent, node, ndepth;
const void *data;
@@ -122,7 +132,7 @@ static int spl_fit_images_find_uboot(void *blob)
if (!data)
continue;
- if (genimg_get_os_id(data) == IH_OS_U_BOOT)
+ if (genimg_get_os_id(data) == os)
return node;
};
@@ -143,19 +153,29 @@ uintptr_t spl_fit_images_get_entry(void *blob, int node)
void spl_invoke_atf(struct spl_image_info *spl_image)
{
+ uintptr_t bl32_entry = 0;
uintptr_t bl33_entry = CONFIG_SYS_TEXT_BASE;
void *blob = spl_image->fdt_addr;
uintptr_t platform_param = (uintptr_t)blob;
int node;
/*
+ * Find the OP-TEE binary (in /fit-images) load address or
+ * entry point (if different) and pass it as the BL3-2 entry
+ * point, this is optional.
+ */
+ node = spl_fit_images_find(blob, IH_OS_TEE);
+ if (node >= 0)
+ bl32_entry = spl_fit_images_get_entry(blob, node);
+
+ /*
* Find the U-Boot binary (in /fit-images) load addreess or
* entry point (if different) and pass it as the BL3-3 entry
* point.
* This will need to be extended to support Falcon mode.
*/
- node = spl_fit_images_find_uboot(blob);
+ node = spl_fit_images_find(blob, IH_OS_U_BOOT);
if (node >= 0)
bl33_entry = spl_fit_images_get_entry(blob, node);
@@ -172,5 +192,6 @@ void spl_invoke_atf(struct spl_image_info *spl_image)
* We don't provide a BL3-2 entry yet, but this will be possible
* using similar logic.
*/
- bl31_entry(spl_image->entry_point, bl33_entry, platform_param);
+ bl31_entry(spl_image->entry_point, bl32_entry,
+ bl33_entry, platform_param);
}
diff --git a/configs/chromebook_bob_defconfig b/configs/chromebook_bob_defconfig
index 8059c633ce..b6e31a4c49 100644
--- a/configs/chromebook_bob_defconfig
+++ b/configs/chromebook_bob_defconfig
@@ -8,7 +8,6 @@ CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x4000
# CONFIG_SPL_MMC_SUPPORT is not set
CONFIG_TARGET_CHROMEBOOK_BOB=y
CONFIG_NR_DRAM_BANKS=1
-CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xff1a0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_SPL_SPI_FLASH_SUPPORT=y
diff --git a/configs/evb-px5_defconfig b/configs/evb-px5_defconfig
index 5a06b2a99f..1d2d8e1078 100644
--- a/configs/evb-px5_defconfig
+++ b/configs/evb-px5_defconfig
@@ -2,7 +2,6 @@ CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_ROCKCHIP_RK3368=y
-CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x40000
CONFIG_TPL_LIBCOMMON_SUPPORT=y
CONFIG_TPL_LIBGENERIC_SUPPORT=y
CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig
index f161c40ae7..a4405a6a9d 100644
--- a/configs/evb-rk3328_defconfig
+++ b/configs/evb-rk3328_defconfig
@@ -3,7 +3,6 @@ CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_ROCKCHIP_RK3328=y
CONFIG_TPL_ROCKCHIP_COMMON_BOARD=y
-CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x40000
CONFIG_TPL_LIBCOMMON_SUPPORT=y
CONFIG_TPL_LIBGENERIC_SUPPORT=y
CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
diff --git a/configs/evb-rk3399_defconfig b/configs/evb-rk3399_defconfig
index a0d215a5f1..c1d7d613a9 100644
--- a/configs/evb-rk3399_defconfig
+++ b/configs/evb-rk3399_defconfig
@@ -2,9 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_ROCKCHIP_RK3399=y
-CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
CONFIG_NR_DRAM_BANKS=1
-CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
diff --git a/configs/ficus-rk3399_defconfig b/configs/ficus-rk3399_defconfig
index 05bbfbf381..0dcc9a760d 100644
--- a/configs/ficus-rk3399_defconfig
+++ b/configs/ficus-rk3399_defconfig
@@ -4,7 +4,6 @@ CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_ROCKCHIP_RK3399=y
CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x4000
CONFIG_TARGET_ROCK960_RK3399=y
-CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig
index 29935d869c..64a83a17f2 100644
--- a/configs/firefly-rk3288_defconfig
+++ b/configs/firefly-rk3288_defconfig
@@ -1,15 +1,14 @@
CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
-CONFIG_SYS_TEXT_BASE=0x00000000
+CONFIG_SYS_TEXT_BASE=0x01000000
CONFIG_ROCKCHIP_RK3288=y
-CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y
CONFIG_TARGET_FIREFLY_RK3288=y
CONFIG_NR_DRAM_BANKS=1
+CONFIG_SPL_SIZE_LIMIT=262144
CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xff690000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
-CONFIG_SPL_TEXT_BASE=0xff704000
# CONFIG_ANDROID_BOOT_IMAGE is not set
CONFIG_USE_PREBOOT=y
CONFIG_SILENT_CONSOLE=y
diff --git a/configs/firefly-rk3399_defconfig b/configs/firefly-rk3399_defconfig
index d022631465..ba57fbd527 100644
--- a/configs/firefly-rk3399_defconfig
+++ b/configs/firefly-rk3399_defconfig
@@ -2,9 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_ROCKCHIP_RK3399=y
-CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
CONFIG_NR_DRAM_BANKS=1
-CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
diff --git a/configs/khadas-edge-captain-rk3399_defconfig b/configs/khadas-edge-captain-rk3399_defconfig
index acfd91dbe7..80d92e1aad 100644
--- a/configs/khadas-edge-captain-rk3399_defconfig
+++ b/configs/khadas-edge-captain-rk3399_defconfig
@@ -2,9 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_ROCKCHIP_RK3399=y
-CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
CONFIG_NR_DRAM_BANKS=1
-CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
diff --git a/configs/khadas-edge-rk3399_defconfig b/configs/khadas-edge-rk3399_defconfig
index b71fd3a286..9ba25b7d57 100644
--- a/configs/khadas-edge-rk3399_defconfig
+++ b/configs/khadas-edge-rk3399_defconfig
@@ -2,9 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_ROCKCHIP_RK3399=y
-CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
CONFIG_NR_DRAM_BANKS=1
-CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
diff --git a/configs/khadas-edge-v-rk3399_defconfig b/configs/khadas-edge-v-rk3399_defconfig
index 0a789872dc..424dec1fba 100644
--- a/configs/khadas-edge-v-rk3399_defconfig
+++ b/configs/khadas-edge-v-rk3399_defconfig
@@ -2,9 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_ROCKCHIP_RK3399=y
-CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
CONFIG_NR_DRAM_BANKS=1
-CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
diff --git a/configs/leez-rk3399_defconfig b/configs/leez-rk3399_defconfig
new file mode 100644
index 0000000000..c671879d9a
--- /dev/null
+++ b/configs/leez-rk3399_defconfig
@@ -0,0 +1,56 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_SYS_TEXT_BASE=0x00200000
+CONFIG_ROCKCHIP_RK3399=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_DEBUG_UART_BASE=0xFF1A0000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART=y
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-leez-p710.dtb"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x10000
+CONFIG_TPL=y
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TIME=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="rk3399-leez-p710"
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_RAM_RK3399_LPDDR4=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PMIC_RK8XX=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_REGULATOR_RK8XX=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_HOST_ETHER=y
+CONFIG_USB_ETHER_ASIX=y
+CONFIG_USB_ETHER_ASIX88179=y
+CONFIG_USB_ETHER_MCS7830=y
+CONFIG_USB_ETHER_RTL8152=y
+CONFIG_USB_ETHER_SMSC95XX=y
+CONFIG_USE_TINY_PRINTF=y
+CONFIG_SPL_TINY_MEMSET=y
+CONFIG_ERRNO_STR=y
diff --git a/configs/nanopc-t4-rk3399_defconfig b/configs/nanopc-t4-rk3399_defconfig
index 1d4c8f8a02..ae09273a48 100644
--- a/configs/nanopc-t4-rk3399_defconfig
+++ b/configs/nanopc-t4-rk3399_defconfig
@@ -2,9 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_ROCKCHIP_RK3399=y
-CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
CONFIG_NR_DRAM_BANKS=1
-CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
diff --git a/configs/nanopi-m4-rk3399_defconfig b/configs/nanopi-m4-rk3399_defconfig
index 7375b758a2..e1a61e5a57 100644
--- a/configs/nanopi-m4-rk3399_defconfig
+++ b/configs/nanopi-m4-rk3399_defconfig
@@ -2,9 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_ROCKCHIP_RK3399=y
-CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
CONFIG_NR_DRAM_BANKS=1
-CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
diff --git a/configs/nanopi-neo4-rk3399_defconfig b/configs/nanopi-neo4-rk3399_defconfig
index 874ee5efb6..c3a592d8fe 100644
--- a/configs/nanopi-neo4-rk3399_defconfig
+++ b/configs/nanopi-neo4-rk3399_defconfig
@@ -2,9 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_ROCKCHIP_RK3399=y
-CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
CONFIG_NR_DRAM_BANKS=1
-CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
diff --git a/configs/orangepi-rk3399_defconfig b/configs/orangepi-rk3399_defconfig
index 7b02c59f08..296fd5f0a0 100644
--- a/configs/orangepi-rk3399_defconfig
+++ b/configs/orangepi-rk3399_defconfig
@@ -2,9 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_ROCKCHIP_RK3399=y
-CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
CONFIG_NR_DRAM_BANKS=1
-CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
diff --git a/configs/puma-rk3399_defconfig b/configs/puma-rk3399_defconfig
index 30b0f4ac6c..351b0ea3d0 100644
--- a/configs/puma-rk3399_defconfig
+++ b/configs/puma-rk3399_defconfig
@@ -6,7 +6,6 @@ CONFIG_ROCKCHIP_RK3399=y
CONFIG_ROCKCHIP_BOOT_MODE_REG=0x0
CONFIG_TARGET_PUMA_RK3399=y
CONFIG_NR_DRAM_BANKS=1
-CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xFF180000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_SPL_SPI_FLASH_SUPPORT=y
diff --git a/configs/roc-rk3399-pc_defconfig b/configs/roc-rk3399-pc_defconfig
index 28b18333d7..809f522236 100644
--- a/configs/roc-rk3399-pc_defconfig
+++ b/configs/roc-rk3399-pc_defconfig
@@ -2,9 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_ROCKCHIP_RK3399=y
-CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
CONFIG_NR_DRAM_BANKS=1
-CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
diff --git a/configs/rock-pi-4-rk3399_defconfig b/configs/rock-pi-4-rk3399_defconfig
index 554945dd19..f4bb3818ce 100644
--- a/configs/rock-pi-4-rk3399_defconfig
+++ b/configs/rock-pi-4-rk3399_defconfig
@@ -2,9 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_ROCKCHIP_RK3399=y
-CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
CONFIG_NR_DRAM_BANKS=1
-CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
diff --git a/configs/rock64-rk3328_defconfig b/configs/rock64-rk3328_defconfig
index 60a0d1473c..3b3ac96cc0 100644
--- a/configs/rock64-rk3328_defconfig
+++ b/configs/rock64-rk3328_defconfig
@@ -3,7 +3,6 @@ CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_ROCKCHIP_RK3328=y
CONFIG_TPL_ROCKCHIP_COMMON_BOARD=y
-CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x40000
CONFIG_TPL_LIBCOMMON_SUPPORT=y
CONFIG_TPL_LIBGENERIC_SUPPORT=y
CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
diff --git a/configs/rock960-rk3399_defconfig b/configs/rock960-rk3399_defconfig
index cb3c68db6b..0d6c55ce74 100644
--- a/configs/rock960-rk3399_defconfig
+++ b/configs/rock960-rk3399_defconfig
@@ -4,7 +4,6 @@ CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_ROCKCHIP_RK3399=y
CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x4000
CONFIG_TARGET_ROCK960_RK3399=y
-CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
diff --git a/configs/rockpro64-rk3399_defconfig b/configs/rockpro64-rk3399_defconfig
index 22b8bc503b..68f0dca7b2 100644
--- a/configs/rockpro64-rk3399_defconfig
+++ b/configs/rockpro64-rk3399_defconfig
@@ -2,9 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_ROCKCHIP_RK3399=y
-CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x50000
CONFIG_NR_DRAM_BANKS=1
-CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
diff --git a/doc/device-tree-bindings/regulator/regulator.txt b/doc/device-tree-bindings/regulator/regulator.txt
index 4ba642b7c7..6c9a02120f 100644
--- a/doc/device-tree-bindings/regulator/regulator.txt
+++ b/doc/device-tree-bindings/regulator/regulator.txt
@@ -36,6 +36,28 @@ Optional properties:
- regulator-always-on: regulator should never be disabled
- regulator-boot-on: enabled by bootloader/firmware
- regulator-ramp-delay: ramp delay for regulator (in uV/us)
+- regulator-init-microvolt: a init allowed Voltage value
+- regulator-state-(standby|mem|disk)
+ type: object
+ description:
+ sub-nodes for regulator state in Standby, Suspend-to-RAM, and
+ Suspend-to-DISK modes. Equivalent with standby, mem, and disk Linux
+ sleep states.
+
+ properties:
+ regulator-on-in-suspend:
+ description: regulator should be on in suspend state.
+ type: boolean
+
+ regulator-off-in-suspend:
+ description: regulator should be off in suspend state.
+ type: boolean
+
+ regulator-suspend-microvolt:
+ description: the default voltage which regulator would be set in
+ suspend. This property is now deprecated, instead setting voltage
+ for suspend mode via the API which regulator driver provides is
+ recommended.
Note
The "regulator-name" constraint is used for setting the device's uclass
@@ -59,7 +81,12 @@ ldo0 {
regulator-max-microvolt = <1800000>;
regulator-min-microamp = <100000>;
regulator-max-microamp = <100000>;
+ regulator-init-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <12000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
};
diff --git a/drivers/clk/rockchip/clk_rk3328.c b/drivers/clk/rockchip/clk_rk3328.c
index a89e2ecc4a..4331048a87 100644
--- a/drivers/clk/rockchip/clk_rk3328.c
+++ b/drivers/clk/rockchip/clk_rk3328.c
@@ -282,6 +282,8 @@ static void rkclk_init(struct rk3328_cru *cru)
u32 hclk_div;
u32 pclk_div;
+ rk3328_configure_cpu(cru, APLL_600_MHZ);
+
/* configure gpll cpll */
rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg);
diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c
index 25c339ab12..52e6d9d8c0 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -10,6 +10,13 @@
#include <power/rk8xx_pmic.h>
#include <power/pmic.h>
+static struct reg_data rk817_init_reg[] = {
+/* enable the under-voltage protection,
+ * the under-voltage protection will shutdown the LDO3 and reset the PMIC
+ */
+ { RK817_BUCK4_CMIN, 0x60, 0x60},
+};
+
static const struct pmic_child_info pmic_children_info[] = {
{ .prefix = "DCDC_REG", .driver = "rk8xx_buck"},
{ .prefix = "LDO_REG", .driver = "rk8xx_ldo"},
@@ -76,13 +83,85 @@ static int rk8xx_bind(struct udevice *dev)
static int rk8xx_probe(struct udevice *dev)
{
struct rk8xx_priv *priv = dev_get_priv(dev);
- uint8_t msb, lsb;
+ struct reg_data *init_data = NULL;
+ int init_data_num = 0;
+ int ret = 0, i, show_variant;
+ u8 msb, lsb, id_msb, id_lsb;
+ u8 on_source = 0, off_source = 0;
+ u8 power_en0, power_en1, power_en2, power_en3;
+ u8 value;
/* read Chip variant */
- rk8xx_read(dev, ID_MSB, &msb, 1);
- rk8xx_read(dev, ID_LSB, &lsb, 1);
+ if (device_is_compatible(dev, "rockchip,rk817") ||
+ device_is_compatible(dev, "rockchip,rk809")) {
+ id_msb = RK817_ID_MSB;
+ id_lsb = RK817_ID_LSB;
+ } else {
+ id_msb = ID_MSB;
+ id_lsb = ID_LSB;
+ }
+
+ ret = rk8xx_read(dev, id_msb, &msb, 1);
+ if (ret)
+ return ret;
+ ret = rk8xx_read(dev, id_lsb, &lsb, 1);
+ if (ret)
+ return ret;
priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
+ show_variant = priv->variant;
+ switch (priv->variant) {
+ case RK808_ID:
+ show_variant = 0x808; /* RK808 hardware ID is 0 */
+ break;
+ case RK805_ID:
+ case RK816_ID:
+ case RK818_ID:
+ on_source = RK8XX_ON_SOURCE;
+ off_source = RK8XX_OFF_SOURCE;
+ break;
+ case RK809_ID:
+ case RK817_ID:
+ on_source = RK817_ON_SOURCE;
+ off_source = RK817_OFF_SOURCE;
+ init_data = rk817_init_reg;
+ init_data_num = ARRAY_SIZE(rk817_init_reg);
+ power_en0 = pmic_reg_read(dev, RK817_POWER_EN0);
+ power_en1 = pmic_reg_read(dev, RK817_POWER_EN1);
+ power_en2 = pmic_reg_read(dev, RK817_POWER_EN2);
+ power_en3 = pmic_reg_read(dev, RK817_POWER_EN3);
+
+ value = (power_en0 & 0x0f) | ((power_en1 & 0x0f) << 4);
+ pmic_reg_write(dev, RK817_POWER_EN_SAVE0, value);
+ value = (power_en2 & 0x0f) | ((power_en3 & 0x0f) << 4);
+ pmic_reg_write(dev, RK817_POWER_EN_SAVE1, value);
+ break;
+ default:
+ printf("Unknown PMIC: RK%x!!\n", priv->variant);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < init_data_num; i++) {
+ ret = pmic_clrsetbits(dev,
+ init_data[i].reg,
+ init_data[i].mask,
+ init_data[i].val);
+ if (ret < 0) {
+ printf("%s: i2c set reg 0x%x failed, ret=%d\n",
+ __func__, init_data[i].reg, ret);
+ }
+
+ debug("%s: reg[0x%x] = 0x%x\n", __func__, init_data[i].reg,
+ pmic_reg_read(dev, init_data[i].reg));
+ }
+
+ printf("PMIC: RK%x ", show_variant);
+
+ if (on_source && off_source)
+ printf("(on=0x%02x, off=0x%02x)",
+ pmic_reg_read(dev, on_source),
+ pmic_reg_read(dev, off_source));
+ printf("\n");
return 0;
}
@@ -94,7 +173,11 @@ static struct dm_pmic_ops rk8xx_ops = {
};
static const struct udevice_id rk8xx_ids[] = {
+ { .compatible = "rockchip,rk805" },
{ .compatible = "rockchip,rk808" },
+ { .compatible = "rockchip,rk809" },
+ { .compatible = "rockchip,rk816" },
+ { .compatible = "rockchip,rk817" },
{ .compatible = "rockchip,rk818" },
{ }
};
diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c
index 76be95bcd1..4986c87e7b 100644
--- a/drivers/power/regulator/regulator-uclass.c
+++ b/drivers/power/regulator/regulator-uclass.c
@@ -77,6 +77,33 @@ int regulator_set_value(struct udevice *dev, int uV)
return ret;
}
+int regulator_set_suspend_value(struct udevice *dev, int uV)
+{
+ const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
+ struct dm_regulator_uclass_platdata *uc_pdata;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+ if (uc_pdata->min_uV != -ENODATA && uV < uc_pdata->min_uV)
+ return -EINVAL;
+ if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV)
+ return -EINVAL;
+
+ if (!ops->set_suspend_value)
+ return -ENOSYS;
+
+ return ops->set_suspend_value(dev, uV);
+}
+
+int regulator_get_suspend_value(struct udevice *dev)
+{
+ const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
+
+ if (!ops->get_suspend_value)
+ return -ENOSYS;
+
+ return ops->get_suspend_value(dev);
+}
+
/*
* To be called with at most caution as there is no check
* before setting the actual voltage value.
@@ -170,6 +197,26 @@ int regulator_set_enable_if_allowed(struct udevice *dev, bool enable)
return ret;
}
+int regulator_set_suspend_enable(struct udevice *dev, bool enable)
+{
+ const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
+
+ if (!ops->set_suspend_enable)
+ return -ENOSYS;
+
+ return ops->set_suspend_enable(dev, enable);
+}
+
+int regulator_get_suspend_enable(struct udevice *dev)
+{
+ const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
+
+ if (!ops->get_suspend_enable)
+ return -ENOSYS;
+
+ return ops->get_suspend_enable(dev);
+}
+
int regulator_get_mode(struct udevice *dev)
{
const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
@@ -235,6 +282,14 @@ int regulator_autoset(struct udevice *dev)
int ret = 0;
uc_pdata = dev_get_uclass_platdata(dev);
+
+ ret = regulator_set_suspend_enable(dev, uc_pdata->suspend_on);
+ if (!ret && uc_pdata->suspend_on) {
+ ret = regulator_set_suspend_value(dev, uc_pdata->suspend_uV);
+ if (!ret)
+ return ret;
+ }
+
if (!uc_pdata->always_on && !uc_pdata->boot_on)
return -EMEDIUMTYPE;
@@ -243,6 +298,8 @@ int regulator_autoset(struct udevice *dev)
if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
ret = regulator_set_value(dev, uc_pdata->min_uV);
+ if (uc_pdata->init_uV > 0)
+ ret = regulator_set_value(dev, uc_pdata->init_uV);
if (!ret && (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA))
ret = regulator_set_current(dev, uc_pdata->min_uA);
@@ -363,6 +420,7 @@ static int regulator_post_bind(struct udevice *dev)
static int regulator_pre_probe(struct udevice *dev)
{
struct dm_regulator_uclass_platdata *uc_pdata;
+ ofnode node;
uc_pdata = dev_get_uclass_platdata(dev);
if (!uc_pdata)
@@ -373,6 +431,8 @@ static int regulator_pre_probe(struct udevice *dev)
-ENODATA);
uc_pdata->max_uV = dev_read_u32_default(dev, "regulator-max-microvolt",
-ENODATA);
+ uc_pdata->init_uV = dev_read_u32_default(dev, "regulator-init-microvolt",
+ -ENODATA);
uc_pdata->min_uA = dev_read_u32_default(dev, "regulator-min-microamp",
-ENODATA);
uc_pdata->max_uA = dev_read_u32_default(dev, "regulator-max-microamp",
@@ -382,6 +442,16 @@ static int regulator_pre_probe(struct udevice *dev)
uc_pdata->ramp_delay = dev_read_u32_default(dev, "regulator-ramp-delay",
0);
+ node = dev_read_subnode(dev, "regulator-state-mem");
+ if (ofnode_valid(node)) {
+ uc_pdata->suspend_on = !ofnode_read_bool(node, "regulator-off-in-suspend");
+ if (ofnode_read_u32(node, "regulator-suspend-microvolt", &uc_pdata->suspend_uV))
+ uc_pdata->suspend_uV = uc_pdata->max_uV;
+ } else {
+ uc_pdata->suspend_on = true;
+ uc_pdata->suspend_uV = uc_pdata->max_uV;
+ }
+
/* Those values are optional (-ENODATA if unset) */
if ((uc_pdata->min_uV != -ENODATA) &&
(uc_pdata->max_uV != -ENODATA) &&
diff --git a/drivers/power/regulator/rk8xx.c b/drivers/power/regulator/rk8xx.c
index aa4f3a161c..194086c6d2 100644
--- a/drivers/power/regulator/rk8xx.c
+++ b/drivers/power/regulator/rk8xx.c
@@ -19,11 +19,33 @@
#define ENABLE_DRIVER
#endif
+/* Not used or exisit register and configure */
+#define NA -1
+
/* Field Definitions */
#define RK808_BUCK_VSEL_MASK 0x3f
#define RK808_BUCK4_VSEL_MASK 0xf
#define RK808_LDO_VSEL_MASK 0x1f
+/* RK809 BUCK5 */
+#define RK809_BUCK5_CONFIG(n) (0xde + (n) * 1)
+#define RK809_BUCK5_VSEL_MASK 0x07
+
+/* RK817 BUCK */
+#define RK817_BUCK_ON_VSEL(n) (0xbb + 3 * (n - 1))
+#define RK817_BUCK_SLP_VSEL(n) (0xbc + 3 * (n - 1))
+#define RK817_BUCK_VSEL_MASK 0x7f
+#define RK817_BUCK_CONFIG(i) (0xba + (i) * 3)
+
+/* RK817 LDO */
+#define RK817_LDO_ON_VSEL(n) (0xcc + 2 * (n - 1))
+#define RK817_LDO_SLP_VSEL(n) (0xcd + 2 * (n - 1))
+#define RK817_LDO_VSEL_MASK 0x7f
+
+/* RK817 ENABLE */
+#define RK817_POWER_EN(n) (0xb1 + (n))
+#define RK817_POWER_SLP_EN(n) (0xb5 + (n))
+
#define RK818_BUCK_VSEL_MASK 0x3f
#define RK818_BUCK4_VSEL_MASK 0x1f
#define RK818_LDO_VSEL_MASK 0x1f
@@ -32,49 +54,156 @@
#define RK818_USB_ILIM_SEL_MASK 0x0f
#define RK818_USB_CHG_SD_VSEL_MASK 0x70
+/*
+ * Ramp delay
+ */
+#define RK805_RAMP_RATE_OFFSET 3
+#define RK805_RAMP_RATE_MASK (3 << RK805_RAMP_RATE_OFFSET)
+#define RK805_RAMP_RATE_3MV_PER_US (0 << RK805_RAMP_RATE_OFFSET)
+#define RK805_RAMP_RATE_6MV_PER_US (1 << RK805_RAMP_RATE_OFFSET)
+#define RK805_RAMP_RATE_12_5MV_PER_US (2 << RK805_RAMP_RATE_OFFSET)
+#define RK805_RAMP_RATE_25MV_PER_US (3 << RK805_RAMP_RATE_OFFSET)
+
+#define RK808_RAMP_RATE_OFFSET 3
+#define RK808_RAMP_RATE_MASK (3 << RK808_RAMP_RATE_OFFSET)
+#define RK808_RAMP_RATE_2MV_PER_US (0 << RK808_RAMP_RATE_OFFSET)
+#define RK808_RAMP_RATE_4MV_PER_US (1 << RK808_RAMP_RATE_OFFSET)
+#define RK808_RAMP_RATE_6MV_PER_US (2 << RK808_RAMP_RATE_OFFSET)
+#define RK808_RAMP_RATE_10MV_PER_US (3 << RK808_RAMP_RATE_OFFSET)
+
+#define RK817_RAMP_RATE_OFFSET 6
+#define RK817_RAMP_RATE_MASK (0x3 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_3MV_PER_US (0x0 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_6_3MV_PER_US (0x1 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_12_5MV_PER_US (0x2 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_25MV_PER_US (0x3 << RK817_RAMP_RATE_OFFSET)
struct rk8xx_reg_info {
uint min_uv;
uint step_uv;
- s8 vsel_reg;
+ u8 vsel_reg;
+ u8 vsel_sleep_reg;
+ u8 config_reg;
u8 vsel_mask;
+ u8 min_sel;
};
static const struct rk8xx_reg_info rk808_buck[] = {
- { 712500, 12500, REG_BUCK1_ON_VSEL, RK808_BUCK_VSEL_MASK, },
- { 712500, 12500, REG_BUCK2_ON_VSEL, RK808_BUCK_VSEL_MASK, },
- { 712500, 12500, -1, RK808_BUCK_VSEL_MASK, },
- { 1800000, 100000, REG_BUCK4_ON_VSEL, RK808_BUCK4_VSEL_MASK, },
+ { 712500, 12500, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, REG_BUCK1_CONFIG, RK808_BUCK_VSEL_MASK, },
+ { 712500, 12500, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, REG_BUCK2_CONFIG, RK808_BUCK_VSEL_MASK, },
+ { 712500, 12500, NA, NA, REG_BUCK3_CONFIG, RK808_BUCK_VSEL_MASK, },
+ { 1800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, REG_BUCK4_CONFIG, RK808_BUCK4_VSEL_MASK, },
+};
+
+static const struct rk8xx_reg_info rk816_buck[] = {
+ /* buck 1 */
+ { 712500, 12500, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, REG_BUCK1_CONFIG, RK818_BUCK_VSEL_MASK, 0x00, },
+ { 1800000, 200000, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, REG_BUCK1_CONFIG, RK818_BUCK_VSEL_MASK, 0x3c, },
+ { 2300000, 0, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, REG_BUCK1_CONFIG, RK818_BUCK_VSEL_MASK, 0x3f, },
+ /* buck 2 */
+ { 712500, 12500, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, REG_BUCK2_CONFIG, RK818_BUCK_VSEL_MASK, 0x00, },
+ { 1800000, 200000, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, REG_BUCK2_CONFIG, RK818_BUCK_VSEL_MASK, 0x3c, },
+ { 2300000, 0, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, REG_BUCK2_CONFIG, RK818_BUCK_VSEL_MASK, 0x3f, },
+ /* buck 3 */
+ { 712500, 12500, NA, NA, REG_BUCK3_CONFIG, RK818_BUCK_VSEL_MASK, },
+ /* buck 4 */
+ { 800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, REG_BUCK4_CONFIG, RK818_BUCK4_VSEL_MASK, },
+};
+
+static const struct rk8xx_reg_info rk809_buck5[] = {
+ /* buck 5 */
+ { 1500000, 0, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), NA, RK809_BUCK5_VSEL_MASK, 0x00, },
+ { 1800000, 200000, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), NA, RK809_BUCK5_VSEL_MASK, 0x01, },
+ { 2800000, 200000, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), NA, RK809_BUCK5_VSEL_MASK, 0x04, },
+ { 3300000, 300000, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), NA, RK809_BUCK5_VSEL_MASK, 0x06, },
+};
+
+static const struct rk8xx_reg_info rk817_buck[] = {
+ /* buck 1 */
+ { 500000, 12500, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_CONFIG(1), RK817_BUCK_VSEL_MASK, 0x00, },
+ { 1500000, 100000, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_CONFIG(1), RK817_BUCK_VSEL_MASK, 0x50, },
+ { 2400000, 0, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_CONFIG(1), RK817_BUCK_VSEL_MASK, 0x59, },
+ /* buck 2 */
+ { 500000, 12500, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_CONFIG(2), RK817_BUCK_VSEL_MASK, 0x00, },
+ { 1500000, 100000, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_CONFIG(2), RK817_BUCK_VSEL_MASK, 0x50, },
+ { 2400000, 0, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_CONFIG(2), RK817_BUCK_VSEL_MASK, 0x59, },
+ /* buck 3 */
+ { 500000, 12500, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_CONFIG(3), RK817_BUCK_VSEL_MASK, 0x00, },
+ { 1500000, 100000, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_CONFIG(3), RK817_BUCK_VSEL_MASK, 0x50, },
+ { 2400000, 0, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_CONFIG(3), RK817_BUCK_VSEL_MASK, 0x59, },
+ /* buck 4 */
+ { 500000, 12500, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_CONFIG(4), RK817_BUCK_VSEL_MASK, 0x00, },
+ { 1500000, 100000, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_CONFIG(4), RK817_BUCK_VSEL_MASK, 0x50, },
+ { 3400000, 0, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_CONFIG(4), RK817_BUCK_VSEL_MASK, 0x63, },
};
static const struct rk8xx_reg_info rk818_buck[] = {
- { 712500, 12500, REG_BUCK1_ON_VSEL, RK818_BUCK_VSEL_MASK, },
- { 712500, 12500, REG_BUCK2_ON_VSEL, RK818_BUCK_VSEL_MASK, },
- { 712500, 12500, -1, RK818_BUCK_VSEL_MASK, },
- { 1800000, 100000, REG_BUCK4_ON_VSEL, RK818_BUCK4_VSEL_MASK, },
+ { 712500, 12500, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, REG_BUCK1_CONFIG, RK818_BUCK_VSEL_MASK, },
+ { 712500, 12500, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, REG_BUCK2_CONFIG, RK818_BUCK_VSEL_MASK, },
+ { 712500, 12500, NA, NA, REG_BUCK3_CONFIG, RK818_BUCK_VSEL_MASK, },
+ { 1800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, REG_BUCK4_CONFIG, RK818_BUCK4_VSEL_MASK, },
};
#ifdef ENABLE_DRIVER
static const struct rk8xx_reg_info rk808_ldo[] = {
- { 1800000, 100000, REG_LDO1_ON_VSEL, RK808_LDO_VSEL_MASK, },
- { 1800000, 100000, REG_LDO2_ON_VSEL, RK808_LDO_VSEL_MASK, },
- { 800000, 100000, REG_LDO3_ON_VSEL, RK808_BUCK4_VSEL_MASK, },
- { 1800000, 100000, REG_LDO4_ON_VSEL, RK808_LDO_VSEL_MASK, },
- { 1800000, 100000, REG_LDO5_ON_VSEL, RK808_LDO_VSEL_MASK, },
- { 800000, 100000, REG_LDO6_ON_VSEL, RK808_LDO_VSEL_MASK, },
- { 800000, 100000, REG_LDO7_ON_VSEL, RK808_LDO_VSEL_MASK, },
- { 1800000, 100000, REG_LDO8_ON_VSEL, RK808_LDO_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO1_ON_VSEL, REG_LDO1_SLP_VSEL, NA, RK808_LDO_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO2_ON_VSEL, REG_LDO2_SLP_VSEL, NA, RK808_LDO_VSEL_MASK, },
+ { 800000, 100000, REG_LDO3_ON_VSEL, REG_LDO3_SLP_VSEL, NA, RK808_BUCK4_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO4_ON_VSEL, REG_LDO4_SLP_VSEL, NA, RK808_LDO_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO5_ON_VSEL, REG_LDO5_SLP_VSEL, NA, RK808_LDO_VSEL_MASK, },
+ { 800000, 100000, REG_LDO6_ON_VSEL, REG_LDO6_SLP_VSEL, NA, RK808_LDO_VSEL_MASK, },
+ { 800000, 100000, REG_LDO7_ON_VSEL, REG_LDO7_SLP_VSEL, NA, RK808_LDO_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO8_ON_VSEL, REG_LDO8_SLP_VSEL, NA, RK808_LDO_VSEL_MASK, },
+};
+
+static const struct rk8xx_reg_info rk816_ldo[] = {
+ { 800000, 100000, REG_LDO1_ON_VSEL, REG_LDO1_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
+ { 800000, 100000, REG_LDO2_ON_VSEL, REG_LDO2_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
+ { 800000, 100000, REG_LDO3_ON_VSEL, REG_LDO3_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
+ { 800000, 100000, REG_LDO4_ON_VSEL, REG_LDO4_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
+ { 800000, 100000, REG_LDO5_ON_VSEL, REG_LDO5_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
+ { 800000, 100000, REG_LDO6_ON_VSEL, REG_LDO6_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
+};
+
+static const struct rk8xx_reg_info rk817_ldo[] = {
+ /* ldo1 */
+ { 600000, 25000, RK817_LDO_ON_VSEL(1), RK817_LDO_SLP_VSEL(1), NA, RK817_LDO_VSEL_MASK, 0x00, },
+ { 3400000, 0, RK817_LDO_ON_VSEL(1), RK817_LDO_SLP_VSEL(1), NA, RK817_LDO_VSEL_MASK, 0x70, },
+ /* ldo2 */
+ { 600000, 25000, RK817_LDO_ON_VSEL(2), RK817_LDO_SLP_VSEL(2), NA, RK817_LDO_VSEL_MASK, 0x00, },
+ { 3400000, 0, RK817_LDO_ON_VSEL(2), RK817_LDO_SLP_VSEL(2), NA, RK817_LDO_VSEL_MASK, 0x70, },
+ /* ldo3 */
+ { 600000, 25000, RK817_LDO_ON_VSEL(3), RK817_LDO_SLP_VSEL(3), NA, RK817_LDO_VSEL_MASK, 0x00, },
+ { 3400000, 0, RK817_LDO_ON_VSEL(3), RK817_LDO_SLP_VSEL(3), NA, RK817_LDO_VSEL_MASK, 0x70, },
+ /* ldo4 */
+ { 600000, 25000, RK817_LDO_ON_VSEL(4), RK817_LDO_SLP_VSEL(4), NA, RK817_LDO_VSEL_MASK, 0x00, },
+ { 3400000, 0, RK817_LDO_ON_VSEL(4), RK817_LDO_SLP_VSEL(4), NA, RK817_LDO_VSEL_MASK, 0x70, },
+ /* ldo5 */
+ { 600000, 25000, RK817_LDO_ON_VSEL(5), RK817_LDO_SLP_VSEL(5), NA, RK817_LDO_VSEL_MASK, 0x00, },
+ { 3400000, 0, RK817_LDO_ON_VSEL(5), RK817_LDO_SLP_VSEL(5), NA, RK817_LDO_VSEL_MASK, 0x70, },
+ /* ldo6 */
+ { 600000, 25000, RK817_LDO_ON_VSEL(6), RK817_LDO_SLP_VSEL(6), NA, RK817_LDO_VSEL_MASK, 0x00, },
+ { 3400000, 0, RK817_LDO_ON_VSEL(6), RK817_LDO_SLP_VSEL(6), NA, RK817_LDO_VSEL_MASK, 0x70, },
+ /* ldo7 */
+ { 600000, 25000, RK817_LDO_ON_VSEL(7), RK817_LDO_SLP_VSEL(7), NA, RK817_LDO_VSEL_MASK, 0x00, },
+ { 3400000, 0, RK817_LDO_ON_VSEL(7), RK817_LDO_SLP_VSEL(7), NA, RK817_LDO_VSEL_MASK, 0x70, },
+ /* ldo8 */
+ { 600000, 25000, RK817_LDO_ON_VSEL(8), RK817_LDO_SLP_VSEL(8), NA, RK817_LDO_VSEL_MASK, 0x00, },
+ { 3400000, 0, RK817_LDO_ON_VSEL(8), RK817_LDO_SLP_VSEL(8), NA, RK817_LDO_VSEL_MASK, 0x70, },
+ /* ldo9 */
+ { 600000, 25000, RK817_LDO_ON_VSEL(9), RK817_LDO_SLP_VSEL(9), NA, RK817_LDO_VSEL_MASK, 0x00, },
+ { 3400000, 0, RK817_LDO_ON_VSEL(9), RK817_LDO_SLP_VSEL(9), NA, RK817_LDO_VSEL_MASK, 0x70, },
};
static const struct rk8xx_reg_info rk818_ldo[] = {
- { 1800000, 100000, REG_LDO1_ON_VSEL, RK818_LDO_VSEL_MASK, },
- { 1800000, 100000, REG_LDO2_ON_VSEL, RK818_LDO_VSEL_MASK, },
- { 800000, 100000, REG_LDO3_ON_VSEL, RK818_LDO3_ON_VSEL_MASK, },
- { 1800000, 100000, REG_LDO4_ON_VSEL, RK818_LDO_VSEL_MASK, },
- { 1800000, 100000, REG_LDO5_ON_VSEL, RK818_LDO_VSEL_MASK, },
- { 800000, 100000, REG_LDO6_ON_VSEL, RK818_LDO_VSEL_MASK, },
- { 800000, 100000, REG_LDO7_ON_VSEL, RK818_LDO_VSEL_MASK, },
- { 1800000, 100000, REG_LDO8_ON_VSEL, RK818_LDO_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO1_ON_VSEL, REG_LDO1_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO2_ON_VSEL, REG_LDO2_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
+ { 800000, 100000, REG_LDO3_ON_VSEL, REG_LDO3_SLP_VSEL, NA, RK818_LDO3_ON_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO4_ON_VSEL, REG_LDO4_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO5_ON_VSEL, REG_LDO5_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
+ { 800000, 100000, REG_LDO6_ON_VSEL, REG_LDO6_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
+ { 800000, 100000, REG_LDO7_ON_VSEL, REG_LDO7_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
+ { 1800000, 100000, REG_LDO8_ON_VSEL, REG_LDO8_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
};
#endif
@@ -87,10 +216,54 @@ static const uint rk818_chrg_shutdown_vsel_array[] = {
};
static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic,
- int num)
+ int num, int uvolt)
{
struct rk8xx_priv *priv = dev_get_priv(pmic);
+
switch (priv->variant) {
+ case RK805_ID:
+ case RK816_ID:
+ switch (num) {
+ case 0:
+ case 1:
+ if (uvolt <= 1450000)
+ return &rk816_buck[num * 3 + 0];
+ else if (uvolt <= 2200000)
+ return &rk816_buck[num * 3 + 1];
+ else
+ return &rk816_buck[num * 3 + 2];
+ default:
+ return &rk816_buck[num + 4];
+ }
+
+ case RK809_ID:
+ case RK817_ID:
+ switch (num) {
+ case 0 ... 2:
+ if (uvolt < 1500000)
+ return &rk817_buck[num * 3 + 0];
+ else if (uvolt < 2400000)
+ return &rk817_buck[num * 3 + 1];
+ else
+ return &rk817_buck[num * 3 + 2];
+ case 3:
+ if (uvolt < 1500000)
+ return &rk817_buck[num * 3 + 0];
+ else if (uvolt < 3400000)
+ return &rk817_buck[num * 3 + 1];
+ else
+ return &rk817_buck[num * 3 + 2];
+ /* BUCK5 for RK809 */
+ default:
+ if (uvolt < 1800000)
+ return &rk809_buck5[0];
+ else if (uvolt < 2800000)
+ return &rk809_buck5[1];
+ else if (uvolt < 3300000)
+ return &rk809_buck5[2];
+ else
+ return &rk809_buck5[3];
+ }
case RK818_ID:
return &rk818_buck[num];
default:
@@ -100,44 +273,245 @@ static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic,
static int _buck_set_value(struct udevice *pmic, int buck, int uvolt)
{
- const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck - 1);
+ const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck, uvolt);
+ struct rk8xx_priv *priv = dev_get_priv(pmic);
int mask = info->vsel_mask;
int val;
- if (info->vsel_reg == -1)
+ if (info->vsel_reg == NA)
return -ENOSYS;
- val = (uvolt - info->min_uv) / info->step_uv;
- debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask,
- val);
- return pmic_clrsetbits(pmic, info->vsel_reg, mask, val);
+ if (info->step_uv == 0) /* Fixed voltage */
+ val = info->min_sel;
+ else
+ val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
+
+ debug("%s: volt=%d, buck=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
+ __func__, uvolt, buck + 1, info->vsel_reg, mask, val);
+
+ if (priv->variant == RK816_ID) {
+ pmic_clrsetbits(pmic, info->vsel_reg, mask, val);
+ return pmic_clrsetbits(pmic, RK816_REG_DCDC_EN2,
+ 1 << 7, 1 << 7);
+ } else {
+ return pmic_clrsetbits(pmic, info->vsel_reg, mask, val);
+ }
}
static int _buck_set_enable(struct udevice *pmic, int buck, bool enable)
{
- uint mask;
- int ret;
+ uint mask, value, en_reg;
+ int ret = 0;
+ struct rk8xx_priv *priv = dev_get_priv(pmic);
- buck--;
- mask = 1 << buck;
- if (enable) {
- ret = pmic_clrsetbits(pmic, REG_DCDC_ILMAX, 0, 3 << (buck * 2));
- if (ret)
- return ret;
- ret = pmic_clrsetbits(pmic, REG_DCDC_UV_ACT, 1 << buck, 0);
- if (ret)
- return ret;
+ switch (priv->variant) {
+ case RK805_ID:
+ case RK816_ID:
+ if (buck >= 4) {
+ buck -= 4;
+ en_reg = RK816_REG_DCDC_EN2;
+ } else {
+ en_reg = RK816_REG_DCDC_EN1;
+ }
+ if (enable)
+ value = ((1 << buck) | (1 << (buck + 4)));
+ else
+ value = ((0 << buck) | (1 << (buck + 4)));
+ ret = pmic_reg_write(pmic, en_reg, value);
+ break;
+
+ case RK808_ID:
+ case RK818_ID:
+ mask = 1 << buck;
+ if (enable) {
+ ret = pmic_clrsetbits(pmic, REG_DCDC_ILMAX,
+ 0, 3 << (buck * 2));
+ if (ret)
+ return ret;
+ }
+ ret = pmic_clrsetbits(pmic, REG_DCDC_EN, mask,
+ enable ? mask : 0);
+ break;
+ case RK809_ID:
+ case RK817_ID:
+ if (buck < 4) {
+ if (enable)
+ value = ((1 << buck) | (1 << (buck + 4)));
+ else
+ value = ((0 << buck) | (1 << (buck + 4)));
+ ret = pmic_reg_write(pmic, RK817_POWER_EN(0), value);
+ /* BUCK5 for RK809 */
+ } else {
+ if (enable)
+ value = ((1 << 1) | (1 << 5));
+ else
+ value = ((0 << 1) | (1 << 5));
+ ret = pmic_reg_write(pmic, RK817_POWER_EN(3), value);
+ }
+ break;
+ default:
+ ret = -EINVAL;
}
- return pmic_clrsetbits(pmic, REG_DCDC_EN, mask, enable ? mask : 0);
+ return ret;
}
#ifdef ENABLE_DRIVER
+static int _buck_set_suspend_value(struct udevice *pmic, int buck, int uvolt)
+{
+ const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck, uvolt);
+ int mask = info->vsel_mask;
+ int val;
+
+ if (info->vsel_sleep_reg == NA)
+ return -ENOSYS;
+
+ if (info->step_uv == 0)
+ val = info->min_sel;
+ else
+ val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
+
+ debug("%s: volt=%d, buck=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
+ __func__, uvolt, buck + 1, info->vsel_sleep_reg, mask, val);
+
+ return pmic_clrsetbits(pmic, info->vsel_sleep_reg, mask, val);
+}
+
+static int _buck_get_enable(struct udevice *pmic, int buck)
+{
+ struct rk8xx_priv *priv = dev_get_priv(pmic);
+ uint mask = 0;
+ int ret = 0;
+
+ switch (priv->variant) {
+ case RK805_ID:
+ case RK816_ID:
+ if (buck >= 4) {
+ mask = 1 << (buck - 4);
+ ret = pmic_reg_read(pmic, RK816_REG_DCDC_EN2);
+ } else {
+ mask = 1 << buck;
+ ret = pmic_reg_read(pmic, RK816_REG_DCDC_EN1);
+ }
+ break;
+ case RK808_ID:
+ case RK818_ID:
+ mask = 1 << buck;
+ ret = pmic_reg_read(pmic, REG_DCDC_EN);
+ if (ret < 0)
+ return ret;
+ break;
+ case RK809_ID:
+ case RK817_ID:
+ if (buck < 4) {
+ mask = 1 << buck;
+ ret = pmic_reg_read(pmic, RK817_POWER_EN(0));
+ /* BUCK5 for RK809 */
+ } else {
+ mask = 1 << 1;
+ ret = pmic_reg_read(pmic, RK817_POWER_EN(3));
+ }
+ break;
+ }
+
+ if (ret < 0)
+ return ret;
+
+ return ret & mask ? true : false;
+}
+
+static int _buck_set_suspend_enable(struct udevice *pmic, int buck, bool enable)
+{
+ uint mask = 0;
+ int ret;
+ struct rk8xx_priv *priv = dev_get_priv(pmic);
+
+ switch (priv->variant) {
+ case RK805_ID:
+ case RK816_ID:
+ mask = 1 << buck;
+ ret = pmic_clrsetbits(pmic, RK816_REG_DCDC_SLP_EN, mask,
+ enable ? mask : 0);
+ break;
+ case RK808_ID:
+ case RK818_ID:
+ mask = 1 << buck;
+ ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF1, mask,
+ enable ? 0 : mask);
+ break;
+ case RK809_ID:
+ case RK817_ID:
+ if (buck < 4)
+ mask = 1 << buck;
+ else
+ mask = 1 << 5; /* BUCK5 for RK809 */
+ ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask,
+ enable ? mask : 0);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int _buck_get_suspend_enable(struct udevice *pmic, int buck)
+{
+ struct rk8xx_priv *priv = dev_get_priv(pmic);
+ int ret, val;
+ uint mask = 0;
+
+ switch (priv->variant) {
+ case RK805_ID:
+ case RK816_ID:
+ mask = 1 << buck;
+ val = pmic_reg_read(pmic, RK816_REG_DCDC_SLP_EN);
+ if (val < 0)
+ return val;
+ ret = val & mask ? 1 : 0;
+ break;
+ case RK808_ID:
+ case RK818_ID:
+ mask = 1 << buck;
+ val = pmic_reg_read(pmic, REG_SLEEP_SET_OFF1);
+ if (val < 0)
+ return val;
+ ret = val & mask ? 0 : 1;
+ break;
+ case RK809_ID:
+ case RK817_ID:
+ if (buck < 4)
+ mask = 1 << buck;
+ else
+ mask = 1 << 5; /* BUCK5 for RK809 */
+
+ val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(0));
+ if (val < 0)
+ return val;
+ ret = val & mask ? 1 : 0;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
- int num)
+ int num, int uvolt)
{
struct rk8xx_priv *priv = dev_get_priv(pmic);
+
switch (priv->variant) {
+ case RK805_ID:
+ case RK816_ID:
+ return &rk816_ldo[num];
+ case RK809_ID:
+ case RK817_ID:
+ if (uvolt < 3400000)
+ return &rk817_ldo[num * 2 + 0];
+ else
+ return &rk817_ldo[num * 2 + 1];
case RK818_ID:
return &rk818_ldo[num];
default:
@@ -145,15 +519,196 @@ static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
}
}
+static int _ldo_get_enable(struct udevice *pmic, int ldo)
+{
+ struct rk8xx_priv *priv = dev_get_priv(pmic);
+ uint mask = 0;
+ int ret = 0;
+
+ switch (priv->variant) {
+ case RK805_ID:
+ case RK816_ID:
+ if (ldo >= 4) {
+ mask = 1 << (ldo - 4);
+ ret = pmic_reg_read(pmic, RK816_REG_LDO_EN2);
+ } else {
+ mask = 1 << ldo;
+ ret = pmic_reg_read(pmic, RK816_REG_LDO_EN1);
+ }
+ break;
+ case RK808_ID:
+ case RK818_ID:
+ mask = 1 << ldo;
+ ret = pmic_reg_read(pmic, REG_LDO_EN);
+ if (ret < 0)
+ return ret;
+ break;
+ case RK809_ID:
+ case RK817_ID:
+ if (ldo < 4) {
+ mask = 1 << ldo;
+ ret = pmic_reg_read(pmic, RK817_POWER_EN(1));
+ } else if (ldo < 8) {
+ mask = 1 << (ldo - 4);
+ ret = pmic_reg_read(pmic, RK817_POWER_EN(2));
+ } else if (ldo == 8) {
+ mask = 1 << 0;
+ ret = pmic_reg_read(pmic, RK817_POWER_EN(3));
+ } else {
+ return false;
+ }
+ break;
+ }
+
+ if (ret < 0)
+ return ret;
+
+ return ret & mask ? true : false;
+}
+
+static int _ldo_set_enable(struct udevice *pmic, int ldo, bool enable)
+{
+ struct rk8xx_priv *priv = dev_get_priv(pmic);
+ uint mask, value, en_reg;
+ int ret = 0;
+
+ switch (priv->variant) {
+ case RK805_ID:
+ case RK816_ID:
+ if (ldo >= 4) {
+ ldo -= 4;
+ en_reg = RK816_REG_LDO_EN2;
+ } else {
+ en_reg = RK816_REG_LDO_EN1;
+ }
+ if (enable)
+ value = ((1 << ldo) | (1 << (ldo + 4)));
+ else
+ value = ((0 << ldo) | (1 << (ldo + 4)));
+
+ ret = pmic_reg_write(pmic, en_reg, value);
+ break;
+ case RK808_ID:
+ case RK818_ID:
+ mask = 1 << ldo;
+ ret = pmic_clrsetbits(pmic, REG_LDO_EN, mask,
+ enable ? mask : 0);
+ break;
+ case RK809_ID:
+ case RK817_ID:
+ if (ldo < 4) {
+ en_reg = RK817_POWER_EN(1);
+ } else if (ldo < 8) {
+ ldo -= 4;
+ en_reg = RK817_POWER_EN(2);
+ } else if (ldo == 8) {
+ ldo = 0; /* BIT 0 */
+ en_reg = RK817_POWER_EN(3);
+ } else {
+ return -EINVAL;
+ }
+ if (enable)
+ value = ((1 << ldo) | (1 << (ldo + 4)));
+ else
+ value = ((0 << ldo) | (1 << (ldo + 4)));
+ ret = pmic_reg_write(pmic, en_reg, value);
+ break;
+ }
+
+ return ret;
+}
+
+static int _ldo_set_suspend_enable(struct udevice *pmic, int ldo, bool enable)
+{
+ struct rk8xx_priv *priv = dev_get_priv(pmic);
+ uint mask;
+ int ret = 0;
+
+ switch (priv->variant) {
+ case RK805_ID:
+ case RK816_ID:
+ mask = 1 << ldo;
+ ret = pmic_clrsetbits(pmic, RK816_REG_LDO_SLP_EN, mask,
+ enable ? mask : 0);
+ break;
+ case RK808_ID:
+ case RK818_ID:
+ mask = 1 << ldo;
+ ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF2, mask,
+ enable ? 0 : mask);
+ break;
+ case RK809_ID:
+ case RK817_ID:
+ if (ldo == 8) {
+ mask = 1 << 4; /* LDO9 */
+ ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask,
+ enable ? mask : 0);
+ } else {
+ mask = 1 << ldo;
+ ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(1), mask,
+ enable ? mask : 0);
+ }
+ break;
+ }
+
+ return ret;
+}
+
+static int _ldo_get_suspend_enable(struct udevice *pmic, int ldo)
+{
+ struct rk8xx_priv *priv = dev_get_priv(pmic);
+ int val, ret = 0;
+ uint mask;
+
+ switch (priv->variant) {
+ case RK805_ID:
+ case RK816_ID:
+ mask = 1 << ldo;
+ val = pmic_reg_read(pmic, RK816_REG_LDO_SLP_EN);
+ if (val < 0)
+ return val;
+ ret = val & mask ? 1 : 0;
+ break;
+ case RK808_ID:
+ case RK818_ID:
+ mask = 1 << ldo;
+ val = pmic_reg_read(pmic, REG_SLEEP_SET_OFF2);
+ if (val < 0)
+ return val;
+ ret = val & mask ? 0 : 1;
+ break;
+ case RK809_ID:
+ case RK817_ID:
+ if (ldo == 8) {
+ mask = 1 << 4; /* LDO9 */
+ val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(0));
+ if (val < 0)
+ return val;
+ ret = val & mask ? 1 : 0;
+ } else {
+ mask = 1 << ldo;
+ val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(1));
+ if (val < 0)
+ return val;
+ ret = val & mask ? 1 : 0;
+ }
+ break;
+ }
+
+ return ret;
+}
+
static int buck_get_value(struct udevice *dev)
{
int buck = dev->driver_data - 1;
- const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck);
+ /* We assume level-1 voltage is enough for usage in U-Boot */
+ const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck, 0);
int mask = info->vsel_mask;
int ret, val;
- if (info->vsel_reg == -1)
+ if (info->vsel_reg == NA)
return -ENOSYS;
+
ret = pmic_reg_read(dev->parent, info->vsel_reg);
if (ret < 0)
return ret;
@@ -164,41 +719,74 @@ static int buck_get_value(struct udevice *dev)
static int buck_set_value(struct udevice *dev, int uvolt)
{
- int buck = dev->driver_data;
+ int buck = dev->driver_data - 1;
return _buck_set_value(dev->parent, buck, uvolt);
}
+static int buck_get_suspend_value(struct udevice *dev)
+{
+ int buck = dev->driver_data - 1;
+ /* We assume level-1 voltage is enough for usage in U-Boot */
+ const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck, 0);
+ int mask = info->vsel_mask;
+ int ret, val;
+
+ if (info->vsel_sleep_reg == NA)
+ return -ENOSYS;
+
+ ret = pmic_reg_read(dev->parent, info->vsel_sleep_reg);
+ if (ret < 0)
+ return ret;
+
+ val = ret & mask;
+
+ return info->min_uv + val * info->step_uv;
+}
+
+static int buck_set_suspend_value(struct udevice *dev, int uvolt)
+{
+ int buck = dev->driver_data - 1;
+
+ return _buck_set_suspend_value(dev->parent, buck, uvolt);
+}
+
static int buck_set_enable(struct udevice *dev, bool enable)
{
- int buck = dev->driver_data;
+ int buck = dev->driver_data - 1;
return _buck_set_enable(dev->parent, buck, enable);
}
-static int buck_get_enable(struct udevice *dev)
+static int buck_set_suspend_enable(struct udevice *dev, bool enable)
{
int buck = dev->driver_data - 1;
- int ret;
- uint mask;
- mask = 1 << buck;
+ return _buck_set_suspend_enable(dev->parent, buck, enable);
+}
- ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
- if (ret < 0)
- return ret;
+static int buck_get_suspend_enable(struct udevice *dev)
+{
+ int buck = dev->driver_data - 1;
- return ret & mask ? true : false;
+ return _buck_get_suspend_enable(dev->parent, buck);
+}
+
+static int buck_get_enable(struct udevice *dev)
+{
+ int buck = dev->driver_data - 1;
+
+ return _buck_get_enable(dev->parent, buck);
}
static int ldo_get_value(struct udevice *dev)
{
int ldo = dev->driver_data - 1;
- const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo);
+ const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, 0);
int mask = info->vsel_mask;
int ret, val;
- if (info->vsel_reg == -1)
+ if (info->vsel_reg == NA)
return -ENOSYS;
ret = pmic_reg_read(dev->parent, info->vsel_reg);
if (ret < 0)
@@ -211,71 +799,238 @@ static int ldo_get_value(struct udevice *dev)
static int ldo_set_value(struct udevice *dev, int uvolt)
{
int ldo = dev->driver_data - 1;
- const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo);
+ const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, uvolt);
int mask = info->vsel_mask;
int val;
- if (info->vsel_reg == -1)
+ if (info->vsel_reg == NA)
return -ENOSYS;
- val = (uvolt - info->min_uv) / info->step_uv;
- debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask,
- val);
+
+ if (info->step_uv == 0)
+ val = info->min_sel;
+ else
+ val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
+
+ debug("%s: volt=%d, ldo=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
+ __func__, uvolt, ldo + 1, info->vsel_reg, mask, val);
return pmic_clrsetbits(dev->parent, info->vsel_reg, mask, val);
}
-static int ldo_set_enable(struct udevice *dev, bool enable)
+static int ldo_set_suspend_value(struct udevice *dev, int uvolt)
{
int ldo = dev->driver_data - 1;
- uint mask;
+ const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, uvolt);
+ int mask = info->vsel_mask;
+ int val;
- mask = 1 << ldo;
+ if (info->vsel_sleep_reg == NA)
+ return -ENOSYS;
- return pmic_clrsetbits(dev->parent, REG_LDO_EN, mask,
- enable ? mask : 0);
+ if (info->step_uv == 0)
+ val = info->min_sel;
+ else
+ val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
+
+ debug("%s: volt=%d, ldo=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
+ __func__, uvolt, ldo + 1, info->vsel_sleep_reg, mask, val);
+
+ return pmic_clrsetbits(dev->parent, info->vsel_sleep_reg, mask, val);
}
-static int ldo_get_enable(struct udevice *dev)
+static int ldo_get_suspend_value(struct udevice *dev)
{
int ldo = dev->driver_data - 1;
- int ret;
- uint mask;
+ const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, 0);
+ int mask = info->vsel_mask;
+ int val, ret;
- mask = 1 << ldo;
+ if (info->vsel_sleep_reg == NA)
+ return -ENOSYS;
- ret = pmic_reg_read(dev->parent, REG_LDO_EN);
+ ret = pmic_reg_read(dev->parent, info->vsel_sleep_reg);
if (ret < 0)
return ret;
- return ret & mask ? true : false;
+ val = ret & mask;
+
+ return info->min_uv + val * info->step_uv;
+}
+
+static int ldo_set_enable(struct udevice *dev, bool enable)
+{
+ int ldo = dev->driver_data - 1;
+
+ return _ldo_set_enable(dev->parent, ldo, enable);
+}
+
+static int ldo_set_suspend_enable(struct udevice *dev, bool enable)
+{
+ int ldo = dev->driver_data - 1;
+
+ return _ldo_set_suspend_enable(dev->parent, ldo, enable);
+}
+
+static int ldo_get_suspend_enable(struct udevice *dev)
+{
+ int ldo = dev->driver_data - 1;
+
+ return _ldo_get_suspend_enable(dev->parent, ldo);
+}
+
+static int ldo_get_enable(struct udevice *dev)
+{
+ int ldo = dev->driver_data - 1;
+
+ return _ldo_get_enable(dev->parent, ldo);
}
static int switch_set_enable(struct udevice *dev, bool enable)
{
- int sw = dev->driver_data - 1;
- uint mask;
+ struct rk8xx_priv *priv = dev_get_priv(dev->parent);
+ int ret = 0, sw = dev->driver_data - 1;
+ uint mask = 0;
+
+ switch (priv->variant) {
+ case RK808_ID:
+ mask = 1 << (sw + 5);
+ ret = pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
+ enable ? mask : 0);
+ break;
+ case RK809_ID:
+ mask = (1 << (sw + 2)) | (1 << (sw + 6));
+ ret = pmic_clrsetbits(dev->parent, RK817_POWER_EN(3), mask,
+ enable ? mask : 0);
+ break;
+ case RK818_ID:
+ mask = 1 << 6;
+ ret = pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
+ enable ? mask : 0);
+ break;
+ }
- mask = 1 << (sw + 5);
+ debug("%s: switch%d, enable=%d, mask=0x%x\n",
+ __func__, sw + 1, enable, mask);
- return pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
- enable ? mask : 0);
+ return ret;
}
static int switch_get_enable(struct udevice *dev)
{
- int sw = dev->driver_data - 1;
- int ret;
- uint mask;
+ struct rk8xx_priv *priv = dev_get_priv(dev->parent);
+ int ret = 0, sw = dev->driver_data - 1;
+ uint mask = 0;
- mask = 1 << (sw + 5);
+ switch (priv->variant) {
+ case RK808_ID:
+ mask = 1 << (sw + 5);
+ ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
+ break;
+ case RK809_ID:
+ mask = 1 << (sw + 2);
+ ret = pmic_reg_read(dev->parent, RK817_POWER_EN(3));
+ break;
+ case RK818_ID:
+ mask = 1 << 6;
+ ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
+ break;
+ }
- ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
if (ret < 0)
return ret;
return ret & mask ? true : false;
}
+static int switch_set_suspend_value(struct udevice *dev, int uvolt)
+{
+ return 0;
+}
+
+static int switch_get_suspend_value(struct udevice *dev)
+{
+ return 0;
+}
+
+static int switch_set_suspend_enable(struct udevice *dev, bool enable)
+{
+ struct rk8xx_priv *priv = dev_get_priv(dev->parent);
+ int ret = 0, sw = dev->driver_data - 1;
+ uint mask = 0;
+
+ switch (priv->variant) {
+ case RK808_ID:
+ mask = 1 << (sw + 5);
+ ret = pmic_clrsetbits(dev->parent, REG_SLEEP_SET_OFF1, mask,
+ enable ? 0 : mask);
+ break;
+ case RK809_ID:
+ mask = 1 << (sw + 6);
+ ret = pmic_clrsetbits(dev->parent, RK817_POWER_SLP_EN(0), mask,
+ enable ? mask : 0);
+ break;
+ case RK818_ID:
+ mask = 1 << 6;
+ ret = pmic_clrsetbits(dev->parent, REG_SLEEP_SET_OFF1, mask,
+ enable ? 0 : mask);
+ break;
+ }
+
+ debug("%s: switch%d, enable=%d, mask=0x%x\n",
+ __func__, sw + 1, enable, mask);
+
+ return ret;
+}
+
+static int switch_get_suspend_enable(struct udevice *dev)
+{
+ struct rk8xx_priv *priv = dev_get_priv(dev->parent);
+ int val, ret = 0, sw = dev->driver_data - 1;
+ uint mask = 0;
+
+ switch (priv->variant) {
+ case RK808_ID:
+ mask = 1 << (sw + 5);
+ val = pmic_reg_read(dev->parent, REG_SLEEP_SET_OFF1);
+ if (val < 0)
+ return val;
+ ret = val & mask ? 0 : 1;
+ break;
+ case RK809_ID:
+ mask = 1 << (sw + 6);
+ val = pmic_reg_read(dev->parent, RK817_POWER_SLP_EN(0));
+ if (val < 0)
+ return val;
+ ret = val & mask ? 1 : 0;
+ break;
+ case RK818_ID:
+ mask = 1 << 6;
+ val = pmic_reg_read(dev->parent, REG_SLEEP_SET_OFF1);
+ if (val < 0)
+ return val;
+ ret = val & mask ? 0 : 1;
+ break;
+ }
+
+ return ret;
+}
+
+/*
+ * RK8xx switch does not need to set the voltage,
+ * but if dts set regulator-min-microvolt/regulator-max-microvolt,
+ * will cause regulator set value fail and not to enable this switch.
+ * So add an empty function to return success.
+ */
+static int switch_get_value(struct udevice *dev)
+{
+ return 0;
+}
+
+static int switch_set_value(struct udevice *dev, int uvolt)
+{
+ return 0;
+}
+
static int rk8xx_buck_probe(struct udevice *dev)
{
struct dm_regulator_uclass_platdata *uc_pdata;
@@ -315,20 +1070,34 @@ static int rk8xx_switch_probe(struct udevice *dev)
static const struct dm_regulator_ops rk8xx_buck_ops = {
.get_value = buck_get_value,
.set_value = buck_set_value,
+ .set_suspend_value = buck_set_suspend_value,
+ .get_suspend_value = buck_get_suspend_value,
.get_enable = buck_get_enable,
.set_enable = buck_set_enable,
+ .set_suspend_enable = buck_set_suspend_enable,
+ .get_suspend_enable = buck_get_suspend_enable,
};
static const struct dm_regulator_ops rk8xx_ldo_ops = {
.get_value = ldo_get_value,
.set_value = ldo_set_value,
+ .set_suspend_value = ldo_set_suspend_value,
+ .get_suspend_value = ldo_get_suspend_value,
.get_enable = ldo_get_enable,
.set_enable = ldo_set_enable,
+ .set_suspend_enable = ldo_set_suspend_enable,
+ .get_suspend_enable = ldo_get_suspend_enable,
};
static const struct dm_regulator_ops rk8xx_switch_ops = {
+ .get_value = switch_get_value,
+ .set_value = switch_set_value,
.get_enable = switch_get_enable,
.set_enable = switch_set_enable,
+ .set_suspend_enable = switch_set_suspend_enable,
+ .get_suspend_enable = switch_get_suspend_enable,
+ .set_suspend_value = switch_set_suspend_value,
+ .get_suspend_value = switch_get_suspend_value,
};
U_BOOT_DRIVER(rk8xx_buck) = {
diff --git a/drivers/ram/rockchip/sdram_rk3328.c b/drivers/ram/rockchip/sdram_rk3328.c
index 656696ac3c..e84c9be6a2 100644
--- a/drivers/ram/rockchip/sdram_rk3328.c
+++ b/drivers/ram/rockchip/sdram_rk3328.c
@@ -311,12 +311,12 @@ static void phy_dll_bypass_set(struct dram_info *dram, u32 freq)
setbits_le32(PHY_REG(phy_base, 0x56), 1 << 4);
clrbits_le32(PHY_REG(phy_base, 0x57), 1 << 3);
- if (freq <= (400 * MHz))
+ if (freq <= 400)
/* DLL bypass */
setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
else
clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
- if (freq <= (680 * MHz))
+ if (freq <= 680)
tmp = 2;
else
tmp = 1;
@@ -394,7 +394,7 @@ static void phy_cfg(struct dram_info *dram,
copy_to_reg(PHY_REG(phy_base, 0x70),
&sdram_params->skew.cs0_dm0_skew[0], 44 * 4);
copy_to_reg(PHY_REG(phy_base, 0xc0),
- &sdram_params->skew.cs0_dm1_skew[0], 44 * 4);
+ &sdram_params->skew.cs1_dm0_skew[0], 44 * 4);
}
static int update_refresh_reg(struct dram_info *dram)
diff --git a/include/configs/rk3328_common.h b/include/configs/rk3328_common.h
index 3ff3331c80..e51e1b0e0e 100644
--- a/include/configs/rk3328_common.h
+++ b/include/configs/rk3328_common.h
@@ -18,7 +18,7 @@
#define CONFIG_SYS_INIT_SP_ADDR 0x00300000
#define CONFIG_SYS_LOAD_ADDR 0x00800800
#define CONFIG_SPL_STACK 0x00400000
-#define CONFIG_SPL_MAX_SIZE 0x100000
+#define CONFIG_SPL_MAX_SIZE 0x40000
#define CONFIG_SPL_BSS_START_ADDR 0x2000000
#define CONFIG_SPL_BSS_MAX_SIZE 0x2000
diff --git a/include/configs/rk3368_common.h b/include/configs/rk3368_common.h
index e4b2114a0d..e57d0efa7f 100644
--- a/include/configs/rk3368_common.h
+++ b/include/configs/rk3368_common.h
@@ -27,7 +27,7 @@
#define CONFIG_SYS_INIT_SP_ADDR 0x00300000
#define CONFIG_SYS_LOAD_ADDR 0x00280000
-#define CONFIG_SPL_MAX_SIZE 0x60000
+#define CONFIG_SPL_MAX_SIZE 0x40000
#define CONFIG_SPL_BSS_START_ADDR 0x400000
#define CONFIG_SPL_BSS_MAX_SIZE 0x20000
#define CONFIG_SPL_STACK 0x00188000
diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h
index 126c34763e..7331c6dc02 100644
--- a/include/configs/rk3399_common.h
+++ b/include/configs/rk3399_common.h
@@ -21,7 +21,7 @@
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_TPL_BOOTROM_SUPPORT)
#define CONFIG_SPL_STACK 0x00400000
-#define CONFIG_SPL_MAX_SIZE 0x100000
+#define CONFIG_SPL_MAX_SIZE 0x40000
#define CONFIG_SPL_BSS_START_ADDR 0x00400000
#define CONFIG_SPL_BSS_MAX_SIZE 0x2000
#else
diff --git a/include/power/regulator.h b/include/power/regulator.h
index 6c6e2cd4f9..dd61eb4ccb 100644
--- a/include/power/regulator.h
+++ b/include/power/regulator.h
@@ -168,6 +168,7 @@ struct dm_regulator_uclass_platdata {
int mode_count;
int min_uV;
int max_uV;
+ int init_uV;
int min_uA;
int max_uA;
unsigned int ramp_delay;
@@ -177,6 +178,8 @@ struct dm_regulator_uclass_platdata {
int flags;
u8 ctrl_reg;
u8 volt_reg;
+ bool suspend_on;
+ u32 suspend_uV;
};
/* Regulator device operations */
@@ -194,6 +197,19 @@ struct dm_regulator_ops {
int (*set_value)(struct udevice *dev, int uV);
/**
+ * The regulator suspend output value function calls operates
+ * on a micro Volts.
+ *
+ * get/set_suspen_value - get/set suspend mode output value
+ * @dev - regulator device
+ * Sets:
+ * @uV - set the suspend output value [micro Volts]
+ * @return output value [uV] on success or negative errno if fail.
+ */
+ int (*set_suspend_value)(struct udevice *dev, int uV);
+ int (*get_suspend_value)(struct udevice *dev);
+
+ /**
* The regulator output current function calls operates on a micro Amps.
*
* get/set_current - get/set output current of the given output number
@@ -218,6 +234,19 @@ struct dm_regulator_ops {
int (*set_enable)(struct udevice *dev, bool enable);
/**
+ * The most basic feature of the regulator output is its enable state
+ * in suspend mode.
+ *
+ * get/set_suspend_enable - get/set enable state of the suspend output
+ * @dev - regulator device
+ * Sets:
+ * @enable - set true - enable or false - disable
+ * @return true/false for get or -errno if fail; 0 / -errno for set.
+ */
+ int (*set_suspend_enable)(struct udevice *dev, bool enable);
+ int (*get_suspend_enable)(struct udevice *dev);
+
+ /**
* The 'get/set_mode()' function calls should operate on a driver-
* specific mode id definitions, which should be found in:
* field 'id' of struct dm_regulator_mode.
@@ -262,6 +291,23 @@ int regulator_get_value(struct udevice *dev);
int regulator_set_value(struct udevice *dev, int uV);
/**
+ * regulator_set_suspend_value: set the suspend microvoltage value of a given regulator.
+ *
+ * @dev - pointer to the regulator device
+ * @uV - the output suspend value to set [micro Volts]
+ * @return - 0 on success or -errno val if fails
+ */
+int regulator_set_suspend_value(struct udevice *dev, int uV);
+
+/**
+ * regulator_get_suspend_value: get the suspend microvoltage value of a given regulator.
+ *
+ * @dev - pointer to the regulator device
+ * @return - positive output value [uV] on success or negative errno if fail.
+ */
+int regulator_get_suspend_value(struct udevice *dev);
+
+/**
* regulator_set_value_force: set the microvoltage value of a given regulator
* without any min-,max condition check
*
@@ -317,6 +363,24 @@ int regulator_set_enable(struct udevice *dev, bool enable);
int regulator_set_enable_if_allowed(struct udevice *dev, bool enable);
/**
+ * regulator_set_suspend_enable: set regulator suspend enable state
+ *
+ * @dev - pointer to the regulator device
+ * @enable - set true or false
+ * @return - 0 on success or -errno val if fails
+ */
+int regulator_set_suspend_enable(struct udevice *dev, bool enable);
+
+
+/**
+ * regulator_get_suspend_enable: get regulator suspend enable state
+ *
+ * @dev - pointer to the regulator device
+ * @return - true/false of enable state or -errno val if fails
+ */
+int regulator_get_suspend_enable(struct udevice *dev);
+
+/**
* regulator_get_mode: get active operation mode id of a given regulator
*
* @dev - pointer to the regulator device
diff --git a/include/power/rk8xx_pmic.h b/include/power/rk8xx_pmic.h
index c06248f751..8ff0af35c5 100644
--- a/include/power/rk8xx_pmic.h
+++ b/include/power/rk8xx_pmic.h
@@ -170,13 +170,55 @@ enum {
};
enum {
+ RK817_REG_SYS_CFG3 = 0xf4,
+};
+
+enum {
+ RK816_REG_DCDC_EN1 = 0x23,
+ RK816_REG_DCDC_EN2,
+ RK816_REG_DCDC_SLP_EN,
+ RK816_REG_LDO_SLP_EN,
+ RK816_REG_LDO_EN1 = 0x27,
+ RK816_REG_LDO_EN2,
+};
+
+enum {
RK805_ID = 0x8050,
RK808_ID = 0x0000,
+ RK809_ID = 0x8090,
+ RK816_ID = 0x8160,
+ RK817_ID = 0x8170,
RK818_ID = 0x8180,
};
+enum {
+ RK817_POWER_EN0 = 0xb1,
+ RK817_POWER_EN1,
+ RK817_POWER_EN2,
+ RK817_POWER_EN3,
+};
+
+#define RK817_POWER_EN_SAVE0 0x99
+#define RK817_POWER_EN_SAVE1 0xa4
+
+#define RK817_ID_MSB 0xed
+#define RK817_ID_LSB 0xee
#define RK8XX_ID_MSK 0xfff0
+#define RK817_PMIC_SYS_CFG3 0xf4
+#define RK817_GPIO_INT_CFG 0xfe
+
+#define RK8XX_ON_SOURCE 0xae
+#define RK8XX_OFF_SOURCE 0xaf
+#define RK817_BUCK4_CMIN 0xc6
+#define RK817_ON_SOURCE 0xf5
+#define RK817_OFF_SOURCE 0xf6
+
+struct reg_data {
+ u8 reg;
+ u8 val;
+ u8 mask;
+};
struct rk8xx_reg_table {
char *name;
u8 reg_ctl;
diff --git a/test/dm/regulator.c b/test/dm/regulator.c
index e510539542..b967902493 100644
--- a/test/dm/regulator.c
+++ b/test/dm/regulator.c
@@ -215,6 +215,63 @@ static int dm_test_power_regulator_set_get_mode(struct unit_test_state *uts)
}
DM_TEST(dm_test_power_regulator_set_get_mode, DM_TESTF_SCAN_FDT);
+/* Test regulator set and get suspend Voltage method */
+static int dm_test_power_regulator_set_get_suspend_voltage(struct unit_test_state *uts)
+{
+ struct dm_regulator_uclass_platdata *uc_pdata;
+ const struct dm_regulator_ops *ops;
+ struct udevice *dev;
+ const char *platname;
+ int val_set, val_get;
+
+ /* Set and get Voltage of BUCK1 - set to 'min' constraint */
+ platname = regulator_names[BUCK1][PLATNAME];
+ ut_assertok(regulator_get_by_platname(platname, &dev));
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+ ut_assert(uc_pdata);
+
+ ops = dev_get_driver_ops(dev);
+
+ if (ops->set_suspend_value && ops->get_suspend_value) {
+ val_set = uc_pdata->suspend_uV;
+ ut_assertok(regulator_set_suspend_value(dev, val_set));
+ val_get = regulator_get_suspend_value(dev);
+ ut_assert(val_get >= 0);
+
+ ut_asserteq(val_set, val_get);
+ }
+ return 0;
+}
+DM_TEST(dm_test_power_regulator_set_get_suspend_voltage, DM_TESTF_SCAN_FDT);
+
+/* Test regulator set and get suspend Enable method */
+static int dm_test_power_regulator_set_get_suspend_enable(struct unit_test_state *uts)
+{
+ const struct dm_regulator_ops *ops;
+ const char *platname;
+ struct udevice *dev;
+ bool val_set = true;
+
+ /* Set the Enable of LDO1 - default is disabled */
+ platname = regulator_names[LDO1][PLATNAME];
+ ut_assertok(regulator_get_by_platname(platname, &dev));
+
+ ops = dev_get_driver_ops(dev);
+
+ if (ops->set_suspend_enable && ops->get_suspend_enable) {
+ ut_assertok(regulator_set_suspend_enable(dev, val_set));
+
+ /*
+ * Get the Enable state of LDO1 and
+ * compare it with the requested one
+ */
+ ut_asserteq(regulator_get_suspend_enable(dev), val_set);
+ }
+ return 0;
+}
+DM_TEST(dm_test_power_regulator_set_get_suspend_enable, DM_TESTF_SCAN_FDT);
+
/* Test regulator autoset method */
static int dm_test_power_regulator_autoset(struct unit_test_state *uts)
{