summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2017-10-01 13:05:53 -0400
committerTom Rini <trini@konsulko.com>2017-10-01 13:05:53 -0400
commit16d4ff76c524fa8b0adb5328a9977b6939cd5416 (patch)
tree8b07bc434bb14904afce38003fe7e29ca278c95d
parent958046fc78f95a3d28b06980a7eb3ed80123c533 (diff)
parente19fa89c9d344201da25a7b67fdd9d6896af6847 (diff)
Merge git://git.denx.de/u-boot-rockchip
-rw-r--r--arch/arm/Kconfig3
-rw-r--r--arch/arm/dts/rk3229-evb.dts1
-rw-r--r--arch/arm/dts/rk3288-popmetal.dtsi4
-rw-r--r--arch/arm/dts/rk3328-evb.dts122
-rw-r--r--arch/arm/dts/rk3368-px5-evb.dts4
-rw-r--r--arch/arm/dts/rk3368-sheep.dts4
-rw-r--r--arch/arm/dts/rk3399-evb.dts4
-rw-r--r--arch/arm/dts/rk3399-puma.dtsi33
-rw-r--r--arch/arm/dts/rv1108-evb.dts4
-rw-r--r--arch/arm/dts/rv1108.dtsi11
-rw-r--r--arch/arm/include/asm/arch-rockchip/bootrom.h18
-rw-r--r--arch/arm/include/asm/arch-rockchip/cru_rk3368.h5
-rw-r--r--arch/arm/include/asm/arch-rockchip/cru_rv1108.h5
-rw-r--r--arch/arm/include/asm/arch-rockchip/grf_rk3036.h4
-rw-r--r--arch/arm/include/asm/arch-rockchip/sdram_rk322x.h581
-rw-r--r--arch/arm/include/asm/arch-rockchip/sys_proto.h23
-rw-r--r--arch/arm/include/asm/armv7.h21
-rw-r--r--arch/arm/mach-rockchip/Makefile1
-rw-r--r--arch/arm/mach-rockchip/rk3188/Makefile1
-rw-r--r--arch/arm/mach-rockchip/rk322x-board.c4
-rw-r--r--arch/arm/mach-rockchip/rk3288-board-spl.c61
-rw-r--r--arch/arm/mach-rockchip/rk3288-board-tpl.c84
-rw-r--r--arch/arm/mach-rockchip/rk3288/Kconfig16
-rw-r--r--arch/arm/mach-rockchip/rk3288/Makefile1
-rw-r--r--arch/arm/mach-rockchip/rk3328/Makefile1
-rw-r--r--arch/arm/mach-rockchip/rk3399-board-spl.c69
-rw-r--r--arch/arm/mach-rockchip/rk3399/Makefile1
-rw-r--r--arch/arm/mach-rockchip/spl-boot-order.c48
-rw-r--r--board/amarula/vyasa-rk3288/vyasa-rk3288.c13
-rw-r--r--board/rockchip/evb_rk3399/evb-rk3399.c30
-rw-r--r--board/theobroma-systems/lion_rk3368/fit_spl_atf.its4
-rw-r--r--board/theobroma-systems/puma_rk3399/puma-rk3399.c56
-rw-r--r--configs/evb-rk3328_defconfig6
-rw-r--r--configs/lion-rk3368_defconfig1
-rw-r--r--configs/puma-rk3399_defconfig7
-rw-r--r--configs/vyasa-rk3288_defconfig3
-rw-r--r--doc/README.rockchip18
-rw-r--r--doc/device-tree-bindings/chosen.txt12
-rw-r--r--drivers/adc/Kconfig9
-rw-r--r--drivers/adc/Makefile1
-rw-r--r--drivers/adc/rockchip-saradc.c183
-rw-r--r--drivers/clk/rockchip/clk_rk322x.c8
-rw-r--r--drivers/clk/rockchip/clk_rk3288.c41
-rw-r--r--drivers/clk/rockchip/clk_rk3328.c35
-rw-r--r--drivers/clk/rockchip/clk_rk3368.c32
-rw-r--r--drivers/clk/rockchip/clk_rk3399.c36
-rw-r--r--drivers/clk/rockchip/clk_rv1108.c33
-rw-r--r--drivers/i2c/rk_i2c.c1
-rw-r--r--drivers/pinctrl/rockchip/pinctrl_rk3368.c39
-rw-r--r--drivers/power/regulator/Kconfig7
-rw-r--r--drivers/ram/rockchip/Makefile5
-rw-r--r--drivers/ram/rockchip/sdram_rk3188.c (renamed from arch/arm/mach-rockchip/rk3188/sdram_rk3188.c)11
-rw-r--r--drivers/ram/rockchip/sdram_rk322x.c855
-rw-r--r--drivers/ram/rockchip/sdram_rk3288.c (renamed from arch/arm/mach-rockchip/rk3288/sdram_rk3288.c)0
-rw-r--r--drivers/ram/rockchip/sdram_rk3328.c (renamed from arch/arm/mach-rockchip/rk3328/sdram_rk3328.c)0
-rw-r--r--drivers/ram/rockchip/sdram_rk3399.c (renamed from arch/arm/mach-rockchip/rk3399/sdram_rk3399.c)0
-rw-r--r--include/configs/evb_rk3399.h6
-rw-r--r--include/configs/rk3288_common.h6
-rw-r--r--include/configs/vyasa-rk3288.h17
-rw-r--r--include/dt-bindings/clock/rv1108-cru.h2
-rw-r--r--tools/rkcommon.c1
61 files changed, 2462 insertions, 150 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fca23b4e64..d6d9558c69 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1115,6 +1115,9 @@ config ARCH_ROCKCHIP
imply FAT_WRITE
imply USB_FUNCTION_FASTBOOT
imply SPL_SYSRESET
+ imply TPL_SYSRESET
+ imply ADC
+ imply SARADC_ROCKCHIP
config TARGET_THUNDERX_88XX
bool "Support ThunderX 88xx"
diff --git a/arch/arm/dts/rk3229-evb.dts b/arch/arm/dts/rk3229-evb.dts
index 64f1c2d7da..ae0b0a4b8e 100644
--- a/arch/arm/dts/rk3229-evb.dts
+++ b/arch/arm/dts/rk3229-evb.dts
@@ -40,7 +40,6 @@
};
&dmc {
- rockchip,sdram-channel = /bits/ 8 <1 10 3 2 1 0 15 15>;
rockchip,pctl-timing = <0x96 0xC8 0x1F3 0xF 0x8000004D 0x4 0x4E 0x6 0x3
0x0 0x6 0x5 0xC 0x10 0x6 0x4 0x4
0x5 0x4 0x200 0x3 0xA 0x40 0x0 0x1
diff --git a/arch/arm/dts/rk3288-popmetal.dtsi b/arch/arm/dts/rk3288-popmetal.dtsi
index dd6ce8b69e..63785eb55e 100644
--- a/arch/arm/dts/rk3288-popmetal.dtsi
+++ b/arch/arm/dts/rk3288-popmetal.dtsi
@@ -491,6 +491,10 @@
};
};
+&saradc {
+ status = "okay";
+};
+
&tsadc {
rockchip,hw-tshut-mode = <0>;
rockchip,hw-tshut-polarity = <0>;
diff --git a/arch/arm/dts/rk3328-evb.dts b/arch/arm/dts/rk3328-evb.dts
index 8a14c653e4..3dd9d81961 100644
--- a/arch/arm/dts/rk3328-evb.dts
+++ b/arch/arm/dts/rk3328-evb.dts
@@ -42,6 +42,10 @@
};
};
+&saradc {
+ status = "okay";
+};
+
&uart2 {
status = "okay";
};
@@ -87,3 +91,121 @@
vbus-supply = <&vcc5v0_host_xhci>;
status = "okay";
};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ i2c-scl-rising-time-ns = <168>;
+ i2c-scl-falling-time-ns = <4>;
+ status = "okay";
+
+ rk805: pmic@18 {
+ compatible = "rockchip,rk805";
+ status = "okay";
+ reg = <0x18>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int_l>;
+ rockchip,system-power-controller;
+ wakeup-source;
+ gpio-controller;
+ #gpio-cells = <2>;
+ #clock-cells = <1>;
+ clock-output-names = "xin32k", "rk805-clkout2";
+
+ regulators {
+ vdd_logic: DCDC_REG1 {
+ regulator-name = "vdd_logic";
+ regulator-min-microvolt = <712500>;
+ regulator-max-microvolt = <1450000>;
+ regulator-ramp-delay = <6001>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
+ };
+
+ vdd_arm: DCDC_REG2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <712500>;
+ regulator-max-microvolt = <1450000>;
+ regulator-ramp-delay = <6001>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-name = "vcc_ddr";
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_io: DCDC_REG4 {
+ regulator-name = "vcc_io";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vdd_18: LDO_REG1 {
+ regulator-name = "vdd_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vcc_18emmc: LDO_REG2 {
+ regulator-name = "vcc_18emmc";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_10: LDO_REG3 {
+ regulator-name = "vdd_10";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
+ };
+ };
+ };
+};
+
+&pinctrl {
+ pmic {
+ pmic_int_l: pmic-int-l {
+ rockchip,pins =
+ <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; /* gpio2_a6 */
+ };
+ };
+};
+
diff --git a/arch/arm/dts/rk3368-px5-evb.dts b/arch/arm/dts/rk3368-px5-evb.dts
index c7478f7ddb..e9c5ebad47 100644
--- a/arch/arm/dts/rk3368-px5-evb.dts
+++ b/arch/arm/dts/rk3368-px5-evb.dts
@@ -296,6 +296,10 @@
};
};
+&saradc {
+ status = "okay";
+};
+
&tsadc {
status = "okay";
rockchip,hw-tshut-mode = <0>; /* CRU */
diff --git a/arch/arm/dts/rk3368-sheep.dts b/arch/arm/dts/rk3368-sheep.dts
index 7c190f7456..27befadd67 100644
--- a/arch/arm/dts/rk3368-sheep.dts
+++ b/arch/arm/dts/rk3368-sheep.dts
@@ -260,6 +260,10 @@
};
};
+&saradc {
+ status = "okay";
+};
+
&tsadc {
status = "okay";
rockchip,hw-tshut-mode = <0>; /* CRU */
diff --git a/arch/arm/dts/rk3399-evb.dts b/arch/arm/dts/rk3399-evb.dts
index be0c6d98bd..0e5d8d79a1 100644
--- a/arch/arm/dts/rk3399-evb.dts
+++ b/arch/arm/dts/rk3399-evb.dts
@@ -149,6 +149,10 @@
status = "okay";
};
+&saradc {
+ status = "okay";
+};
+
&sdmmc {
bus-width = <4>;
status = "okay";
diff --git a/arch/arm/dts/rk3399-puma.dtsi b/arch/arm/dts/rk3399-puma.dtsi
index a04878e223..65ab380139 100644
--- a/arch/arm/dts/rk3399-puma.dtsi
+++ b/arch/arm/dts/rk3399-puma.dtsi
@@ -20,7 +20,8 @@
chosen {
stdout-path = "serial0:115200n8";
- u-boot,spl-boot-order = &spiflash, &sdhci, &sdmmc;
+ u-boot,spl-boot-order = \
+ "same-as-spl", &spiflash, &sdhci, &sdmmc;
};
aliases {
@@ -100,6 +101,24 @@
regulator-max-microvolt = <3300000>;
};
+ /*
+ * The Qseven BIOS_DISABLE signal on the RK3399-Q7 keeps the on-module
+ * eMMC and SPI flash powered-down initially (in fact it keeps the
+ * reset signal asserted). Even though it is an enable signal, we
+ * model this as a regulator.
+ */
+ bios_enable: bios_enable {
+ compatible = "regulator-fixed";
+ u-boot,dm-pre-reloc;
+ regulator-name = "bios_enable";
+ enable-active-low;
+ gpio = <&gpio3 29 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
vccadc_ref: vccadc-ref {
compatible = "regulator-fixed";
regulator-name = "vcc1v8_sys";
@@ -458,7 +477,7 @@
};
&pcie_phy {
- status = "okay";
+ status = "okay";
};
&pmu_io_domains {
@@ -485,7 +504,7 @@
};
&sdmmc {
- u-boot,dm-pre-reloc;
+ u-boot,dm-pre-reloc;
clock-frequency = <150000000>;
clock-freq-min-max = <100000 150000000>;
supports-sd;
@@ -532,10 +551,15 @@
status = "okay";
};
+&gpio3 {
+ u-boot,dm-pre-reloc;
+};
+
&pinctrl {
/* Pins that are not explicitely used by any devices */
pinctrl-names = "default";
pinctrl-0 = <&puma_pin_hog>;
+
hog {
puma_pin_hog: puma_pin_hog {
rockchip,pins =
@@ -575,7 +599,7 @@
i2c8 {
i2c8_xfer_a: i2c8-xfer {
rockchip,pins = <1 21 RK_FUNC_1 &pcfg_pull_up>,
- <1 20 RK_FUNC_1 &pcfg_pull_up>;
+ <1 20 RK_FUNC_1 &pcfg_pull_up>;
};
};
};
@@ -651,4 +675,3 @@
&spi5 {
status = "okay";
};
-
diff --git a/arch/arm/dts/rv1108-evb.dts b/arch/arm/dts/rv1108-evb.dts
index 2b221b6d61..8e857b2c89 100644
--- a/arch/arm/dts/rv1108-evb.dts
+++ b/arch/arm/dts/rv1108-evb.dts
@@ -39,6 +39,10 @@
snps,reset-gpio = <&gpio1 RK_PC1 GPIO_ACTIVE_LOW>;
};
+&saradc {
+ status = "okay";
+};
+
&sfc {
status = "okay";
flash@0 {
diff --git a/arch/arm/dts/rv1108.dtsi b/arch/arm/dts/rv1108.dtsi
index 3153dfe658..31b4d93b07 100644
--- a/arch/arm/dts/rv1108.dtsi
+++ b/arch/arm/dts/rv1108.dtsi
@@ -126,6 +126,17 @@
reg = <0x10300000 0x1000>;
};
+ saradc: saradc@1038c000 {
+ compatible = "rockchip,rv1108-saradc", "rockchip,rk3399-saradc";
+ reg = <0x1038c000 0x100>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ #io-channel-cells = <1>;
+ clock-frequency = <1000000>;
+ clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
+ clock-names = "saradc", "apb_pclk";
+ status = "disabled";
+ };
+
pmugrf: syscon@20060000 {
compatible = "rockchip,rv1108-pmugrf", "syscon";
reg = <0x20060000 0x1000>;
diff --git a/arch/arm/include/asm/arch-rockchip/bootrom.h b/arch/arm/include/asm/arch-rockchip/bootrom.h
index 92eb8783a3..169cc5e50b 100644
--- a/arch/arm/include/asm/arch-rockchip/bootrom.h
+++ b/arch/arm/include/asm/arch-rockchip/bootrom.h
@@ -24,4 +24,22 @@ void back_to_bootrom(void);
*/
void _back_to_bootrom_s(void);
+/**
+ * Boot-device identifiers as used by the BROM
+ */
+enum {
+ BROM_BOOTSOURCE_NAND = 1,
+ BROM_BOOTSOURCE_EMMC = 2,
+ BROM_BOOTSOURCE_SPINOR = 3,
+ BROM_BOOTSOURCE_SPINAND = 4,
+ BROM_BOOTSOURCE_SD = 5,
+ BROM_BOOTSOURCE_USB = 10,
+ BROM_LAST_BOOTSOURCE = BROM_BOOTSOURCE_USB
+};
+
+/**
+ * Locations of the boot-device identifier in SRAM
+ */
+#define RK3399_BROM_BOOTSOURCE_ID_ADDR 0xff8c0010
+
#endif
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3368.h b/arch/arm/include/asm/arch-rockchip/cru_rk3368.h
index 2b1197fd46..5f6a5fbe4c 100644
--- a/arch/arm/include/asm/arch-rockchip/cru_rk3368.h
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3368.h
@@ -89,6 +89,11 @@ enum {
MCU_CLK_DIV_SHIFT = 0,
MCU_CLK_DIV_MASK = GENMASK(4, 0),
+ /* CLKSEL_CON25 */
+ CLK_SARADC_DIV_CON_SHIFT = 8,
+ CLK_SARADC_DIV_CON_MASK = GENMASK(15, 8),
+ CLK_SARADC_DIV_CON_WIDTH = 8,
+
/* CLKSEL43_CON */
GMAC_MUX_SEL_EXTCLK = BIT(8),
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rv1108.h b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h
index 2a1ae692be..ad2dc96467 100644
--- a/arch/arm/include/asm/arch-rockchip/cru_rv1108.h
+++ b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h
@@ -90,6 +90,11 @@ enum {
CORE_CLK_DIV_SHIFT = 0,
CORE_CLK_DIV_MASK = 0x1f << CORE_CLK_DIV_SHIFT,
+ /* CLKSEL_CON22 */
+ CLK_SARADC_DIV_CON_SHIFT= 0,
+ CLK_SARADC_DIV_CON_MASK = GENMASK(9, 0),
+ CLK_SARADC_DIV_CON_WIDTH= 10,
+
/* CLKSEL24_CON */
MAC_PLL_SEL_SHIFT = 12,
MAC_PLL_SEL_MASK = 1 << MAC_PLL_SEL_SHIFT,
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3036.h b/arch/arm/include/asm/arch-rockchip/grf_rk3036.h
index 7625f249bd..d995b7db14 100644
--- a/arch/arm/include/asm/arch-rockchip/grf_rk3036.h
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3036.h
@@ -209,10 +209,10 @@ enum {
GPIO1A3_I2S_LRCKTX,
GPIO1A2_SHIFT = 4,
- GPIO1A2_MASK = 6 << GPIO1A2_SHIFT,
+ GPIO1A2_MASK = 3 << GPIO1A2_SHIFT,
GPIO1A2_GPIO = 0,
GPIO1A2_I2S_LRCKRX,
- GPIO1A2_I2S_PWM1_0,
+ GPIO1A2_PWM1_0,
GPIO1A1_SHIFT = 2,
GPIO1A1_MASK = 1 << GPIO1A1_SHIFT,
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk322x.h b/arch/arm/include/asm/arch-rockchip/sdram_rk322x.h
new file mode 100644
index 0000000000..b40da409d4
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_rk322x.h
@@ -0,0 +1,581 @@
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef _ASM_ARCH_SDRAM_RK322X_H
+#define _ASM_ARCH_SDRAM_RK322X_H
+
+#include <common.h>
+
+enum {
+ DDR3 = 3,
+ LPDDR2 = 5,
+ LPDDR3 = 6,
+ UNUSED = 0xFF,
+};
+
+struct rk322x_sdram_channel {
+ /*
+ * bit width in address, eg:
+ * 8 banks using 3 bit to address,
+ * 2 cs using 1 bit to address.
+ */
+ u8 rank;
+ u8 col;
+ u8 bk;
+ u8 bw;
+ u8 dbw;
+ u8 row_3_4;
+ u8 cs0_row;
+ u8 cs1_row;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ /*
+ * For of-platdata, which would otherwise convert this into two
+ * byte-swapped integers. With a size of 9 bytes, this struct will
+ * appear in of-platdata as a byte array.
+ *
+ * If OF_PLATDATA enabled, need to add a dummy byte in dts.(i.e 0xff)
+ */
+ u8 dummy;
+#endif
+};
+
+struct rk322x_ddr_pctl {
+ u32 scfg;
+ u32 sctl;
+ u32 stat;
+ u32 intrstat;
+ u32 reserved0[(0x40 - 0x10) / 4];
+ u32 mcmd;
+ u32 powctl;
+ u32 powstat;
+ u32 cmdtstat;
+ u32 cmdtstaten;
+ u32 reserved1[(0x60 - 0x54) / 4];
+ u32 mrrcfg0;
+ u32 mrrstat0;
+ u32 mrrstat1;
+ u32 reserved2[(0x7c - 0x6c) / 4];
+
+ u32 mcfg1;
+ u32 mcfg;
+ u32 ppcfg;
+ u32 mstat;
+ u32 lpddr2zqcfg;
+ u32 reserved3;
+
+ u32 dtupdes;
+ u32 dtuna;
+ u32 dtune;
+ u32 dtuprd0;
+ u32 dtuprd1;
+ u32 dtuprd2;
+ u32 dtuprd3;
+ u32 dtuawdt;
+ u32 reserved4[(0xc0 - 0xb4) / 4];
+
+ u32 togcnt1u;
+ u32 tinit;
+ u32 trsth;
+ u32 togcnt100n;
+ u32 trefi;
+ u32 tmrd;
+ u32 trfc;
+ u32 trp;
+ u32 trtw;
+ u32 tal;
+ u32 tcl;
+ u32 tcwl;
+ u32 tras;
+ u32 trc;
+ u32 trcd;
+ u32 trrd;
+ u32 trtp;
+ u32 twr;
+ u32 twtr;
+ u32 texsr;
+ u32 txp;
+ u32 txpdll;
+ u32 tzqcs;
+ u32 tzqcsi;
+ u32 tdqs;
+ u32 tcksre;
+ u32 tcksrx;
+ u32 tcke;
+ u32 tmod;
+ u32 trstl;
+ u32 tzqcl;
+ u32 tmrr;
+ u32 tckesr;
+ u32 tdpd;
+ u32 tref_mem_ddr3;
+ u32 reserved5[(0x180 - 0x14c) / 4];
+ u32 ecccfg;
+ u32 ecctst;
+ u32 eccclr;
+ u32 ecclog;
+ u32 reserved6[(0x200 - 0x190) / 4];
+ u32 dtuwactl;
+ u32 dturactl;
+ u32 dtucfg;
+ u32 dtuectl;
+ u32 dtuwd0;
+ u32 dtuwd1;
+ u32 dtuwd2;
+ u32 dtuwd3;
+ u32 dtuwdm;
+ u32 dturd0;
+ u32 dturd1;
+ u32 dturd2;
+ u32 dturd3;
+ u32 dtulfsrwd;
+ u32 dtulfsrrd;
+ u32 dtueaf;
+ /* dfi control registers */
+ u32 dfitctrldelay;
+ u32 dfiodtcfg;
+ u32 dfiodtcfg1;
+ u32 dfiodtrankmap;
+ /* dfi write data registers */
+ u32 dfitphywrdata;
+ u32 dfitphywrlat;
+ u32 reserved7[(0x260 - 0x258) / 4];
+ u32 dfitrddataen;
+ u32 dfitphyrdlat;
+ u32 reserved8[(0x270 - 0x268) / 4];
+ u32 dfitphyupdtype0;
+ u32 dfitphyupdtype1;
+ u32 dfitphyupdtype2;
+ u32 dfitphyupdtype3;
+ u32 dfitctrlupdmin;
+ u32 dfitctrlupdmax;
+ u32 dfitctrlupddly;
+ u32 reserved9;
+ u32 dfiupdcfg;
+ u32 dfitrefmski;
+ u32 dfitctrlupdi;
+ u32 reserved10[(0x2ac - 0x29c) / 4];
+ u32 dfitrcfg0;
+ u32 dfitrstat0;
+ u32 dfitrwrlvlen;
+ u32 dfitrrdlvlen;
+ u32 dfitrrdlvlgateen;
+ u32 dfiststat0;
+ u32 dfistcfg0;
+ u32 dfistcfg1;
+ u32 reserved11;
+ u32 dfitdramclken;
+ u32 dfitdramclkdis;
+ u32 dfistcfg2;
+ u32 dfistparclr;
+ u32 dfistparlog;
+ u32 reserved12[(0x2f0 - 0x2e4) / 4];
+
+ u32 dfilpcfg0;
+ u32 reserved13[(0x300 - 0x2f4) / 4];
+ u32 dfitrwrlvlresp0;
+ u32 dfitrwrlvlresp1;
+ u32 dfitrwrlvlresp2;
+ u32 dfitrrdlvlresp0;
+ u32 dfitrrdlvlresp1;
+ u32 dfitrrdlvlresp2;
+ u32 dfitrwrlvldelay0;
+ u32 dfitrwrlvldelay1;
+ u32 dfitrwrlvldelay2;
+ u32 dfitrrdlvldelay0;
+ u32 dfitrrdlvldelay1;
+ u32 dfitrrdlvldelay2;
+ u32 dfitrrdlvlgatedelay0;
+ u32 dfitrrdlvlgatedelay1;
+ u32 dfitrrdlvlgatedelay2;
+ u32 dfitrcmd;
+ u32 reserved14[(0x3f8 - 0x340) / 4];
+ u32 ipvr;
+ u32 iptr;
+};
+check_member(rk322x_ddr_pctl, iptr, 0x03fc);
+
+struct rk322x_ddr_phy {
+ u32 ddrphy_reg[0x100];
+};
+
+struct rk322x_pctl_timing {
+ u32 togcnt1u;
+ u32 tinit;
+ u32 trsth;
+ u32 togcnt100n;
+ u32 trefi;
+ u32 tmrd;
+ u32 trfc;
+ u32 trp;
+ u32 trtw;
+ u32 tal;
+ u32 tcl;
+ u32 tcwl;
+ u32 tras;
+ u32 trc;
+ u32 trcd;
+ u32 trrd;
+ u32 trtp;
+ u32 twr;
+ u32 twtr;
+ u32 texsr;
+ u32 txp;
+ u32 txpdll;
+ u32 tzqcs;
+ u32 tzqcsi;
+ u32 tdqs;
+ u32 tcksre;
+ u32 tcksrx;
+ u32 tcke;
+ u32 tmod;
+ u32 trstl;
+ u32 tzqcl;
+ u32 tmrr;
+ u32 tckesr;
+ u32 tdpd;
+ u32 trefi_mem_ddr3;
+};
+
+struct rk322x_phy_timing {
+ u32 mr[4];
+ u32 mr11;
+ u32 bl;
+ u32 cl_al;
+};
+
+struct rk322x_msch_timings {
+ u32 ddrtiming;
+ u32 ddrmode;
+ u32 readlatency;
+ u32 activate;
+ u32 devtodev;
+};
+
+struct rk322x_service_sys {
+ u32 id_coreid;
+ u32 id_revisionid;
+ u32 ddrconf;
+ u32 ddrtiming;
+ u32 ddrmode;
+ u32 readlatency;
+ u32 activate;
+ u32 devtodev;
+};
+
+struct rk322x_base_params {
+ struct rk322x_msch_timings noc_timing;
+ u32 ddrconfig;
+ u32 ddr_freq;
+ u32 dramtype;
+ /*
+ * unused for rk322x
+ */
+ u32 stride;
+ u32 odt;
+};
+
+/* PCT_DFISTCFG0 */
+#define DFI_INIT_START BIT(0)
+#define DFI_DATA_BYTE_DISABLE_EN BIT(2)
+
+/* PCT_DFISTCFG1 */
+#define DFI_DRAM_CLK_SR_EN BIT(0)
+#define DFI_DRAM_CLK_DPD_EN BIT(1)
+
+/* PCT_DFISTCFG2 */
+#define DFI_PARITY_INTR_EN BIT(0)
+#define DFI_PARITY_EN BIT(1)
+
+/* PCT_DFILPCFG0 */
+#define TLP_RESP_TIME_SHIFT 16
+#define LP_SR_EN BIT(8)
+#define LP_PD_EN BIT(0)
+
+/* PCT_DFITCTRLDELAY */
+#define TCTRL_DELAY_TIME_SHIFT 0
+
+/* PCT_DFITPHYWRDATA */
+#define TPHY_WRDATA_TIME_SHIFT 0
+
+/* PCT_DFITPHYRDLAT */
+#define TPHY_RDLAT_TIME_SHIFT 0
+
+/* PCT_DFITDRAMCLKDIS */
+#define TDRAM_CLK_DIS_TIME_SHIFT 0
+
+/* PCT_DFITDRAMCLKEN */
+#define TDRAM_CLK_EN_TIME_SHIFT 0
+
+/* PCTL_DFIODTCFG */
+#define RANK0_ODT_WRITE_SEL BIT(3)
+#define RANK1_ODT_WRITE_SEL BIT(11)
+
+/* PCTL_DFIODTCFG1 */
+#define ODT_LEN_BL8_W_SHIFT 16
+
+/* PUBL_ACDLLCR */
+#define ACDLLCR_DLLDIS BIT(31)
+#define ACDLLCR_DLLSRST BIT(30)
+
+/* PUBL_DXDLLCR */
+#define DXDLLCR_DLLDIS BIT(31)
+#define DXDLLCR_DLLSRST BIT(30)
+
+/* PUBL_DLLGCR */
+#define DLLGCR_SBIAS BIT(30)
+
+/* PUBL_DXGCR */
+#define DQSRTT BIT(9)
+#define DQRTT BIT(10)
+
+/* PIR */
+#define PIR_INIT BIT(0)
+#define PIR_DLLSRST BIT(1)
+#define PIR_DLLLOCK BIT(2)
+#define PIR_ZCAL BIT(3)
+#define PIR_ITMSRST BIT(4)
+#define PIR_DRAMRST BIT(5)
+#define PIR_DRAMINIT BIT(6)
+#define PIR_QSTRN BIT(7)
+#define PIR_RVTRN BIT(8)
+#define PIR_ICPC BIT(16)
+#define PIR_DLLBYP BIT(17)
+#define PIR_CTLDINIT BIT(18)
+#define PIR_CLRSR BIT(28)
+#define PIR_LOCKBYP BIT(29)
+#define PIR_ZCALBYP BIT(30)
+#define PIR_INITBYP BIT(31)
+
+/* PGCR */
+#define PGCR_DFTLMT_SHIFT 3
+#define PGCR_DFTCMP_SHIFT 2
+#define PGCR_DQSCFG_SHIFT 1
+#define PGCR_ITMDMD_SHIFT 0
+
+/* PGSR */
+#define PGSR_IDONE BIT(0)
+#define PGSR_DLDONE BIT(1)
+#define PGSR_ZCDONE BIT(2)
+#define PGSR_DIDONE BIT(3)
+#define PGSR_DTDONE BIT(4)
+#define PGSR_DTERR BIT(5)
+#define PGSR_DTIERR BIT(6)
+#define PGSR_DFTERR BIT(7)
+#define PGSR_RVERR BIT(8)
+#define PGSR_RVEIRR BIT(9)
+
+/* PTR0 */
+#define PRT_ITMSRST_SHIFT 18
+#define PRT_DLLLOCK_SHIFT 6
+#define PRT_DLLSRST_SHIFT 0
+
+/* PTR1 */
+#define PRT_DINIT0_SHIFT 0
+#define PRT_DINIT1_SHIFT 19
+
+/* PTR2 */
+#define PRT_DINIT2_SHIFT 0
+#define PRT_DINIT3_SHIFT 17
+
+/* DCR */
+#define DDRMD_LPDDR 0
+#define DDRMD_DDR 1
+#define DDRMD_DDR2 2
+#define DDRMD_DDR3 3
+#define DDRMD_LPDDR2_LPDDR3 4
+#define DDRMD_MASK 7
+#define DDRMD_SHIFT 0
+#define PDQ_MASK 7
+#define PDQ_SHIFT 4
+
+/* DXCCR */
+#define DQSNRES_MASK 0xf
+#define DQSNRES_SHIFT 8
+#define DQSRES_MASK 0xf
+#define DQSRES_SHIFT 4
+
+/* DTPR */
+#define TDQSCKMAX_SHIFT 27
+#define TDQSCKMAX_MASK 7
+#define TDQSCK_SHIFT 24
+#define TDQSCK_MASK 7
+
+/* DSGCR */
+#define DQSGX_SHIFT 5
+#define DQSGX_MASK 7
+#define DQSGE_SHIFT 8
+#define DQSGE_MASK 7
+
+/* SCTL */
+#define INIT_STATE 0
+#define CFG_STATE 1
+#define GO_STATE 2
+#define SLEEP_STATE 3
+#define WAKEUP_STATE 4
+
+/* STAT */
+#define LP_TRIG_SHIFT 4
+#define LP_TRIG_MASK 7
+#define PCTL_STAT_MASK 7
+#define INIT_MEM 0
+#define CONFIG 1
+#define CONFIG_REQ 2
+#define ACCESS 3
+#define ACCESS_REQ 4
+#define LOW_POWER 5
+#define LOW_POWER_ENTRY_REQ 6
+#define LOW_POWER_EXIT_REQ 7
+
+/* ZQCR*/
+#define PD_OUTPUT_SHIFT 0
+#define PU_OUTPUT_SHIFT 5
+#define PD_ONDIE_SHIFT 10
+#define PU_ONDIE_SHIFT 15
+#define ZDEN_SHIFT 28
+
+/* DDLGCR */
+#define SBIAS_BYPASS BIT(23)
+
+/* MCFG */
+#define MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT 24
+#define PD_IDLE_SHIFT 8
+#define MDDR_EN (2 << 22)
+#define LPDDR2_EN (3 << 22)
+#define LPDDR3_EN (1 << 22)
+#define DDR2_EN (0 << 5)
+#define DDR3_EN (1 << 5)
+#define LPDDR2_S2 (0 << 6)
+#define LPDDR2_S4 (1 << 6)
+#define MDDR_LPDDR2_BL_2 (0 << 20)
+#define MDDR_LPDDR2_BL_4 (1 << 20)
+#define MDDR_LPDDR2_BL_8 (2 << 20)
+#define MDDR_LPDDR2_BL_16 (3 << 20)
+#define DDR2_DDR3_BL_4 0
+#define DDR2_DDR3_BL_8 1
+#define TFAW_SHIFT 18
+#define PD_EXIT_SLOW (0 << 17)
+#define PD_EXIT_FAST (1 << 17)
+#define PD_TYPE_SHIFT 16
+#define BURSTLENGTH_SHIFT 20
+
+/* POWCTL */
+#define POWER_UP_START BIT(0)
+
+/* POWSTAT */
+#define POWER_UP_DONE BIT(0)
+
+/* MCMD */
+enum {
+ DESELECT_CMD = 0,
+ PREA_CMD,
+ REF_CMD,
+ MRS_CMD,
+ ZQCS_CMD,
+ ZQCL_CMD,
+ RSTL_CMD,
+ MRR_CMD = 8,
+ DPDE_CMD,
+};
+
+#define BANK_ADDR_MASK 7
+#define BANK_ADDR_SHIFT 17
+#define CMD_ADDR_MASK 0x1fff
+#define CMD_ADDR_SHIFT 4
+
+#define LPDDR23_MA_SHIFT 4
+#define LPDDR23_MA_MASK 0xff
+#define LPDDR23_OP_SHIFT 12
+#define LPDDR23_OP_MASK 0xff
+
+#define START_CMD (1u << 31)
+
+/* DDRPHY REG */
+enum {
+ /* DDRPHY_REG0 */
+ SOFT_RESET_MASK = 3,
+ SOFT_DERESET_ANALOG = 1 << 2,
+ SOFT_DERESET_DIGITAL = 1 << 3,
+ SOFT_RESET_SHIFT = 2,
+
+ /* DDRPHY REG1 */
+ PHY_DDR3 = 0,
+ PHY_DDR2 = 1,
+ PHY_LPDDR3 = 2,
+ PHY_LPDDR2 = 3,
+
+ PHT_BL_8 = 1 << 2,
+ PHY_BL_4 = 0 << 2,
+
+ /* DDRPHY_REG2 */
+ MEMORY_SELECT_DDR3 = 0 << 0,
+ MEMORY_SELECT_LPDDR3 = 2 << 0,
+ MEMORY_SELECT_LPDDR2 = 3 << 0,
+ DQS_SQU_CAL_SEL_CS0_CS1 = 0 << 4,
+ DQS_SQU_CAL_SEL_CS1 = 1 << 4,
+ DQS_SQU_CAL_SEL_CS0 = 2 << 4,
+ DQS_SQU_CAL_NORMAL_MODE = 0 << 1,
+ DQS_SQU_CAL_BYPASS_MODE = 1 << 1,
+ DQS_SQU_CAL_START = 1 << 0,
+ DQS_SQU_NO_CAL = 0 << 0,
+};
+
+/* CK pull up/down driver strength control */
+enum {
+ PHY_RON_RTT_DISABLE = 0,
+ PHY_RON_RTT_451OHM = 1,
+ PHY_RON_RTT_225OHM,
+ PHY_RON_RTT_150OHM,
+ PHY_RON_RTT_112OHM,
+ PHY_RON_RTT_90OHM,
+ PHY_RON_RTT_75OHM,
+ PHY_RON_RTT_64OHM = 7,
+
+ PHY_RON_RTT_56OHM = 16,
+ PHY_RON_RTT_50OHM,
+ PHY_RON_RTT_45OHM,
+ PHY_RON_RTT_41OHM,
+ PHY_RON_RTT_37OHM,
+ PHY_RON_RTT_34OHM,
+ PHY_RON_RTT_33OHM,
+ PHY_RON_RTT_30OHM = 23,
+
+ PHY_RON_RTT_28OHM = 24,
+ PHY_RON_RTT_26OHM,
+ PHY_RON_RTT_25OHM,
+ PHY_RON_RTT_23OHM,
+ PHY_RON_RTT_22OHM,
+ PHY_RON_RTT_21OHM,
+ PHY_RON_RTT_20OHM,
+ PHY_RON_RTT_19OHM = 31,
+};
+
+/* DQS squelch DLL delay */
+enum {
+ DQS_DLL_NO_DELAY = 0,
+ DQS_DLL_22P5_DELAY,
+ DQS_DLL_45_DELAY,
+ DQS_DLL_67P5_DELAY,
+ DQS_DLL_90_DELAY,
+ DQS_DLL_112P5_DELAY,
+ DQS_DLL_135_DELAY,
+ DQS_DLL_157P5_DELAY,
+};
+
+/* GRF_SOC_CON0 */
+#define GRF_DDR_16BIT_EN (((0x1 << 0) << 16) | (0x1 << 0))
+#define GRF_DDR_32BIT_EN (((0x1 << 0) << 16) | (0x0 << 0))
+#define GRF_MSCH_NOC_16BIT_EN (((0x1 << 7) << 16) | (0x1 << 7))
+#define GRF_MSCH_NOC_32BIT_EN (((0x1 << 7) << 16) | (0x0 << 7))
+
+#define GRF_DDRPHY_BUFFEREN_CORE_EN (((0x1 << 8) << 16) | (0x0 << 8))
+#define GRF_DDRPHY_BUFFEREN_CORE_DIS (((0x1 << 8) << 16) | (0x1 << 8))
+
+#define GRF_DDR3_EN (((0x1 << 6) << 16) | (0x1 << 6))
+#define GRF_LPDDR2_3_EN (((0x1 << 6) << 16) | (0x0 << 6))
+
+#define PHY_DRV_ODT_SET(n) (((n) << 4) | (n))
+#define DDR3_DLL_RESET (1 << 8)
+
+#endif /* _ASM_ARCH_SDRAM_RK322X_H */
diff --git a/arch/arm/include/asm/arch-rockchip/sys_proto.h b/arch/arm/include/asm/arch-rockchip/sys_proto.h
index 35423e1ba0..e428d59336 100644
--- a/arch/arm/include/asm/arch-rockchip/sys_proto.h
+++ b/arch/arm/include/asm/arch-rockchip/sys_proto.h
@@ -7,4 +7,27 @@
#ifndef _ASM_ARCH_SYS_PROTO_H
#define _ASM_ARCH_SYS_PROTO_H
+#ifdef CONFIG_ROCKCHIP_RK3288
+#include <asm/armv7.h>
+
+static void configure_l2ctlr(void)
+{
+ uint32_t l2ctlr;
+
+ l2ctlr = read_l2ctlr();
+ l2ctlr &= 0xfffc0000; /* clear bit0~bit17 */
+
+ /*
+ * Data RAM write latency: 2 cycles
+ * Data RAM read latency: 2 cycles
+ * Data RAM setup latency: 1 cycle
+ * Tag RAM write latency: 1 cycle
+ * Tag RAM read latency: 1 cycle
+ * Tag RAM setup latency: 1 cycle
+ */
+ l2ctlr |= (1 << 3 | 1 << 0);
+ write_l2ctlr(l2ctlr);
+}
+#endif /* CONFIG_ROCKCHIP_RK3288 */
+
#endif /* _ASM_ARCH_SYS_PROTO_H */
diff --git a/arch/arm/include/asm/armv7.h b/arch/arm/include/asm/armv7.h
index a20702e612..efc515eb33 100644
--- a/arch/arm/include/asm/armv7.h
+++ b/arch/arm/include/asm/armv7.h
@@ -61,6 +61,27 @@
#include <asm/io.h>
#include <asm/barriers.h>
+/* read L2 control register (L2CTLR) */
+static inline uint32_t read_l2ctlr(void)
+{
+ uint32_t val = 0;
+
+ asm volatile ("mrc p15, 1, %0, c9, c0, 2" : "=r" (val));
+
+ return val;
+}
+
+/* write L2 control register (L2CTLR) */
+static inline void write_l2ctlr(uint32_t val)
+{
+ /*
+ * Note: L2CTLR can only be written when the L2 memory system
+ * is idle, ie before the MMU is enabled.
+ */
+ asm volatile("mcr p15, 1, %0, c9, c0, 2" : : "r" (val) : "memory");
+ isb();
+}
+
/*
* Workaround for ARM errata # 798870
* Set L2ACTLR[7] to reissue any memory transaction in the L2 that has been
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 79e9704a2c..daafc8de6a 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -12,6 +12,7 @@ obj-spl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o save_boot_param.o
obj-tpl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o save_boot_param.o
obj-tpl-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board-tpl.o
+obj-tpl-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-tpl.o
obj-tpl-$(CONFIG_ROCKCHIP_RK3368) += rk3368-board-tpl.o
obj-spl-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o
diff --git a/arch/arm/mach-rockchip/rk3188/Makefile b/arch/arm/mach-rockchip/rk3188/Makefile
index 2dc9511de7..7fa010405b 100644
--- a/arch/arm/mach-rockchip/rk3188/Makefile
+++ b/arch/arm/mach-rockchip/rk3188/Makefile
@@ -6,6 +6,5 @@
ifndef CONFIG_TPL_BUILD
obj-y += clk_rk3188.o
-obj-y += sdram_rk3188.o
obj-y += syscon_rk3188.o
endif
diff --git a/arch/arm/mach-rockchip/rk322x-board.c b/arch/arm/mach-rockchip/rk322x-board.c
index dcd8cf805f..d44311457a 100644
--- a/arch/arm/mach-rockchip/rk322x-board.c
+++ b/arch/arm/mach-rockchip/rk322x-board.c
@@ -21,12 +21,12 @@ DECLARE_GLOBAL_DATA_PTR;
static void setup_boot_mode(void)
{
struct rk322x_grf *const grf = (void *)GRF_BASE;
- int boot_mode = readl(&grf->os_reg[4]);
+ int boot_mode = readl(&grf->os_reg[0]);
debug("boot mode %x.\n", boot_mode);
/* Clear boot mode */
- writel(BOOT_NORMAL, &grf->os_reg[4]);
+ writel(BOOT_NORMAL, &grf->os_reg[0]);
switch (boot_mode) {
case BOOT_FASTBOOT:
diff --git a/arch/arm/mach-rockchip/rk3288-board-spl.c b/arch/arm/mach-rockchip/rk3288-board-spl.c
index 6b7bf85d8d..7b7fd5a6f1 100644
--- a/arch/arm/mach-rockchip/rk3288-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3288-board-spl.c
@@ -19,7 +19,10 @@
#include <asm/arch/clock.h>
#include <asm/arch/hardware.h>
#include <asm/arch/periph.h>
+#include <asm/arch/pmu_rk3288.h>
#include <asm/arch/sdram.h>
+#include <asm/arch/sdram_common.h>
+#include <asm/arch/sys_proto.h>
#include <asm/arch/timer.h>
#include <dm/pinctrl.h>
#include <dm/root.h>
@@ -80,46 +83,6 @@ u32 spl_boot_mode(const u32 boot_device)
return MMCSD_MODE_RAW;
}
-/* read L2 control register (L2CTLR) */
-static inline uint32_t read_l2ctlr(void)
-{
- uint32_t val = 0;
-
- asm volatile ("mrc p15, 1, %0, c9, c0, 2" : "=r" (val));
-
- return val;
-}
-
-/* write L2 control register (L2CTLR) */
-static inline void write_l2ctlr(uint32_t val)
-{
- /*
- * Note: L2CTLR can only be written when the L2 memory system
- * is idle, ie before the MMU is enabled.
- */
- asm volatile("mcr p15, 1, %0, c9, c0, 2" : : "r" (val) : "memory");
- isb();
-}
-
-static void configure_l2ctlr(void)
-{
- uint32_t l2ctlr;
-
- l2ctlr = read_l2ctlr();
- l2ctlr &= 0xfffc0000; /* clear bit0~bit17 */
-
- /*
- * Data RAM write latency: 2 cycles
- * Data RAM read latency: 2 cycles
- * Data RAM setup latency: 1 cycle
- * Tag RAM write latency: 1 cycle
- * Tag RAM read latency: 1 cycle
- * Tag RAM setup latency: 1 cycle
- */
- l2ctlr |= (1 << 3 | 1 << 0);
- write_l2ctlr(l2ctlr);
-}
-
#ifdef CONFIG_SPL_MMC_SUPPORT
static int configure_emmc(struct udevice *pinctrl)
{
@@ -243,12 +206,15 @@ void board_init_f(ulong dummy)
}
#endif
+#if !defined(CONFIG_SUPPORT_TPL)
debug("\nspl:init dram\n");
ret = uclass_get_device(UCLASS_RAM, 0, &dev);
if (ret) {
debug("DRAM init failed: %d\n", ret);
return;
}
+#endif
+
#if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT)
back_to_bootrom();
#endif
@@ -326,3 +292,18 @@ err:
/* No way to report error here */
hang();
}
+
+#ifdef CONFIG_SPL_OS_BOOT
+
+#define PMU_BASE 0xff730000
+int dram_init_banksize(void)
+{
+ struct rk3288_pmu *const pmu = (void *)PMU_BASE;
+ size_t size = rockchip_sdram_size((phys_addr_t)&pmu->sys_reg[2]);
+
+ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+ gd->bd->bi_dram[0].size = size;
+
+ return 0;
+}
+#endif
diff --git a/arch/arm/mach-rockchip/rk3288-board-tpl.c b/arch/arm/mach-rockchip/rk3288-board-tpl.c
new file mode 100644
index 0000000000..3d08b5b6d8
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3288-board-tpl.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2017 Amarula Solutions
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <ram.h>
+#include <spl.h>
+#include <version.h>
+#include <asm/io.h>
+#include <asm/arch/bootrom.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3288.h>
+#include <asm/arch/periph.h>
+#include <asm/arch/pmu_rk3288.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/timer.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define GRF_BASE 0xff770000
+void board_init_f(ulong dummy)
+{
+ struct udevice *dev;
+ int ret;
+
+ /* Example code showing how to enable the debug UART on RK3288 */
+ /* Enable early UART on the RK3288 */
+ struct rk3288_grf * const grf = (void *)GRF_BASE;
+
+ rk_clrsetreg(&grf->gpio7ch_iomux, GPIO7C7_MASK << GPIO7C7_SHIFT |
+ GPIO7C6_MASK << GPIO7C6_SHIFT,
+ GPIO7C7_UART2DBG_SOUT << GPIO7C7_SHIFT |
+ GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT);
+ /*
+ * Debug UART can be used from here if required:
+ *
+ * debug_uart_init();
+ * printch('a');
+ * printhex8(0x1234);
+ * printascii("string");
+ */
+ debug_uart_init();
+
+ ret = spl_early_init();
+ if (ret) {
+ debug("spl_early_init() failed: %d\n", ret);
+ hang();
+ }
+
+ rockchip_timer_init();
+ configure_l2ctlr();
+
+ ret = rockchip_get_clk(&dev);
+ if (ret) {
+ debug("CLK init failed: %d\n", ret);
+ return;
+ }
+
+ ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+ if (ret) {
+ debug("DRAM init failed: %d\n", ret);
+ return;
+ }
+}
+
+void board_return_to_bootrom(void)
+{
+ back_to_bootrom();
+}
+
+u32 spl_boot_device(void)
+{
+ return BOOT_DEVICE_BOOTROM;
+}
+
+void spl_board_init(void)
+{
+ puts("\nU-Boot TPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
+ U_BOOT_TIME ")\n");
+}
diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig
index 4ad2940069..6beb26fd7a 100644
--- a/arch/arm/mach-rockchip/rk3288/Kconfig
+++ b/arch/arm/mach-rockchip/rk3288/Kconfig
@@ -87,6 +87,22 @@ config TARGET_POPMETAL_RK3288
config TARGET_VYASA_RK3288
bool "Vyasa-RK3288"
select BOARD_LATE_INIT
+ select TPL
+ select SUPPORT_TPL
+ select TPL_DM
+ select TPL_REGMAP
+ select TPL_SYSCON
+ select TPL_CLK
+ select TPL_RAM
+ select TPL_OF_PLATDATA
+ select TPL_OF_CONTROL
+ select TPL_BOOTROM_SUPPORT
+ select TPL_NEEDS_SEPARATE_TEXT_BASE if SPL
+ select ROCKCHIP_BROM_HELPER
+ select TPL_DRIVERS_MISC_SUPPORT
+ select TPL_LIBCOMMON_SUPPORT
+ select TPL_LIBGENERIC_SUPPORT
+ select TPL_SERIAL_SUPPORT
help
Vyasa 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/Makefile b/arch/arm/mach-rockchip/rk3288/Makefile
index b5b28efbe8..a0033a0d84 100644
--- a/arch/arm/mach-rockchip/rk3288/Makefile
+++ b/arch/arm/mach-rockchip/rk3288/Makefile
@@ -6,5 +6,4 @@
obj-y += clk_rk3288.o
obj-y += rk3288.o
-obj-y += sdram_rk3288.o
obj-y += syscon_rk3288.o
diff --git a/arch/arm/mach-rockchip/rk3328/Makefile b/arch/arm/mach-rockchip/rk3328/Makefile
index 72873e29e6..bbab036a12 100644
--- a/arch/arm/mach-rockchip/rk3328/Makefile
+++ b/arch/arm/mach-rockchip/rk3328/Makefile
@@ -6,5 +6,4 @@
obj-y += clk_rk3328.o
obj-y += rk3328.o
-obj-y += sdram_rk3328.o
obj-y += syscon_rk3328.o
diff --git a/arch/arm/mach-rockchip/rk3399-board-spl.c b/arch/arm/mach-rockchip/rk3399-board-spl.c
index 3406156447..9c20f56dc9 100644
--- a/arch/arm/mach-rockchip/rk3399-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3399-board-spl.c
@@ -1,10 +1,12 @@
/*
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <asm/arch/bootrom.h>
#include <asm/arch/clock.h>
#include <asm/arch/grf_rk3399.h>
#include <asm/arch/hardware.h>
@@ -19,9 +21,43 @@
DECLARE_GLOBAL_DATA_PTR;
+void board_return_to_bootrom(void)
+{
+ back_to_bootrom();
+}
+
+static const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+ [BROM_BOOTSOURCE_EMMC] = "/sdhci@fe330000",
+ [BROM_BOOTSOURCE_SPINOR] = "/spi@ff1d0000",
+ [BROM_BOOTSOURCE_SD] = "/dwmmc@fe320000",
+};
+
+const char *board_spl_was_booted_from(void)
+{
+ u32 bootdevice_brom_id = readl(RK3399_BROM_BOOTSOURCE_ID_ADDR);
+ const char *bootdevice_ofpath = NULL;
+
+ if (bootdevice_brom_id < ARRAY_SIZE(boot_devices))
+ bootdevice_ofpath = boot_devices[bootdevice_brom_id];
+
+ if (bootdevice_ofpath)
+ debug("%s: brom_bootdevice_id %x maps to '%s'\n",
+ __func__, bootdevice_brom_id, bootdevice_ofpath);
+ else
+ debug("%s: failed to resolve brom_bootdevice_id %x\n",
+ __func__, bootdevice_brom_id);
+
+ return bootdevice_ofpath;
+}
+
u32 spl_boot_device(void)
{
- return BOOT_DEVICE_MMC1;
+ u32 boot_device = BOOT_DEVICE_MMC1;
+
+ if (CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM))
+ return BOOT_DEVICE_BOOTROM;
+
+ return boot_device;
}
u32 spl_boot_mode(const u32 boot_device)
@@ -137,37 +173,6 @@ void board_init_f(ulong dummy)
}
}
-void spl_board_init(void)
-{
- struct udevice *pinctrl;
- int ret;
-
- ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
- if (ret) {
- debug("%s: Cannot find pinctrl device\n", __func__);
- goto err;
- }
-
- /* Enable debug UART */
- ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_UART_DBG);
- if (ret) {
- debug("%s: Failed to set up console UART\n", __func__);
- goto err;
- }
-
- preloader_console_init();
-#if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
- back_to_bootrom();
-#endif
-
- return;
-err:
- printf("spl_board_init: Error %d\n", ret);
-
- /* No way to report error here */
- hang();
-}
-
#ifdef CONFIG_SPL_LOAD_FIT
int board_fit_config_name_match(const char *name)
{
diff --git a/arch/arm/mach-rockchip/rk3399/Makefile b/arch/arm/mach-rockchip/rk3399/Makefile
index 793ce31c12..98ebeac340 100644
--- a/arch/arm/mach-rockchip/rk3399/Makefile
+++ b/arch/arm/mach-rockchip/rk3399/Makefile
@@ -6,5 +6,4 @@
obj-y += clk_rk3399.o
obj-y += rk3399.o
-obj-y += sdram_rk3399.o
obj-y += syscon_rk3399.o
diff --git a/arch/arm/mach-rockchip/spl-boot-order.c b/arch/arm/mach-rockchip/spl-boot-order.c
index 4f78c72720..843998dfdc 100644
--- a/arch/arm/mach-rockchip/spl-boot-order.c
+++ b/arch/arm/mach-rockchip/spl-boot-order.c
@@ -10,6 +10,25 @@
#include <spl.h>
#if CONFIG_IS_ENABLED(OF_CONTROL)
+/**
+ * spl_node_to_boot_device() - maps from a DT-node to a SPL boot device
+ * @node: of_offset of the node
+ *
+ * The SPL framework uses BOOT_DEVICE_... constants to identify its boot
+ * sources. These may take on a device-specific meaning, depending on
+ * what nodes are enabled in a DTS (e.g. BOOT_DEVICE_MMC1 may refer to
+ * different controllers/block-devices, depending on which SD/MMC controllers
+ * are enabled in any given DTS). This function maps from a DT-node back
+ * onto a BOOT_DEVICE_... constant, considering the currently active devices.
+ *
+ * Returns
+ * -ENOENT, if no device matching the node could be found
+ * -ENOSYS, if the device matching the node can not be mapped onto a
+ * SPL boot device (e.g. the third MMC device)
+ * -1, for unspecified failures
+ * a positive integer (from the BOOT_DEVICE_... family) on succes.
+ */
+
static int spl_node_to_boot_device(int node)
{
struct udevice *parent;
@@ -57,6 +76,24 @@ static int spl_node_to_boot_device(int node)
return -1;
}
+/**
+ * board_spl_was_booted_from() - retrieves the of-path the SPL was loaded from
+ *
+ * To support a 'same-as-spl' specification in the search-order for the next
+ * stage, we need a SoC- or board-specific way to handshake with what 'came
+ * before us' (either a BROM or TPL stage) and map the info retrieved onto
+ * a OF path.
+ *
+ * Returns
+ * NULL, on failure or if the device could not be identified
+ * a of_path (a string), on success
+ */
+__weak const char *board_spl_was_booted_from(void)
+{
+ debug("%s: no support for 'same-as-spl' for this board\n", __func__);
+ return NULL;
+}
+
void board_boot_order(u32 *spl_boot_list)
{
const void *blob = gd->fdt_blob;
@@ -78,8 +115,17 @@ void board_boot_order(u32 *spl_boot_list)
(conf = fdt_stringlist_get(blob, chosen_node,
"u-boot,spl-boot-order", elem, NULL));
elem++) {
+ const char *alias;
+
+ /* Handle the case of 'same device the SPL was loaded from' */
+ if (strncmp(conf, "same-as-spl", 11) == 0) {
+ conf = board_spl_was_booted_from();
+ if (!conf)
+ continue;
+ }
+
/* First check if the list element is an alias */
- const char *alias = fdt_get_alias(blob, conf);
+ alias = fdt_get_alias(blob, conf);
if (alias)
conf = alias;
diff --git a/board/amarula/vyasa-rk3288/vyasa-rk3288.c b/board/amarula/vyasa-rk3288/vyasa-rk3288.c
index ceee42c16e..7985671fbd 100644
--- a/board/amarula/vyasa-rk3288/vyasa-rk3288.c
+++ b/board/amarula/vyasa-rk3288/vyasa-rk3288.c
@@ -5,3 +5,16 @@
*/
#include <common.h>
+
+#ifndef CONFIG_TPL_BUILD
+#include <spl.h>
+
+int spl_start_uboot(void)
+{
+ /* break into full u-boot on 'c' */
+ if (serial_tstc() && serial_getc() == 'c')
+ return 1;
+
+ return 0;
+}
+#endif
diff --git a/board/rockchip/evb_rk3399/evb-rk3399.c b/board/rockchip/evb_rk3399/evb-rk3399.c
index d50c59db8d..502dec325f 100644
--- a/board/rockchip/evb_rk3399/evb-rk3399.c
+++ b/board/rockchip/evb_rk3399/evb-rk3399.c
@@ -3,13 +3,14 @@
*
* SPDX-License-Identifier: GPL-2.0+
*/
+
#include <common.h>
#include <dm.h>
-#include <ram.h>
#include <dm/pinctrl.h>
#include <dm/uclass-internal.h>
#include <asm/arch/periph.h>
#include <power/regulator.h>
+#include <spl.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -67,3 +68,30 @@ int board_init(void)
out:
return 0;
}
+
+void spl_board_init(void)
+{
+ struct udevice *pinctrl;
+ int ret;
+
+ ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
+ if (ret) {
+ debug("%s: Cannot find pinctrl device\n", __func__);
+ goto err;
+ }
+
+ /* Enable debug UART */
+ ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_UART_DBG);
+ if (ret) {
+ debug("%s: Failed to set up console UART\n", __func__);
+ goto err;
+ }
+
+ preloader_console_init();
+ return;
+err:
+ printf("%s: Error %d\n", __func__, ret);
+
+ /* No way to report error here */
+ hang();
+}
diff --git a/board/theobroma-systems/lion_rk3368/fit_spl_atf.its b/board/theobroma-systems/lion_rk3368/fit_spl_atf.its
index 405750f351..60daddcc44 100644
--- a/board/theobroma-systems/lion_rk3368/fit_spl_atf.its
+++ b/board/theobroma-systems/lion_rk3368/fit_spl_atf.its
@@ -27,8 +27,8 @@
type = "firmware";
arch = "arm64";
compression = "none";
- load = <0x00010000>;
- entry = <0x00010000>;
+ load = <0x00100000>;
+ entry = <0x00100000>;
};
fdt {
diff --git a/board/theobroma-systems/puma_rk3399/puma-rk3399.c b/board/theobroma-systems/puma_rk3399/puma-rk3399.c
index 45d56cd99e..2b4988e2d2 100644
--- a/board/theobroma-systems/puma_rk3399/puma-rk3399.c
+++ b/board/theobroma-systems/puma_rk3399/puma-rk3399.c
@@ -3,60 +3,48 @@
*
* SPDX-License-Identifier: GPL-2.0+
*/
+
#include <common.h>
#include <dm.h>
#include <misc.h>
-#include <ram.h>
#include <dm/pinctrl.h>
#include <dm/uclass-internal.h>
#include <asm/setup.h>
#include <asm/arch/periph.h>
#include <power/regulator.h>
+#include <spl.h>
#include <u-boot/sha256.h>
DECLARE_GLOBAL_DATA_PTR;
int board_init(void)
{
- struct udevice *pinctrl, *regulator;
int ret;
/*
- * The PWM does not have decicated interrupt number in dts and can
- * not get periph_id by pinctrl framework, so let's init them here.
- * The PWM2 and PWM3 are for pwm regulators.
+ * We need to call into regulators_enable_boot_on() again, as the call
+ * during SPL may have not included all regulators.
*/
- ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
- if (ret) {
- debug("%s: Cannot find pinctrl device\n", __func__);
- goto out;
- }
-
- ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_PWM2);
- if (ret) {
- debug("%s PWM2 pinctrl init fail!\n", __func__);
- goto out;
- }
-
- /* rk3399 need to init vdd_center to get the correct output voltage */
- ret = regulator_get_by_platname("vdd_center", &regulator);
+ ret = regulators_enable_boot_on(false);
if (ret)
- debug("%s: Cannot get vdd_center regulator\n", __func__);
+ debug("%s: Cannot enable boot on regulator\n", __func__);
- ret = regulator_get_by_platname("vcc5v0_host", &regulator);
- if (ret) {
- debug("%s vcc5v0_host init fail! ret %d\n", __func__, ret);
- goto out;
- }
+ return 0;
+}
- ret = regulator_set_enable(regulator, true);
- if (ret) {
- debug("%s vcc5v0-host-en set fail!\n", __func__);
- goto out;
- }
+void spl_board_init(void)
+{
+ int ret;
-out:
- return 0;
+ /*
+ * Turning the eMMC and SPI back on (if disabled via the Qseven
+ * BIOS_ENABLE) signal is done through a always-on regulator).
+ */
+ ret = regulators_enable_boot_on(false);
+ if (ret)
+ debug("%s: Cannot enable boot on regulator\n", __func__);
+
+ preloader_console_init();
}
static void setup_macaddr(void)
@@ -91,8 +79,6 @@ static void setup_macaddr(void)
mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
eth_env_set_enetaddr("ethaddr", mac_addr);
#endif
-
- return;
}
static void setup_serial(void)
@@ -147,8 +133,6 @@ static void setup_serial(void)
env_set("cpuid#", cpuid_str);
env_set("serial#", serialno_str);
#endif
-
- return;
}
int misc_init_r(void)
diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig
index 7bec001786..6d0f3af7a3 100644
--- a/configs/evb-rk3328_defconfig
+++ b/configs/evb-rk3328_defconfig
@@ -22,12 +22,18 @@ CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_CLK=y
CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_ROCKCHIP_RK3328=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_RK8XX=y
+CONFIG_DM_REGULATOR=y
CONFIG_REGULATOR_PWM=y
CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_REGULATOR_RK8XX=y
+CONFIG_PWM_ROCKCHIP=y
CONFIG_RAM=y
CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART_BASE=0xFF130000
diff --git a/configs/lion-rk3368_defconfig b/configs/lion-rk3368_defconfig
index c7ee7b3f97..985fb1ce98 100644
--- a/configs/lion-rk3368_defconfig
+++ b/configs/lion-rk3368_defconfig
@@ -23,7 +23,6 @@ CONFIG_BOOTSTAGE=y
CONFIG_SPL_BOOTSTAGE=y
CONFIG_BOOTSTAGE_REPORT=y
CONFIG_BOOTSTAGE_FDT=y
-CONFIG_ENV_IS_IN_MMC=y
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_ARCH_EARLY_INIT_R=y
CONFIG_SPL=y
diff --git a/configs/puma-rk3399_defconfig b/configs/puma-rk3399_defconfig
index 2ab2516c01..62a8d7c859 100644
--- a/configs/puma-rk3399_defconfig
+++ b/configs/puma-rk3399_defconfig
@@ -1,5 +1,6 @@
CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
+CONFIG_SPL_GPIO_SUPPORT=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_SYS_MALLOC_F_LEN=0x4000
@@ -20,6 +21,8 @@ CONFIG_SPL_BOARD_INIT=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x4000
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x200
+CONFIG_SPL_I2C_SUPPORT=y
+CONFIG_SPL_POWER_SUPPORT=y
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_IMLS is not set
CONFIG_CMD_GPT=y
@@ -63,8 +66,10 @@ CONFIG_SPL_PINCTRL=y
CONFIG_PINCTRL_ROCKCHIP_RK3399=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_RK8XX=y
-CONFIG_REGULATOR_PWM=y
+CONFIG_SPL_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_SPL_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
CONFIG_RAM=y
diff --git a/configs/vyasa-rk3288_defconfig b/configs/vyasa-rk3288_defconfig
index 7db7b0b6f9..7bd6068e0c 100644
--- a/configs/vyasa-rk3288_defconfig
+++ b/configs/vyasa-rk3288_defconfig
@@ -1,8 +1,11 @@
CONFIG_ARM=y
+# CONFIG_SPL_USE_ARCH_MEMCPY is not set
+# CONFIG_SPL_USE_ARCH_MEMSET is not set
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_ROCKCHIP_RK3288=y
CONFIG_TARGET_VYASA_RK3288=y
+CONFIG_TPL_TEXT_BASE=0xff704004
CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEFAULT_DEVICE_TREE="rk3288-vyasa"
CONFIG_DEBUG_UART=y
diff --git a/doc/README.rockchip b/doc/README.rockchip
index 12fec38139..4b7be0b715 100644
--- a/doc/README.rockchip
+++ b/doc/README.rockchip
@@ -150,6 +150,24 @@ Note: rk3036 SDMMC and debug uart use the same iomux, so if you boot from SD, th
debug uart must be disabled
+Booting from an SD card on RK3288 with TPL
+==========================================
+
+Since the size of SPL can't be exceeded 0x8000 bytes in RK3288, it is not possible add
+new SPL features like Falcon mode or etc.
+
+So introduce TPL so-that adding new features to SPL is possible because now TPL should
+run minimal with code like DDR, clock etc and rest of new features in SPL.
+
+As of now TPL is added on Vyasa-RK3288 board.
+
+To write an image that boots from an SD card (assumed to be /dev/mmcblk0):
+
+ ./tools/mkimage -n rk3288 -T rksd -d ./tpl/u-boot-tpl.bin out &&
+ cat ./spl/u-boot-spl-dtb.bin >> out &&
+ sudo dd if=out of=/dev/mmcblk0 seek=64 &&
+ sudo dd if=u-boot-dtb.img of=/dev/mmcblk0 seek=256
+
Booting from an SD card on RK3188
=================================
diff --git a/doc/device-tree-bindings/chosen.txt b/doc/device-tree-bindings/chosen.txt
index 5625d210e8..c96b8f7109 100644
--- a/doc/device-tree-bindings/chosen.txt
+++ b/doc/device-tree-bindings/chosen.txt
@@ -56,10 +56,20 @@ Each list element of the property should specify a device to be probed
in the order they are listed: references (i.e. implicit paths), a full
path or an alias is expected for each entry.
+A special specifier "same-as-spl" can be used at any position in the
+boot-order to direct U-Boot to insert the device the SPL was booted
+from there. Whether this is indeed inserted or silently ignored (if
+it is not supported on any given SoC/board or if the boot-device is
+not available to continue booting from) is implementation-defined.
+Note that if "same-as-spl" expands to an actual node for a given
+board, the corresponding node may appear multiple times in the
+boot-order (as there currently exists no mechanism to suppress
+duplicates from the list).
+
Example
-------
/ {
chosen {
- u-boot,spl-boot-order = &sdmmc, "/sdhci@fe330000";
+ u-boot,spl-boot-order = "same-as-spl", &sdmmc, "/sdhci@fe330000";
};
};
diff --git a/drivers/adc/Kconfig b/drivers/adc/Kconfig
index e5335f7234..8094420548 100644
--- a/drivers/adc/Kconfig
+++ b/drivers/adc/Kconfig
@@ -28,3 +28,12 @@ config ADC_SANDBOX
- 4 analog input channels
- 16-bit resolution
- single and multi-channel conversion mode
+
+config SARADC_ROCKCHIP
+ bool "Enable Rockchip SARADC driver"
+ help
+ This enables driver for Rockchip SARADC.
+ It provides:
+ - 2~6 analog input channels
+ - 1O or 12 bits resolution
+ - Up to 1MSPS of sample rate
diff --git a/drivers/adc/Makefile b/drivers/adc/Makefile
index cebf26de07..4b5aa693ec 100644
--- a/drivers/adc/Makefile
+++ b/drivers/adc/Makefile
@@ -8,3 +8,4 @@
obj-$(CONFIG_ADC) += adc-uclass.o
obj-$(CONFIG_ADC_EXYNOS) += exynos-adc.o
obj-$(CONFIG_ADC_SANDBOX) += sandbox.o
+obj-$(CONFIG_SARADC_ROCKCHIP) += rockchip-saradc.o
diff --git a/drivers/adc/rockchip-saradc.c b/drivers/adc/rockchip-saradc.c
new file mode 100644
index 0000000000..0e6271d097
--- /dev/null
+++ b/drivers/adc/rockchip-saradc.c
@@ -0,0 +1,183 @@
+/*
+ * (C) Copyright 2017, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Rockchip SARADC driver for U-Boot
+ */
+
+#include <common.h>
+#include <adc.h>
+#include <clk.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+
+#define SARADC_CTRL_CHN_MASK GENMASK(2, 0)
+#define SARADC_CTRL_POWER_CTRL BIT(3)
+#define SARADC_CTRL_IRQ_ENABLE BIT(5)
+#define SARADC_CTRL_IRQ_STATUS BIT(6)
+
+#define SARADC_TIMEOUT (100 * 1000)
+
+struct rockchip_saradc_regs {
+ unsigned int data;
+ unsigned int stas;
+ unsigned int ctrl;
+ unsigned int dly_pu_soc;
+};
+
+struct rockchip_saradc_data {
+ int num_bits;
+ int num_channels;
+ unsigned long clk_rate;
+};
+
+struct rockchip_saradc_priv {
+ struct rockchip_saradc_regs *regs;
+ int active_channel;
+ const struct rockchip_saradc_data *data;
+};
+
+int rockchip_saradc_channel_data(struct udevice *dev, int channel,
+ unsigned int *data)
+{
+ struct rockchip_saradc_priv *priv = dev_get_priv(dev);
+ struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+
+ if (channel != priv->active_channel) {
+ error("Requested channel is not active!");
+ return -EINVAL;
+ }
+
+ if ((readl(&priv->regs->ctrl) & SARADC_CTRL_IRQ_STATUS) !=
+ SARADC_CTRL_IRQ_STATUS)
+ return -EBUSY;
+
+ /* Read value */
+ *data = readl(&priv->regs->data);
+ *data &= uc_pdata->data_mask;
+
+ /* Power down adc */
+ writel(0, &priv->regs->ctrl);
+
+ return 0;
+}
+
+int rockchip_saradc_start_channel(struct udevice *dev, int channel)
+{
+ struct rockchip_saradc_priv *priv = dev_get_priv(dev);
+
+ if (channel < 0 || channel >= priv->data->num_channels) {
+ error("Requested channel is invalid!");
+ return -EINVAL;
+ }
+
+ /* 8 clock periods as delay between power up and start cmd */
+ writel(8, &priv->regs->dly_pu_soc);
+
+ /* Select the channel to be used and trigger conversion */
+ writel(SARADC_CTRL_POWER_CTRL | (channel & SARADC_CTRL_CHN_MASK) |
+ SARADC_CTRL_IRQ_ENABLE, &priv->regs->ctrl);
+
+ priv->active_channel = channel;
+
+ return 0;
+}
+
+int rockchip_saradc_stop(struct udevice *dev)
+{
+ struct rockchip_saradc_priv *priv = dev_get_priv(dev);
+
+ /* Power down adc */
+ writel(0, &priv->regs->ctrl);
+
+ priv->active_channel = -1;
+
+ return 0;
+}
+
+int rockchip_saradc_probe(struct udevice *dev)
+{
+ struct rockchip_saradc_priv *priv = dev_get_priv(dev);
+ struct clk clk;
+ int ret;
+
+ ret = clk_get_by_index(dev, 0, &clk);
+ if (ret)
+ return ret;
+
+ ret = clk_set_rate(&clk, priv->data->clk_rate);
+ if (IS_ERR_VALUE(ret))
+ return ret;
+
+ priv->active_channel = -1;
+
+ return 0;
+}
+
+int rockchip_saradc_ofdata_to_platdata(struct udevice *dev)
+{
+ struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+ struct rockchip_saradc_priv *priv = dev_get_priv(dev);
+ struct rockchip_saradc_data *data;
+
+ data = (struct rockchip_saradc_data *)dev_get_driver_data(dev);
+ priv->regs = (struct rockchip_saradc_regs *)dev_read_addr(dev);
+ if (priv->regs == (struct rockchip_saradc_regs *)FDT_ADDR_T_NONE) {
+ error("Dev: %s - can't get address!", dev->name);
+ return -ENODATA;
+ }
+
+ priv->data = data;
+ uc_pdata->data_mask = (1 << priv->data->num_bits) - 1;;
+ uc_pdata->data_format = ADC_DATA_FORMAT_BIN;
+ uc_pdata->data_timeout_us = SARADC_TIMEOUT / 5;
+ uc_pdata->channel_mask = (1 << priv->data->num_channels) - 1;
+
+ return 0;
+}
+
+static const struct adc_ops rockchip_saradc_ops = {
+ .start_channel = rockchip_saradc_start_channel,
+ .channel_data = rockchip_saradc_channel_data,
+ .stop = rockchip_saradc_stop,
+};
+
+static const struct rockchip_saradc_data saradc_data = {
+ .num_bits = 10,
+ .num_channels = 3,
+ .clk_rate = 1000000,
+};
+
+static const struct rockchip_saradc_data rk3066_tsadc_data = {
+ .num_bits = 12,
+ .num_channels = 2,
+ .clk_rate = 50000,
+};
+
+static const struct rockchip_saradc_data rk3399_saradc_data = {
+ .num_bits = 10,
+ .num_channels = 6,
+ .clk_rate = 1000000,
+};
+
+static const struct udevice_id rockchip_saradc_ids[] = {
+ { .compatible = "rockchip,saradc",
+ .data = (ulong)&saradc_data },
+ { .compatible = "rockchip,rk3066-tsadc",
+ .data = (ulong)&rk3066_tsadc_data },
+ { .compatible = "rockchip,rk3399-saradc",
+ .data = (ulong)&rk3399_saradc_data },
+ { }
+};
+
+U_BOOT_DRIVER(rockchip_saradc) = {
+ .name = "rockchip_saradc",
+ .id = UCLASS_ADC,
+ .of_match = rockchip_saradc_ids,
+ .ops = &rockchip_saradc_ops,
+ .probe = rockchip_saradc_probe,
+ .ofdata_to_platdata = rockchip_saradc_ofdata_to_platdata,
+ .priv_auto_alloc_size = sizeof(struct rockchip_saradc_priv),
+};
diff --git a/drivers/clk/rockchip/clk_rk322x.c b/drivers/clk/rockchip/clk_rk322x.c
index d7f6a3c313..e87267d239 100644
--- a/drivers/clk/rockchip/clk_rk322x.c
+++ b/drivers/clk/rockchip/clk_rk322x.c
@@ -117,16 +117,16 @@ static void rkclk_init(struct rk322x_cru *cru)
pclk_div << CORE_PERI_DIV_SHIFT);
/*
- * select apll as pd_bus bus clock source and
+ * select gpll as pd_bus bus clock source and
* set up dependent divisors for PCLK/HCLK and ACLK clocks.
*/
aclk_div = GPLL_HZ / BUS_ACLK_HZ - 1;
assert((aclk_div + 1) * BUS_ACLK_HZ == GPLL_HZ && aclk_div <= 0x1f);
- pclk_div = GPLL_HZ / BUS_PCLK_HZ - 1;
+ pclk_div = BUS_ACLK_HZ / BUS_PCLK_HZ - 1;
assert((pclk_div + 1) * BUS_PCLK_HZ == GPLL_HZ && pclk_div <= 0x7);
- hclk_div = GPLL_HZ / BUS_HCLK_HZ - 1;
+ hclk_div = BUS_ACLK_HZ / BUS_HCLK_HZ - 1;
assert((hclk_div + 1) * BUS_HCLK_HZ == GPLL_HZ && hclk_div <= 0x3);
rk_clrsetreg(&cru->cru_clksel_con[0],
@@ -389,7 +389,7 @@ static int rk322x_clk_bind(struct udevice *dev)
/* The reset driver does not have a device node, so bind it here */
ret = device_bind_driver(gd->dm_root, "rk322x_sysreset", "reset", &dev);
if (ret)
- debug("Warning: No RK3036 reset driver: ret=%d\n", ret);
+ debug("Warning: No RK322x reset driver: ret=%d\n", ret);
return 0;
}
diff --git a/drivers/clk/rockchip/clk_rk3288.c b/drivers/clk/rockchip/clk_rk3288.c
index 478195b10b..a133810bf6 100644
--- a/drivers/clk/rockchip/clk_rk3288.c
+++ b/drivers/clk/rockchip/clk_rk3288.c
@@ -5,6 +5,7 @@
*/
#include <common.h>
+#include <bitfield.h>
#include <clk-uclass.h>
#include <dm.h>
#include <dt-structs.h>
@@ -111,6 +112,15 @@ enum {
PERI_ACLK_DIV_SHIFT = 0,
PERI_ACLK_DIV_MASK = 0x1f << PERI_ACLK_DIV_SHIFT,
+ /*
+ * CLKSEL24
+ * saradc_div_con:
+ * clk_saradc=24MHz/(saradc_div_con+1)
+ */
+ CLK_SARADC_DIV_CON_SHIFT = 8,
+ CLK_SARADC_DIV_CON_MASK = GENMASK(15, 8),
+ CLK_SARADC_DIV_CON_WIDTH = 8,
+
SOCSTS_DPLL_LOCK = 1 << 5,
SOCSTS_APLL_LOCK = 1 << 6,
SOCSTS_CPLL_LOCK = 1 << 7,
@@ -634,6 +644,31 @@ static ulong rockchip_spi_set_clk(struct rk3288_cru *cru, uint gclk_rate,
return rockchip_spi_get_clk(cru, gclk_rate, periph);
}
+static ulong rockchip_saradc_get_clk(struct rk3288_cru *cru)
+{
+ u32 div, val;
+
+ val = readl(&cru->cru_clksel_con[24]);
+ div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
+ CLK_SARADC_DIV_CON_WIDTH);
+
+ return DIV_TO_RATE(OSC_HZ, div);
+}
+
+static ulong rockchip_saradc_set_clk(struct rk3288_cru *cru, uint hz)
+{
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
+ assert(src_clk_div < 128);
+
+ rk_clrsetreg(&cru->cru_clksel_con[24],
+ CLK_SARADC_DIV_CON_MASK,
+ src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
+
+ return rockchip_saradc_get_clk(cru);
+}
+
static ulong rk3288_clk_get_rate(struct clk *clk)
{
struct rk3288_clk_priv *priv = dev_get_priv(clk->dev);
@@ -666,6 +701,9 @@ static ulong rk3288_clk_get_rate(struct clk *clk)
return gclk_rate;
case PCLK_PWM:
return PD_BUS_PCLK_HZ;
+ case SCLK_SARADC:
+ new_rate = rockchip_saradc_get_clk(priv->cru);
+ break;
default:
return -ENOENT;
}
@@ -756,6 +794,9 @@ static ulong rk3288_clk_set_rate(struct clk *clk, ulong rate)
new_rate = rate;
break;
#endif
+ case SCLK_SARADC:
+ new_rate = rockchip_saradc_set_clk(priv->cru, rate);
+ break;
default:
return -ENOENT;
}
diff --git a/drivers/clk/rockchip/clk_rk3328.c b/drivers/clk/rockchip/clk_rk3328.c
index c3a6650de0..540d9104c3 100644
--- a/drivers/clk/rockchip/clk_rk3328.c
+++ b/drivers/clk/rockchip/clk_rk3328.c
@@ -5,6 +5,7 @@
*/
#include <common.h>
+#include <bitfield.h>
#include <clk-uclass.h>
#include <dm.h>
#include <errno.h>
@@ -114,7 +115,8 @@ enum {
/* CLKSEL_CON23 */
CLK_SARADC_DIV_CON_SHIFT = 0,
- CLK_SARADC_DIV_CON_MASK = 0x3ff << CLK_SARADC_DIV_CON_SHIFT,
+ CLK_SARADC_DIV_CON_MASK = GENMASK(9, 0),
+ CLK_SARADC_DIV_CON_WIDTH = 10,
/* CLKSEL_CON24 */
CLK_PWM_PLL_SEL_CPLL = 0,
@@ -478,6 +480,31 @@ static ulong rk3328_pwm_set_clk(struct rk3328_cru *cru, uint hz)
return DIV_TO_RATE(GPLL_HZ, div);
}
+static ulong rk3328_saradc_get_clk(struct rk3328_cru *cru)
+{
+ u32 div, val;
+
+ val = readl(&cru->clksel_con[23]);
+ div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
+ CLK_SARADC_DIV_CON_WIDTH);
+
+ return DIV_TO_RATE(OSC_HZ, div);
+}
+
+static ulong rk3328_saradc_set_clk(struct rk3328_cru *cru, uint hz)
+{
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
+ assert(src_clk_div < 128);
+
+ rk_clrsetreg(&cru->clksel_con[23],
+ CLK_SARADC_DIV_CON_MASK,
+ src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
+
+ return rk3328_saradc_get_clk(cru);
+}
+
static ulong rk3328_clk_get_rate(struct clk *clk)
{
struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
@@ -501,6 +528,9 @@ static ulong rk3328_clk_get_rate(struct clk *clk)
case SCLK_PWM:
rate = rk3328_pwm_get_clk(priv->cru);
break;
+ case SCLK_SARADC:
+ rate = rk3328_saradc_get_clk(priv->cru);
+ break;
default:
return -ENOENT;
}
@@ -531,6 +561,9 @@ static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate)
case SCLK_PWM:
ret = rk3328_pwm_set_clk(priv->cru, rate);
break;
+ case SCLK_SARADC:
+ ret = rk3328_saradc_set_clk(priv->cru, rate);
+ break;
default:
return -ENOENT;
}
diff --git a/drivers/clk/rockchip/clk_rk3368.c b/drivers/clk/rockchip/clk_rk3368.c
index e2747816b9..3a12be7728 100644
--- a/drivers/clk/rockchip/clk_rk3368.c
+++ b/drivers/clk/rockchip/clk_rk3368.c
@@ -12,6 +12,7 @@
#include <errno.h>
#include <mapmem.h>
#include <syscon.h>
+#include <bitfield.h>
#include <asm/arch/clock.h>
#include <asm/arch/cru_rk3368.h>
#include <asm/arch/hardware.h>
@@ -397,6 +398,31 @@ static ulong rk3368_spi_set_clk(struct rk3368_cru *cru, ulong clk_id, uint hz)
return rk3368_spi_get_clk(cru, clk_id);
}
+static ulong rk3368_saradc_get_clk(struct rk3368_cru *cru)
+{
+ u32 div, val;
+
+ val = readl(&cru->clksel_con[25]);
+ div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
+ CLK_SARADC_DIV_CON_WIDTH);
+
+ return DIV_TO_RATE(OSC_HZ, div);
+}
+
+static ulong rk3368_saradc_set_clk(struct rk3368_cru *cru, uint hz)
+{
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
+ assert(src_clk_div < 128);
+
+ rk_clrsetreg(&cru->clksel_con[25],
+ CLK_SARADC_DIV_CON_MASK,
+ src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
+
+ return rk3368_saradc_get_clk(cru);
+}
+
static ulong rk3368_clk_get_rate(struct clk *clk)
{
struct rk3368_clk_priv *priv = dev_get_priv(clk->dev);
@@ -419,6 +445,9 @@ static ulong rk3368_clk_get_rate(struct clk *clk)
rate = rk3368_mmc_get_clk(priv->cru, clk->id);
break;
#endif
+ case SCLK_SARADC:
+ rate = rk3368_saradc_get_clk(priv->cru);
+ break;
default:
return -ENOENT;
}
@@ -453,6 +482,9 @@ static ulong rk3368_clk_set_rate(struct clk *clk, ulong rate)
ret = rk3368_gmac_set_clk(priv->cru, clk->id, rate);
break;
#endif
+ case SCLK_SARADC:
+ ret = rk3368_saradc_set_clk(priv->cru, rate);
+ break;
default:
return -ENOENT;
}
diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
index 9d963be552..50faf5d193 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -12,6 +12,7 @@
#include <errno.h>
#include <mapmem.h>
#include <syscon.h>
+#include <bitfield.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/cru_rk3399.h>
@@ -181,7 +182,8 @@ enum {
/* CLKSEL_CON26 */
CLK_SARADC_DIV_CON_SHIFT = 8,
- CLK_SARADC_DIV_CON_MASK = 0xff << CLK_SARADC_DIV_CON_SHIFT,
+ CLK_SARADC_DIV_CON_MASK = GENMASK(15, 8),
+ CLK_SARADC_DIV_CON_WIDTH = 8,
/* CLKSEL_CON27 */
CLK_TSADC_SEL_X24M = 0x0,
@@ -860,6 +862,32 @@ static ulong rk3399_ddr_set_clk(struct rk3399_cru *cru,
return set_rate;
}
+
+static ulong rk3399_saradc_get_clk(struct rk3399_cru *cru)
+{
+ u32 div, val;
+
+ val = readl(&cru->clksel_con[26]);
+ div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
+ CLK_SARADC_DIV_CON_WIDTH);
+
+ return DIV_TO_RATE(OSC_HZ, div);
+}
+
+static ulong rk3399_saradc_set_clk(struct rk3399_cru *cru, uint hz)
+{
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
+ assert(src_clk_div < 128);
+
+ rk_clrsetreg(&cru->clksel_con[26],
+ CLK_SARADC_DIV_CON_MASK,
+ src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
+
+ return rk3399_saradc_get_clk(cru);
+}
+
static ulong rk3399_clk_get_rate(struct clk *clk)
{
struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
@@ -895,6 +923,9 @@ static ulong rk3399_clk_get_rate(struct clk *clk)
break;
case PCLK_EFUSE1024NS:
break;
+ case SCLK_SARADC:
+ rate = rk3399_saradc_get_clk(priv->cru);
+ break;
default:
return -ENOENT;
}
@@ -943,6 +974,9 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
break;
case PCLK_EFUSE1024NS:
break;
+ case SCLK_SARADC:
+ ret = rk3399_saradc_set_clk(priv->cru, rate);
+ break;
default:
return -ENOENT;
}
diff --git a/drivers/clk/rockchip/clk_rv1108.c b/drivers/clk/rockchip/clk_rv1108.c
index cf966bbdc3..86e73e414c 100644
--- a/drivers/clk/rockchip/clk_rv1108.c
+++ b/drivers/clk/rockchip/clk_rv1108.c
@@ -5,6 +5,7 @@
*/
#include <common.h>
+#include <bitfield.h>
#include <clk-uclass.h>
#include <dm.h>
#include <errno.h>
@@ -36,7 +37,7 @@ enum {
#hz "Hz cannot be hit with PLL "\
"divisors on line " __stringify(__LINE__));
-/* use interge mode*/
+/* use integer mode */
static inline int rv1108_pll_id(enum rk_clk_id clk_id)
{
int id = 0;
@@ -130,6 +131,31 @@ static int rv1108_sfc_set_clk(struct rv1108_cru *cru, uint rate)
return DIV_TO_RATE(pll_rate, div);
}
+static ulong rv1108_saradc_get_clk(struct rv1108_cru *cru)
+{
+ u32 div, val;
+
+ val = readl(&cru->clksel_con[22]);
+ div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
+ CLK_SARADC_DIV_CON_WIDTH);
+
+ return DIV_TO_RATE(OSC_HZ, div);
+}
+
+static ulong rv1108_saradc_set_clk(struct rv1108_cru *cru, uint hz)
+{
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
+ assert(src_clk_div < 128);
+
+ rk_clrsetreg(&cru->clksel_con[22],
+ CLK_SARADC_DIV_CON_MASK,
+ src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
+
+ return rv1108_saradc_get_clk(cru);
+}
+
static ulong rv1108_clk_get_rate(struct clk *clk)
{
struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
@@ -137,6 +163,8 @@ static ulong rv1108_clk_get_rate(struct clk *clk)
switch (clk->id) {
case 0 ... 63:
return rkclk_pll_get_rate(priv->cru, clk->id);
+ case SCLK_SARADC:
+ return rv1108_saradc_get_clk(priv->cru);
default:
return -ENOENT;
}
@@ -154,6 +182,9 @@ static ulong rv1108_clk_set_rate(struct clk *clk, ulong rate)
case SCLK_SFC:
new_rate = rv1108_sfc_set_clk(priv->cru, rate);
break;
+ case SCLK_SARADC:
+ new_rate = rv1108_saradc_set_clk(priv->cru, rate);
+ break;
default:
return -ENOENT;
}
diff --git a/drivers/i2c/rk_i2c.c b/drivers/i2c/rk_i2c.c
index 840b3f6046..332280c220 100644
--- a/drivers/i2c/rk_i2c.c
+++ b/drivers/i2c/rk_i2c.c
@@ -396,6 +396,7 @@ static const struct udevice_id rockchip_i2c_ids[] = {
{ .compatible = "rockchip,rk3066-i2c" },
{ .compatible = "rockchip,rk3188-i2c" },
{ .compatible = "rockchip,rk3288-i2c" },
+ { .compatible = "rockchip,rk3328-i2c" },
{ .compatible = "rockchip,rk3399-i2c" },
{ }
};
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3368.c b/drivers/pinctrl/rockchip/pinctrl_rk3368.c
index b1f5704164..25249e377a 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3368.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3368.c
@@ -208,6 +208,29 @@ enum {
GPIO2A0_FLASH_CSN0 = (1 << GPIO2A0_SHIFT),
};
+/*GRF_GPIO2B_IOMUX*/
+enum {
+ GPIO2B3_SHIFT = 6,
+ GPIO2B3_MASK = GENMASK(GPIO2B3_SHIFT + 1, GPIO2B3_SHIFT),
+ GPIO2B3_GPIO = 0,
+ GPIO2B3_SDMMC0_DTECTN = (1 << GPIO2B3_SHIFT),
+
+ GPIO2B2_SHIFT = 4,
+ GPIO2B2_MASK = GENMASK(GPIO2B2_SHIFT + 1, GPIO2B2_SHIFT),
+ GPIO2B2_GPIO = 0,
+ GPIO2B2_SDMMC0_CMD = (1 << GPIO2B2_SHIFT),
+
+ GPIO2B1_SHIFT = 2,
+ GPIO2B1_MASK = GENMASK(GPIO2B1_SHIFT + 1, GPIO2B1_SHIFT),
+ GPIO2B1_GPIO = 0,
+ GPIO2B1_SDMMC0_CLKOUT = (1 << GPIO2B1_SHIFT),
+
+ GPIO2B0_SHIFT = 0,
+ GPIO2B0_MASK = GENMASK(GPIO2B0_SHIFT + 1, GPIO2B0_SHIFT),
+ GPIO2B0_GPIO = 0,
+ GPIO2B0_SDMMC0_D3 = (1 << GPIO2B0_SHIFT),
+};
+
/*GRF_GPIO2D_IOMUX*/
enum {
GPIO2D7_SHIFT = 14,
@@ -580,11 +603,17 @@ static void pinctrl_rk3368_sdmmc_config(struct rk3368_grf *grf, int mmc_id)
GPIO2A4_EMMC_CLKOUT);
break;
case PERIPH_ID_SDCARD:
- /*
- * We assume that the BROM has already set this up
- * correctly for us and that there's nothing to do
- * here.
- */
+ debug("mmc id = %d setting registers!\n", mmc_id);
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GPIO2A5_MASK | GPIO2A7_MASK |
+ GPIO2A7_MASK,
+ GPIO2A5_SDMMC0_D0 | GPIO2A6_SDMMC0_D1 |
+ GPIO2A7_SDMMC0_D2);
+ rk_clrsetreg(&grf->gpio2b_iomux,
+ GPIO2B0_MASK | GPIO2B1_MASK |
+ GPIO2B2_MASK | GPIO2B3_MASK,
+ GPIO2B0_SDMMC0_D3 | GPIO2B1_SDMMC0_CLKOUT |
+ GPIO2B2_SDMMC0_CMD | GPIO2B3_SDMMC0_DTECTN);
break;
default:
debug("mmc id = %d iomux error!\n", mmc_id);
diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig
index 2cfade1cb2..8892fa14e0 100644
--- a/drivers/power/regulator/Kconfig
+++ b/drivers/power/regulator/Kconfig
@@ -77,6 +77,13 @@ config DM_REGULATOR_FIXED
features for fixed value regulators. The driver implements get/set api
for enable and get only for voltage value.
+config SPL_DM_REGULATOR_FIXED
+ bool "Enable Driver Model for REGULATOR Fixed value in SPL"
+ depends on DM_REGULATOR_FIXED
+ ---help---
+ This config enables implementation of driver-model regulator uclass
+ features for fixed value regulators in SPL.
+
config DM_REGULATOR_GPIO
bool "Enable Driver Model for GPIO REGULATOR"
depends on DM_REGULATOR
diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile
index b09d03c2c9..45b5fe7247 100644
--- a/drivers/ram/rockchip/Makefile
+++ b/drivers/ram/rockchip/Makefile
@@ -5,3 +5,8 @@
#
obj-$(CONFIG_ROCKCHIP_RK3368) = dmc-rk3368.o
+obj-$(CONFIG_ROCKCHIP_RK3188) = sdram_rk3188.o
+obj-$(CONFIG_ROCKCHIP_RK322X) = sdram_rk322x.o
+obj-$(CONFIG_ROCKCHIP_RK3288) = sdram_rk3288.o
+obj-$(CONFIG_ROCKCHIP_RK3328) = sdram_rk3328.o
+obj-$(CONFIG_ROCKCHIP_RK3399) = sdram_rk3399.o
diff --git a/arch/arm/mach-rockchip/rk3188/sdram_rk3188.c b/drivers/ram/rockchip/sdram_rk3188.c
index 9d8b225dfa..365d00ef54 100644
--- a/arch/arm/mach-rockchip/rk3188/sdram_rk3188.c
+++ b/drivers/ram/rockchip/sdram_rk3188.c
@@ -682,11 +682,18 @@ out:
static int sdram_get_niu_config(struct rk3188_sdram_params *sdram_params)
{
- int i, tmp, size, ret = 0;
+ int i, tmp, size, row, ret = 0;
+ row = sdram_params->ch[0].cs0_row;
+ /*
+ * RK3188 share the rank and row bit15, we use same ddr config for 15bit
+ * and 16bit row
+ */
+ if (row == 16)
+ row = 15;
tmp = sdram_params->ch[0].col - 9;
tmp -= (sdram_params->ch[0].bw == 2) ? 0 : 1;
- tmp |= ((sdram_params->ch[0].cs0_row - 13) << 4);
+ tmp |= ((row - 13) << 4);
size = sizeof(ddrconf_table)/sizeof(ddrconf_table[0]);
for (i = 0; i < size; i++)
if (tmp == ddrconf_table[i])
diff --git a/drivers/ram/rockchip/sdram_rk322x.c b/drivers/ram/rockchip/sdram_rk322x.c
new file mode 100644
index 0000000000..cc3138b21d
--- /dev/null
+++ b/drivers/ram/rockchip/sdram_rk322x.c
@@ -0,0 +1,855 @@
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dt-structs.h>
+#include <errno.h>
+#include <ram.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk322x.h>
+#include <asm/arch/grf_rk322x.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sdram_rk322x.h>
+#include <asm/arch/timer.h>
+#include <asm/arch/uart.h>
+#include <asm/arch/sdram_common.h>
+#include <asm/types.h>
+#include <linux/err.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+struct chan_info {
+ struct rk322x_ddr_pctl *pctl;
+ struct rk322x_ddr_phy *phy;
+ struct rk322x_service_sys *msch;
+};
+
+struct dram_info {
+ struct chan_info chan[1];
+ struct ram_info info;
+ struct clk ddr_clk;
+ struct rk322x_cru *cru;
+ struct rk322x_grf *grf;
+};
+
+struct rk322x_sdram_params {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_rockchip_rk3228_dmc of_plat;
+#endif
+ struct rk322x_sdram_channel ch[1];
+ struct rk322x_pctl_timing pctl_timing;
+ struct rk322x_phy_timing phy_timing;
+ struct rk322x_base_params base;
+ int num_channels;
+ struct regmap *map;
+};
+
+#ifdef CONFIG_TPL_BUILD
+/*
+ * [7:6] bank(n:n bit bank)
+ * [5:4] row(13+n)
+ * [3] cs(0:1 cs, 1:2 cs)
+ * [2:1] bank(n:n bit bank)
+ * [0] col(10+n)
+ */
+const char ddr_cfg_2_rbc[] = {
+ ((0 << 6) | (0 << 4) | (0 << 3) | (1 << 2) | 1),
+ ((0 << 6) | (1 << 4) | (0 << 3) | (1 << 2) | 1),
+ ((0 << 6) | (2 << 4) | (0 << 3) | (1 << 2) | 1),
+ ((0 << 6) | (3 << 4) | (0 << 3) | (1 << 2) | 1),
+ ((0 << 6) | (1 << 4) | (0 << 3) | (1 << 2) | 2),
+ ((0 << 6) | (2 << 4) | (0 << 3) | (1 << 2) | 2),
+ ((0 << 6) | (3 << 4) | (0 << 3) | (1 << 2) | 2),
+ ((0 << 6) | (0 << 4) | (0 << 3) | (1 << 2) | 0),
+ ((0 << 6) | (1 << 4) | (0 << 3) | (1 << 2) | 0),
+ ((0 << 6) | (2 << 4) | (0 << 3) | (1 << 2) | 0),
+ ((0 << 6) | (3 << 4) | (0 << 3) | (1 << 2) | 0),
+ ((0 << 6) | (2 << 4) | (0 << 3) | (0 << 2) | 1),
+ ((1 << 6) | (1 << 4) | (0 << 3) | (0 << 2) | 2),
+ ((1 << 6) | (1 << 4) | (0 << 3) | (0 << 2) | 1),
+ ((0 << 6) | (3 << 4) | (1 << 3) | (1 << 2) | 1),
+ ((0 << 6) | (3 << 4) | (1 << 3) | (1 << 2) | 0),
+};
+
+static void copy_to_reg(u32 *dest, const u32 *src, u32 n)
+{
+ int i;
+
+ for (i = 0; i < n / sizeof(u32); i++) {
+ writel(*src, dest);
+ src++;
+ dest++;
+ }
+}
+
+void phy_pctrl_reset(struct rk322x_cru *cru,
+ struct rk322x_ddr_phy *ddr_phy)
+{
+ rk_clrsetreg(&cru->cru_softrst_con[5], 1 << DDRCTRL_PSRST_SHIFT |
+ 1 << DDRCTRL_SRST_SHIFT | 1 << DDRPHY_PSRST_SHIFT |
+ 1 << DDRPHY_SRST_SHIFT,
+ 1 << DDRCTRL_PSRST_SHIFT | 1 << DDRCTRL_SRST_SHIFT |
+ 1 << DDRPHY_PSRST_SHIFT | 1 << DDRPHY_SRST_SHIFT);
+
+ rockchip_udelay(10);
+
+ rk_clrreg(&cru->cru_softrst_con[5], 1 << DDRPHY_PSRST_SHIFT |
+ 1 << DDRPHY_SRST_SHIFT);
+ rockchip_udelay(10);
+
+ rk_clrreg(&cru->cru_softrst_con[5], 1 << DDRCTRL_PSRST_SHIFT |
+ 1 << DDRCTRL_SRST_SHIFT);
+ rockchip_udelay(10);
+
+ clrbits_le32(&ddr_phy->ddrphy_reg[0],
+ SOFT_RESET_MASK << SOFT_RESET_SHIFT);
+ rockchip_udelay(10);
+ setbits_le32(&ddr_phy->ddrphy_reg[0],
+ SOFT_DERESET_ANALOG);
+ rockchip_udelay(5);
+ setbits_le32(&ddr_phy->ddrphy_reg[0],
+ SOFT_DERESET_DIGITAL);
+
+ rockchip_udelay(1);
+}
+
+void phy_dll_bypass_set(struct rk322x_ddr_phy *ddr_phy, u32 freq)
+{
+ u32 tmp;
+
+ setbits_le32(&ddr_phy->ddrphy_reg[0x13], 0x10);
+ setbits_le32(&ddr_phy->ddrphy_reg[0x26], 0x10);
+ setbits_le32(&ddr_phy->ddrphy_reg[0x36], 0x10);
+ setbits_le32(&ddr_phy->ddrphy_reg[0x46], 0x10);
+ setbits_le32(&ddr_phy->ddrphy_reg[0x56], 0x10);
+
+ clrbits_le32(&ddr_phy->ddrphy_reg[0x14], 0x8);
+ clrbits_le32(&ddr_phy->ddrphy_reg[0x27], 0x8);
+ clrbits_le32(&ddr_phy->ddrphy_reg[0x37], 0x8);
+ clrbits_le32(&ddr_phy->ddrphy_reg[0x47], 0x8);
+ clrbits_le32(&ddr_phy->ddrphy_reg[0x57], 0x8);
+
+ if (freq <= 400)
+ setbits_le32(&ddr_phy->ddrphy_reg[0xa4], 0x1f);
+ else
+ clrbits_le32(&ddr_phy->ddrphy_reg[0xa4], 0x1f);
+
+ if (freq <= 680)
+ tmp = 3;
+ else
+ tmp = 2;
+
+ writel(tmp, &ddr_phy->ddrphy_reg[0x28]);
+ writel(tmp, &ddr_phy->ddrphy_reg[0x38]);
+ writel(tmp, &ddr_phy->ddrphy_reg[0x48]);
+ writel(tmp, &ddr_phy->ddrphy_reg[0x58]);
+}
+
+static void send_command(struct rk322x_ddr_pctl *pctl,
+ u32 rank, u32 cmd, u32 arg)
+{
+ writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd);
+ rockchip_udelay(1);
+ while (readl(&pctl->mcmd) & START_CMD)
+ ;
+}
+
+static void memory_init(struct chan_info *chan,
+ struct rk322x_sdram_params *sdram_params)
+{
+ struct rk322x_ddr_pctl *pctl = chan->pctl;
+ u32 dramtype = sdram_params->base.dramtype;
+
+ if (dramtype == DDR3) {
+ send_command(pctl, 3, DESELECT_CMD, 0);
+ rockchip_udelay(1);
+ send_command(pctl, 3, PREA_CMD, 0);
+ send_command(pctl, 3, MRS_CMD,
+ (0x02 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
+ (sdram_params->phy_timing.mr[2] & CMD_ADDR_MASK) <<
+ CMD_ADDR_SHIFT);
+
+ send_command(pctl, 3, MRS_CMD,
+ (0x03 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
+ (sdram_params->phy_timing.mr[3] & CMD_ADDR_MASK) <<
+ CMD_ADDR_SHIFT);
+
+ send_command(pctl, 3, MRS_CMD,
+ (0x01 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
+ (sdram_params->phy_timing.mr[1] & CMD_ADDR_MASK) <<
+ CMD_ADDR_SHIFT);
+
+ send_command(pctl, 3, MRS_CMD,
+ (0x00 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
+ ((sdram_params->phy_timing.mr[0] |
+ DDR3_DLL_RESET) &
+ CMD_ADDR_MASK) << CMD_ADDR_SHIFT);
+
+ send_command(pctl, 3, ZQCL_CMD, 0);
+ } else {
+ send_command(pctl, 3, MRS_CMD,
+ (0x63 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
+ (0 & LPDDR23_OP_MASK) <<
+ LPDDR23_OP_SHIFT);
+ rockchip_udelay(10);
+ send_command(pctl, 3, MRS_CMD,
+ (0x10 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
+ (0xff & LPDDR23_OP_MASK) <<
+ LPDDR23_OP_SHIFT);
+ rockchip_udelay(1);
+ send_command(pctl, 3, MRS_CMD,
+ (0x10 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
+ (0xff & LPDDR23_OP_MASK) <<
+ LPDDR23_OP_SHIFT);
+ rockchip_udelay(1);
+ send_command(pctl, 3, MRS_CMD,
+ (1 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
+ (sdram_params->phy_timing.mr[1] &
+ LPDDR23_OP_MASK) << LPDDR23_OP_SHIFT);
+ send_command(pctl, 3, MRS_CMD,
+ (2 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
+ (sdram_params->phy_timing.mr[2] &
+ LPDDR23_OP_MASK) << LPDDR23_OP_SHIFT);
+ send_command(pctl, 3, MRS_CMD,
+ (3 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
+ (sdram_params->phy_timing.mr[3] &
+ LPDDR23_OP_MASK) << LPDDR23_OP_SHIFT);
+ if (dramtype == LPDDR3)
+ send_command(pctl, 3, MRS_CMD, (11 & LPDDR23_MA_MASK) <<
+ LPDDR23_MA_SHIFT |
+ (sdram_params->phy_timing.mr11 &
+ LPDDR23_OP_MASK) << LPDDR23_OP_SHIFT);
+ }
+}
+
+static u32 data_training(struct chan_info *chan)
+{
+ struct rk322x_ddr_phy *ddr_phy = chan->phy;
+ struct rk322x_ddr_pctl *pctl = chan->pctl;
+ u32 value;
+ u32 bw = (readl(&ddr_phy->ddrphy_reg[0]) >> 4) & 0xf;
+ u32 ret;
+
+ /* disable auto refresh */
+ value = readl(&pctl->trefi) | (1 << 31);
+ writel(1 << 31, &pctl->trefi);
+
+ clrsetbits_le32(&ddr_phy->ddrphy_reg[2], 0x30,
+ DQS_SQU_CAL_SEL_CS0);
+ setbits_le32(&ddr_phy->ddrphy_reg[2], DQS_SQU_CAL_START);
+
+ rockchip_udelay(30);
+ ret = readl(&ddr_phy->ddrphy_reg[0xff]);
+
+ clrbits_le32(&ddr_phy->ddrphy_reg[2],
+ DQS_SQU_CAL_START);
+
+ /*
+ * since data training will take about 20us, so send some auto
+ * refresh(about 7.8us) to complement the lost time
+ */
+ send_command(pctl, 3, PREA_CMD, 0);
+ send_command(pctl, 3, REF_CMD, 0);
+
+ writel(value, &pctl->trefi);
+
+ if (ret & 0x10) {
+ ret = -1;
+ } else {
+ ret = (ret & 0xf) ^ bw;
+ ret = (ret == 0) ? 0 : -1;
+ }
+ return ret;
+}
+
+static void move_to_config_state(struct rk322x_ddr_pctl *pctl)
+{
+ unsigned int state;
+
+ while (1) {
+ state = readl(&pctl->stat) & PCTL_STAT_MASK;
+ switch (state) {
+ case LOW_POWER:
+ writel(WAKEUP_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK)
+ != ACCESS)
+ ;
+ /*
+ * If at low power state, need wakeup first, and then
+ * enter the config, so fallthrough
+ */
+ case ACCESS:
+ /* fallthrough */
+ case INIT_MEM:
+ writel(CFG_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK) != CONFIG)
+ ;
+ break;
+ case CONFIG:
+ return;
+ default:
+ break;
+ }
+ }
+}
+
+static void move_to_access_state(struct rk322x_ddr_pctl *pctl)
+{
+ unsigned int state;
+
+ while (1) {
+ state = readl(&pctl->stat) & PCTL_STAT_MASK;
+ switch (state) {
+ case LOW_POWER:
+ writel(WAKEUP_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK) != ACCESS)
+ ;
+ break;
+ case INIT_MEM:
+ writel(CFG_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK) != CONFIG)
+ ;
+ /* fallthrough */
+ case CONFIG:
+ writel(GO_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK) != ACCESS)
+ ;
+ break;
+ case ACCESS:
+ return;
+ default:
+ break;
+ }
+ }
+}
+
+static void move_to_lowpower_state(struct rk322x_ddr_pctl *pctl)
+{
+ unsigned int state;
+
+ while (1) {
+ state = readl(&pctl->stat) & PCTL_STAT_MASK;
+ switch (state) {
+ case INIT_MEM:
+ writel(CFG_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK) != CONFIG)
+ ;
+ /* fallthrough */
+ case CONFIG:
+ writel(GO_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK) != ACCESS)
+ ;
+ break;
+ case ACCESS:
+ writel(SLEEP_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK) !=
+ LOW_POWER)
+ ;
+ break;
+ case LOW_POWER:
+ return;
+ default:
+ break;
+ }
+ }
+}
+
+/* pctl should in low power mode when call this function */
+static void phy_softreset(struct dram_info *dram)
+{
+ struct rk322x_ddr_phy *ddr_phy = dram->chan[0].phy;
+ struct rk322x_grf *grf = dram->grf;
+
+ writel(GRF_DDRPHY_BUFFEREN_CORE_EN, &grf->soc_con[0]);
+ clrbits_le32(&ddr_phy->ddrphy_reg[0], 0x3 << 2);
+ rockchip_udelay(1);
+ setbits_le32(&ddr_phy->ddrphy_reg[0], 1 << 2);
+ rockchip_udelay(5);
+ setbits_le32(&ddr_phy->ddrphy_reg[0], 1 << 3);
+ writel(GRF_DDRPHY_BUFFEREN_CORE_DIS, &grf->soc_con[0]);
+}
+
+/* bw: 2: 32bit, 1:16bit */
+static void set_bw(struct dram_info *dram, u32 bw)
+{
+ struct rk322x_ddr_pctl *pctl = dram->chan[0].pctl;
+ struct rk322x_ddr_phy *ddr_phy = dram->chan[0].phy;
+ struct rk322x_grf *grf = dram->grf;
+
+ if (bw == 1) {
+ setbits_le32(&pctl->ppcfg, 1);
+ clrbits_le32(&ddr_phy->ddrphy_reg[0], 0xc << 4);
+ writel(GRF_MSCH_NOC_16BIT_EN, &grf->soc_con[0]);
+ clrbits_le32(&ddr_phy->ddrphy_reg[0x46], 0x8);
+ clrbits_le32(&ddr_phy->ddrphy_reg[0x56], 0x8);
+ } else {
+ clrbits_le32(&pctl->ppcfg, 1);
+ setbits_le32(&ddr_phy->ddrphy_reg[0], 0xf << 4);
+ writel(GRF_DDR_32BIT_EN | GRF_MSCH_NOC_32BIT_EN,
+ &grf->soc_con[0]);
+ setbits_le32(&ddr_phy->ddrphy_reg[0x46], 0x8);
+ setbits_le32(&ddr_phy->ddrphy_reg[0x56], 0x8);
+ }
+}
+
+static void pctl_cfg(struct rk322x_ddr_pctl *pctl,
+ struct rk322x_sdram_params *sdram_params,
+ struct rk322x_grf *grf)
+{
+ u32 burst_len;
+ u32 bw;
+ u32 dramtype = sdram_params->base.dramtype;
+
+ if (sdram_params->ch[0].bw == 2)
+ bw = GRF_DDR_32BIT_EN | GRF_MSCH_NOC_32BIT_EN;
+ else
+ bw = GRF_MSCH_NOC_16BIT_EN;
+
+ writel(DFI_INIT_START | DFI_DATA_BYTE_DISABLE_EN, &pctl->dfistcfg0);
+ writel(DFI_DRAM_CLK_SR_EN | DFI_DRAM_CLK_DPD_EN, &pctl->dfistcfg1);
+ writel(DFI_PARITY_INTR_EN | DFI_PARITY_EN, &pctl->dfistcfg2);
+ writel(0x51010, &pctl->dfilpcfg0);
+
+ writel(1, &pctl->dfitphyupdtype0);
+ writel(0x0d, &pctl->dfitphyrdlat);
+ writel(0, &pctl->dfitphywrdata);
+
+ writel(0, &pctl->dfiupdcfg);
+ copy_to_reg(&pctl->togcnt1u, &sdram_params->pctl_timing.togcnt1u,
+ sizeof(struct rk322x_pctl_timing));
+ if (dramtype == DDR3) {
+ writel((1 << 3) | (1 << 11),
+ &pctl->dfiodtcfg);
+ writel(7 << 16, &pctl->dfiodtcfg1);
+ writel((readl(&pctl->tcl) - 1) / 2 - 1, &pctl->dfitrddataen);
+ writel((readl(&pctl->tcwl) - 1) / 2 - 1, &pctl->dfitphywrlat);
+ writel(500, &pctl->trsth);
+ writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT | DDR3_EN |
+ DDR2_DDR3_BL_8 | (6 - 4) << TFAW_SHIFT | PD_EXIT_SLOW |
+ 1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
+ &pctl->mcfg);
+ writel(bw | GRF_DDR3_EN, &grf->soc_con[0]);
+ } else {
+ if (sdram_params->phy_timing.bl & PHT_BL_8)
+ burst_len = MDDR_LPDDR2_BL_8;
+ else
+ burst_len = MDDR_LPDDR2_BL_4;
+
+ writel(readl(&pctl->tcl) / 2 - 1, &pctl->dfitrddataen);
+ writel(readl(&pctl->tcwl) / 2 - 1, &pctl->dfitphywrlat);
+ writel(0, &pctl->trsth);
+ if (dramtype == LPDDR2) {
+ writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT |
+ LPDDR2_S4 | LPDDR2_EN | burst_len |
+ (6 - 4) << TFAW_SHIFT | PD_EXIT_FAST |
+ 1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
+ &pctl->mcfg);
+ writel(0, &pctl->dfiodtcfg);
+ writel(0, &pctl->dfiodtcfg1);
+ } else {
+ writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT |
+ LPDDR2_S4 | LPDDR3_EN | burst_len |
+ (6 - 4) << TFAW_SHIFT | PD_EXIT_FAST |
+ 1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
+ &pctl->mcfg);
+ writel((1 << 3) | (1 << 2), &pctl->dfiodtcfg);
+ writel((7 << 16) | 4, &pctl->dfiodtcfg1);
+ }
+ writel(bw | GRF_LPDDR2_3_EN, &grf->soc_con[0]);
+ }
+ setbits_le32(&pctl->scfg, 1);
+}
+
+static void phy_cfg(struct chan_info *chan,
+ struct rk322x_sdram_params *sdram_params)
+{
+ struct rk322x_ddr_phy *ddr_phy = chan->phy;
+ struct rk322x_service_sys *axi_bus = chan->msch;
+ struct rk322x_msch_timings *noc_timing = &sdram_params->base.noc_timing;
+ struct rk322x_phy_timing *phy_timing = &sdram_params->phy_timing;
+ struct rk322x_pctl_timing *pctl_timing = &sdram_params->pctl_timing;
+ u32 cmd_drv, clk_drv, dqs_drv, dqs_odt;
+
+ writel(noc_timing->ddrtiming, &axi_bus->ddrtiming);
+ writel(noc_timing->ddrmode, &axi_bus->ddrmode);
+ writel(noc_timing->readlatency, &axi_bus->readlatency);
+ writel(noc_timing->activate, &axi_bus->activate);
+ writel(noc_timing->devtodev, &axi_bus->devtodev);
+
+ switch (sdram_params->base.dramtype) {
+ case DDR3:
+ writel(PHY_DDR3 | phy_timing->bl, &ddr_phy->ddrphy_reg[1]);
+ break;
+ case LPDDR2:
+ writel(PHY_LPDDR2 | phy_timing->bl, &ddr_phy->ddrphy_reg[1]);
+ break;
+ default:
+ writel(PHY_LPDDR2 | phy_timing->bl, &ddr_phy->ddrphy_reg[1]);
+ break;
+ }
+
+ writel(phy_timing->cl_al, &ddr_phy->ddrphy_reg[0xb]);
+ writel(pctl_timing->tcwl, &ddr_phy->ddrphy_reg[0xc]);
+
+ cmd_drv = PHY_RON_RTT_34OHM;
+ clk_drv = PHY_RON_RTT_45OHM;
+ dqs_drv = PHY_RON_RTT_34OHM;
+ if (sdram_params->base.dramtype == LPDDR2)
+ dqs_odt = PHY_RON_RTT_DISABLE;
+ else
+ dqs_odt = PHY_RON_RTT_225OHM;
+
+ writel(cmd_drv, &ddr_phy->ddrphy_reg[0x11]);
+ clrsetbits_le32(&ddr_phy->ddrphy_reg[0x12], (0x1f << 3), cmd_drv << 3);
+ writel(clk_drv, &ddr_phy->ddrphy_reg[0x16]);
+ writel(clk_drv, &ddr_phy->ddrphy_reg[0x18]);
+
+ writel(dqs_drv, &ddr_phy->ddrphy_reg[0x20]);
+ writel(dqs_drv, &ddr_phy->ddrphy_reg[0x2f]);
+ writel(dqs_drv, &ddr_phy->ddrphy_reg[0x30]);
+ writel(dqs_drv, &ddr_phy->ddrphy_reg[0x3f]);
+ writel(dqs_drv, &ddr_phy->ddrphy_reg[0x40]);
+ writel(dqs_drv, &ddr_phy->ddrphy_reg[0x4f]);
+ writel(dqs_drv, &ddr_phy->ddrphy_reg[0x50]);
+ writel(dqs_drv, &ddr_phy->ddrphy_reg[0x5f]);
+
+ writel(dqs_odt, &ddr_phy->ddrphy_reg[0x21]);
+ writel(dqs_odt, &ddr_phy->ddrphy_reg[0x2e]);
+ writel(dqs_odt, &ddr_phy->ddrphy_reg[0x31]);
+ writel(dqs_odt, &ddr_phy->ddrphy_reg[0x3e]);
+ writel(dqs_odt, &ddr_phy->ddrphy_reg[0x41]);
+ writel(dqs_odt, &ddr_phy->ddrphy_reg[0x4e]);
+ writel(dqs_odt, &ddr_phy->ddrphy_reg[0x51]);
+ writel(dqs_odt, &ddr_phy->ddrphy_reg[0x5e]);
+}
+
+void dram_cfg_rbc(struct chan_info *chan,
+ struct rk322x_sdram_params *sdram_params)
+{
+ char noc_config;
+ int i = 0;
+ struct rk322x_sdram_channel *config = &sdram_params->ch[0];
+ struct rk322x_service_sys *axi_bus = chan->msch;
+
+ move_to_config_state(chan->pctl);
+
+ if ((config->rank == 2) && (config->cs1_row == config->cs0_row)) {
+ if ((config->col + config->bw) == 12) {
+ i = 14;
+ goto finish;
+ } else if ((config->col + config->bw) == 11) {
+ i = 15;
+ goto finish;
+ }
+ }
+ noc_config = ((config->cs0_row - 13) << 4) | ((config->bk - 2) << 2) |
+ (config->col + config->bw - 11);
+ for (i = 0; i < 11; i++) {
+ if (noc_config == ddr_cfg_2_rbc[i])
+ break;
+ }
+
+ if (i < 11)
+ goto finish;
+
+ noc_config = ((config->bk - 2) << 6) | ((config->cs0_row - 13) << 4) |
+ (config->col + config->bw - 11);
+
+ for (i = 11; i < 14; i++) {
+ if (noc_config == ddr_cfg_2_rbc[i])
+ break;
+ }
+ if (i < 14)
+ goto finish;
+ else
+ i = 0;
+
+finish:
+ writel(i, &axi_bus->ddrconf);
+ move_to_access_state(chan->pctl);
+}
+
+static void dram_all_config(const struct dram_info *dram,
+ struct rk322x_sdram_params *sdram_params)
+{
+ struct rk322x_sdram_channel *info = &sdram_params->ch[0];
+ u32 sys_reg = 0;
+
+ sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT;
+ sys_reg |= (1 - 1) << SYS_REG_NUM_CH_SHIFT;
+ sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(0);
+ sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(0);
+ sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(0);
+ sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(0);
+ sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(0);
+ sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(0);
+ sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(0);
+ sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(0);
+ sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(0);
+
+ writel(sys_reg, &dram->grf->os_reg[2]);
+}
+
+#define TEST_PATTEN 0x5aa5f00f
+
+static int dram_cap_detect(struct dram_info *dram,
+ struct rk322x_sdram_params *sdram_params)
+{
+ u32 bw, row, col, addr;
+ u32 ret = 0;
+ struct rk322x_service_sys *axi_bus = dram->chan[0].msch;
+
+ if (sdram_params->base.dramtype == DDR3)
+ sdram_params->ch[0].dbw = 1;
+ else
+ sdram_params->ch[0].dbw = 2;
+
+ move_to_config_state(dram->chan[0].pctl);
+ /* bw detect */
+ set_bw(dram, 2);
+ if (data_training(&dram->chan[0]) == 0) {
+ bw = 2;
+ } else {
+ bw = 1;
+ set_bw(dram, 1);
+ move_to_lowpower_state(dram->chan[0].pctl);
+ phy_softreset(dram);
+ move_to_config_state(dram->chan[0].pctl);
+ if (data_training(&dram->chan[0])) {
+ printf("BW detect error\n");
+ ret = -EINVAL;
+ }
+ }
+ sdram_params->ch[0].bw = bw;
+ sdram_params->ch[0].bk = 3;
+
+ if (bw == 2)
+ writel(6, &axi_bus->ddrconf);
+ else
+ writel(3, &axi_bus->ddrconf);
+ move_to_access_state(dram->chan[0].pctl);
+ for (col = 11; col >= 9; col--) {
+ writel(0, CONFIG_SYS_SDRAM_BASE);
+ addr = CONFIG_SYS_SDRAM_BASE +
+ (1 << (col + bw - 1));
+ writel(TEST_PATTEN, addr);
+ if ((readl(addr) == TEST_PATTEN) &&
+ (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+ break;
+ }
+ if (col == 8) {
+ printf("Col detect error\n");
+ ret = -EINVAL;
+ goto out;
+ } else {
+ sdram_params->ch[0].col = col;
+ }
+
+ writel(10, &axi_bus->ddrconf);
+
+ /* Detect row*/
+ for (row = 16; row >= 12; row--) {
+ writel(0, CONFIG_SYS_SDRAM_BASE);
+ addr = CONFIG_SYS_SDRAM_BASE + (1u << (row + 11 + 3 - 1));
+ writel(TEST_PATTEN, addr);
+ if ((readl(addr) == TEST_PATTEN) &&
+ (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+ break;
+ }
+ if (row == 11) {
+ printf("Row detect error\n");
+ ret = -EINVAL;
+ } else {
+ sdram_params->ch[0].cs1_row = row;
+ sdram_params->ch[0].row_3_4 = 0;
+ sdram_params->ch[0].cs0_row = row;
+ }
+ /* cs detect */
+ writel(0, CONFIG_SYS_SDRAM_BASE);
+ writel(TEST_PATTEN, CONFIG_SYS_SDRAM_BASE + (1u << 30));
+ writel(~TEST_PATTEN, CONFIG_SYS_SDRAM_BASE + (1u << 30) + 4);
+ if ((readl(CONFIG_SYS_SDRAM_BASE + (1u << 30)) == TEST_PATTEN) &&
+ (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+ sdram_params->ch[0].rank = 2;
+ else
+ sdram_params->ch[0].rank = 1;
+out:
+ return ret;
+}
+
+static int sdram_init(struct dram_info *dram,
+ struct rk322x_sdram_params *sdram_params)
+{
+ int ret;
+
+ ret = clk_set_rate(&dram->ddr_clk,
+ sdram_params->base.ddr_freq * MHz * 2);
+ if (ret < 0) {
+ printf("Could not set DDR clock\n");
+ return ret;
+ }
+
+ phy_pctrl_reset(dram->cru, dram->chan[0].phy);
+ phy_dll_bypass_set(dram->chan[0].phy, sdram_params->base.ddr_freq);
+ pctl_cfg(dram->chan[0].pctl, sdram_params, dram->grf);
+ phy_cfg(&dram->chan[0], sdram_params);
+ writel(POWER_UP_START, &dram->chan[0].pctl->powctl);
+ while (!(readl(&dram->chan[0].pctl->powstat) & POWER_UP_DONE))
+ ;
+ memory_init(&dram->chan[0], sdram_params);
+ move_to_access_state(dram->chan[0].pctl);
+ ret = dram_cap_detect(dram, sdram_params);
+ if (ret)
+ goto out;
+ dram_cfg_rbc(&dram->chan[0], sdram_params);
+ dram_all_config(dram, sdram_params);
+out:
+ return ret;
+}
+
+static int rk322x_dmc_ofdata_to_platdata(struct udevice *dev)
+{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct rk322x_sdram_params *params = dev_get_platdata(dev);
+ const void *blob = gd->fdt_blob;
+ int node = dev_of_offset(dev);
+ int ret;
+
+ params->num_channels = 1;
+
+ ret = fdtdec_get_int_array(blob, node, "rockchip,pctl-timing",
+ (u32 *)&params->pctl_timing,
+ sizeof(params->pctl_timing) / sizeof(u32));
+ if (ret) {
+ printf("%s: Cannot read rockchip,pctl-timing\n", __func__);
+ return -EINVAL;
+ }
+ ret = fdtdec_get_int_array(blob, node, "rockchip,phy-timing",
+ (u32 *)&params->phy_timing,
+ sizeof(params->phy_timing) / sizeof(u32));
+ if (ret) {
+ printf("%s: Cannot read rockchip,phy-timing\n", __func__);
+ return -EINVAL;
+ }
+ ret = fdtdec_get_int_array(blob, node, "rockchip,sdram-params",
+ (u32 *)&params->base,
+ sizeof(params->base) / sizeof(u32));
+ if (ret) {
+ printf("%s: Cannot read rockchip,sdram-params\n", __func__);
+ return -EINVAL;
+ }
+ ret = regmap_init_mem(dev, &params->map);
+ if (ret)
+ return ret;
+#endif
+
+ return 0;
+}
+#endif /* CONFIG_TPL_BUILD */
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int conv_of_platdata(struct udevice *dev)
+{
+ struct rk322x_sdram_params *plat = dev_get_platdata(dev);
+ struct dtd_rockchip_rk322x_dmc *of_plat = &plat->of_plat;
+ int ret;
+
+ memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing,
+ sizeof(plat->pctl_timing));
+ memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing,
+ sizeof(plat->phy_timing));
+ memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
+
+ plat->num_channels = 1;
+ ret = regmap_init_mem_platdata(dev, of_plat->reg,
+ ARRAY_SIZE(of_plat->reg) / 2,
+ &plat->map);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+#endif
+
+static int rk322x_dmc_probe(struct udevice *dev)
+{
+#ifdef CONFIG_TPL_BUILD
+ struct rk322x_sdram_params *plat = dev_get_platdata(dev);
+ int ret;
+ struct udevice *dev_clk;
+#endif
+ struct dram_info *priv = dev_get_priv(dev);
+
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+#ifdef CONFIG_TPL_BUILD
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ ret = conv_of_platdata(dev);
+ if (ret)
+ return ret;
+#endif
+
+ priv->chan[0].msch = syscon_get_first_range(ROCKCHIP_SYSCON_MSCH);
+ priv->chan[0].pctl = regmap_get_range(plat->map, 0);
+ priv->chan[0].phy = regmap_get_range(plat->map, 1);
+ ret = rockchip_get_clk(&dev_clk);
+ if (ret)
+ return ret;
+ priv->ddr_clk.id = CLK_DDR;
+ ret = clk_request(dev_clk, &priv->ddr_clk);
+ if (ret)
+ return ret;
+
+ priv->cru = rockchip_get_cru();
+ if (IS_ERR(priv->cru))
+ return PTR_ERR(priv->cru);
+ ret = sdram_init(priv, plat);
+ if (ret)
+ return ret;
+#else
+ priv->info.base = CONFIG_SYS_SDRAM_BASE;
+ priv->info.size = rockchip_sdram_size(
+ (phys_addr_t)&priv->grf->os_reg[2]);
+#endif
+
+ return 0;
+}
+
+static int rk322x_dmc_get_info(struct udevice *dev, struct ram_info *info)
+{
+ struct dram_info *priv = dev_get_priv(dev);
+
+ *info = priv->info;
+
+ return 0;
+}
+
+static struct ram_ops rk322x_dmc_ops = {
+ .get_info = rk322x_dmc_get_info,
+};
+
+static const struct udevice_id rk322x_dmc_ids[] = {
+ { .compatible = "rockchip,rk3228-dmc" },
+ { }
+};
+
+U_BOOT_DRIVER(dmc_rk322x) = {
+ .name = "rockchip_rk322x_dmc",
+ .id = UCLASS_RAM,
+ .of_match = rk322x_dmc_ids,
+ .ops = &rk322x_dmc_ops,
+#ifdef CONFIG_TPL_BUILD
+ .ofdata_to_platdata = rk322x_dmc_ofdata_to_platdata,
+#endif
+ .probe = rk322x_dmc_probe,
+ .priv_auto_alloc_size = sizeof(struct dram_info),
+#ifdef CONFIG_TPL_BUILD
+ .platdata_auto_alloc_size = sizeof(struct rk322x_sdram_params),
+#endif
+};
+
diff --git a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c b/drivers/ram/rockchip/sdram_rk3288.c
index 95efb117fc..95efb117fc 100644
--- a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
+++ b/drivers/ram/rockchip/sdram_rk3288.c
diff --git a/arch/arm/mach-rockchip/rk3328/sdram_rk3328.c b/drivers/ram/rockchip/sdram_rk3328.c
index 9637a35e23..9637a35e23 100644
--- a/arch/arm/mach-rockchip/rk3328/sdram_rk3328.c
+++ b/drivers/ram/rockchip/sdram_rk3328.c
diff --git a/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index 5ed4b03837..5ed4b03837 100644
--- a/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
diff --git a/include/configs/evb_rk3399.h b/include/configs/evb_rk3399.h
index 015f25a774..66ead6c117 100644
--- a/include/configs/evb_rk3399.h
+++ b/include/configs/evb_rk3399.h
@@ -10,12 +10,6 @@
#include <configs/rk3399_common.h>
#define CONFIG_SYS_MMC_ENV_DEV 1
-/*
- * SPL @ 32k for ~36k
- * ENV @ 96k
- * u-boot @ 128K
- */
-#define CONFIG_ENV_OFFSET (96 * 1024)
#define SDRAM_BANK_SIZE (2UL << 30)
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h
index e9e3c4013c..34f255847a 100644
--- a/include/configs/rk3288_common.h
+++ b/include/configs/rk3288_common.h
@@ -32,7 +32,11 @@
#define CONFIG_SYS_INIT_SP_ADDR 0x00100000
#define CONFIG_SYS_LOAD_ADDR 0x00800800
#define CONFIG_SPL_STACK 0xff718000
-#define CONFIG_SPL_TEXT_BASE 0xff704004
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_TPL_BOOTROM_SUPPORT)
+# define CONFIG_SPL_TEXT_BASE 0x0
+#else
+# define CONFIG_SPL_TEXT_BASE 0xff704004
+#endif
/* MMC/SD IP block */
#define CONFIG_BOUNCE_BUFFER
diff --git a/include/configs/vyasa-rk3288.h b/include/configs/vyasa-rk3288.h
index 9d6c80f549..8774e42430 100644
--- a/include/configs/vyasa-rk3288.h
+++ b/include/configs/vyasa-rk3288.h
@@ -20,4 +20,21 @@
#define CONFIG_SYS_MMC_ENV_DEV 1
#undef CONFIG_CMD_USB_MASS_STORAGE
+#ifndef CONFIG_TPL_BUILD
+
+#define CONFIG_SPL_OS_BOOT
+
+/* Falcon Mode */
+#define CONFIG_SPL_FS_LOAD_ARGS_NAME "args"
+#define CONFIG_SPL_FS_LOAD_KERNEL_NAME "uImage"
+#define CONFIG_CMD_SPL
+#define CONFIG_SYS_SPL_ARGS_ADDR 0x0ffe5000
+#define CONFIG_CMD_SPL_WRITE_SIZE (128 * SZ_1K)
+
+/* Falcon Mode - MMC support: args@1MB kernel@2MB */
+#define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR 0x800 /* 1MB */
+#define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS (CONFIG_CMD_SPL_WRITE_SIZE / 512)
+#define CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR 0x1000 /* 2MB */
+#endif
+
#endif
diff --git a/include/dt-bindings/clock/rv1108-cru.h b/include/dt-bindings/clock/rv1108-cru.h
index d2ad3bb52d..7defc6b282 100644
--- a/include/dt-bindings/clock/rv1108-cru.h
+++ b/include/dt-bindings/clock/rv1108-cru.h
@@ -39,6 +39,7 @@
#define SCLK_MAC_TX 88
#define SCLK_MACREF 89
#define SCLK_MACREF_OUT 90
+#define SCLK_SARADC 91
/* aclk gates */
@@ -67,6 +68,7 @@
#define PCLK_TIMER 270
#define PCLK_PERI 271
#define PCLK_GMAC 272
+#define PCLK_SARADC 273
/* hclk gates */
#define HCLK_I2S0_8CH 320
diff --git a/tools/rkcommon.c b/tools/rkcommon.c
index 04e8272fd5..1a24e16589 100644
--- a/tools/rkcommon.c
+++ b/tools/rkcommon.c
@@ -73,6 +73,7 @@ struct spl_info {
static struct spl_info spl_infos[] = {
{ "rk3036", "RK30", 0x1000, false, false },
+ { "rk3128", "RK31", 0x1800, false, false },
{ "rk3188", "RK31", 0x8000 - 0x800, true, false },
{ "rk322x", "RK32", 0x8000 - 0x1000, false, false },
{ "rk3288", "RK32", 0x8000, false, false },