summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2017-03-17 13:11:12 (GMT)
committerTom Rini <trini@konsulko.com>2017-03-17 18:15:17 (GMT)
commitf9515756b6d76cde99b385dda905dfb20d31ea48 (patch)
treeb2cd0007fb90a43992cb51f1a02d4e191e3dde10
parente245f1a5db086d676cbd97371046ea5c5e554326 (diff)
parent520c174b3564ae183f0e7c118dc8ce3770ae20b0 (diff)
downloadu-boot-fsl-qoriq-f9515756b6d76cde99b385dda905dfb20d31ea48.tar.xz
Merge git://git.denx.de/u-boot-rockchip
This includes support for rk3188 from Heiko Stübner and and rk3328 from Kever Yang. Also included is SPL support for rk3399 and a fix for rk3288 to get it booting again (spl_early_init()).
-rw-r--r--arch/arm/dts/Makefile1
-rw-r--r--arch/arm/dts/rk3036-sdk.dts2
-rw-r--r--arch/arm/dts/rk3036.dtsi13
-rw-r--r--arch/arm/dts/rk3188.dtsi601
-rw-r--r--arch/arm/dts/rk3288-evb.dtsi22
-rw-r--r--arch/arm/dts/rk3288-popmetal.dtsi2
-rw-r--r--arch/arm/dts/rk3288-tinker.dts11
-rw-r--r--arch/arm/dts/rk3288-tinker.dtsi14
-rw-r--r--arch/arm/dts/rk3328-evb.dts45
-rw-r--r--arch/arm/dts/rk3328.dtsi1477
-rw-r--r--arch/arm/dts/rk3399-evb.dts2
-rw-r--r--arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi1536
-rw-r--r--arch/arm/dts/rk3399.dtsi46
-rw-r--r--arch/arm/dts/rk3xxx.dtsi417
-rw-r--r--arch/arm/include/asm/arch-rockchip/bootrom.h22
-rw-r--r--arch/arm/include/asm/arch-rockchip/clock.h9
-rw-r--r--arch/arm/include/asm/arch-rockchip/cru_rk3188.h191
-rw-r--r--arch/arm/include/asm/arch-rockchip/cru_rk3328.h70
-rw-r--r--arch/arm/include/asm/arch-rockchip/cru_rk3399.h5
-rw-r--r--arch/arm/include/asm/arch-rockchip/ddr_rk3188.h25
-rw-r--r--arch/arm/include/asm/arch-rockchip/ddr_rk3288.h8
-rw-r--r--arch/arm/include/asm/arch-rockchip/grf_rk3188.h589
-rw-r--r--arch/arm/include/asm/arch-rockchip/grf_rk3328.h134
-rw-r--r--arch/arm/include/asm/arch-rockchip/grf_rk3399.h118
-rw-r--r--arch/arm/include/asm/arch-rockchip/pmu_rk3188.h36
-rw-r--r--arch/arm/include/asm/arch-rockchip/sdram_rk3399.h119
-rw-r--r--arch/arm/mach-rockchip/Kconfig34
-rw-r--r--arch/arm/mach-rockchip/Makefile16
-rw-r--r--arch/arm/mach-rockchip/rk3036-board-spl.c3
-rw-r--r--arch/arm/mach-rockchip/rk3188-board-spl.c218
-rw-r--r--arch/arm/mach-rockchip/rk3188-board-tpl.c86
-rw-r--r--arch/arm/mach-rockchip/rk3188-board.c71
-rw-r--r--arch/arm/mach-rockchip/rk3188/Kconfig24
-rw-r--r--arch/arm/mach-rockchip/rk3188/Makefile11
-rw-r--r--arch/arm/mach-rockchip/rk3188/clk_rk3188.c33
-rw-r--r--arch/arm/mach-rockchip/rk3188/sdram_rk3188.c995
-rw-r--r--arch/arm/mach-rockchip/rk3188/syscon_rk3188.c55
-rw-r--r--arch/arm/mach-rockchip/rk3288-board-spl.c7
-rw-r--r--arch/arm/mach-rockchip/rk3288/sdram_rk3288.c59
-rw-r--r--arch/arm/mach-rockchip/rk3328/Kconfig23
-rw-r--r--arch/arm/mach-rockchip/rk3328/Makefile9
-rw-r--r--arch/arm/mach-rockchip/rk3328/clk_rk3328.c31
-rw-r--r--arch/arm/mach-rockchip/rk3328/rk3328.c39
-rw-r--r--arch/arm/mach-rockchip/rk3328/syscon_rk3328.c20
-rw-r--r--arch/arm/mach-rockchip/rk3399-board-spl.c158
-rw-r--r--arch/arm/mach-rockchip/rk3399/Makefile1
-rw-r--r--arch/arm/mach-rockchip/rk3399/clk_rk3399.c21
-rw-r--r--arch/arm/mach-rockchip/rk3399/rk3399.c1
-rw-r--r--arch/arm/mach-rockchip/rk3399/sdram_rk3399.c1321
-rw-r--r--arch/arm/mach-rockchip/rk3399/syscon_rk3399.c40
-rw-r--r--board/rockchip/evb_rk3328/Kconfig15
-rw-r--r--board/rockchip/evb_rk3328/MAINTAINERS6
-rw-r--r--board/rockchip/evb_rk3328/Makefile7
-rw-r--r--board/rockchip/evb_rk3328/README70
-rw-r--r--board/rockchip/evb_rk3328/evb-rk3328.c40
-rw-r--r--common/spl/spl.c46
-rw-r--r--configs/evb-rk3288_defconfig5
-rw-r--r--configs/evb-rk3328_defconfig36
-rw-r--r--configs/evb-rk3399_defconfig19
-rw-r--r--configs/fennec-rk3288_defconfig8
-rw-r--r--configs/firefly-rk3288_defconfig4
-rw-r--r--configs/popmetal-rk3288_defconfig4
-rw-r--r--configs/tinker-rk3288_defconfig7
-rw-r--r--doc/device-tree-bindings/clock/rockchip,rk3399-dmc.txt42
-rw-r--r--doc/driver-model/README.txt4
-rw-r--r--drivers/clk/at91/pmc.c3
-rw-r--r--drivers/clk/rockchip/Makefile2
-rw-r--r--drivers/clk/rockchip/clk_rk3188.c527
-rw-r--r--drivers/clk/rockchip/clk_rk3288.c2
-rw-r--r--drivers/clk/rockchip/clk_rk3328.c581
-rw-r--r--drivers/clk/rockchip/clk_rk3399.c91
-rw-r--r--drivers/core/root.c2
-rw-r--r--drivers/core/util.c25
-rw-r--r--drivers/mmc/rockchip_sdhci.c17
-rw-r--r--drivers/pinctrl/Kconfig18
-rw-r--r--drivers/pinctrl/pinctrl-uclass.c3
-rw-r--r--drivers/pinctrl/rockchip/Makefile2
-rw-r--r--drivers/pinctrl/rockchip/pinctrl_rk3188.c611
-rw-r--r--drivers/pinctrl/rockchip/pinctrl_rk3328.c419
-rw-r--r--drivers/pinctrl/rockchip/pinctrl_rk3399.c111
-rw-r--r--drivers/serial/serial_rockchip.c19
-rw-r--r--drivers/sysreset/Makefile2
-rw-r--r--drivers/sysreset/sysreset_rk3188.c47
-rw-r--r--drivers/sysreset/sysreset_rk3328.c45
-rw-r--r--drivers/video/rockchip/rk_hdmi.c71
-rw-r--r--include/asm-generic/global_data.h1
-rw-r--r--include/configs/evb_rk3328.h26
-rw-r--r--include/configs/rk3188_common.h120
-rw-r--r--include/configs/rk3328_common.h65
-rw-r--r--include/configs/rk3399_common.h11
-rw-r--r--include/configs/tinker_rk3288.h2
-rw-r--r--include/dm/util.h26
-rw-r--r--include/dt-bindings/clock/rk3066a-cru.h32
-rw-r--r--include/dt-bindings/clock/rk3188-cru-common.h256
-rw-r--r--include/dt-bindings/clock/rk3188-cru.h48
-rw-r--r--include/dt-bindings/clock/rk3328-cru.h394
-rw-r--r--include/dt-bindings/clock/rk3399-cru.h16
-rw-r--r--include/dt-bindings/pinctrl/rockchip.h2
-rw-r--r--include/spl.h24
-rw-r--r--scripts/Makefile.spl7
-rwxr-xr-xtools/dtoc/dtoc.py2
-rw-r--r--tools/rkcommon.c34
-rw-r--r--tools/rkcommon.h22
-rw-r--r--tools/rkimage.c3
-rw-r--r--tools/rksd.c4
-rw-r--r--tools/rkspi.c4
106 files changed, 12558 insertions, 243 deletions
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 231ebfa..d00651c 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -38,6 +38,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
rk3288-fennec.dtb \
rk3288-tinker.dtb \
rk3288-popmetal.dtb \
+ rk3328-evb.dtb \
rk3399-evb.dtb
dtb-$(CONFIG_ARCH_MESON) += \
meson-gxbb-odroidc2.dtb
diff --git a/arch/arm/dts/rk3036-sdk.dts b/arch/arm/dts/rk3036-sdk.dts
index bdc7b98..6754625 100644
--- a/arch/arm/dts/rk3036-sdk.dts
+++ b/arch/arm/dts/rk3036-sdk.dts
@@ -51,10 +51,12 @@
};
&usb_host {
+ vbus-supply = <&vcc5v0_host>;
status = "okay";
};
&usb_otg {
+ vbus-supply = <&vcc5v0_otg>;
status = "okay";
};
diff --git a/arch/arm/dts/rk3036.dtsi b/arch/arm/dts/rk3036.dtsi
index ecf5416..4f44217 100644
--- a/arch/arm/dts/rk3036.dtsi
+++ b/arch/arm/dts/rk3036.dtsi
@@ -23,6 +23,7 @@
serial1 = &uart1;
serial2 = &uart2;
mmc0 = &emmc;
+ mmc1 = &sdmmc;
};
memory {
@@ -265,6 +266,18 @@
pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
};
+ sdmmc: dwmmc@10214000 {
+ compatible = "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0x10214000 0x4000>;
+ clock-frequency = <37500000>;
+ max-frequency = <37500000>;
+ clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
pinctrl: pinctrl {
compatible = "rockchip,rk3036-pinctrl";
rockchip,grf = <&grf>;
diff --git a/arch/arm/dts/rk3188.dtsi b/arch/arm/dts/rk3188.dtsi
new file mode 100644
index 0000000..f4d438e
--- /dev/null
+++ b/arch/arm/dts/rk3188.dtsi
@@ -0,0 +1,601 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+ or X11
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/clock/rk3188-cru.h>
+#include "rk3xxx.dtsi"
+
+/ {
+ compatible = "rockchip,rk3188";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "rockchip,rk3066-smp";
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x0>;
+ operating-points = <
+ /* kHz uV */
+ 1608000 1350000
+ 1416000 1250000
+ 1200000 1150000
+ 1008000 1075000
+ 816000 975000
+ 600000 950000
+ 504000 925000
+ 312000 875000
+ >;
+ clock-latency = <40000>;
+ clocks = <&cru ARMCLK>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x1>;
+ };
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x2>;
+ };
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x3>;
+ };
+ };
+
+ sram: sram@10080000 {
+ compatible = "mmio-sram";
+ reg = <0x10080000 0x8000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x10080000 0x8000>;
+
+ smp-sram@0 {
+ compatible = "rockchip,rk3066-smp-sram";
+ reg = <0x0 0x50>;
+ };
+ };
+
+ i2s0: i2s@1011a000 {
+ compatible = "rockchip,rk3188-i2s", "rockchip,rk3066-i2s";
+ reg = <0x1011a000 0x2000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_bus>;
+ dmas = <&dmac1_s 6>, <&dmac1_s 7>;
+ dma-names = "tx", "rx";
+ clock-names = "i2s_hclk", "i2s_clk";
+ clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>;
+ rockchip,playback-channels = <2>;
+ rockchip,capture-channels = <2>;
+ status = "disabled";
+ };
+
+ spdif: sound@1011e000 {
+ compatible = "rockchip,rk3188-spdif", "rockchip,rk3066-spdif";
+ reg = <0x1011e000 0x2000>;
+ #sound-dai-cells = <0>;
+ clock-names = "hclk", "mclk";
+ clocks = <&cru HCLK_SPDIF>, <&cru SCLK_SPDIF>;
+ dmas = <&dmac1_s 8>;
+ dma-names = "tx";
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spdif_tx>;
+ status = "disabled";
+ };
+
+ cru: clock-controller@20000000 {
+ compatible = "rockchip,rk3188-cru";
+ reg = <0x20000000 0x1000>;
+ rockchip,grf = <&grf>;
+ u-boot,dm-spl;
+
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ efuse: efuse@20010000 {
+ compatible = "rockchip,rockchip-efuse";
+ reg = <0x20010000 0x4000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cru PCLK_EFUSE>;
+ clock-names = "pclk_efuse";
+
+ cpu_leakage: cpu_leakage@17 {
+ reg = <0x17 0x1>;
+ };
+ };
+
+ usbphy: phy {
+ compatible = "rockchip,rk3188-usb-phy", "rockchip,rk3288-usb-phy";
+ rockchip,grf = <&grf>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ usbphy0: usb-phy@10c {
+ #phy-cells = <0>;
+ reg = <0x10c>;
+ clocks = <&cru SCLK_OTGPHY0>;
+ clock-names = "phyclk";
+ #clock-cells = <0>;
+ };
+
+ usbphy1: usb-phy@11c {
+ #phy-cells = <0>;
+ reg = <0x11c>;
+ clocks = <&cru SCLK_OTGPHY1>;
+ clock-names = "phyclk";
+ #clock-cells = <0>;
+ };
+ };
+
+ pinctrl: pinctrl {
+ compatible = "rockchip,rk3188-pinctrl";
+ rockchip,grf = <&grf>;
+ rockchip,pmu = <&pmu>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ u-boot,dm-spl;
+
+ gpio0: gpio0@2000a000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x2000a000 0x100>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio1@2003c000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x2003c000 0x100>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO1>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio2@2003e000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x2003e000 0x100>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO2>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio3@20080000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20080000 0x100>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO3>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pcfg_pull_up: pcfg_pull_up {
+ bias-pull-up;
+ };
+
+ pcfg_pull_down: pcfg_pull_down {
+ bias-pull-down;
+ };
+
+ pcfg_pull_none: pcfg_pull_none {
+ bias-disable;
+ };
+
+ emmc {
+ emmc_clk: emmc-clk {
+ rockchip,pins = <RK_GPIO0 24 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ emmc_cmd: emmc-cmd {
+ rockchip,pins = <RK_GPIO0 26 RK_FUNC_2 &pcfg_pull_up>;
+ };
+
+ emmc_rst: emmc-rst {
+ rockchip,pins = <RK_GPIO0 27 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ /*
+ * The data pins are shared between nandc and emmc and
+ * not accessible through pinctrl. Also they should've
+ * been already set correctly by firmware, as
+ * flash/emmc is the boot-device.
+ */
+ };
+
+ emac {
+ emac_xfer: emac-xfer {
+ rockchip,pins = <RK_GPIO3 16 RK_FUNC_2 &pcfg_pull_none>, /* tx_en */
+ <RK_GPIO3 17 RK_FUNC_2 &pcfg_pull_none>, /* txd1 */
+ <RK_GPIO3 18 RK_FUNC_2 &pcfg_pull_none>, /* txd0 */
+ <RK_GPIO3 19 RK_FUNC_2 &pcfg_pull_none>, /* rxd0 */
+ <RK_GPIO3 20 RK_FUNC_2 &pcfg_pull_none>, /* rxd1 */
+ <RK_GPIO3 21 RK_FUNC_2 &pcfg_pull_none>, /* mac_clk */
+ <RK_GPIO3 22 RK_FUNC_2 &pcfg_pull_none>, /* rx_err */
+ <RK_GPIO3 23 RK_FUNC_2 &pcfg_pull_none>; /* crs_dvalid */
+ };
+
+ emac_mdio: emac-mdio {
+ rockchip,pins = <RK_GPIO3 24 RK_FUNC_2 &pcfg_pull_none>,
+ <RK_GPIO3 25 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ i2c0 {
+ i2c0_xfer: i2c0-xfer {
+ rockchip,pins = <RK_GPIO1 24 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 25 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c1 {
+ i2c1_xfer: i2c1-xfer {
+ rockchip,pins = <RK_GPIO1 26 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 27 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c2 {
+ i2c2_xfer: i2c2-xfer {
+ rockchip,pins = <RK_GPIO1 28 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 29 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c3 {
+ i2c3_xfer: i2c3-xfer {
+ rockchip,pins = <RK_GPIO3 14 RK_FUNC_2 &pcfg_pull_none>,
+ <RK_GPIO3 15 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ i2c4 {
+ i2c4_xfer: i2c4-xfer {
+ rockchip,pins = <RK_GPIO1 30 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 31 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm0 {
+ pwm0_out: pwm0-out {
+ rockchip,pins = <RK_GPIO3 27 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm1 {
+ pwm1_out: pwm1-out {
+ rockchip,pins = <RK_GPIO3 28 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm2 {
+ pwm2_out: pwm2-out {
+ rockchip,pins = <RK_GPIO3 29 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm3 {
+ pwm3_out: pwm3-out {
+ rockchip,pins = <RK_GPIO3 30 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ spi0 {
+ spi0_clk: spi0-clk {
+ rockchip,pins = <RK_GPIO1 6 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi0_cs0: spi0-cs0 {
+ rockchip,pins = <RK_GPIO1 7 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi0_tx: spi0-tx {
+ rockchip,pins = <RK_GPIO1 5 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi0_rx: spi0-rx {
+ rockchip,pins = <RK_GPIO1 4 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi0_cs1: spi0-cs1 {
+ rockchip,pins = <RK_GPIO1 15 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ };
+
+ spi1 {
+ spi1_clk: spi1-clk {
+ rockchip,pins = <RK_GPIO0 30 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi1_cs0: spi1-cs0 {
+ rockchip,pins = <RK_GPIO0 31 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi1_rx: spi1-rx {
+ rockchip,pins = <RK_GPIO0 28 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi1_tx: spi1-tx {
+ rockchip,pins = <RK_GPIO0 29 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi1_cs1: spi1-cs1 {
+ rockchip,pins = <RK_GPIO1 14 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ };
+
+ uart0 {
+ uart0_xfer: uart0-xfer {
+ rockchip,pins = <RK_GPIO1 0 RK_FUNC_1 &pcfg_pull_up>,
+ <RK_GPIO1 1 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_cts: uart0-cts {
+ rockchip,pins = <RK_GPIO1 2 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_rts: uart0-rts {
+ rockchip,pins = <RK_GPIO1 3 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart1 {
+ uart1_xfer: uart1-xfer {
+ rockchip,pins = <RK_GPIO1 4 RK_FUNC_1 &pcfg_pull_up>,
+ <RK_GPIO1 5 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart1_cts: uart1-cts {
+ rockchip,pins = <RK_GPIO1 6 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart1_rts: uart1-rts {
+ rockchip,pins = <RK_GPIO1 7 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart2 {
+ uart2_xfer: uart2-xfer {
+ rockchip,pins = <RK_GPIO1 8 RK_FUNC_1 &pcfg_pull_up>,
+ <RK_GPIO1 9 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ /* no rts / cts for uart2 */
+ };
+
+ uart3 {
+ uart3_xfer: uart3-xfer {
+ rockchip,pins = <RK_GPIO1 10 RK_FUNC_1 &pcfg_pull_up>,
+ <RK_GPIO1 11 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart3_cts: uart3-cts {
+ rockchip,pins = <RK_GPIO1 12 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart3_rts: uart3-rts {
+ rockchip,pins = <RK_GPIO1 13 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ sd0 {
+ sd0_clk: sd0-clk {
+ rockchip,pins = <RK_GPIO3 2 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ rockchip,pins = <RK_GPIO3 3 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_cd: sd0-cd {
+ rockchip,pins = <RK_GPIO3 8 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_wp: sd0-wp {
+ rockchip,pins = <RK_GPIO3 9 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_pwr: sd0-pwr {
+ rockchip,pins = <RK_GPIO3 1 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_bus1: sd0-bus-width1 {
+ rockchip,pins = <RK_GPIO3 4 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_bus4: sd0-bus-width4 {
+ rockchip,pins = <RK_GPIO3 4 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 5 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 6 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 7 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ sd1 {
+ sd1_clk: sd1-clk {
+ rockchip,pins = <RK_GPIO3 21 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ rockchip,pins = <RK_GPIO3 16 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd1_cd: sd1-cd {
+ rockchip,pins = <RK_GPIO3 22 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd1_wp: sd1-wp {
+ rockchip,pins = <RK_GPIO3 23 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 18 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 19 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 20 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2s0 {
+ i2s0_bus: i2s0-bus {
+ rockchip,pins = <RK_GPIO1 16 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 17 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 18 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 19 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 20 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 21 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ spdif {
+ spdif_tx: spdif-tx {
+ rockchip,pins = <RK_GPIO1 14 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+ };
+};
+
+&emac {
+ compatible = "rockchip,rk3188-emac";
+};
+
+&global_timer {
+ interrupts = <GIC_PPI 11 0xf04>;
+};
+
+&grf {
+ compatible = "rockchip,rk3188-grf", "syscon";
+};
+
+&local_timer {
+ interrupts = <GIC_PPI 13 0xf04>;
+};
+
+&i2c0 {
+ compatible = "rockchip,rk3188-i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_xfer>;
+};
+
+&i2c1 {
+ compatible = "rockchip,rk3188-i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_xfer>;
+};
+
+&i2c2 {
+ compatible = "rockchip,rk3188-i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_xfer>;
+};
+
+&i2c3 {
+ compatible = "rockchip,rk3188-i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_xfer>;
+};
+
+&i2c4 {
+ compatible = "rockchip,rk3188-i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_xfer>;
+};
+
+&pmu {
+ compatible = "rockchip,rk3188-pmu", "syscon";
+};
+
+&pwm0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_out>;
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm1_out>;
+};
+
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm2_out>;
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_out>;
+};
+
+&spi0 {
+ compatible = "rockchip,rk3188-spi", "rockchip,rk3066-spi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>;
+};
+
+&spi1 {
+ compatible = "rockchip,rk3188-spi", "rockchip,rk3066-spi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>;
+};
+
+&uart0 {
+ compatible = "rockchip,rk3188-uart", "snps,dw-apb-uart";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer>;
+};
+
+&uart1 {
+ compatible = "rockchip,rk3188-uart", "snps,dw-apb-uart";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_xfer>;
+};
+
+&uart2 {
+ compatible = "rockchip,rk3188-uart", "snps,dw-apb-uart";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_xfer>;
+};
+
+&uart3 {
+ compatible = "rockchip,rk3188-uart", "snps,dw-apb-uart";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_xfer>;
+};
+
+&wdt {
+ compatible = "rockchip,rk3188-wdt", "snps,dw-wdt";
+};
diff --git a/arch/arm/dts/rk3288-evb.dtsi b/arch/arm/dts/rk3288-evb.dtsi
index cb7d03e..4960f33 100644
--- a/arch/arm/dts/rk3288-evb.dtsi
+++ b/arch/arm/dts/rk3288-evb.dtsi
@@ -11,6 +11,13 @@
reg = <0 0x80000000>;
};
+ ext_gmac: external-gmac-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <125000000>;
+ clock-output-names = "ext_gmac";
+ };
+
keys: gpio-keys {
compatible = "gpio-keys";
#address-cells = <1>;
@@ -98,6 +105,21 @@
status = "okay";
};
+&gmac {
+ phy-mode = "rgmii";
+ clock_in_out = "input";
+ snps,reset-gpio = <&gpio4 7 0>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 1000000>;
+ assigned-clocks = <&cru SCLK_MAC>;
+ assigned-clock-parents = <&ext_gmac>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins>;
+ tx_delay = <0x30>;
+ rx_delay = <0x10>;
+ status = "okay";
+};
+
&hdmi {
ddc-i2c-bus = <&i2c5>;
status = "okay";
diff --git a/arch/arm/dts/rk3288-popmetal.dtsi b/arch/arm/dts/rk3288-popmetal.dtsi
index e5be4cb..dd6ce8b 100644
--- a/arch/arm/dts/rk3288-popmetal.dtsi
+++ b/arch/arm/dts/rk3288-popmetal.dtsi
@@ -203,7 +203,7 @@
pinctrl-0 = <&rgmii_pins>;
tx_delay = <0x30>;
rx_delay = <0x10>;
- status = "ok";
+ status = "okay";
};
&hdmi {
diff --git a/arch/arm/dts/rk3288-tinker.dts b/arch/arm/dts/rk3288-tinker.dts
index c0550970..22881cb 100644
--- a/arch/arm/dts/rk3288-tinker.dts
+++ b/arch/arm/dts/rk3288-tinker.dts
@@ -30,6 +30,12 @@
&pinctrl {
u-boot,dm-pre-reloc;
+
+ usb {
+ host_vbus_drv: host-vbus-drv {
+ rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
};
&pwm1 {
@@ -41,6 +47,11 @@
reg-shift = <2>;
};
+&usb_host1 {
+ vbus-supply = <&vcc5v0_host>;
+ status = "okay";
+};
+
&sdmmc {
u-boot,dm-pre-reloc;
};
diff --git a/arch/arm/dts/rk3288-tinker.dtsi b/arch/arm/dts/rk3288-tinker.dtsi
index ceb4e2b..a752458 100644
--- a/arch/arm/dts/rk3288-tinker.dtsi
+++ b/arch/arm/dts/rk3288-tinker.dtsi
@@ -110,6 +110,18 @@
startup-delay-us = <100000>;
vin-supply = <&vcc_io>;
};
+
+ vcc5v0_host: usb-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&host_vbus_drv>;
+ regulator-name = "vcc5v0_host";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
};
&cpu0 {
@@ -149,7 +161,7 @@
pinctrl-0 = <&rgmii_pins>;
tx_delay = <0x30>;
rx_delay = <0x10>;
- status = "ok";
+ status = "okay";
};
&hdmi {
diff --git a/arch/arm/dts/rk3328-evb.dts b/arch/arm/dts/rk3328-evb.dts
new file mode 100644
index 0000000..01794ed
--- /dev/null
+++ b/arch/arm/dts/rk3328-evb.dts
@@ -0,0 +1,45 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/dts-v1/;
+#include "rk3328.dtsi"
+
+/ {
+ model = "Rockchip RK3328 EVB";
+ compatible = "rockchip,rk3328-evb", "rockchip,rk3328";
+
+ chosen {
+ stdout-path = &uart2;
+ };
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ disable-wp;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>;
+ status = "okay";
+};
+
+&emmc {
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ supports-emmc;
+ disable-wp;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
+ status = "okay";
+};
diff --git a/arch/arm/dts/rk3328.dtsi b/arch/arm/dts/rk3328.dtsi
new file mode 100644
index 0000000..8a98ee3
--- /dev/null
+++ b/arch/arm/dts/rk3328.dtsi
@@ -0,0 +1,1477 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <dt-bindings/clock/rk3328-cru.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+
+/ {
+ compatible = "rockchip,rk3328";
+
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ };
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+// clocks = <&cru ARMCLK>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ };
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x1>;
+ enable-method = "psci";
+ };
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x2>;
+ enable-method = "psci";
+ };
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x3>;
+ enable-method = "psci";
+ };
+ };
+
+ cpu0_opp_table: opp_table0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp@408000000 {
+ opp-hz = /bits/ 64 <408000000>;
+ opp-microvolt = <950000>;
+ clock-latency-ns = <40000>;
+ opp-suspend;
+ };
+ opp@600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <950000>;
+ clock-latency-ns = <40000>;
+ };
+ opp@816000000 {
+ opp-hz = /bits/ 64 <816000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <40000>;
+ };
+ opp@1008000000 {
+ opp-hz = /bits/ 64 <1008000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <40000>;
+ };
+ opp@1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <1225000>;
+ clock-latency-ns = <40000>;
+ };
+ opp@1296000000 {
+ opp-hz = /bits/ 64 <1296000000>;
+ opp-microvolt = <1300000>;
+ clock-latency-ns = <40000>;
+ };
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a53-pmu";
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ xin24m: xin24m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "xin24m";
+ };
+
+ i2s0: i2s@ff000000 {
+ compatible = "rockchip,rk3328-i2s", "rockchip,rk3066-i2s";
+ reg = <0x0 0xff000000 0x0 0x1000>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_I2S0>, <&cru HCLK_I2S0_8CH>;
+ clock-names = "i2s_clk", "i2s_hclk";
+ dmas = <&dmac 11>, <&dmac 12>;
+ #dma-cells = <2>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ i2s1: i2s@ff010000 {
+ compatible = "rockchip,rk3328-i2s", "rockchip,rk3066-i2s";
+ reg = <0x0 0xff010000 0x0 0x1000>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S1_8CH>;
+ clock-names = "i2s_clk", "i2s_hclk";
+ dmas = <&dmac 14>, <&dmac 15>;
+ #dma-cells = <2>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ i2s2: i2s@ff020000 {
+ compatible = "rockchip,rk3328-i2s", "rockchip,rk3066-i2s";
+ reg = <0x0 0xff020000 0x0 0x1000>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_I2S2>, <&cru HCLK_I2S2_2CH>;
+ clock-names = "i2s_clk", "i2s_hclk";
+ dmas = <&dmac 0>, <&dmac 1>;
+ #dma-cells = <2>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2s2m0_mclk
+ &i2s2m0_sclk
+ &i2s2m0_lrcktx
+ &i2s2m0_lrckrx
+ &i2s2m0_sdo
+ &i2s2m0_sdi>;
+ pinctrl-1 = <&i2s2m0_sleep>;
+ status = "disabled";
+ };
+
+ spdif: spdif@ff030000 {
+ compatible = "rockchip,rk3328-spdif";
+ reg = <0x0 0xff030000 0x0 0x1000>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_SPDIF>, <&cru HCLK_SPDIF_8CH>;
+ clock-names = "mclk", "hclk";
+ dmas = <&dmac 10>;
+ #dma-cells = <1>;
+ dma-names = "tx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spdifm2_tx>;
+ status = "disabled";
+ };
+
+ grf: syscon@ff100000 {
+ compatible = "rockchip,rk3328-grf", "syscon", "simple-mfd";
+ reg = <0x0 0xff100000 0x0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ io_domains: io-domains {
+ compatible = "rockchip,rk3328-io-voltage-domain";
+ status = "disabled";
+ };
+ };
+
+ uart0: serial@ff110000 {
+ compatible = "rockchip,rk3328-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xff110000 0x0 0x100>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+ clock-names = "baudclk", "apb_pclk";
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ dmas = <&dmac 2>, <&dmac 3>;
+ #dma-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+ status = "disabled";
+ };
+
+ uart1: serial@ff120000 {
+ compatible = "rockchip,rk3328-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xff120000 0x0 0x100>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+ clock-names = "sclk_uart", "pclk_uart";
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ dmas = <&dmac 4>, <&dmac 5>;
+ #dma-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_xfer &uart1_cts &uart1_rts>;
+ status = "disabled";
+ };
+
+ uart2: serial@ff130000 {
+ compatible = "rockchip,rk3328-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xff130000 0x0 0x100>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+ clock-names = "baudclk", "apb_pclk";
+ clock-frequency = <24000000>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ dmas = <&dmac 6>, <&dmac 7>;
+ #dma-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2m1_xfer>;
+ status = "disabled";
+ };
+
+ pmu: power-management@ff140000 {
+ compatible = "rockchip,rk3328-pmu", "syscon", "simple-mfd";
+ reg = <0x0 0xff140000 0x0 0x1000>;
+ };
+
+ i2c0: i2c@ff150000 {
+ compatible = "rockchip,rk3328-i2c";
+ reg = <0x0 0xff150000 0x0 0x1000>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cru SCLK_I2C0>, <&cru PCLK_I2C0>;
+ clock-names = "i2c", "pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_xfer>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@ff160000 {
+ compatible = "rockchip,rk3328-i2c";
+ reg = <0x0 0xff160000 0x0 0x1000>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cru SCLK_I2C1>, <&cru PCLK_I2C1>;
+ clock-names = "i2c", "pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_xfer>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@ff170000 {
+ compatible = "rockchip,rk3328-i2c";
+ reg = <0x0 0xff170000 0x0 0x1000>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cru SCLK_I2C2>, <&cru PCLK_I2C2>;
+ clock-names = "i2c", "pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_xfer>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@ff180000 {
+ compatible = "rockchip,rk3328-i2c";
+ reg = <0x0 0xff180000 0x0 0x1000>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cru SCLK_I2C3>, <&cru PCLK_I2C3>;
+ clock-names = "i2c", "pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_xfer>;
+ status = "disabled";
+ };
+
+ spi0: spi@ff190000 {
+ compatible = "rockchip,rk3328-spi", "rockchip,rk3066-spi";
+ reg = <0x0 0xff190000 0x0 0x1000>;
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cru SCLK_SPI>, <&cru PCLK_SPI>;
+ clock-names = "spiclk", "apb_pclk";
+ dmas = <&dmac 8>, <&dmac 9>;
+ #dma-cells = <2>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0m2_clk &spi0m2_tx &spi0m2_rx &spi0m2_cs0>;
+ status = "disabled";
+ };
+
+ wdt: watchdog@ff1a0000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x0 0xff1a0000 0x0 0x100>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ amba {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ dmac: dmac@ff1f0000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x0 0xff1f0000 0x0 0x4000>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_DMAC>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ };
+ };
+
+ saradc: saradc@ff280000 {
+ compatible = "rockchip,rk3328-saradc", "rockchip,saradc";
+ reg = <0x0 0xff280000 0x0 0x100>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ #io-channel-cells = <1>;
+ clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
+ clock-names = "saradc", "apb_pclk";
+ resets = <&cru SRST_SARADC_P>;
+ reset-names = "saradc-apb";
+ status = "disabled";
+ };
+
+ cru: clock-controller@ff440000 {
+ compatible = "rockchip,rk3328-cru", "rockchip,cru", "syscon";
+ reg = <0x0 0xff440000 0x0 0x1000>;
+ rockchip,grf = <&grf>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ assigned-clocks =
+ <&cru DCLK_LCDC>, <&cru SCLK_PDM>,
+ <&cru SCLK_RTC32K>, <&cru SCLK_UART0>,
+ <&cru SCLK_UART1>, <&cru SCLK_UART2>,
+ <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>,
+ <&cru ACLK_VIO_PRE>, <&cru ACLK_RGA_PRE>,
+ <&cru ACLK_VOP_PRE>, <&cru ACLK_RKVDEC_PRE>,
+ <&cru ACLK_RKVENC>, <&cru ACLK_VPU_PRE>,
+ <&cru SCLK_VDEC_CABAC>, <&cru SCLK_VDEC_CORE>,
+ <&cru SCLK_VENC_CORE>, <&cru SCLK_VENC_DSP>,
+ <&cru SCLK_SDIO>, <&cru SCLK_TSP>,
+ <&cru SCLK_WIFI>, <&cru ARMCLK>,
+ <&cru PLL_GPLL>, <&cru PLL_CPLL>,
+ <&cru ACLK_BUS_PRE>, <&cru HCLK_BUS_PRE>,
+ <&cru PCLK_BUS_PRE>, <&cru ACLK_PERI_PRE>,
+ <&cru HCLK_PERI>, <&cru PCLK_PERI>,
+ <&cru ACLK_VIO_PRE>, <&cru HCLK_VIO_PRE>,
+ <&cru ACLK_RGA_PRE>, <&cru SCLK_RGA>,
+ <&cru ACLK_VOP_PRE>, <&cru ACLK_RKVDEC_PRE>,
+ <&cru ACLK_RKVENC>, <&cru ACLK_VPU_PRE>,
+ <&cru SCLK_VDEC_CABAC>, <&cru SCLK_VDEC_CORE>,
+ <&cru SCLK_VENC_CORE>, <&cru SCLK_VENC_DSP>,
+ <&cru SCLK_EFUSE>, <&cru PCLK_DDR>,
+ <&cru ACLK_GMAC>, <&cru PCLK_GMAC>,
+ <&cru SCLK_RTC32K>, <&cru SCLK_USB3OTG_SUSPEND>;
+ assigned-clock-parents =
+ <&cru HDMIPHY>, <&cru PLL_APLL>,
+ <&cru PLL_GPLL>, <&xin24m>,
+ <&xin24m>, <&xin24m>;
+ assigned-clock-rates =
+ <0>, <61440000>,
+ <0>, <24000000>,
+ <24000000>, <24000000>,
+ <15000000>, <15000000>,
+ <100000000>, <100000000>,
+ <100000000>, <100000000>,
+ <50000000>, <100000000>,
+ <100000000>, <100000000>,
+ <50000000>, <50000000>,
+ <50000000>, <50000000>,
+ <24000000>, <600000000>,
+ <491520000>, <1200000000>,
+ <150000000>, <75000000>,
+ <75000000>, <150000000>,
+ <75000000>, <75000000>,
+ <300000000>, <100000000>,
+ <300000000>, <200000000>,
+ <400000000>, <500000000>,
+ <200000000>, <300000000>,
+ <300000000>, <250000000>,
+ <200000000>, <100000000>,
+ <24000000>, <100000000>,
+ <150000000>, <50000000>,
+ <32768>, <32768>;
+ };
+
+ sdmmc: rksdmmc@ff500000 {
+ compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0x0 0xff500000 0x0 0x4000>;
+ clock-freq-min-max = <400000 150000000>;
+ clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ sdio: dwmmc@ff510000 {
+ compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0x0 0xff510000 0x0 0x4000>;
+ clock-freq-min-max = <400000 150000000>;
+ clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
+ <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ emmc: rksdmmc@ff520000 {
+ compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0x0 0xff520000 0x0 0x4000>;
+ clock-freq-min-max = <400000 150000000>;
+ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ sdmmc_ext: rksdmmc@ff5f0000 {
+ compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0x0 0xff5f0000 0x0 0x4000>;
+ clock-freq-min-max = <400000 150000000>;
+ clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@ffb70000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x0 0xff811000 0 0x1000>,
+ <0x0 0xff812000 0 0x2000>,
+ <0x0 0xff814000 0 0x2000>,
+ <0x0 0xff816000 0 0x2000>;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ pinctrl: pinctrl {
+ compatible = "rockchip,rk3328-pinctrl";
+ rockchip,grf = <&grf>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gpio0: gpio0@ff210000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x0 0xff210000 0x0 0x100>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio1@ff220000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x0 0xff220000 0x0 0x100>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO1>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio2@ff230000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x0 0xff230000 0x0 0x100>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO2>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio3@ff240000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x0 0xff240000 0x0 0x100>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO3>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pcfg_pull_up: pcfg-pull-up {
+ bias-pull-up;
+ };
+
+ pcfg_pull_down: pcfg-pull-down {
+ bias-pull-down;
+ };
+
+ pcfg_pull_none: pcfg-pull-none {
+ bias-disable;
+ };
+
+ pcfg_pull_none_2ma: pcfg-pull-none-2ma {
+ bias-disable;
+ drive-strength = <2>;
+ };
+
+ pcfg_pull_up_2ma: pcfg-pull-up-2ma {
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+
+ pcfg_pull_up_4ma: pcfg-pull-up-4ma {
+ bias-pull-up;
+ drive-strength = <4>;
+ };
+
+ pcfg_pull_none_4ma: pcfg-pull-none-4ma {
+ bias-disable;
+ drive-strength = <4>;
+ };
+
+ pcfg_pull_down_4ma: pcfg-pull-down-4ma {
+ bias-pull-down;
+ drive-strength = <4>;
+ };
+
+ pcfg_pull_none_8ma: pcfg-pull-none-8ma {
+ bias-disable;
+ drive-strength = <8>;
+ };
+
+ pcfg_pull_up_8ma: pcfg-pull-up-8ma {
+ bias-pull-up;
+ drive-strength = <8>;
+ };
+
+ pcfg_pull_none_12ma: pcfg-pull-none-12ma {
+ bias-disable;
+ drive-strength = <12>;
+ };
+
+ pcfg_pull_up_12ma: pcfg-pull-up-12ma {
+ bias-pull-up;
+ drive-strength = <12>;
+ };
+
+ pcfg_output_high: pcfg-output-high {
+ output-high;
+ };
+
+ pcfg_output_low: pcfg-output-low {
+ output-low;
+ };
+
+ pcfg_input_high: pcfg-input-high {
+ bias-pull-up;
+ input-enable;
+ };
+
+ pcfg_input: pcfg-input {
+ input-enable;
+ };
+
+ i2c0 {
+ i2c0_xfer: i2c0-xfer {
+ rockchip,pins =
+ <2 24 RK_FUNC_1 &pcfg_pull_none>,
+ <2 25 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c1 {
+ i2c1_xfer: i2c1-xfer {
+ rockchip,pins =
+ <2 4 RK_FUNC_2 &pcfg_pull_none>,
+ <2 5 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ i2c2 {
+ i2c2_xfer: i2c2-xfer {
+ rockchip,pins =
+ <2 13 RK_FUNC_1 &pcfg_pull_none>,
+ <2 14 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c3 {
+ i2c3_xfer: i2c3-xfer {
+ rockchip,pins =
+ <0 5 RK_FUNC_2 &pcfg_pull_none>,
+ <0 6 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ i2c3_gpio: i2c3-gpio {
+ rockchip,pins =
+ <0 5 RK_FUNC_GPIO &pcfg_pull_none>,
+ <0 6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ hdmi_i2c {
+ hdmii2c_xfer: hdmii2c-xfer {
+ rockchip,pins =
+ <0 5 RK_FUNC_1 &pcfg_pull_none>,
+ <0 6 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart0 {
+ uart0_xfer: uart0-xfer {
+ rockchip,pins =
+ <1 9 RK_FUNC_1 &pcfg_pull_up>,
+ <1 8 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_cts: uart0-cts {
+ rockchip,pins =
+ <1 11 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_rts: uart0-rts {
+ rockchip,pins =
+ <1 10 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_rts_gpio: uart0-rts-gpio {
+ rockchip,pins =
+ <1 10 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ uart1 {
+ uart1_xfer: uart1-xfer {
+ rockchip,pins =
+ <3 4 RK_FUNC_4 &pcfg_pull_up>,
+ <3 6 RK_FUNC_4 &pcfg_pull_none>;
+ };
+
+ uart1_cts: uart1-cts {
+ rockchip,pins =
+ <3 7 RK_FUNC_4 &pcfg_pull_none>;
+ };
+
+ uart1_rts: uart1-rts {
+ rockchip,pins =
+ <3 5 RK_FUNC_4 &pcfg_pull_none>;
+ };
+
+ uart1_rts_gpio: uart1-rts-gpio {
+ rockchip,pins =
+ <3 5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ uart2-0 {
+ uart2m0_xfer: uart2m0-xfer {
+ rockchip,pins =
+ <1 0 RK_FUNC_2 &pcfg_pull_up>,
+ <1 1 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ uart2-1 {
+ uart2m1_xfer: uart2m1-xfer {
+ rockchip,pins =
+ <2 0 RK_FUNC_1 &pcfg_pull_up>,
+ <2 1 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ spi0-0 {
+ spi0m0_clk: spi0m0-clk {
+ rockchip,pins =
+ <2 8 RK_FUNC_1 &pcfg_pull_up>;
+ };
+
+ spi0m0_cs0: spi0m0-cs0 {
+ rockchip,pins =
+ <2 11 RK_FUNC_1 &pcfg_pull_up>;
+ };
+
+ spi0m0_tx: spi0m0-tx {
+ rockchip,pins =
+ <2 9 RK_FUNC_1 &pcfg_pull_up>;
+ };
+
+ spi0m0_rx: spi0m0-rx {
+ rockchip,pins =
+ <2 10 RK_FUNC_1 &pcfg_pull_up>;
+ };
+
+ spi0m0_cs1: spi0m0-cs1 {
+ rockchip,pins =
+ <2 12 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ };
+
+ spi0-1 {
+ spi0m1_clk: spi0m1-clk {
+ rockchip,pins =
+ <3 23 RK_FUNC_2 &pcfg_pull_up>;
+ };
+
+ spi0m1_cs0: spi0m1-cs0 {
+ rockchip,pins =
+ <3 26 RK_FUNC_2 &pcfg_pull_up>;
+ };
+
+ spi0m1_tx: spi0m1-tx {
+ rockchip,pins =
+ <3 25 RK_FUNC_2 &pcfg_pull_up>;
+ };
+
+ spi0m1_rx: spi0m1-rx {
+ rockchip,pins =
+ <3 24 RK_FUNC_2 &pcfg_pull_up>;
+ };
+
+ spi0m1_cs1: spi0m1-cs1 {
+ rockchip,pins =
+ <3 27 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ };
+
+ spi0-2 {
+ spi0m2_clk: spi0m2-clk {
+ rockchip,pins =
+ <3 0 RK_FUNC_4 &pcfg_pull_up>;
+ };
+
+ spi0m2_cs0: spi0m2-cs0 {
+ rockchip,pins =
+ <3 8 RK_FUNC_3 &pcfg_pull_up>;
+ };
+
+ spi0m2_tx: spi0m2-tx {
+ rockchip,pins =
+ <3 1 RK_FUNC_4 &pcfg_pull_up>;
+ };
+
+ spi0m2_rx: spi0m2-rx {
+ rockchip,pins =
+ <3 2 RK_FUNC_4 &pcfg_pull_up>;
+ };
+ };
+
+ i2s1 {
+ i2s1_mclk: i2s1-mclk {
+ rockchip,pins =
+ <2 15 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ i2s1_sclk: i2s1-sclk {
+ rockchip,pins =
+ <2 18 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ i2s1_lrckrx: i2s1-lrckrx {
+ rockchip,pins =
+ <2 16 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ i2s1_lrcktx: i2s1-lrcktx {
+ rockchip,pins =
+ <2 17 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ i2s1_sdi: i2s1-sdi {
+ rockchip,pins =
+ <2 19 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ i2s1_sdo: i2s1-sdo {
+ rockchip,pins =
+ <2 23 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ i2s1_sdio1: i2s1-sdio1 {
+ rockchip,pins =
+ <2 20 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ i2s1_sdio2: i2s1-sdio2 {
+ rockchip,pins =
+ <2 21 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ i2s1_sdio3: i2s1-sdio3 {
+ rockchip,pins =
+ <2 22 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ i2s1_sleep: i2s1-sleep {
+ rockchip,pins =
+ <2 15 RK_FUNC_GPIO &pcfg_input_high>,
+ <2 16 RK_FUNC_GPIO &pcfg_input_high>,
+ <2 17 RK_FUNC_GPIO &pcfg_input_high>,
+ <2 18 RK_FUNC_GPIO &pcfg_input_high>,
+ <2 19 RK_FUNC_GPIO &pcfg_input_high>,
+ <2 20 RK_FUNC_GPIO &pcfg_input_high>,
+ <2 21 RK_FUNC_GPIO &pcfg_input_high>,
+ <2 22 RK_FUNC_GPIO &pcfg_input_high>,
+ <2 23 RK_FUNC_GPIO &pcfg_input_high>;
+ };
+ };
+
+ i2s2-0 {
+ i2s2m0_mclk: i2s2m0-mclk {
+ rockchip,pins =
+ <1 21 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ i2s2m0_sclk: i2s2m0-sclk {
+ rockchip,pins =
+ <1 22 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ i2s2m0_lrckrx: i2s2m0-lrckrx {
+ rockchip,pins =
+ <1 26 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ i2s2m0_lrcktx: i2s2m0-lrcktx {
+ rockchip,pins =
+ <1 23 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ i2s2m0_sdi: i2s2m0-sdi {
+ rockchip,pins =
+ <1 24 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ i2s2m0_sdo: i2s2m0-sdo {
+ rockchip,pins =
+ <1 25 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ i2s2m0_sleep: i2s2m0-sleep {
+ rockchip,pins =
+ <1 21 RK_FUNC_GPIO &pcfg_input_high>,
+ <1 22 RK_FUNC_GPIO &pcfg_input_high>,
+ <1 26 RK_FUNC_GPIO &pcfg_input_high>,
+ <1 23 RK_FUNC_GPIO &pcfg_input_high>,
+ <1 24 RK_FUNC_GPIO &pcfg_input_high>,
+ <1 25 RK_FUNC_GPIO &pcfg_input_high>;
+ };
+ };
+
+ i2s2-1 {
+ i2s2m1_mclk: i2s2m1-mclk {
+ rockchip,pins =
+ <1 21 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ i2s2m1_sclk: i2s2m1-sclk {
+ rockchip,pins =
+ <3 0 RK_FUNC_6 &pcfg_pull_none>;
+ };
+
+ i2s2m1_lrckrx: i2sm1-lrckrx {
+ rockchip,pins =
+ <3 8 RK_FUNC_6 &pcfg_pull_none>;
+ };
+
+ i2s2m1_lrcktx: i2s2m1-lrcktx {
+ rockchip,pins =
+ <3 8 RK_FUNC_4 &pcfg_pull_none>;
+ };
+
+ i2s2m1_sdi: i2s2m1-sdi {
+ rockchip,pins =
+ <3 2 RK_FUNC_6 &pcfg_pull_none>;
+ };
+
+ i2s2m1_sdo: i2s2m1-sdo {
+ rockchip,pins =
+ <3 1 RK_FUNC_6 &pcfg_pull_none>;
+ };
+
+ i2s2m1_sleep: i2s2m1-sleep {
+ rockchip,pins =
+ <1 21 RK_FUNC_GPIO &pcfg_input_high>,
+ <3 0 RK_FUNC_GPIO &pcfg_input_high>,
+ <3 8 RK_FUNC_GPIO &pcfg_input_high>,
+ <3 2 RK_FUNC_GPIO &pcfg_input_high>,
+ <3 1 RK_FUNC_GPIO &pcfg_input_high>;
+ };
+ };
+
+ spdif-0 {
+ spdifm0_tx: spdifm0-tx {
+ rockchip,pins =
+ <0 27 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ spdif-1 {
+ spdifm1_tx: spdifm1-tx {
+ rockchip,pins =
+ <2 17 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ spdif-2 {
+ spdifm2_tx: spdifm2-tx {
+ rockchip,pins =
+ <0 2 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ sdmmc0-0 {
+ sdmmc0m0_pwren: sdmmc0m0-pwren {
+ rockchip,pins =
+ <2 7 RK_FUNC_1 &pcfg_pull_up_4ma>;
+ };
+
+ sdmmc0m0_gpio: sdmmc0m0-gpio {
+ rockchip,pins =
+ <2 7 RK_FUNC_GPIO &pcfg_pull_up_4ma>;
+ };
+ };
+
+ sdmmc0-1 {
+ sdmmc0m1_pwren: sdmmc0m1-pwren {
+ rockchip,pins =
+ <0 30 RK_FUNC_3 &pcfg_pull_up_4ma>;
+ };
+
+ sdmmc0m1_gpio: sdmmc0m1-gpio {
+ rockchip,pins =
+ <0 30 RK_FUNC_GPIO &pcfg_pull_up_4ma>;
+ };
+ };
+
+ sdmmc0 {
+ sdmmc0_clk: sdmmc0-clk {
+ rockchip,pins =
+ <1 6 RK_FUNC_1 &pcfg_pull_none_4ma>;
+ };
+
+ sdmmc0_cmd: sdmmc0-cmd {
+ rockchip,pins =
+ <1 4 RK_FUNC_1 &pcfg_pull_up_4ma>;
+ };
+
+ sdmmc0_dectn: sdmmc0-dectn {
+ rockchip,pins =
+ <1 5 RK_FUNC_1 &pcfg_pull_up_4ma>;
+ };
+
+ sdmmc0_wrprt: sdmmc0-wrprt {
+ rockchip,pins =
+ <1 7 RK_FUNC_1 &pcfg_pull_up_4ma>;
+ };
+
+ sdmmc0_bus1: sdmmc0-bus1 {
+ rockchip,pins =
+ <1 0 RK_FUNC_1 &pcfg_pull_up_4ma>;
+ };
+
+ sdmmc0_bus4: sdmmc0-bus4 {
+ rockchip,pins =
+ <1 0 RK_FUNC_1 &pcfg_pull_up_4ma>,
+ <1 1 RK_FUNC_1 &pcfg_pull_up_4ma>,
+ <1 2 RK_FUNC_1 &pcfg_pull_up_4ma>,
+ <1 3 RK_FUNC_1 &pcfg_pull_up_4ma>;
+ };
+
+ sdmmc0_gpio: sdmmc0-gpio {
+ rockchip,pins =
+ <1 6 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <1 4 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <1 5 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <1 7 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <1 3 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <1 2 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <1 1 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <1 0 RK_FUNC_GPIO &pcfg_pull_up_4ma>;
+ };
+ };
+
+ sdmmc0ext {
+ sdmmc0ext_clk: sdmmc0ext-clk {
+ rockchip,pins =
+ <3 2 RK_FUNC_3 &pcfg_pull_none_4ma>;
+ };
+
+ sdmmc0ext_cmd: sdmmc0ext-cmd {
+ rockchip,pins =
+ <3 0 RK_FUNC_3 &pcfg_pull_up_4ma>;
+ };
+
+ sdmmc0ext_wrprt: sdmmc0ext-wrprt {
+ rockchip,pins =
+ <3 3 RK_FUNC_3 &pcfg_pull_up_4ma>;
+ };
+
+ sdmmc0ext_dectn: sdmmc0ext-dectn {
+ rockchip,pins =
+ <3 1 RK_FUNC_3 &pcfg_pull_up_4ma>;
+ };
+
+ sdmmc0ext_bus1: sdmmc0ext-bus1 {
+ rockchip,pins =
+ <3 4 RK_FUNC_3 &pcfg_pull_up_4ma>;
+ };
+
+ sdmmc0ext_bus4: sdmmc0ext-bus4 {
+ rockchip,pins =
+ <3 4 RK_FUNC_3 &pcfg_pull_up_4ma>,
+ <3 5 RK_FUNC_3 &pcfg_pull_up_4ma>,
+ <3 6 RK_FUNC_3 &pcfg_pull_up_4ma>,
+ <3 7 RK_FUNC_3 &pcfg_pull_up_4ma>;
+ };
+
+ sdmmc0ext_gpio: sdmmc0ext-gpio {
+ rockchip,pins =
+ <3 0 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <3 1 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <3 2 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <3 3 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <3 4 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <3 5 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <3 6 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <3 7 RK_FUNC_GPIO &pcfg_pull_up_4ma>;
+ };
+ };
+
+ sdmmc1 {
+ sdmmc1_clk: sdmmc1-clk {
+ rockchip,pins =
+ <1 12 RK_FUNC_1 &pcfg_pull_none_8ma>;
+ };
+
+ sdmmc1_cmd: sdmmc1-cmd {
+ rockchip,pins =
+ <1 13 RK_FUNC_1 &pcfg_pull_up_8ma>;
+ };
+
+ sdmmc1_pwren: sdmmc1-pwren {
+ rockchip,pins =
+ <1 18 RK_FUNC_1 &pcfg_pull_up_8ma>;
+ };
+
+ sdmmc1_wrprt: sdmmc1-wrprt {
+ rockchip,pins =
+ <1 20 RK_FUNC_1 &pcfg_pull_up_8ma>;
+ };
+
+ sdmmc1_dectn: sdmmc1-dectn {
+ rockchip,pins =
+ <1 19 RK_FUNC_1 &pcfg_pull_up_8ma>;
+ };
+
+ sdmmc1_bus1: sdmmc1-bus1 {
+ rockchip,pins =
+ <1 14 RK_FUNC_1 &pcfg_pull_up_8ma>;
+ };
+
+ sdmmc1_bus4: sdmmc1-bus4 {
+ rockchip,pins =
+ <1 12 RK_FUNC_1 &pcfg_pull_up_8ma>,
+ <1 13 RK_FUNC_1 &pcfg_pull_up_8ma>,
+ <1 16 RK_FUNC_1 &pcfg_pull_up_8ma>,
+ <1 17 RK_FUNC_1 &pcfg_pull_up_8ma>;
+ };
+
+ sdmmc1_gpio: sdmmc1-gpio {
+ rockchip,pins =
+ <1 12 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <1 13 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <1 14 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <1 15 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <1 16 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <1 17 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <1 18 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <1 19 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+ <1 20 RK_FUNC_GPIO &pcfg_pull_up_4ma>;
+ };
+ };
+
+ emmc {
+ emmc_clk: emmc-clk {
+ rockchip,pins =
+ <3 21 RK_FUNC_2 &pcfg_pull_none_12ma>;
+ };
+
+ emmc_cmd: emmc-cmd {
+ rockchip,pins =
+ <3 19 RK_FUNC_2 &pcfg_pull_up_12ma>;
+ };
+
+ emmc_pwren: emmc-pwren {
+ rockchip,pins =
+ <3 22 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ emmc_rstnout: emmc-rstnout {
+ rockchip,pins =
+ <3 20 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ emmc_bus1: emmc-bus1 {
+ rockchip,pins =
+ <0 7 RK_FUNC_2 &pcfg_pull_up_12ma>;
+ };
+
+ emmc_bus4: emmc-bus4 {
+ rockchip,pins =
+ <0 7 RK_FUNC_2 &pcfg_pull_up_12ma>,
+ <2 28 RK_FUNC_2 &pcfg_pull_up_12ma>,
+ <2 29 RK_FUNC_2 &pcfg_pull_up_12ma>,
+ <2 30 RK_FUNC_2 &pcfg_pull_up_12ma>;
+ };
+
+ emmc_bus8: emmc-bus8 {
+ rockchip,pins =
+ <0 7 RK_FUNC_2 &pcfg_pull_up_12ma>,
+ <2 28 RK_FUNC_2 &pcfg_pull_up_12ma>,
+ <2 29 RK_FUNC_2 &pcfg_pull_up_12ma>,
+ <2 30 RK_FUNC_2 &pcfg_pull_up_12ma>,
+ <2 31 RK_FUNC_2 &pcfg_pull_up_12ma>,
+ <3 16 RK_FUNC_2 &pcfg_pull_up_12ma>,
+ <3 17 RK_FUNC_2 &pcfg_pull_up_12ma>,
+ <3 18 RK_FUNC_2 &pcfg_pull_up_12ma>;
+ };
+ };
+
+ pwm0 {
+ pwm0_pin: pwm0-pin {
+ rockchip,pins =
+ <2 4 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm1 {
+ pwm1_pin: pwm1-pin {
+ rockchip,pins =
+ <2 5 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm2 {
+ pwm2_pin: pwm2-pin {
+ rockchip,pins =
+ <2 6 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwmir {
+ pwmir_pin: pwmir-pin {
+ rockchip,pins =
+ <2 2 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ gmac-0 {
+ rgmiim0_pins: rgmiim0-pins {
+ rockchip,pins =
+ /* mac_txclk */
+ <0 8 RK_FUNC_1 &pcfg_pull_none_12ma>,
+ /* mac_rxclk */
+ <0 10 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_mdio */
+ <0 11 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txen */
+ <0 12 RK_FUNC_1 &pcfg_pull_none_12ma>,
+ /* mac_clk */
+ <0 24 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_rxdv */
+ <0 25 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_mdc */
+ <0 19 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_rxd1 */
+ <0 14 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_rxd0 */
+ <0 15 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txd1 */
+ <0 16 RK_FUNC_1 &pcfg_pull_none_12ma>,
+ /* mac_txd0 */
+ <0 17 RK_FUNC_1 &pcfg_pull_none_12ma>,
+ /* mac_rxd3 */
+ <0 20 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_rxd2 */
+ <0 21 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txd3 */
+ <0 23 RK_FUNC_1 &pcfg_pull_none_12ma>,
+ /* mac_txd2 */
+ <0 22 RK_FUNC_1 &pcfg_pull_none_12ma>;
+ };
+
+ rmiim0_pins: rmiim0-pins {
+ rockchip,pins =
+ /* mac_mdio */
+ <0 11 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txen */
+ <0 12 RK_FUNC_1 &pcfg_pull_none_12ma>,
+ /* mac_clk */
+ <0 24 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_rxer */
+ <0 13 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_rxdv */
+ <0 25 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_mdc */
+ <0 19 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_rxd1 */
+ <0 14 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_rxd0 */
+ <0 15 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txd1 */
+ <0 16 RK_FUNC_1 &pcfg_pull_none_12ma>,
+ /* mac_txd0 */
+ <0 17 RK_FUNC_1 &pcfg_pull_none_12ma>;
+ };
+ };
+
+ gmac-1 {
+ rgmiim1_pins: rgmiim1-pins {
+ rockchip,pins =
+ /* mac_txclk */
+ <1 12 RK_FUNC_2 &pcfg_pull_none_12ma>,
+ /* mac_rxclk */
+ <1 13 RK_FUNC_2 &pcfg_pull_none_2ma>,
+ /* mac_mdio */
+ <1 19 RK_FUNC_2 &pcfg_pull_none_2ma>,
+ /* mac_txen */
+ <1 25 RK_FUNC_2 &pcfg_pull_none_12ma>,
+ /* mac_clk */
+ <1 21 RK_FUNC_2 &pcfg_pull_none_2ma>,
+ /* mac_rxdv */
+ <1 22 RK_FUNC_2 &pcfg_pull_none_2ma>,
+ /* mac_mdc */
+ <1 23 RK_FUNC_2 &pcfg_pull_none_2ma>,
+ /* mac_rxd1 */
+ <1 10 RK_FUNC_2 &pcfg_pull_none_2ma>,
+ /* mac_rxd0 */
+ <1 11 RK_FUNC_2 &pcfg_pull_none_2ma>,
+ /* mac_txd1 */
+ <1 8 RK_FUNC_2 &pcfg_pull_none_12ma>,
+ /* mac_txd0 */
+ <1 9 RK_FUNC_2 &pcfg_pull_none_12ma>,
+ /* mac_rxd3 */
+ <1 14 RK_FUNC_2 &pcfg_pull_none_2ma>,
+ /* mac_rxd2 */
+ <1 15 RK_FUNC_2 &pcfg_pull_none_2ma>,
+ /* mac_txd3 */
+ <1 16 RK_FUNC_2 &pcfg_pull_none_12ma>,
+ /* mac_txd2 */
+ <1 17 RK_FUNC_2 &pcfg_pull_none_12ma>,
+
+ /* mac_txclk */
+ <0 8 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txen */
+ <0 12 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_clk */
+ <0 24 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txd1 */
+ <0 16 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txd0 */
+ <0 17 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txd3 */
+ <0 23 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txd2 */
+ <0 22 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ rmiim1_pins: rmiim1-pins {
+ rockchip,pins =
+ /* mac_mdio */
+ <1 19 RK_FUNC_2 &pcfg_pull_none_2ma>,
+ /* mac_txen */
+ <1 25 RK_FUNC_2 &pcfg_pull_none_12ma>,
+ /* mac_clk */
+ <1 21 RK_FUNC_2 &pcfg_pull_none_2ma>,
+ /* mac_rxer */
+ <1 24 RK_FUNC_2 &pcfg_pull_none_2ma>,
+ /* mac_rxdv */
+ <1 22 RK_FUNC_2 &pcfg_pull_none_2ma>,
+ /* mac_mdc */
+ <1 23 RK_FUNC_2 &pcfg_pull_none_2ma>,
+ /* mac_rxd1 */
+ <1 10 RK_FUNC_2 &pcfg_pull_none_2ma>,
+ /* mac_rxd0 */
+ <1 11 RK_FUNC_2 &pcfg_pull_none_2ma>,
+ /* mac_txd1 */
+ <1 8 RK_FUNC_2 &pcfg_pull_none_12ma>,
+ /* mac_txd0 */
+ <1 9 RK_FUNC_2 &pcfg_pull_none_12ma>,
+
+ /* mac_mdio */
+ <0 11 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txen */
+ <0 12 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_clk */
+ <0 24 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_mdc */
+ <0 19 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txd1 */
+ <0 16 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txd0 */
+ <0 17 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ gmac2phy {
+ fephyled_speed100: fephyled-speed100 {
+ rockchip,pins =
+ <0 31 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ fephyled_speed10: fephyled-speed10 {
+ rockchip,pins =
+ <0 30 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ fephyled_duplex: fephyled-duplex {
+ rockchip,pins =
+ <0 30 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ fephyled_rxm0: fephyled-rxm0 {
+ rockchip,pins =
+ <0 29 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ fephyled_txm0: fephyled-txm0 {
+ rockchip,pins =
+ <0 29 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ fephyled_linkm0: fephyled-linkm0 {
+ rockchip,pins =
+ <0 28 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ fephyled_rxm1: fephyled-rxm1 {
+ rockchip,pins =
+ <2 25 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ fephyled_txm1: fephyled-txm1 {
+ rockchip,pins =
+ <2 25 RK_FUNC_3 &pcfg_pull_none>;
+ };
+
+ fephyled_linkm1: fephyled-linkm1 {
+ rockchip,pins =
+ <2 24 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ tsadc_pin {
+ tsadc_int: tsadc-int {
+ rockchip,pins =
+ <2 13 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ tsadc_gpio: tsadc-gpio {
+ rockchip,pins =
+ <2 13 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ hdmi_pin {
+ hdmi_cec: hdmi-cec {
+ rockchip,pins =
+ <0 3 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ hdmi_hpd: hdmi-hpd {
+ rockchip,pins =
+ <0 4 RK_FUNC_1 &pcfg_pull_down>;
+ };
+ };
+
+ cif-0 {
+ dvp_d2d9_m0:dvp-d2d9-m0 {
+ rockchip,pins =
+ /* cif_d0 */
+ <3 4 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_d1 */
+ <3 5 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_d2 */
+ <3 6 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_d3 */
+ <3 7 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_d4 */
+ <3 8 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_d5m0 */
+ <3 9 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_d6m0 */
+ <3 10 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_d7m0 */
+ <3 11 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_href */
+ <3 1 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_vsync */
+ <3 0 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_clkoutm0 */
+ <3 3 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_clkin */
+ <3 2 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ cif-1 {
+ dvp_d2d9_m1:dvp-d2d9-m1 {
+ rockchip,pins =
+ /* cif_d0 */
+ <3 4 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_d1 */
+ <3 5 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_d2 */
+ <3 6 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_d3 */
+ <3 7 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_d4 */
+ <3 8 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_d5m1 */
+ <2 16 RK_FUNC_4 &pcfg_pull_none>,
+ /* cif_d6m1 */
+ <2 17 RK_FUNC_4 &pcfg_pull_none>,
+ /* cif_d7m1 */
+ <2 18 RK_FUNC_4 &pcfg_pull_none>,
+ /* cif_href */
+ <3 1 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_vsync */
+ <3 0 RK_FUNC_2 &pcfg_pull_none>,
+ /* cif_clkoutm1 */
+ <2 15 RK_FUNC_4 &pcfg_pull_none>,
+ /* cif_clkin */
+ <3 2 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/dts/rk3399-evb.dts b/arch/arm/dts/rk3399-evb.dts
index fa60e19..a959989 100644
--- a/arch/arm/dts/rk3399-evb.dts
+++ b/arch/arm/dts/rk3399-evb.dts
@@ -7,6 +7,7 @@
/dts-v1/;
#include <dt-bindings/pwm/pwm.h>
#include "rk3399.dtsi"
+#include "rk3399-sdram-lpddr3-4GB-1600.dtsi"
/ {
model = "Rockchip RK3399 Evaluation Board";
@@ -69,6 +70,7 @@
};
&sdmmc {
+ bus-width = <4>;
status = "okay";
};
diff --git a/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi b/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
new file mode 100644
index 0000000..65dfc38
--- /dev/null
+++ b/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
@@ -0,0 +1,1536 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+&dmc {
+ rockchip,sdram-params = <
+ 0x2
+ 0xa
+ 0x3
+ 0x2
+ 0x2
+ 0x0
+ 0xf
+ 0xf
+ 1
+ 0x1d191519
+ 0x14040808
+ 0x00000002
+ 0x00006226
+ 0x00000054
+ 0x00000000
+ 0x2
+ 0xa
+ 0x3
+ 0x2
+ 0x2
+ 0x0
+ 0xf
+ 0xf
+ 1
+ 0x1d191519
+ 0x14040808
+ 0x00000002
+ 0x00006226
+ 0x00000054
+ 0x00000000
+ 800
+ 6
+ 2
+ 13
+ 1
+ 0x00000700
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000050
+ 0x00027100
+ 0x00000320
+ 0x00001f40
+ 0x00000050
+ 0x00027100
+ 0x00000320
+ 0x00001f40
+ 0x00000050
+ 0x00027100
+ 0x00000320
+ 0x01001f40
+ 0x00000000
+ 0x00000101
+ 0x00020100
+ 0x000000a0
+ 0x00000190
+ 0x00000000
+ 0x06180000
+ 0x00061800
+ 0x04000618
+ 0x33080004
+ 0x280f0622
+ 0x22330800
+ 0x00280f06
+ 0x06223308
+ 0x0600280f
+ 0x00000a0a
+ 0x0600dac0
+ 0x0a0a060c
+ 0x0600dac0
+ 0x0a0a060c
+ 0x0600dac0
+ 0x0203000c
+ 0x0f0c0f00
+ 0x040c0f0c
+ 0x14000a0a
+ 0x03030a0a
+ 0x00010003
+ 0x031b1b1b
+ 0x00111111
+ 0x00000000
+ 0x03010000
+ 0x0c2800a8
+ 0x0c2800a8
+ 0x0c2800a8
+ 0x00000000
+ 0x00060006
+ 0x00140006
+ 0x00140014
+ 0x000f0f0f
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00b00000
+ 0x00b000b0
+ 0x00b000b0
+ 0x000000b0
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000301
+ 0x00000001
+ 0x00000000
+ 0x00000000
+ 0x01000000
+ 0x80104002
+ 0x00040003
+ 0x00040005
+ 0x00030000
+ 0x00050004
+ 0x00000004
+ 0x00040003
+ 0x00040005
+ 0x30a00000
+ 0x00001850
+ 0x185030a0
+ 0x30a00000
+ 0x00001850
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x02020200
+ 0x00020202
+ 0x00030200
+ 0x00040700
+ 0x00000302
+ 0x02000407
+ 0x00000003
+ 0x00030f04
+ 0x00070004
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00010000
+ 0x20040020
+ 0x00200400
+ 0x01000400
+ 0x00000b80
+ 0x00000000
+ 0x00000001
+ 0x00000002
+ 0x0000000e
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00a00000
+ 0x00c80050
+ 0x00c80000
+ 0x005000a0
+ 0x000000c8
+ 0x00a000c8
+ 0x00c80050
+ 0x00c80000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00430000
+ 0x0000001a
+ 0x001a0043
+ 0x00430000
+ 0x0000001a
+ 0x00010001
+ 0x07000001
+ 0x00000707
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00430000
+ 0x0000001a
+ 0x001a0043
+ 0x00430000
+ 0x0000001a
+ 0x00010001
+ 0x07000001
+ 0x00000707
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x01000000
+ 0x00000000
+ 0x00000000
+ 0x18151100
+ 0x0000000c
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00032003
+ 0x00480120
+ 0x00000000
+ 0x01200320
+ 0x00000048
+ 0x00032000
+ 0x00480120
+ 0x00000000
+ 0x00280000
+ 0x00280028
+ 0x01010100
+ 0x01000202
+ 0x0a000002
+ 0x01000f0f
+ 0x00000000
+ 0x00000000
+ 0x00010003
+ 0x00000c03
+ 0x00000100
+ 0x00010000
+ 0x01000000
+ 0x00010000
+ 0x00000001
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00010000
+ 0x03030301
+ 0x01010808
+ 0x03030001
+ 0x0a0a0a03
+ 0x02080808
+ 0x02050103
+ 0x02050103
+ 0x00050103
+ 0x00020202
+ 0x05020500
+ 0x00020502
+ 0x00000000
+ 0x00000000
+ 0x0d000001
+ 0x00010028
+ 0x00010000
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00010100
+ 0x01000000
+ 0x00000001
+ 0x00000303
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000556aa
+ 0x000aaaaa
+ 0x000aa955
+ 0x00055555
+ 0x000b3133
+ 0x0004cd33
+ 0x0004cecc
+ 0x000b32cc
+ 0x00010300
+ 0x03000100
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00ffff00
+ 0x1e1e0000
+ 0x0800001e
+ 0x00001850
+ 0x00000200
+ 0x00000200
+ 0x00000200
+ 0x00000200
+ 0x00001850
+ 0x0000f320
+ 0x1850050a
+ 0x00000200
+ 0x00000200
+ 0x00000200
+ 0x00000200
+ 0x00001850
+ 0x0000f320
+ 0x1850050a
+ 0x00000200
+ 0x00000200
+ 0x00000200
+ 0x00000200
+ 0x00001850
+ 0x0000f320
+ 0x0202050a
+ 0x03030202
+ 0x00000018
+ 0x00000000
+ 0x00000000
+ 0x00001403
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00030000
+ 0x000e0020
+ 0x000e0020
+ 0x000e0020
+ 0x00000000
+ 0x00000000
+ 0x01000000
+ 0x00070007
+ 0x00050007
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x01000101
+ 0x01010101
+ 0x01000101
+ 0x01000100
+ 0x00010001
+ 0x00010002
+ 0x00020100
+ 0x00000002
+ 0x00000700
+ 0x00000000
+ 0x000030a0
+ 0x00001850
+ 0x000030a0
+ 0x00001850
+ 0x000030a0
+ 0x18501850
+ 0x00000200
+ 0x00000200
+ 0x00000200
+ 0x00000200
+ 0x00001850
+ 0x00000200
+ 0x00000200
+ 0x00000200
+ 0x00000200
+ 0x00001850
+ 0x00000200
+ 0x00000200
+ 0x00000200
+ 0x00000200
+ 0x00010000
+ 0x00000007
+ 0x81000001
+ 0x0f0003f0
+ 0x3fffffff
+ 0x0f0000a0
+ 0x377ff000
+ 0x0f000020
+ 0x377ff000
+ 0x0f000030
+ 0x377ff000
+ 0x0f0000b0
+ 0x377ff000
+ 0x0f000100
+ 0x377ff000
+ 0x0f000110
+ 0x377ff000
+ 0x0f000010
+ 0x377ff000
+ 0x03000101
+ 0x042e2e2e
+ 0x06180006
+ 0x00061800
+ 0x00000018
+ 0x0c2800a8
+ 0x0c2800a8
+ 0x0c2800a8
+ 0x00000500
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x04040000
+ 0x0d000004
+ 0x00000128
+ 0x00000000
+ 0x00030003
+ 0x00000018
+ 0x00000000
+ 0x00000000
+ 0x03060002
+ 0x03010301
+ 0x01080801
+ 0x04020201
+ 0x01080804
+ 0x00000000
+ 0x03030000
+ 0x0a0a0a03
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00030300
+ 0x00000014
+ 0x00000000
+ 0x01010300
+ 0x00000000
+ 0x00000000
+ 0x01000000
+ 0x00000101
+ 0x55555a5a
+ 0x55555a5a
+ 0x55555a5a
+ 0x55555a5a
+ 0x0a0a0001
+ 0x0505000a
+ 0x00000005
+ 0x00000100
+ 0x00030000
+ 0x17030000
+ 0x000e0020
+ 0x000e0020
+ 0x000e0020
+ 0x00000000
+ 0x00000000
+ 0x00000100
+ 0x140a0000
+ 0x000a030a
+ 0x03000a03
+ 0x010a000a
+ 0x00000100
+ 0x01000000
+ 0x00000000
+ 0x00000100
+ 0x1e1a0000
+ 0x10010204
+ 0x07070705
+ 0x20000202
+ 0x00201000
+ 0x00201000
+ 0x04041000
+ 0x10100100
+ 0x00010110
+ 0x004b004a
+ 0x1a030000
+ 0x0102041e
+ 0x34000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00004300
+ 0x0001001a
+ 0x004d4d07
+ 0x001a0043
+ 0x4d070001
+ 0x0000434d
+ 0x0001001a
+ 0x004d4d07
+ 0x001a0043
+ 0x4d070001
+ 0x0000434d
+ 0x0001001a
+ 0x004d4d07
+ 0x001a0043
+ 0x4d070001
+ 0x0043004d
+ 0x0001001a
+ 0x004d4d07
+ 0x001a0043
+ 0x4d070001
+ 0x0000434d
+ 0x0001001a
+ 0x004d4d07
+ 0x001a0043
+ 0x4d070001
+ 0x0000434d
+ 0x0001001a
+ 0x004d4d07
+ 0x001a0043
+ 0x4d070001
+ 0x0100004d
+ 0x00c800c8
+ 0x060400c8
+ 0x0c060f11
+ 0x2200d890
+ 0x0a0c2005
+ 0x0f11060a
+ 0x00000c06
+ 0x2200d890
+ 0x0a0c2005
+ 0x0f11060a
+ 0x00000c06
+ 0x2200d890
+ 0x0a0c2005
+ 0x0200020a
+ 0x02000200
+ 0x02000200
+ 0x02000200
+ 0x02000200
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x01000300
+ 0x00185000
+ 0x0000f320
+ 0x00001850
+ 0x0000f320
+ 0x00001850
+ 0x0000f320
+ 0x08000000
+ 0x00000100
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000002
+ 0x76543210
+ 0x0004c008
+ 0x000000b3
+ 0x00000000
+ 0x00000000
+ 0x00010000
+ 0x01665555
+ 0x00665555
+ 0x00010f00
+ 0x05010200
+ 0x00000003
+ 0x001700c0
+ 0x00cc0101
+ 0x00030066
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x04080000
+ 0x04080400
+ 0x08000000
+ 0x0c00c007
+ 0x00000100
+ 0x00000100
+ 0x55555555
+ 0xaaaaaaaa
+ 0x55555555
+ 0xaaaaaaaa
+ 0x00005555
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00200000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x02700270
+ 0x02700270
+ 0x02700270
+ 0x02700270
+ 0x00000270
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00800000
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00b30080
+ 0x00000003
+ 0x00000000
+ 0x00020000
+ 0x00000200
+ 0x00000000
+ 0x51315152
+ 0xc0013150
+ 0x020000c0
+ 0x00100001
+ 0x07054208
+ 0x000f0c18
+ 0x01000140
+ 0x00000c20
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x76543210
+ 0x0004c008
+ 0x000000b3
+ 0x00000000
+ 0x00000000
+ 0x00010000
+ 0x01665555
+ 0x00665555
+ 0x00010f00
+ 0x05010200
+ 0x00000003
+ 0x001700c0
+ 0x00cc0101
+ 0x00030066
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x04080000
+ 0x04080400
+ 0x08000000
+ 0x0c00c007
+ 0x00000100
+ 0x00000100
+ 0x55555555
+ 0xaaaaaaaa
+ 0x55555555
+ 0xaaaaaaaa
+ 0x00005555
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00200000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x02700270
+ 0x02700270
+ 0x02700270
+ 0x02700270
+ 0x00000270
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00800000
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00b30080
+ 0x00000003
+ 0x00000000
+ 0x00020000
+ 0x00000200
+ 0x00000000
+ 0x51315152
+ 0xc0013150
+ 0x020000c0
+ 0x00100001
+ 0x07054208
+ 0x000f0c18
+ 0x01000140
+ 0x00000c20
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x76543210
+ 0x0004c008
+ 0x000000b3
+ 0x00000000
+ 0x00000000
+ 0x00010000
+ 0x01665555
+ 0x00665555
+ 0x00010f00
+ 0x05010200
+ 0x00000003
+ 0x001700c0
+ 0x00cc0101
+ 0x00030066
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x04080000
+ 0x04080400
+ 0x08000000
+ 0x0c00c007
+ 0x00000100
+ 0x00000100
+ 0x55555555
+ 0xaaaaaaaa
+ 0x55555555
+ 0xaaaaaaaa
+ 0x00005555
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00200000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x02700270
+ 0x02700270
+ 0x02700270
+ 0x02700270
+ 0x00000270
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00800000
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00b30080
+ 0x00000003
+ 0x00000000
+ 0x00020000
+ 0x00000200
+ 0x00000000
+ 0x51315152
+ 0xc0013150
+ 0x020000c0
+ 0x00100001
+ 0x07054208
+ 0x000f0c18
+ 0x01000140
+ 0x00000c20
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x76543210
+ 0x0004c008
+ 0x000000b3
+ 0x00000000
+ 0x00000000
+ 0x00010000
+ 0x01665555
+ 0x00665555
+ 0x00010f00
+ 0x05010200
+ 0x00000003
+ 0x001700c0
+ 0x00cc0101
+ 0x00030066
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x04080000
+ 0x04080400
+ 0x08000000
+ 0x0c00c007
+ 0x00000100
+ 0x00000100
+ 0x55555555
+ 0xaaaaaaaa
+ 0x55555555
+ 0xaaaaaaaa
+ 0x00005555
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00200000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x02700270
+ 0x02700270
+ 0x02700270
+ 0x02700270
+ 0x00000270
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00800000
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00800080
+ 0x00b30080
+ 0x00000003
+ 0x00000000
+ 0x00020000
+ 0x00000200
+ 0x00000000
+ 0x51315152
+ 0xc0013150
+ 0x020000c0
+ 0x00100001
+ 0x07054208
+ 0x000f0c18
+ 0x01000140
+ 0x00000c20
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00800000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000001
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00400320
+ 0x00000040
+ 0x00806420
+ 0x00917531
+ 0x00806420
+ 0x01917531
+ 0x00020003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000556aa
+ 0x000aaaaa
+ 0x000aa955
+ 0x00055555
+ 0x000b3133
+ 0x0004cd33
+ 0x0004cecc
+ 0x000b32cc
+ 0x0a418820
+ 0x103f0000
+ 0x0000003f
+ 0x00038055
+ 0x03800380
+ 0x03800380
+ 0x00000380
+ 0x42080010
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00800000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000001
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00400320
+ 0x00000040
+ 0x00008eca
+ 0x00009fdb
+ 0x00008eca
+ 0x01009fdb
+ 0x00020003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000556aa
+ 0x000aaaaa
+ 0x000aa955
+ 0x00055555
+ 0x000b3133
+ 0x0004cd33
+ 0x0004cecc
+ 0x000b32cc
+ 0x0004a0e6
+ 0x080f0000
+ 0x0000000f
+ 0x00038055
+ 0x03800380
+ 0x03800380
+ 0x00000380
+ 0x42080010
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00800000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000001
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00400320
+ 0x00000040
+ 0x00008eca
+ 0x00009fdb
+ 0x00008eca
+ 0x01009fdb
+ 0x00020003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x000556aa
+ 0x000aaaaa
+ 0x000aa955
+ 0x00055555
+ 0x000b3133
+ 0x0004cd33
+ 0x0004cecc
+ 0x000b32cc
+ 0x1ee6b16a
+ 0x10000000
+ 0x00000000
+ 0x00038055
+ 0x03800380
+ 0x03800380
+ 0x00000380
+ 0x42080010
+ 0x00000003
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000001
+ 0x00000000
+ 0x01000005
+ 0x04000f00
+ 0x00020040
+ 0x00020055
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000050
+ 0x00000000
+ 0x00010100
+ 0x00000601
+ 0x00000000
+ 0x00006400
+ 0x01221102
+ 0x00000000
+ 0x00051f00
+ 0x051f051f
+ 0x051f051f
+ 0x00030003
+ 0x03000300
+ 0x00000300
+ 0x01221102
+ 0x00000000
+ 0x00000000
+ 0x03020000
+ 0x00000001
+ 0x00000011
+ 0x00000011
+ 0x00000400
+ 0x00000000
+ 0x00000011
+ 0x00000011
+ 0x00004410
+ 0x00004410
+ 0x00004410
+ 0x00004410
+ 0x00004410
+ 0x00000011
+ 0x00004410
+ 0x00000011
+ 0x00004410
+ 0x00000011
+ 0x00004410
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x04000000
+ 0x00000000
+ 0x00000000
+ 0x00000508
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0x00000000
+ 0xe4000000
+ 0x00000000
+ 0x00000000
+ 0x01010000
+ 0x00000000
+ >;
+};
diff --git a/arch/arm/dts/rk3399.dtsi b/arch/arm/dts/rk3399.dtsi
index 22277ff..456fdb6 100644
--- a/arch/arm/dts/rk3399.dtsi
+++ b/arch/arm/dts/rk3399.dtsi
@@ -24,6 +24,8 @@
serial2 = &uart2;
serial3 = &uart3;
serial4 = &uart4;
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
};
cpus {
@@ -183,6 +185,7 @@
};
sdhci: sdhci@fe330000 {
+ u-boot,dm-pre-reloc;
compatible = "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1";
reg = <0x0 0xfe330000 0x0 0x10000>;
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
@@ -416,6 +419,7 @@
};
pmugrf: syscon@ff320000 {
+ u-boot,dm-pre-reloc;
compatible = "rockchip,rk3399-pmugrf", "syscon", "simple-mfd";
reg = <0x0 0xff320000 0x0 0x1000>;
#address-cells = <1>;
@@ -427,6 +431,12 @@
};
};
+ pmusgrf: syscon@ff330000 {
+ u-boot,dm-pre-reloc;
+ compatible = "rockchip,rk3399-pmusgrf", "syscon";
+ reg = <0x0 0xff330000 0x0 0xe3d4>;
+ };
+
spi3: spi@ff350000 {
compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi";
reg = <0x0 0xff350000 0x0 0x1000>;
@@ -497,7 +507,40 @@
status = "disabled";
};
+ cic: syscon@ff620000 {
+ u-boot,dm-pre-reloc;
+ compatible = "rockchip,rk3399-cic", "syscon";
+ reg = <0x0 0xff620000 0x0 0x100>;
+ };
+
+ dfi: dfi@ff630000 {
+ reg = <0x00 0xff630000 0x00 0x4000>;
+ compatible = "rockchip,rk3399-dfi";
+ rockchip,pmu = <&pmugrf>;
+ clocks = <&cru PCLK_DDR_MON>;
+ clock-names = "pclk_ddr_mon";
+ status = "disabled";
+ };
+
+ dmc: dmc {
+ u-boot,dm-pre-reloc;
+ compatible = "rockchip,rk3399-dmc";
+ devfreq-events = <&dfi>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru SCLK_DDRCLK>;
+ clock-names = "dmc_clk";
+ reg = <0x0 0xffa80000 0x0 0x0800
+ 0x0 0xffa80800 0x0 0x1800
+ 0x0 0xffa82000 0x0 0x2000
+ 0x0 0xffa84000 0x0 0x1000
+ 0x0 0xffa88000 0x0 0x0800
+ 0x0 0xffa88800 0x0 0x1800
+ 0x0 0xffa8a000 0x0 0x2000
+ 0x0 0xffa8c000 0x0 0x1000>;
+ };
+
pmucru: pmu-clock-controller@ff750000 {
+ u-boot,dm-pre-reloc;
compatible = "rockchip,rk3399-pmucru";
reg = <0x0 0xff750000 0x0 0x1000>;
#clock-cells = <1>;
@@ -507,6 +550,7 @@
};
cru: clock-controller@ff760000 {
+ u-boot,dm-pre-reloc;
compatible = "rockchip,rk3399-cru";
reg = <0x0 0xff760000 0x0 0x1000>;
#clock-cells = <1>;
@@ -530,6 +574,7 @@
};
grf: syscon@ff770000 {
+ u-boot,dm-pre-reloc;
compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd";
reg = <0x0 0xff770000 0x0 0x10000>;
#address-cells = <1>;
@@ -607,6 +652,7 @@
};
pinctrl: pinctrl {
+ u-boot,dm-pre-reloc;
compatible = "rockchip,rk3399-pinctrl";
rockchip,grf = <&grf>;
rockchip,pmu = <&pmugrf>;
diff --git a/arch/arm/dts/rk3xxx.dtsi b/arch/arm/dts/rk3xxx.dtsi
new file mode 100644
index 0000000..6d9e36d
--- /dev/null
+++ b/arch/arm/dts/rk3xxx.dtsi
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+ or X11
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&gic>;
+
+ aliases {
+ ethernet0 = &emac;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
+ mshc0 = &emmc;
+ mshc1 = &mmc0;
+ mshc2 = &mmc1;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ };
+
+ amba {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dmac1_s: dma-controller@20018000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x20018000 0x4000>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ arm,pl330-broken-no-flushp;
+ clocks = <&cru ACLK_DMA1>;
+ clock-names = "apb_pclk";
+ };
+
+ dmac1_ns: dma-controller@2001c000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x2001c000 0x4000>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ arm,pl330-broken-no-flushp;
+ clocks = <&cru ACLK_DMA1>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ dmac2: dma-controller@20078000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x20078000 0x4000>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ arm,pl330-broken-no-flushp;
+ clocks = <&cru ACLK_DMA2>;
+ clock-names = "apb_pclk";
+ };
+ };
+
+ xin24m: oscillator {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ #clock-cells = <0>;
+ clock-output-names = "xin24m";
+ };
+
+ L2: l2-cache-controller@10138000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x10138000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ scu@1013c000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0x1013c000 0x100>;
+ };
+
+ global_timer: global-timer@1013c200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x1013c200 0x20>;
+ interrupts = <GIC_PPI 11 0x304>;
+ clocks = <&cru CORE_PERI>;
+ };
+
+ local_timer: local-timer@1013c600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x1013c600 0x20>;
+ interrupts = <GIC_PPI 13 0x304>;
+ clocks = <&cru CORE_PERI>;
+ };
+
+ gic: interrupt-controller@1013d000 {
+ compatible = "arm,cortex-a9-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x1013d000 0x1000>,
+ <0x1013c100 0x0100>;
+ };
+
+ uart0: serial@10124000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x10124000 0x400>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <1>;
+ clock-names = "baudclk", "apb_pclk";
+ clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+ status = "disabled";
+ };
+
+ uart1: serial@10126000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x10126000 0x400>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <1>;
+ clock-names = "baudclk", "apb_pclk";
+ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+ status = "disabled";
+ };
+
+ noc: syscon@10128000 {
+ u-boot,dm-spl;
+ compatible = "rockchip,rk3188-noc", "syscon";
+ reg = <0x10128000 0x2000>;
+ };
+
+ usb_otg: usb@10180000 {
+ compatible = "rockchip,rk3066-usb", "snps,dwc2";
+ reg = <0x10180000 0x40000>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_OTG0>;
+ clock-names = "otg";
+ dr_mode = "otg";
+ g-np-tx-fifo-size = <16>;
+ g-rx-fifo-size = <275>;
+ g-tx-fifo-size = <256 128 128 64 64 32>;
+ g-use-dma;
+ phys = <&usbphy0>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
+ usb_host: usb@101c0000 {
+ compatible = "snps,dwc2";
+ reg = <0x101c0000 0x40000>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_OTG1>;
+ clock-names = "otg";
+ dr_mode = "host";
+ phys = <&usbphy1>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
+ emac: ethernet@10204000 {
+ compatible = "snps,arc-emac";
+ reg = <0x10204000 0x3c>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clocks = <&cru HCLK_EMAC>, <&cru SCLK_MAC>;
+ clock-names = "hclk", "macref";
+ max-speed = <100>;
+ phy-mode = "rmii";
+
+ status = "disabled";
+ };
+
+ mmc0: dwmmc@10214000 {
+ compatible = "rockchip,rk2928-dw-mshc";
+ reg = <0x10214000 0x1000>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <256>;
+ status = "disabled";
+ };
+
+ mmc1: dwmmc@10218000 {
+ compatible = "rockchip,rk2928-dw-mshc";
+ reg = <0x10218000 0x1000>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <256>;
+ status = "disabled";
+ };
+
+ emmc: dwmmc@1021c000 {
+ compatible = "rockchip,rk2928-dw-mshc";
+ reg = <0x1021c000 0x1000>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <256>;
+ status = "disabled";
+ };
+
+ pmu: pmu@20004000 {
+ compatible = "rockchip,rk3066-pmu", "syscon";
+ reg = <0x20004000 0x100>;
+ u-boot,dm-spl;
+ };
+
+ grf: grf@20008000 {
+ compatible = "syscon";
+ reg = <0x20008000 0x200>;
+ u-boot,dm-spl;
+ };
+
+ dmc: dmc@20020000 {
+ /* unreviewed u-boot-specific binding */
+ compatible = "rockchip,rk3188-dmc", "syscon";
+ rockchip,cru = <&cru>;
+ rockchip,grf = <&grf>;
+ rockchip,pmu = <&pmu>;
+ rockchip,noc = <&noc>;
+ reg = <0x20020000 0x3fc
+ 0x20040000 0x294>;
+ clocks = <&cru PCLK_DDRUPCTL>, <&cru PCLK_PUBL>;
+ clock-names = "pclk_ddrupctl", "pclk_publ";
+ u-boot,dm-spl;
+ };
+
+ i2c0: i2c@2002d000 {
+ compatible = "rockchip,rk3066-i2c";
+ reg = <0x2002d000 0x1000>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clock-names = "i2c";
+ clocks = <&cru PCLK_I2C0>;
+
+ status = "disabled";
+ };
+
+ i2c1: i2c@2002f000 {
+ compatible = "rockchip,rk3066-i2c";
+ reg = <0x2002f000 0x1000>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clocks = <&cru PCLK_I2C1>;
+ clock-names = "i2c";
+
+ status = "disabled";
+ };
+
+ pwm0: pwm@20030000 {
+ compatible = "rockchip,rk2928-pwm";
+ reg = <0x20030000 0x10>;
+ #pwm-cells = <2>;
+ clocks = <&cru PCLK_PWM01>;
+ status = "disabled";
+ };
+
+ pwm1: pwm@20030010 {
+ compatible = "rockchip,rk2928-pwm";
+ reg = <0x20030010 0x10>;
+ #pwm-cells = <2>;
+ clocks = <&cru PCLK_PWM01>;
+ status = "disabled";
+ };
+
+ wdt: watchdog@2004c000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x2004c000 0x100>;
+ clocks = <&cru PCLK_WDT>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ pwm2: pwm@20050020 {
+ compatible = "rockchip,rk2928-pwm";
+ reg = <0x20050020 0x10>;
+ #pwm-cells = <2>;
+ clocks = <&cru PCLK_PWM23>;
+ status = "disabled";
+ };
+
+ pwm3: pwm@20050030 {
+ compatible = "rockchip,rk2928-pwm";
+ reg = <0x20050030 0x10>;
+ #pwm-cells = <2>;
+ clocks = <&cru PCLK_PWM23>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@20056000 {
+ compatible = "rockchip,rk3066-i2c";
+ reg = <0x20056000 0x1000>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clocks = <&cru PCLK_I2C2>;
+ clock-names = "i2c";
+
+ status = "disabled";
+ };
+
+ i2c3: i2c@2005a000 {
+ compatible = "rockchip,rk3066-i2c";
+ reg = <0x2005a000 0x1000>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clocks = <&cru PCLK_I2C3>;
+ clock-names = "i2c";
+
+ status = "disabled";
+ };
+
+ i2c4: i2c@2005e000 {
+ compatible = "rockchip,rk3066-i2c";
+ reg = <0x2005e000 0x1000>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clocks = <&cru PCLK_I2C4>;
+ clock-names = "i2c";
+
+ status = "disabled";
+ };
+
+ uart2: serial@20064000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x20064000 0x400>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <1>;
+ clock-frequency = <24000000>;
+ clock-names = "baudclk", "apb_pclk";
+ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+ status = "disabled";
+ };
+
+ uart3: serial@20068000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x20068000 0x400>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <1>;
+ clock-names = "baudclk", "apb_pclk";
+ clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+ status = "disabled";
+ };
+
+ saradc: saradc@2006c000 {
+ compatible = "rockchip,saradc";
+ reg = <0x2006c000 0x100>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ #io-channel-cells = <1>;
+ clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
+ clock-names = "saradc", "apb_pclk";
+ status = "disabled";
+ };
+
+ spi0: spi@20070000 {
+ compatible = "rockchip,rk3066-spi";
+ clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
+ clock-names = "spiclk", "apb_pclk";
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x20070000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ dmas = <&dmac2 10>, <&dmac2 11>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ spi1: spi@20074000 {
+ compatible = "rockchip,rk3066-spi";
+ clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>;
+ clock-names = "spiclk", "apb_pclk";
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x20074000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ dmas = <&dmac2 12>, <&dmac2 13>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/include/asm/arch-rockchip/bootrom.h b/arch/arm/include/asm/arch-rockchip/bootrom.h
new file mode 100644
index 0000000..79fb1a0
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/bootrom.h
@@ -0,0 +1,22 @@
+/*
+ * (C) Copyright 2017 Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _ASM_ARCH_BOOTROM_H
+#define _ASM_ARCH_BOOTROM_H
+
+/*
+ * Saved Stack pointer address.
+ * Access might be needed in some special cases.
+ */
+extern u32 SAVE_SP_ADDR;
+
+/*
+ * Hand control back to the bootrom to load another
+ * boot stage.
+ */
+extern void back_to_bootrom(void);
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/clock.h b/arch/arm/include/asm/arch-rockchip/clock.h
index 804c77b..b06bb6c 100644
--- a/arch/arm/include/asm/arch-rockchip/clock.h
+++ b/arch/arm/include/asm/arch-rockchip/clock.h
@@ -17,6 +17,8 @@ enum {
ROCKCHIP_SYSCON_SGRF,
ROCKCHIP_SYSCON_PMU,
ROCKCHIP_SYSCON_PMUGRF,
+ ROCKCHIP_SYSCON_PMUSGRF,
+ ROCKCHIP_SYSCON_CIC,
};
/* Standard Rockchip clock numbers */
@@ -63,6 +65,13 @@ static inline u32 clk_get_divisor(ulong input_rate, uint output_rate)
*/
void *rockchip_get_cru(void);
+/**
+ * rockchip_get_pmucru() - get a pointer to the clock/reset unit registers
+ *
+ * @return pointer to registers, or -ve error on error
+ */
+void *rockchip_get_pmucru(void);
+
struct rk3288_cru;
struct rk3288_grf;
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3188.h b/arch/arm/include/asm/arch-rockchip/cru_rk3188.h
new file mode 100644
index 0000000..74f0fed
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3188.h
@@ -0,0 +1,191 @@
+/*
+ * (C) Copyright 2016 Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef _ASM_ARCH_CRU_RK3188_H
+#define _ASM_ARCH_CRU_RK3188_H
+
+#define OSC_HZ (24 * 1000 * 1000)
+
+#define APLL_HZ (1608 * 1000000)
+#define GPLL_HZ (594 * 1000000)
+#define CPLL_HZ (384 * 1000000)
+
+/* The SRAM is clocked off aclk_cpu, so we want to max it out for boot speed */
+#define CPU_ACLK_HZ 297000000
+#define CPU_HCLK_HZ 148500000
+#define CPU_PCLK_HZ 74250000
+#define CPU_H2P_HZ 74250000
+
+#define PERI_ACLK_HZ 148500000
+#define PERI_HCLK_HZ 148500000
+#define PERI_PCLK_HZ 74250000
+
+/* Private data for the clock driver - used by rockchip_get_cru() */
+struct rk3188_clk_priv {
+ struct rk3188_grf *grf;
+ struct rk3188_cru *cru;
+ ulong rate;
+ bool has_bwadj;
+};
+
+struct rk3188_cru {
+ struct rk3188_pll {
+ u32 con0;
+ u32 con1;
+ u32 con2;
+ u32 con3;
+ } pll[4];
+ u32 cru_mode_con;
+ u32 cru_clksel_con[35];
+ u32 cru_clkgate_con[10];
+ u32 reserved1[2];
+ u32 cru_glb_srst_fst_value;
+ u32 cru_glb_srst_snd_value;
+ u32 reserved2[2];
+ u32 cru_softrst_con[9];
+ u32 cru_misc_con;
+ u32 reserved3[2];
+ u32 cru_glb_cnt_th;
+};
+check_member(rk3188_cru, cru_glb_cnt_th, 0x0140);
+
+/* CRU_CLKSEL0_CON */
+enum {
+ /* a9_core_div: core = core_src / (a9_core_div + 1) */
+ A9_CORE_DIV_SHIFT = 9,
+ A9_CORE_DIV_MASK = 0x1f,
+ CORE_PLL_SHIFT = 8,
+ CORE_PLL_MASK = 1,
+ CORE_PLL_SELECT_APLL = 0,
+ CORE_PLL_SELECT_GPLL,
+
+ /* core peri div: core:core_peri = 2:1, 4:1, 8:1 or 16:1 */
+ CORE_PERI_DIV_SHIFT = 6,
+ CORE_PERI_DIV_MASK = 3,
+
+ /* aclk_cpu pll selection */
+ CPU_ACLK_PLL_SHIFT = 5,
+ CPU_ACLK_PLL_MASK = 1,
+ CPU_ACLK_PLL_SELECT_APLL = 0,
+ CPU_ACLK_PLL_SELECT_GPLL,
+
+ /* a9_cpu_div: aclk_cpu = cpu_src / (a9_cpu_div + 1) */
+ A9_CPU_DIV_SHIFT = 0,
+ A9_CPU_DIV_MASK = 0x1f,
+};
+
+/* CRU_CLKSEL1_CON */
+enum {
+ /* ahb2apb_pclk_div: hclk_cpu:pclk_cpu = 1:1, 2:1 or 4:1 */
+ AHB2APB_DIV_SHIFT = 14,
+ AHB2APB_DIV_MASK = 3,
+
+ /* cpu_pclk_div: aclk_cpu:pclk_cpu = 1:1, 2:1, 4:1 or 8:1 */
+ CPU_PCLK_DIV_SHIFT = 12,
+ CPU_PCLK_DIV_MASK = 3,
+
+ /* cpu_hclk_div: aclk_cpu:hclk_cpu = 1:1, 2:1 or 4:1 */
+ CPU_HCLK_DIV_SHIFT = 8,
+ CPU_HCLK_DIV_MASK = 3,
+
+ /* core_aclk_div: cire:aclk_core = 1:1, 2:1, 3:1, 4:1 or 8:1 */
+ CORE_ACLK_DIV_SHIFT = 3,
+ CORE_ACLK_DIV_MASK = 7,
+};
+
+/* CRU_CLKSEL10_CON */
+enum {
+ PERI_SEL_PLL_MASK = 1,
+ PERI_SEL_PLL_SHIFT = 15,
+ PERI_SEL_CPLL = 0,
+ PERI_SEL_GPLL,
+
+ /* peri pclk div: aclk_bus:pclk_bus = 1:1, 2:1, 4:1 or 8:1 */
+ PERI_PCLK_DIV_SHIFT = 12,
+ PERI_PCLK_DIV_MASK = 3,
+
+ /* peripheral bus hclk div:aclk_bus: hclk_bus = 1:1, 2:1 or 4:1 */
+ PERI_HCLK_DIV_SHIFT = 8,
+ PERI_HCLK_DIV_MASK = 3,
+
+ /* peri aclk div: aclk_peri = periph_src / (peri_aclk_div + 1) */
+ PERI_ACLK_DIV_SHIFT = 0,
+ PERI_ACLK_DIV_MASK = 0x1f,
+};
+/* CRU_CLKSEL11_CON */
+enum {
+ HSICPHY_DIV_SHIFT = 8,
+ HSICPHY_DIV_MASK = 0x3f,
+
+ MMC0_DIV_SHIFT = 0,
+ MMC0_DIV_MASK = 0x3f,
+};
+
+/* CRU_CLKSEL12_CON */
+enum {
+ UART_PLL_SHIFT = 15,
+ UART_PLL_MASK = 1,
+ UART_PLL_SELECT_GENERAL = 0,
+ UART_PLL_SELECT_CODEC,
+
+ EMMC_DIV_SHIFT = 8,
+ EMMC_DIV_MASK = 0x3f,
+
+ SDIO_DIV_SHIFT = 0,
+ SDIO_DIV_MASK = 0x3f,
+};
+
+/* CRU_CLKSEL25_CON */
+enum {
+ SPI1_DIV_SHIFT = 8,
+ SPI1_DIV_MASK = 0x7f,
+
+ SPI0_DIV_SHIFT = 0,
+ SPI0_DIV_MASK = 0x7f,
+};
+
+/* CRU_MODE_CON */
+enum {
+ GPLL_MODE_SHIFT = 12,
+ GPLL_MODE_MASK = 3,
+ GPLL_MODE_SLOW = 0,
+ GPLL_MODE_NORMAL,
+ GPLL_MODE_DEEP,
+
+ CPLL_MODE_SHIFT = 8,
+ CPLL_MODE_MASK = 3,
+ CPLL_MODE_SLOW = 0,
+ CPLL_MODE_NORMAL,
+ CPLL_MODE_DEEP,
+
+ DPLL_MODE_SHIFT = 4,
+ DPLL_MODE_MASK = 3,
+ DPLL_MODE_SLOW = 0,
+ DPLL_MODE_NORMAL,
+ DPLL_MODE_DEEP,
+
+ APLL_MODE_SHIFT = 0,
+ APLL_MODE_MASK = 3,
+ APLL_MODE_SLOW = 0,
+ APLL_MODE_NORMAL,
+ APLL_MODE_DEEP,
+};
+
+/* CRU_APLL_CON0 */
+enum {
+ CLKR_SHIFT = 8,
+ CLKR_MASK = 0x3f,
+
+ CLKOD_SHIFT = 0,
+ CLKOD_MASK = 0x3f,
+};
+
+/* CRU_APLL_CON1 */
+enum {
+ CLKF_SHIFT = 0,
+ CLKF_MASK = 0x1fff,
+};
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3328.h b/arch/arm/include/asm/arch-rockchip/cru_rk3328.h
new file mode 100644
index 0000000..948706e
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3328.h
@@ -0,0 +1,70 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __ASM_ARCH_CRU_RK3328_H_
+#define __ASM_ARCH_CRU_RK3328_H_
+
+#include <common.h>
+
+struct rk3328_clk_priv {
+ struct rk3328_cru *cru;
+ ulong rate;
+};
+
+struct rk3328_cru {
+ u32 apll_con[5];
+ u32 reserved1[3];
+ u32 dpll_con[5];
+ u32 reserved2[3];
+ u32 cpll_con[5];
+ u32 reserved3[3];
+ u32 gpll_con[5];
+ u32 reserved4[3];
+ u32 mode_con;
+ u32 misc;
+ u32 reserved5[2];
+ u32 glb_cnt_th;
+ u32 glb_rst_st;
+ u32 glb_srst_snd_value;
+ u32 glb_srst_fst_value;
+ u32 npll_con[5];
+ u32 reserved6[(0x100 - 0xb4) / 4];
+ u32 clksel_con[53];
+ u32 reserved7[(0x200 - 0x1d4) / 4];
+ u32 clkgate_con[29];
+ u32 reserved8[3];
+ u32 ssgtbl[32];
+ u32 softrst_con[12];
+ u32 reserved9[(0x380 - 0x330) / 4];
+ u32 sdmmc_con[2];
+ u32 sdio_con[2];
+ u32 emmc_con[2];
+ u32 sdmmc_ext_con[2];
+};
+check_member(rk3328_cru, sdmmc_ext_con[1], 0x39c);
+#define MHz 1000000
+#define KHz 1000
+#define OSC_HZ (24 * MHz)
+#define APLL_HZ (600 * MHz)
+#define GPLL_HZ (576 * MHz)
+#define CPLL_HZ (594 * MHz)
+
+#define CLK_CORE_HZ (600 * MHz)
+#define ACLKM_CORE_HZ (300 * MHz)
+#define PCLK_DBG_HZ (300 * MHz)
+
+#define PERIHP_ACLK_HZ (144000 * KHz)
+#define PERIHP_HCLK_HZ (72000 * KHz)
+#define PERIHP_PCLK_HZ (72000 * KHz)
+
+#define PWM_CLOCK_HZ (74 * MHz)
+
+enum apll_frequencies {
+ APLL_816_MHZ,
+ APLL_600_MHZ,
+};
+
+#endif /* __ASM_ARCH_CRU_RK3328_H_ */
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3399.h b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h
index 98fba2b..cf830d0 100644
--- a/arch/arm/include/asm/arch-rockchip/cru_rk3399.h
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h
@@ -15,6 +15,11 @@ struct rk3399_clk_priv {
ulong rate;
};
+struct rk3399_pmuclk_priv {
+ struct rk3399_pmucru *pmucru;
+ ulong rate;
+};
+
struct rk3399_pmucru {
u32 ppll_con[6];
u32 reserved[0x1a];
diff --git a/arch/arm/include/asm/arch-rockchip/ddr_rk3188.h b/arch/arm/include/asm/arch-rockchip/ddr_rk3188.h
new file mode 100644
index 0000000..3d7929f
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/ddr_rk3188.h
@@ -0,0 +1,25 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _ASM_ARCH_DDR_RK3188_H
+#define _ASM_ARCH_DDR_RK3188_H
+
+#include <asm/arch/ddr_rk3288.h>
+
+/*
+ * RK3188 Memory scheduler register map.
+ */
+struct rk3188_msch {
+ u32 coreid;
+ u32 revisionid;
+ u32 ddrconf;
+ u32 ddrtiming;
+ u32 ddrmode;
+ u32 readlatency;
+};
+check_member(rk3188_msch, readlatency, 0x0014);
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/ddr_rk3288.h b/arch/arm/include/asm/arch-rockchip/ddr_rk3288.h
index fccabcd..9a59075 100644
--- a/arch/arm/include/asm/arch-rockchip/ddr_rk3288.h
+++ b/arch/arm/include/asm/arch-rockchip/ddr_rk3288.h
@@ -425,6 +425,14 @@ enum {
#define START_CMD (1u << 31)
+/*
+ * DDRCONF
+ * [5:4] row(13+n)
+ * [1:0] col(9+n), assume bw=2
+ */
+#define DDRCONF_ROW_SHIFT 4
+#define DDRCONF_COL_SHIFT 0
+
/* DEVTODEV */
#define BUSWRTORD_SHIFT 4
#define BUSRDTOWR_SHIFT 2
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3188.h b/arch/arm/include/asm/arch-rockchip/grf_rk3188.h
new file mode 100644
index 0000000..ce7bac5
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3188.h
@@ -0,0 +1,589 @@
+/*
+ * Copyright (c) 2016 Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _ASM_ARCH_GRF_RK3188_H
+#define _ASM_ARCH_GRF_RK3188_H
+
+struct rk3188_grf_gpio_lh {
+ u32 l;
+ u32 h;
+};
+
+struct rk3188_grf {
+ struct rk3188_grf_gpio_lh gpio_dir[4];
+ struct rk3188_grf_gpio_lh gpio_do[4];
+ struct rk3188_grf_gpio_lh gpio_en[4];
+
+ u32 reserved[2];
+ u32 gpio0c_iomux;
+ u32 gpio0d_iomux;
+
+ u32 gpio1a_iomux;
+ u32 gpio1b_iomux;
+ u32 gpio1c_iomux;
+ u32 gpio1d_iomux;
+
+ u32 gpio2a_iomux;
+ u32 gpio2b_iomux;
+ u32 gpio2c_iomux;
+ u32 gpio2d_iomux;
+
+ u32 gpio3a_iomux;
+ u32 gpio3b_iomux;
+ u32 gpio3c_iomux;
+ u32 gpio3d_iomux;
+
+ u32 soc_con0;
+ u32 soc_con1;
+ u32 soc_con2;
+ u32 soc_status0;
+
+ u32 busdmac_con[3];
+ u32 peridmac_con[4];
+
+ u32 cpu_con[6];
+ u32 reserved0[2];
+
+ u32 ddrc_con0;
+ u32 ddrc_stat;
+
+ u32 io_con[5];
+ u32 soc_status1;
+
+ u32 uoc0_con[4];
+ u32 uoc1_con[4];
+ u32 uoc2_con[2];
+ u32 reserved1;
+ u32 uoc3_con[2];
+ u32 hsic_stat;
+ u32 os_reg[8];
+
+ u32 gpio0_p[3];
+ u32 gpio1_p[3][4];
+
+ u32 flash_data_p;
+ u32 flash_cmd_p;
+};
+check_member(rk3188_grf, flash_cmd_p, 0x01a4);
+
+/* GRF_GPIO0D_IOMUX */
+enum {
+ GPIO0D7_SHIFT = 14,
+ GPIO0D7_MASK = 1,
+ GPIO0D7_GPIO = 0,
+ GPIO0D7_SPI1_CSN0,
+
+ GPIO0D6_SHIFT = 12,
+ GPIO0D6_MASK = 1,
+ GPIO0D6_GPIO = 0,
+ GPIO0D6_SPI1_CLK,
+
+ GPIO0D5_SHIFT = 10,
+ GPIO0D5_MASK = 1,
+ GPIO0D5_GPIO = 0,
+ GPIO0D5_SPI1_TXD,
+
+ GPIO0D4_SHIFT = 8,
+ GPIO0D4_MASK = 1,
+ GPIO0D4_GPIO = 0,
+ GPIO0D4_SPI0_RXD,
+
+ GPIO0D3_SHIFT = 6,
+ GPIO0D3_MASK = 3,
+ GPIO0D3_GPIO = 0,
+ GPIO0D3_FLASH_CSN3,
+ GPIO0D3_EMMC_RSTN_OUT,
+
+ GPIO0D2_SHIFT = 4,
+ GPIO0D2_MASK = 3,
+ GPIO0D2_GPIO = 0,
+ GPIO0D2_FLASH_CSN2,
+ GPIO0D2_EMMC_CMD,
+
+ GPIO0D1_SHIFT = 2,
+ GPIO0D1_MASK = 1,
+ GPIO0D1_GPIO = 0,
+ GPIO0D1_FLASH_CSN1,
+
+ GPIO0D0_SHIFT = 0,
+ GPIO0D0_MASK = 3,
+ GPIO0D0_GPIO = 0,
+ GPIO0D0_FLASH_DQS,
+ GPIO0D0_EMMC_CLKOUT
+};
+
+/* GRF_GPIO1A_IOMUX */
+enum {
+ GPIO1A7_SHIFT = 14,
+ GPIO1A7_MASK = 3,
+ GPIO1A7_GPIO = 0,
+ GPIO1A7_UART1_RTS_N,
+ GPIO1A7_SPI0_CSN0,
+
+ GPIO1A6_SHIFT = 12,
+ GPIO1A6_MASK = 3,
+ GPIO1A6_GPIO = 0,
+ GPIO1A6_UART1_CTS_N,
+ GPIO1A6_SPI0_CLK,
+
+ GPIO1A5_SHIFT = 10,
+ GPIO1A5_MASK = 3,
+ GPIO1A5_GPIO = 0,
+ GPIO1A5_UART1_SOUT,
+ GPIO1A5_SPI0_TXD,
+
+ GPIO1A4_SHIFT = 8,
+ GPIO1A4_MASK = 3,
+ GPIO1A4_GPIO = 0,
+ GPIO1A4_UART1_SIN,
+ GPIO1A4_SPI0_RXD,
+
+ GPIO1A3_SHIFT = 6,
+ GPIO1A3_MASK = 1,
+ GPIO1A3_GPIO = 0,
+ GPIO1A3_UART0_RTS_N,
+
+ GPIO1A2_SHIFT = 4,
+ GPIO1A2_MASK = 1,
+ GPIO1A2_GPIO = 0,
+ GPIO1A2_UART0_CTS_N,
+
+ GPIO1A1_SHIFT = 2,
+ GPIO1A1_MASK = 1,
+ GPIO1A1_GPIO = 0,
+ GPIO1A1_UART0_SOUT,
+
+ GPIO1A0_SHIFT = 0,
+ GPIO1A0_MASK = 1,
+ GPIO1A0_GPIO = 0,
+ GPIO1A0_UART0_SIN,
+};
+
+/* GRF_GPIO1B_IOMUX */
+enum {
+ GPIO1B7_SHIFT = 14,
+ GPIO1B7_MASK = 1,
+ GPIO1B7_GPIO = 0,
+ GPIO1B7_SPI0_CSN1,
+
+ GPIO1B6_SHIFT = 12,
+ GPIO1B6_MASK = 3,
+ GPIO1B6_GPIO = 0,
+ GPIO1B6_SPDIF_TX,
+ GPIO1B6_SPI1_CSN1,
+
+ GPIO1B5_SHIFT = 10,
+ GPIO1B5_MASK = 3,
+ GPIO1B5_GPIO = 0,
+ GPIO1B5_UART3_RTS_N,
+ GPIO1B5_RESERVED,
+
+ GPIO1B4_SHIFT = 8,
+ GPIO1B4_MASK = 3,
+ GPIO1B4_GPIO = 0,
+ GPIO1B4_UART3_CTS_N,
+ GPIO1B4_GPS_RFCLK,
+
+ GPIO1B3_SHIFT = 6,
+ GPIO1B3_MASK = 3,
+ GPIO1B3_GPIO = 0,
+ GPIO1B3_UART3_SOUT,
+ GPIO1B3_GPS_SIG,
+
+ GPIO1B2_SHIFT = 4,
+ GPIO1B2_MASK = 3,
+ GPIO1B2_GPIO = 0,
+ GPIO1B2_UART3_SIN,
+ GPIO1B2_GPS_MAG,
+
+ GPIO1B1_SHIFT = 2,
+ GPIO1B1_MASK = 3,
+ GPIO1B1_GPIO = 0,
+ GPIO1B1_UART2_SOUT,
+ GPIO1B1_JTAG_TDO,
+
+ GPIO1B0_SHIFT = 0,
+ GPIO1B0_MASK = 3,
+ GPIO1B0_GPIO = 0,
+ GPIO1B0_UART2_SIN,
+ GPIO1B0_JTAG_TDI,
+};
+
+/* GRF_GPIO1D_IOMUX */
+enum {
+ GPIO1D7_SHIFT = 14,
+ GPIO1D7_MASK = 1,
+ GPIO1D7_GPIO = 0,
+ GPIO1D7_I2C4_SCL,
+
+ GPIO1D6_SHIFT = 12,
+ GPIO1D6_MASK = 1,
+ GPIO1D6_GPIO = 0,
+ GPIO1D6_I2C4_SDA,
+
+ GPIO1D5_SHIFT = 10,
+ GPIO1D5_MASK = 1,
+ GPIO1D5_GPIO = 0,
+ GPIO1D5_I2C2_SCL,
+
+ GPIO1D4_SHIFT = 8,
+ GPIO1D4_MASK = 1,
+ GPIO1D4_GPIO = 0,
+ GPIO1D4_I2C2_SDA,
+
+ GPIO1D3_SHIFT = 6,
+ GPIO1D3_MASK = 1,
+ GPIO1D3_GPIO = 0,
+ GPIO1D3_I2C1_SCL,
+
+ GPIO1D2_SHIFT = 4,
+ GPIO1D2_MASK = 1,
+ GPIO1D2_GPIO = 0,
+ GPIO1D2_I2C1_SDA,
+
+ GPIO1D1_SHIFT = 2,
+ GPIO1D1_MASK = 1,
+ GPIO1D1_GPIO = 0,
+ GPIO1D1_I2C0_SCL,
+
+ GPIO1D0_SHIFT = 0,
+ GPIO1D0_MASK = 1,
+ GPIO1D0_GPIO = 0,
+ GPIO1D0_I2C0_SDA,
+};
+
+/* GRF_GPIO3A_IOMUX */
+enum {
+ GPIO3A7_SHIFT = 14,
+ GPIO3A7_MASK = 1,
+ GPIO3A7_GPIO = 0,
+ GPIO3A7_SDMMC0_DATA3,
+
+ GPIO3A6_SHIFT = 12,
+ GPIO3A6_MASK = 1,
+ GPIO3A6_GPIO = 0,
+ GPIO3A6_SDMMC0_DATA2,
+
+ GPIO3A5_SHIFT = 10,
+ GPIO3A5_MASK = 1,
+ GPIO3A5_GPIO = 0,
+ GPIO3A5_SDMMC0_DATA1,
+
+ GPIO3A4_SHIFT = 8,
+ GPIO3A4_MASK = 1,
+ GPIO3A4_GPIO = 0,
+ GPIO3A4_SDMMC0_DATA0,
+
+ GPIO3A3_SHIFT = 6,
+ GPIO3A3_MASK = 1,
+ GPIO3A3_GPIO = 0,
+ GPIO3A3_SDMMC0_CMD,
+
+ GPIO3A2_SHIFT = 4,
+ GPIO3A2_MASK = 1,
+ GPIO3A2_GPIO = 0,
+ GPIO3A2_SDMMC0_CLKOUT,
+
+ GPIO3A1_SHIFT = 2,
+ GPIO3A1_MASK = 1,
+ GPIO3A1_GPIO = 0,
+ GPIO3A1_SDMMC0_PWREN,
+
+ GPIO3A0_SHIFT = 0,
+ GPIO3A0_MASK = 1,
+ GPIO3A0_GPIO = 0,
+ GPIO3A0_SDMMC0_RSTN,
+};
+
+/* GRF_GPIO3B_IOMUX */
+enum {
+ GPIO3B7_SHIFT = 14,
+ GPIO3B7_MASK = 3,
+ GPIO3B7_GPIO = 0,
+ GPIO3B7_CIF_DATA11,
+ GPIO3B7_I2C3_SCL,
+
+ GPIO3B6_SHIFT = 12,
+ GPIO3B6_MASK = 3,
+ GPIO3B6_GPIO = 0,
+ GPIO3B6_CIF_DATA10,
+ GPIO3B6_I2C3_SDA,
+
+ GPIO3B5_SHIFT = 10,
+ GPIO3B5_MASK = 3,
+ GPIO3B5_GPIO = 0,
+ GPIO3B5_CIF_DATA1,
+ GPIO3B5_HSADC_DATA9,
+
+ GPIO3B4_SHIFT = 8,
+ GPIO3B4_MASK = 3,
+ GPIO3B4_GPIO = 0,
+ GPIO3B4_CIF_DATA0,
+ GPIO3B4_HSADC_DATA8,
+
+ GPIO3B3_SHIFT = 6,
+ GPIO3B3_MASK = 1,
+ GPIO3B3_GPIO = 0,
+ GPIO3B3_CIF_CLKOUT,
+
+ GPIO3B2_SHIFT = 4,
+ GPIO3B2_MASK = 1,
+ GPIO3B2_GPIO = 0,
+ /* no muxes */
+
+ GPIO3B1_SHIFT = 2,
+ GPIO3B1_MASK = 1,
+ GPIO3B1_GPIO = 0,
+ GPIO3B1_SDMMC0_WRITE_PRT,
+
+ GPIO3B0_SHIFT = 0,
+ GPIO3B0_MASK = 1,
+ GPIO3B0_GPIO = 0,
+ GPIO3B0_SDMMC_DETECT_N,
+};
+
+/* GRF_GPIO3C_IOMUX */
+enum {
+ GPIO3C7_SHIFT = 14,
+ GPIO3C7_MASK = 3,
+ GPIO3C7_GPIO = 0,
+ GPIO3C7_SDMMC1_WRITE_PRT,
+ GPIO3C7_RMII_CRS_DVALID,
+ GPIO3C7_RESERVED,
+
+ GPIO3C6_SHIFT = 12,
+ GPIO3C6_MASK = 3,
+ GPIO3C6_GPIO = 0,
+ GPIO3C6_SDMMC1_DECTN,
+ GPIO3C6_RMII_RX_ERR,
+ GPIO3C6_RESERVED,
+
+ GPIO3C5_SHIFT = 10,
+ GPIO3C5_MASK = 3,
+ GPIO3C5_GPIO = 0,
+ GPIO3C5_SDMMC1_CLKOUT,
+ GPIO3C5_RMII_CLKOUT,
+ GPIO3C5_RMII_CLKIN,
+
+ GPIO3C4_SHIFT = 8,
+ GPIO3C4_MASK = 3,
+ GPIO3C4_GPIO = 0,
+ GPIO3C4_SDMMC1_DATA3,
+ GPIO3C4_RMII_RXD1,
+ GPIO3C4_RESERVED,
+
+ GPIO3C3_SHIFT = 6,
+ GPIO3C3_MASK = 3,
+ GPIO3C3_GPIO = 0,
+ GPIO3C3_SDMMC1_DATA2,
+ GPIO3C3_RMII_RXD0,
+ GPIO3C3_RESERVED,
+
+ GPIO3C2_SHIFT = 4,
+ GPIO3C2_MASK = 3,
+ GPIO3C2_GPIO = 0,
+ GPIO3C2_SDMMC1_DATA1,
+ GPIO3C2_RMII_TXD0,
+ GPIO3C2_RESERVED,
+
+ GPIO3C1_SHIFT = 2,
+ GPIO3C1_MASK = 3,
+ GPIO3C1_GPIO = 0,
+ GPIO3C1_SDMMC1_DATA0,
+ GPIO3C1_RMII_TXD1,
+ GPIO3C1_RESERVED,
+
+ GPIO3C0_SHIFT = 0,
+ GPIO3C0_MASK = 3,
+ GPIO3C0_GPIO = 0,
+ GPIO3C0_SDMMC1_CMD,
+ GPIO3C0_RMII_TX_EN,
+ GPIO3C0_RESERVED,
+};
+
+/* GRF_GPIO3D_IOMUX */
+enum {
+ GPIO3D6_SHIFT = 12,
+ GPIO3D6_MASK = 3,
+ GPIO3D6_GPIO = 0,
+ GPIO3D6_PWM_3,
+ GPIO3D6_JTAG_TMS,
+ GPIO3D6_HOST_DRV_VBUS,
+
+ GPIO3D5_SHIFT = 10,
+ GPIO3D5_MASK = 3,
+ GPIO3D5_GPIO = 0,
+ GPIO3D5_PWM_2,
+ GPIO3D5_JTAG_TCK,
+ GPIO3D5_OTG_DRV_VBUS,
+
+ GPIO3D4_SHIFT = 8,
+ GPIO3D4_MASK = 3,
+ GPIO3D4_GPIO = 0,
+ GPIO3D4_PWM_1,
+ GPIO3D4_JTAG_TRSTN,
+
+ GPIO3D3_SHIFT = 6,
+ GPIO3D3_MASK = 3,
+ GPIO3D3_GPIO = 0,
+ GPIO3D3_PWM_0,
+
+ GPIO3D2_SHIFT = 4,
+ GPIO3D2_MASK = 3,
+ GPIO3D2_GPIO = 0,
+ GPIO3D2_SDMMC1_INT_N,
+
+ GPIO3D1_SHIFT = 2,
+ GPIO3D1_MASK = 3,
+ GPIO3D1_GPIO = 0,
+ GPIO3D1_SDMMC1_BACKEND_PWR,
+ GPIO3D1_MII_MDCLK,
+
+ GPIO3D0_SHIFT = 0,
+ GPIO3D0_MASK = 3,
+ GPIO3D0_GPIO = 0,
+ GPIO3D0_SDMMC1_PWR_EN,
+ GPIO3D0_MII_MD,
+};
+
+/* GRF_SOC_CON0 */
+enum {
+ HSADC_CLK_DIR_SHIFT = 15,
+ HSADC_CLK_DIR_MASK = 1,
+
+ HSADC_SEL_SHIFT = 14,
+ HSADC_SEL_MASK = 1,
+
+ NOC_REMAP_SHIFT = 12,
+ NOC_REMAP_MASK = 1,
+
+ EMMC_FLASH_SEL_SHIFT = 11,
+ EMMC_FLASH_SEL_MASK = 1,
+
+ TZPC_REVISION_SHIFT = 7,
+ TZPC_REVISION_MASK = 0xf,
+
+ L2CACHE_ACC_SHIFT = 5,
+ L2CACHE_ACC_MASK = 3,
+
+ L2RD_WAIT_SHIFT = 3,
+ L2RD_WAIT_MASK = 3,
+
+ IMEMRD_WAIT_SHIFT = 1,
+ IMEMRD_WAIT_MASK = 3,
+};
+
+/* GRF_SOC_CON1 */
+enum {
+ RKI2C4_SEL_SHIFT = 15,
+ RKI2C4_SEL_MASK = 1,
+
+ RKI2C3_SEL_SHIFT = 14,
+ RKI2C3_SEL_MASK = 1,
+
+ RKI2C2_SEL_SHIFT = 13,
+ RKI2C2_SEL_MASK = 1,
+
+ RKI2C1_SEL_SHIFT = 12,
+ RKI2C1_SEL_MASK = 1,
+
+ RKI2C0_SEL_SHIFT = 11,
+ RKI2C0_SEL_MASK = 1,
+
+ VCODEC_SEL_SHIFT = 10,
+ VCODEC_SEL_MASK = 1,
+
+ PERI_EMEM_PAUSE_SHIFT = 9,
+ PERI_EMEM_PAUSE_MASK = 1,
+
+ PERI_USB_PAUSE_SHIFT = 8,
+ PERI_USB_PAUSE_MASK = 1,
+
+ SMC_MUX_MODE_0_SHIFT = 6,
+ SMC_MUX_MODE_0_MASK = 1,
+
+ SMC_SRAM_MW_0_SHIFT = 4,
+ SMC_SRAM_MW_0_MASK = 3,
+
+ SMC_REMAP_0_SHIFT = 3,
+ SMC_REMAP_0_MASK = 1,
+
+ SMC_A_GT_M0_SYNC_SHIFT = 2,
+ SMC_A_GT_M0_SYNC_MASK = 1,
+
+ EMAC_SPEED_SHIFT = 1,
+ EMAC_SPEEC_MASK = 1,
+
+ EMAC_MODE_SHIFT = 0,
+ EMAC_MODE_MASK = 1,
+};
+
+/* GRF_SOC_CON2 */
+enum {
+ SDIO_CLK_OUT_SR_SHIFT = 15,
+ SDIO_CLK_OUT_SR_MASK = 1,
+
+ MEM_EMA_L2C_SHIFT = 11,
+ MEM_EMA_L2C_MASK = 7,
+
+ MEM_EMA_A9_SHIFT = 8,
+ MEM_EMA_A9_MASK = 7,
+
+ MSCH4_MAINDDR3_SHIFT = 7,
+ MSCH4_MAINDDR3_MASK = 1,
+ MSCH4_MAINDDR3_DDR3 = 1,
+
+ EMAC_NEWRCV_EN_SHIFT = 6,
+ EMAC_NEWRCV_EN_MASK = 1,
+
+ SW_ADDR15_EN_SHIFT = 5,
+ SW_ADDR15_EN_MASK = 1,
+
+ SW_ADDR16_EN_SHIFT = 4,
+ SW_ADDR16_EN_MASK = 1,
+
+ SW_ADDR17_EN_SHIFT = 3,
+ SW_ADDR17_EN_MASK = 1,
+
+ BANK2_TO_RANK_EN_SHIFT = 2,
+ BANK2_TO_RANK_EN_MASK = 1,
+
+ RANK_TO_ROW15_EN_SHIFT = 1,
+ RANK_TO_ROW15_EN_MASK = 1,
+
+ UPCTL_C_ACTIVE_IN_SHIFT = 0,
+ UPCTL_C_ACTIVE_IN_MASK = 1,
+ UPCTL_C_ACTIVE_IN_MAY = 0,
+ UPCTL_C_ACTIVE_IN_WILL,
+};
+
+/* GRF_DDRC_CON0 */
+enum {
+ DDR_16BIT_EN_SHIFT = 15,
+ DDR_16BIT_EN_MASK = 1,
+
+ DTO_LB_SHIFT = 11,
+ DTO_LB_MASK = 3,
+
+ DTO_TE_SHIFT = 9,
+ DTO_TE_MASK = 3,
+
+ DTO_PDR_SHIFT = 7,
+ DTO_PDR_MASK = 3,
+
+ DTO_PDD_SHIFT = 5,
+ DTO_PDD_MASK = 3,
+
+ DTO_IOM_SHIFT = 3,
+ DTO_IOM_MASK = 3,
+
+ DTO_OE_SHIFT = 1,
+ DTO_OE_MASK = 3,
+
+ ATO_AE_SHIFT = 0,
+ ATO_AE_MASK = 1,
+};
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3328.h b/arch/arm/include/asm/arch-rockchip/grf_rk3328.h
new file mode 100644
index 0000000..2776cef
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3328.h
@@ -0,0 +1,134 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __SOC_ROCKCHIP_RK3328_GRF_H__
+#define __SOC_ROCKCHIP_RK3328_GRF_H__
+
+struct rk3328_grf_regs {
+ u32 gpio0a_iomux;
+ u32 gpio0b_iomux;
+ u32 gpio0c_iomux;
+ u32 gpio0d_iomux;
+ u32 gpio1a_iomux;
+ u32 gpio1b_iomux;
+ u32 gpio1c_iomux;
+ u32 gpio1d_iomux;
+ u32 gpio2a_iomux;
+ u32 gpio2bl_iomux;
+ u32 gpio2bh_iomux;
+ u32 gpio2cl_iomux;
+ u32 gpio2ch_iomux;
+ u32 gpio2d_iomux;
+ u32 gpio3al_iomux;
+ u32 gpio3ah_iomux;
+ u32 gpio3bl_iomux;
+ u32 gpio3bh_iomux;
+ u32 gpio3c_iomux;
+ u32 gpio3d_iomux;
+ u32 com_iomux;
+ u32 reserved1[(0x100 - 0x54) / 4];
+
+ u32 gpio0a_p;
+ u32 gpio0b_p;
+ u32 gpio0c_p;
+ u32 gpio0d_p;
+ u32 gpio1a_p;
+ u32 gpio1b_p;
+ u32 gpio1c_p;
+ u32 gpio1d_p;
+ u32 gpio2a_p;
+ u32 gpio2b_p;
+ u32 gpio2c_p;
+ u32 gpio2d_p;
+ u32 gpio3a_p;
+ u32 gpio3b_p;
+ u32 gpio3c_p;
+ u32 gpio3d_p;
+ u32 reserved2[(0x200 - 0x140) / 4];
+ u32 gpio0a_e;
+ u32 gpio0b_e;
+ u32 gpio0c_e;
+ u32 gpio0d_e;
+ u32 gpio1a_e;
+ u32 gpio1b_e;
+ u32 gpio1c_e;
+ u32 gpio1d_e;
+ u32 gpio2a_e;
+ u32 gpio2b_e;
+ u32 gpio2c_e;
+ u32 gpio2d_e;
+ u32 gpio3a_e;
+ u32 gpio3b_e;
+ u32 gpio3c_e;
+ u32 gpio3d_e;
+ u32 reserved3[(0x300 - 0x240) / 4];
+ u32 gpio0l_sr;
+ u32 gpio0h_sr;
+ u32 gpio1l_sr;
+ u32 gpio1h_sr;
+ u32 gpio2l_sr;
+ u32 gpio2h_sr;
+ u32 gpio3l_sr;
+ u32 gpio3h_sr;
+ u32 reserved4[(0x380 - 0x320) / 4];
+ u32 gpio0l_smt;
+ u32 gpio0h_smt;
+ u32 gpio1l_smt;
+ u32 gpio1h_smt;
+ u32 gpio2l_smt;
+ u32 gpio2h_smt;
+ u32 gpio3l_smt;
+ u32 gpio3h_smt;
+ u32 reserved5[(0x400 - 0x3a0) / 4];
+ u32 soc_con[11];
+ u32 reserved6[(0x480 - 0x42c) / 4];
+ u32 soc_status[5];
+ u32 reserved7[(0x4c0 - 0x494) / 4];
+ u32 otg3_con[2];
+ u32 reserved8[(0x500 - 0x4c8) / 4];
+ u32 cpu_con[2];
+ u32 reserved9[(0x520 - 0x508) / 4];
+ u32 cpu_status[2];
+ u32 reserved10[(0x5c8 - 0x528) / 4];
+ u32 os_reg[8];
+ u32 reserved11[(0x680 - 0x5e8) / 4];
+ u32 sig_detect_con;
+ u32 reserved12[3];
+ u32 sig_detect_status;
+ u32 reserved13[3];
+ u32 sig_detect_status_clr;
+ u32 reserved14[3];
+
+ u32 sdmmc_det_counter;
+ u32 reserved15[(0x700 - 0x6b4) / 4];
+ u32 host0_con[3];
+ u32 reserved16[(0x880 - 0x70c) / 4];
+ u32 otg_con0;
+ u32 reserved17[3];
+ u32 host0_status;
+ u32 reserved18[(0x900 - 0x894) / 4];
+ u32 mac_con[3];
+ u32 reserved19[(0xb00 - 0x90c) / 4];
+ u32 macphy_con[4];
+ u32 macphy_status;
+};
+check_member(rk3328_grf_regs, macphy_status, 0xb10);
+
+struct rk3328_sgrf_regs {
+ u32 soc_con[6];
+ u32 reserved0[(0x100 - 0x18) / 4];
+ u32 dmac_con[6];
+ u32 reserved1[(0x180 - 0x118) / 4];
+ u32 fast_boot_addr;
+ u32 reserved2[(0x200 - 0x184) / 4];
+ u32 chip_fuse_con;
+ u32 reserved3[(0x280 - 0x204) / 4];
+ u32 hdcp_key_reg[8];
+ u32 hdcp_key_access_mask;
+};
+check_member(rk3328_sgrf_regs, hdcp_key_access_mask, 0x2a0);
+
+#endif /* __SOC_ROCKCHIP_RK3328_GRF_H__ */
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3399.h b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
index d3d1467..62d8496 100644
--- a/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
@@ -318,4 +318,122 @@ struct rk3399_pmusgrf_regs {
};
check_member(rk3399_pmusgrf_regs, slv_secure_con4, 0xe3d4);
+enum {
+ /* GRF_GPIO2B_IOMUX */
+ GRF_GPIO2B1_SEL_SHIFT = 0,
+ GRF_GPIO2B1_SEL_MASK = 3 << GRF_GPIO2B1_SEL_SHIFT,
+ GRF_SPI2TPM_RXD = 1,
+ GRF_GPIO2B2_SEL_SHIFT = 2,
+ GRF_GPIO2B2_SEL_MASK = 3 << GRF_GPIO2B2_SEL_SHIFT,
+ GRF_SPI2TPM_TXD = 1,
+ GRF_GPIO2B3_SEL_SHIFT = 6,
+ GRF_GPIO2B3_SEL_MASK = 3 << GRF_GPIO2B3_SEL_SHIFT,
+ GRF_SPI2TPM_CLK = 1,
+ GRF_GPIO2B4_SEL_SHIFT = 8,
+ GRF_GPIO2B4_SEL_MASK = 3 << GRF_GPIO2B4_SEL_SHIFT,
+ GRF_SPI2TPM_CSN0 = 1,
+
+ /* GRF_GPIO3A_IOMUX */
+ GRF_GPIO3A4_SEL_SHIFT = 8,
+ GRF_GPIO3A4_SEL_MASK = 3 << GRF_GPIO3A4_SEL_SHIFT,
+ GRF_SPI0NORCODEC_RXD = 2,
+ GRF_GPIO3A5_SEL_SHIFT = 10,
+ GRF_GPIO3A5_SEL_MASK = 3 << GRF_GPIO3A5_SEL_SHIFT,
+ GRF_SPI0NORCODEC_TXD = 2,
+ GRF_GPIO3A6_SEL_SHIFT = 12,
+ GRF_GPIO3A6_SEL_MASK = 3 << GRF_GPIO3A6_SEL_SHIFT,
+ GRF_SPI0NORCODEC_CLK = 2,
+ GRF_GPIO3A7_SEL_SHIFT = 14,
+ GRF_GPIO3A7_SEL_MASK = 3 << GRF_GPIO3A7_SEL_SHIFT,
+ GRF_SPI0NORCODEC_CSN0 = 2,
+
+ /* GRF_GPIO3B_IOMUX */
+ GRF_GPIO3B0_SEL_SHIFT = 0,
+ GRF_GPIO3B0_SEL_MASK = 3 << GRF_GPIO3B0_SEL_SHIFT,
+ GRF_SPI0NORCODEC_CSN1 = 2,
+
+ /* GRF_GPIO4B_IOMUX */
+ GRF_GPIO4B0_SEL_SHIFT = 0,
+ GRF_GPIO4B0_SEL_MASK = 3 << GRF_GPIO4B0_SEL_SHIFT,
+ GRF_SDMMC_DATA0 = 1,
+ GRF_UART2DBGA_SIN = 2,
+ GRF_GPIO4B1_SEL_SHIFT = 2,
+ GRF_GPIO4B1_SEL_MASK = 3 << GRF_GPIO4B1_SEL_SHIFT,
+ GRF_SDMMC_DATA1 = 1,
+ GRF_UART2DBGA_SOUT = 2,
+ GRF_GPIO4B2_SEL_SHIFT = 4,
+ GRF_GPIO4B2_SEL_MASK = 3 << GRF_GPIO4B2_SEL_SHIFT,
+ GRF_SDMMC_DATA2 = 1,
+ GRF_GPIO4B3_SEL_SHIFT = 6,
+ GRF_GPIO4B3_SEL_MASK = 3 << GRF_GPIO4B3_SEL_SHIFT,
+ GRF_SDMMC_DATA3 = 1,
+ GRF_GPIO4B4_SEL_SHIFT = 8,
+ GRF_GPIO4B4_SEL_MASK = 3 << GRF_GPIO4B4_SEL_SHIFT,
+ GRF_SDMMC_CLKOUT = 1,
+ GRF_GPIO4B5_SEL_SHIFT = 10,
+ GRF_GPIO4B5_SEL_MASK = 3 << GRF_GPIO4B5_SEL_SHIFT,
+ GRF_SDMMC_CMD = 1,
+
+ /* GRF_GPIO4C_IOMUX */
+ GRF_GPIO4C0_SEL_SHIFT = 0,
+ GRF_GPIO4C0_SEL_MASK = 3 << GRF_GPIO4C0_SEL_SHIFT,
+ GRF_UART2DGBB_SIN = 2,
+ GRF_GPIO4C1_SEL_SHIFT = 2,
+ GRF_GPIO4C1_SEL_MASK = 3 << GRF_GPIO4C1_SEL_SHIFT,
+ GRF_UART2DGBB_SOUT = 2,
+ GRF_GPIO4C2_SEL_SHIFT = 4,
+ GRF_GPIO4C2_SEL_MASK = 3 << GRF_GPIO4C2_SEL_SHIFT,
+ GRF_PWM_0 = 1,
+ GRF_GPIO4C3_SEL_SHIFT = 6,
+ GRF_GPIO4C3_SEL_MASK = 3 << GRF_GPIO4C3_SEL_SHIFT,
+ GRF_UART2DGBC_SIN = 1,
+ GRF_GPIO4C4_SEL_SHIFT = 8,
+ GRF_GPIO4C4_SEL_MASK = 3 << GRF_GPIO4C4_SEL_SHIFT,
+ GRF_UART2DBGC_SOUT = 1,
+ GRF_GPIO4C6_SEL_SHIFT = 12,
+ GRF_GPIO4C6_SEL_MASK = 3 << GRF_GPIO4C6_SEL_SHIFT,
+ GRF_PWM_1 = 1,
+
+ /* GRF_SOC_CON7 */
+ GRF_UART_DBG_SEL_SHIFT = 10,
+ GRF_UART_DBG_SEL_MASK = 3 << GRF_UART_DBG_SEL_SHIFT,
+ GRF_UART_DBG_SEL_C = 2,
+
+ /* PMUGRF_GPIO0A_IOMUX */
+ PMUGRF_GPIO0A6_SEL_SHIFT = 12,
+ PMUGRF_GPIO0A6_SEL_MASK = 3 << PMUGRF_GPIO0A6_SEL_SHIFT,
+ PMUGRF_PWM_3A = 1,
+
+ /* PMUGRF_GPIO1A_IOMUX */
+ PMUGRF_GPIO1A7_SEL_SHIFT = 14,
+ PMUGRF_GPIO1A7_SEL_MASK = 3 << PMUGRF_GPIO1A7_SEL_SHIFT,
+ PMUGRF_SPI1EC_RXD = 2,
+
+ /* PMUGRF_GPIO1B_IOMUX */
+ PMUGRF_GPIO1B0_SEL_SHIFT = 0,
+ PMUGRF_GPIO1B0_SEL_MASK = 3 << PMUGRF_GPIO1B0_SEL_SHIFT,
+ PMUGRF_SPI1EC_TXD = 2,
+ PMUGRF_GPIO1B1_SEL_SHIFT = 2,
+ PMUGRF_GPIO1B1_SEL_MASK = 3 << PMUGRF_GPIO1B1_SEL_SHIFT,
+ PMUGRF_SPI1EC_CLK = 2,
+ PMUGRF_GPIO1B2_SEL_SHIFT = 4,
+ PMUGRF_GPIO1B2_SEL_MASK = 3 << PMUGRF_GPIO1B2_SEL_SHIFT,
+ PMUGRF_SPI1EC_CSN0 = 2,
+ PMUGRF_GPIO1B6_SEL_SHIFT = 12,
+ PMUGRF_GPIO1B6_SEL_MASK = 3 << PMUGRF_GPIO1B6_SEL_SHIFT,
+ PMUGRF_PWM_3B = 1,
+ PMUGRF_GPIO1B7_SEL_SHIFT = 14,
+ PMUGRF_GPIO1B7_SEL_MASK = 3 << PMUGRF_GPIO1B7_SEL_SHIFT,
+ PMUGRF_I2C0PMU_SDA = 2,
+
+ /* PMUGRF_GPIO1C_IOMUX */
+ PMUGRF_GPIO1C0_SEL_SHIFT = 0,
+ PMUGRF_GPIO1C0_SEL_MASK = 3 << PMUGRF_GPIO1C0_SEL_SHIFT,
+ PMUGRF_I2C0PMU_SCL = 2,
+ PMUGRF_GPIO1C3_SEL_SHIFT = 6,
+ PMUGRF_GPIO1C3_SEL_MASK = 3 << PMUGRF_GPIO1C3_SEL_SHIFT,
+ PMUGRF_PWM_2 = 1,
+
+};
+
#endif /* __SOC_ROCKCHIP_RK3399_GRF_H__ */
diff --git a/arch/arm/include/asm/arch-rockchip/pmu_rk3188.h b/arch/arm/include/asm/arch-rockchip/pmu_rk3188.h
new file mode 100644
index 0000000..d3feac3
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/pmu_rk3188.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_PMU_RK3188_H
+#define _ASM_ARCH_PMU_RK3188_H
+
+struct rk3188_pmu {
+ u32 wakeup_cfg[2];
+ u32 pwrdn_con;
+ u32 pwrdn_st;
+
+ u32 int_con;
+ u32 int_st;
+ u32 misc_con;
+
+ u32 osc_cnt;
+ u32 pll_cnt;
+ u32 pmu_cnt;
+ u32 ddrio_pwron_cnt;
+ u32 wakeup_rst_clr_cnt;
+ u32 scu_pwrdwn_cnt;
+ u32 scu_pwrup_cnt;
+ u32 misc_con1;
+ u32 gpio0_con;
+
+ u32 sys_reg[4];
+ u32 reserved0[4];
+ u32 stop_int_dly;
+ u32 gpio0_p[2];
+};
+check_member(rk3188_pmu, gpio0_p[1], 0x0068);
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
new file mode 100644
index 0000000..22a6ca9
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2016-2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_SDRAM_RK3399_H
+#define _ASM_ARCH_SDRAM_RK3399_H
+
+enum {
+ DDR3 = 0x3,
+ LPDDR2 = 0x5,
+ LPDDR3 = 0x6,
+ LPDDR4 = 0x7,
+ UNUSED = 0xFF
+};
+
+struct rk3399_ddr_pctl_regs {
+ u32 denali_ctl[332];
+};
+
+struct rk3399_ddr_publ_regs {
+ u32 denali_phy[959];
+};
+
+struct rk3399_ddr_pi_regs {
+ u32 denali_pi[200];
+};
+
+struct rk3399_msch_regs {
+ u32 coreid;
+ u32 revisionid;
+ u32 ddrconf;
+ u32 ddrsize;
+ u32 ddrtiminga0;
+ u32 ddrtimingb0;
+ u32 ddrtimingc0;
+ u32 devtodev0;
+ u32 reserved0[(0x110 - 0x20) / 4];
+ u32 ddrmode;
+ u32 reserved1[(0x1000 - 0x114) / 4];
+ u32 agingx0;
+};
+
+struct rk3399_msch_timings {
+ u32 ddrtiminga0;
+ u32 ddrtimingb0;
+ u32 ddrtimingc0;
+ u32 devtodev0;
+ u32 ddrmode;
+ u32 agingx0;
+};
+
+struct rk3399_ddr_cic_regs {
+ u32 cic_ctrl0;
+ u32 cic_ctrl1;
+ u32 cic_idle_th;
+ u32 cic_cg_wait_th;
+ u32 cic_status0;
+ u32 cic_status1;
+ u32 cic_ctrl2;
+ u32 cic_ctrl3;
+ u32 cic_ctrl4;
+};
+
+/* DENALI_CTL_00 */
+#define START 1
+
+/* DENALI_CTL_68 */
+#define PWRUP_SREFRESH_EXIT (1 << 16)
+
+/* DENALI_CTL_274 */
+#define MEM_RST_VALID 1
+
+struct rk3399_sdram_channel {
+ unsigned int rank;
+ /* dram column number, 0 means this channel is invalid */
+ unsigned int col;
+ /* dram bank number, 3:8bank, 2:4bank */
+ unsigned int bk;
+ /* channel buswidth, 2:32bit, 1:16bit, 0:8bit */
+ unsigned int bw;
+ /* die buswidth, 2:32bit, 1:16bit, 0:8bit */
+ unsigned int dbw;
+ /*
+ * row_3_4 = 1: 6Gb or 12Gb die
+ * row_3_4 = 0: normal die, power of 2
+ */
+ unsigned int row_3_4;
+ unsigned int cs0_row;
+ unsigned int cs1_row;
+ unsigned int ddrconfig;
+ struct rk3399_msch_timings noc_timings;
+};
+
+struct rk3399_base_params {
+ unsigned int ddr_freq;
+ unsigned int dramtype;
+ unsigned int num_channels;
+ unsigned int stride;
+ unsigned int odt;
+};
+
+struct rk3399_sdram_params {
+ struct rk3399_sdram_channel ch[2];
+ struct rk3399_base_params base;
+ struct rk3399_ddr_pctl_regs pctl_regs;
+ struct rk3399_ddr_pi_regs pi_regs;
+ struct rk3399_ddr_publ_regs phy_regs;
+};
+
+#define PI_CA_TRAINING (1 << 0)
+#define PI_WRITE_LEVELING (1 << 1)
+#define PI_READ_GATE_TRAINING (1 << 2)
+#define PI_READ_LEVELING (1 << 3)
+#define PI_WDQ_LEVELING (1 << 4)
+#define PI_FULL_TRAINING 0xff
+
+#endif
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 5c4a4c2..bf8e6be 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -11,6 +11,21 @@ config ROCKCHIP_RK3036
and video codec support. Peripherals include Gigabit Ethernet,
USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
+config ROCKCHIP_RK3188
+ bool "Support Rockchip RK3188"
+ select CPU_V7
+ select SUPPORT_SPL
+ select SUPPORT_TPL
+ select SPL
+ select TPL
+ select ROCKCHIP_BROM_HELPER
+ help
+ The Rockchip RK3188 is a ARM-based SoC with a quad-core Cortex-A9
+ including NEON and GPU, 512KB L2 cache, Mali-400 graphics, two
+ video interfaces, several memory options and video codec support.
+ Peripherals include Fast Ethernet, USB2 host and OTG, SDIO, I2S,
+ UART, SPI, I2C and PWMs.
+
config ROCKCHIP_RK3288
bool "Support Rockchip RK3288"
select CPU_V7
@@ -23,9 +38,22 @@ config ROCKCHIP_RK3288
and video codec support. Peripherals include Gigabit Ethernet,
USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs.
+config ROCKCHIP_RK3328
+ bool "Support Rockchip RK3328"
+ select ARM64
+ help
+ The Rockchip RK3328 is a ARM-based SoC with a quad-core Cortex-A53.
+ including NEON and GPU, 1MB L2 cache, Mali-T7 graphics, two
+ video interfaces supporting HDMI and eDP, several DDR3 options
+ and video codec support. Peripherals include Gigabit Ethernet,
+ USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs.
+
config ROCKCHIP_RK3399
bool "Support Rockchip RK3399"
select ARM64
+ select SUPPORT_SPL
+ select SPL
+ select SPL_SEPARATE_BSS
help
The Rockchip RK3399 is a ARM-based SoC with a dual-core Cortex-A72
and quad-core Cortex-A53.
@@ -37,15 +65,21 @@ config ROCKCHIP_RK3399
config ROCKCHIP_SPL_BACK_TO_BROM
bool "SPL returns to bootrom"
default y if ROCKCHIP_RK3036
+ select ROCKCHIP_BROM_HELPER
help
Rockchip SoCs have ability to load SPL & U-Boot binary. If enabled,
SPL will return to the boot rom, which will then load the U-Boot
binary to keep going on.
+config ROCKCHIP_BROM_HELPER
+ bool
+
config SPL_MMC_SUPPORT
default y if !ROCKCHIP_SPL_BACK_TO_BROM
source "arch/arm/mach-rockchip/rk3036/Kconfig"
+source "arch/arm/mach-rockchip/rk3188/Kconfig"
source "arch/arm/mach-rockchip/rk3288/Kconfig"
+source "arch/arm/mach-rockchip/rk3328/Kconfig"
source "arch/arm/mach-rockchip/rk3399/Kconfig"
endif
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 6e79fed..6b251c7 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -4,11 +4,17 @@
# SPDX-License-Identifier: GPL-2.0+
#
-ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_TPL_BUILD
+obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board-tpl.o
+obj-$(CONFIG_ROCKCHIP_BROM_HELPER) += save_boot_param.o
+else ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o
+obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board-spl.o
obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-spl.o
-obj-$(CONFIG_ROCKCHIP_SPL_BACK_TO_BROM) += save_boot_param.o
+obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399-board-spl.o
+obj-$(CONFIG_ROCKCHIP_BROM_HELPER) += save_boot_param.o
else
+obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board.o
obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board.o
obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board.o
endif
@@ -16,5 +22,11 @@ ifndef CONFIG_ARM64
obj-y += rk_timer.o
endif
obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/
+
+ifndef CONFIG_TPL_BUILD
+obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188/
+endif
+
obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
+obj-$(CONFIG_ROCKCHIP_RK3328) += rk3328/
obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399/
diff --git a/arch/arm/mach-rockchip/rk3036-board-spl.c b/arch/arm/mach-rockchip/rk3036-board-spl.c
index 8015481..0522d65 100644
--- a/arch/arm/mach-rockchip/rk3036-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3036-board-spl.c
@@ -7,6 +7,7 @@
#include <common.h>
#include <debug_uart.h>
#include <asm/io.h>
+#include <asm/arch/bootrom.h>
#include <asm/arch/grf_rk3036.h>
#include <asm/arch/hardware.h>
#include <asm/arch/sdram_rk3036.h>
@@ -20,8 +21,6 @@ static struct rk3036_grf * const grf = (void *)GRF_BASE;
#define DEBUG_UART_BASE 0x20068000
-extern void back_to_bootrom(void);
-
void board_init_f(ulong dummy)
{
#ifdef EARLY_DEBUG
diff --git a/arch/arm/mach-rockchip/rk3188-board-spl.c b/arch/arm/mach-rockchip/rk3188-board-spl.c
new file mode 100644
index 0000000..f93feae
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3188-board-spl.c
@@ -0,0 +1,218 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <led.h>
+#include <malloc.h>
+#include <ram.h>
+#include <spl.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <asm/arch/bootrom.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/periph.h>
+#include <asm/arch/pmu_rk3188.h>
+#include <asm/arch/sdram.h>
+#include <asm/arch/timer.h>
+#include <dm/pinctrl.h>
+#include <dm/root.h>
+#include <dm/test.h>
+#include <dm/util.h>
+#include <power/regulator.h>
+#include <syscon.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+u32 spl_boot_device(void)
+{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ const void *blob = gd->fdt_blob;
+ struct udevice *dev;
+ const char *bootdev;
+ int node;
+ int ret;
+
+ bootdev = fdtdec_get_config_string(blob, "u-boot,boot0");
+ debug("Boot device %s\n", bootdev);
+ if (!bootdev)
+ goto fallback;
+
+ node = fdt_path_offset(blob, bootdev);
+ if (node < 0) {
+ debug("node=%d\n", node);
+ goto fallback;
+ }
+ ret = device_get_global_by_of_offset(node, &dev);
+ if (ret) {
+ debug("device at node %s/%d not found: %d\n", bootdev, node,
+ ret);
+ goto fallback;
+ }
+ debug("Found device %s\n", dev->name);
+ switch (device_get_uclass_id(dev)) {
+ case UCLASS_SPI_FLASH:
+ return BOOT_DEVICE_SPI;
+ case UCLASS_MMC:
+ return BOOT_DEVICE_MMC1;
+ default:
+ debug("Booting from device uclass '%s' not supported\n",
+ dev_get_uclass_name(dev));
+ }
+
+fallback:
+#endif
+ return BOOT_DEVICE_MMC1;
+}
+
+u32 spl_boot_mode(const u32 boot_device)
+{
+ return MMCSD_MODE_RAW;
+}
+
+void board_init_f(ulong dummy)
+{
+ struct udevice *pinctrl, *dev;
+ struct rk3188_pmu *pmu;
+ int ret;
+
+ /* Example code showing how to enable the debug UART on RK3188 */
+#ifdef EARLY_UART
+#include <asm/arch/grf_rk3188.h>
+ /* Enable early UART on the RK3188 */
+#define GRF_BASE 0x20008000
+ struct rk3188_grf * const grf = (void *)GRF_BASE;
+
+ rk_clrsetreg(&grf->gpio1b_iomux,
+ GPIO1B1_MASK << GPIO1B1_SHIFT |
+ GPIO1B0_MASK << GPIO1B0_SHIFT,
+ GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT |
+ GPIO1B0_UART2_SIN << GPIO1B0_SHIFT);
+ /*
+ * Debug UART can be used from here if required:
+ *
+ * debug_uart_init();
+ * printch('a');
+ * printhex8(0x1234);
+ * printascii("string");
+ */
+ debug_uart_init();
+ printch('s');
+ printch('p');
+ printch('l');
+ printch('\n');
+#endif
+
+ ret = spl_init();
+ if (ret) {
+ debug("spl_init() failed: %d\n", ret);
+ hang();
+ }
+
+ rockchip_timer_init();
+
+ ret = rockchip_get_clk(&dev);
+ if (ret) {
+ debug("CLK init failed: %d\n", ret);
+ return;
+ }
+
+ /*
+ * Recover the bootrom's stackpointer.
+ * For whatever reason needs to run after rockchip_get_clk.
+ */
+ pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
+ if (IS_ERR(pmu))
+ error("pmu syscon returned %ld\n", PTR_ERR(pmu));
+ SAVE_SP_ADDR = readl(&pmu->sys_reg[2]);
+
+ ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
+ if (ret) {
+ debug("Pinctrl init failed: %d\n", ret);
+ return;
+ }
+
+ ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+ if (ret) {
+ debug("DRAM init failed: %d\n", ret);
+ return;
+ }
+
+#if defined(CONFIG_ROCKCHIP_SPL_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT)
+ back_to_bootrom();
+#endif
+}
+
+static int setup_led(void)
+{
+#ifdef CONFIG_SPL_LED
+ struct udevice *dev;
+ char *led_name;
+ int ret;
+
+ led_name = fdtdec_get_config_string(gd->fdt_blob, "u-boot,boot-led");
+ if (!led_name)
+ return 0;
+ ret = led_get_by_label(led_name, &dev);
+ if (ret) {
+ debug("%s: get=%d\n", __func__, ret);
+ return ret;
+ }
+ ret = led_set_on(dev, 1);
+ if (ret)
+ return ret;
+#endif
+
+ return 0;
+}
+
+void spl_board_init(void)
+{
+ struct udevice *pinctrl;
+ int ret;
+
+ ret = setup_led();
+ if (ret) {
+ debug("LED ret=%d\n", ret);
+ hang();
+ }
+
+ ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
+ if (ret) {
+ debug("%s: Cannot find pinctrl device\n", __func__);
+ goto err;
+ }
+
+#ifdef CONFIG_SPL_MMC_SUPPORT
+ ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
+ if (ret) {
+ debug("%s: Failed to set up SD card\n", __func__);
+ goto err;
+ }
+#endif
+
+ /* 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();
+#ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
+ back_to_bootrom();
+#endif
+ return;
+
+err:
+ printf("spl_board_init: Error %d\n", ret);
+
+ /* No way to report error here */
+ hang();
+}
diff --git a/arch/arm/mach-rockchip/rk3188-board-tpl.c b/arch/arm/mach-rockchip/rk3188-board-tpl.c
new file mode 100644
index 0000000..442bfe7
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3188-board-tpl.c
@@ -0,0 +1,86 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/bootrom.h>
+#include <asm/arch/pmu_rk3188.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* track how often we were entered */
+static int rk3188_num_entries __attribute__ ((section(".data")));
+
+#define PMU_BASE 0x20004000
+#define TPL_ENTRY 0x10080C00
+
+static void jump_to_spl(void)
+{
+ typedef void __noreturn (*image_entry_noargs_t)(void);
+
+ struct rk3188_pmu * const pmu = (void *)PMU_BASE;
+ image_entry_noargs_t tpl_entry =
+ (image_entry_noargs_t)(unsigned long)TPL_ENTRY;
+
+ /* Store the SAVE_SP_ADDR in a location shared with TPL. */
+ writel(SAVE_SP_ADDR, &pmu->sys_reg[2]);
+ tpl_entry();
+}
+
+void board_init_f(ulong dummy)
+{
+ /* Example code showing how to enable the debug UART on RK3188 */
+#ifdef EARLY_UART
+#include <asm/arch/grf_rk3188.h>
+ /* Enable early UART on the RK3188 */
+#define GRF_BASE 0x20008000
+ struct rk3188_grf * const grf = (void *)GRF_BASE;
+
+ rk_clrsetreg(&grf->gpio1b_iomux,
+ GPIO1B1_MASK << GPIO1B1_SHIFT |
+ GPIO1B0_MASK << GPIO1B0_SHIFT,
+ GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT |
+ GPIO1B0_UART2_SIN << GPIO1B0_SHIFT);
+ /*
+ * Debug UART can be used from here if required:
+ *
+ * debug_uart_init();
+ * printch('a');
+ * printhex8(0x1234);
+ * printascii("string");
+ */
+ debug_uart_init();
+
+ printch('t');
+ printch('p');
+ printch('l');
+ printch('-');
+ printch(rk3188_num_entries + 1 + '0');
+ printch('\n');
+#endif
+
+ rk3188_num_entries++;
+
+ if (rk3188_num_entries == 1) {
+ /*
+ * The original loader did some very basic integrity
+ * checking at this point, but the remaining few bytes
+ * could be used for any improvement making sense
+ * really early on.
+ */
+
+ back_to_bootrom();
+ } else {
+ /*
+ * TPL part of the loader should now wait for us
+ * at offset 0xC00 in the sram. Should never return
+ * from there.
+ */
+ jump_to_spl();
+ }
+}
diff --git a/arch/arm/mach-rockchip/rk3188-board.c b/arch/arm/mach-rockchip/rk3188-board.c
new file mode 100644
index 0000000..16f3855
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3188-board.c
@@ -0,0 +1,71 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <ram.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/periph.h>
+#include <asm/arch/pmu_rk3288.h>
+#include <asm/arch/boot_mode.h>
+#include <asm/gpio.h>
+#include <dm/pinctrl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+#if defined(CONFIG_ROCKCHIP_SPL_BACK_TO_BROM)
+ struct udevice *pinctrl;
+ int ret;
+
+ /*
+ * We need to implement sdcard iomux here for the further
+ * initialization, otherwise, it'll hit sdcard command sending
+ * timeout exception.
+ */
+ ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
+ if (ret) {
+ debug("%s: Cannot find pinctrl device\n", __func__);
+ goto err;
+ }
+ ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
+ if (ret) {
+ debug("%s: Failed to set up SD card\n", __func__);
+ goto err;
+ }
+
+ return 0;
+err:
+ printf("board_init: Error %d\n", ret);
+
+ /* No way to report error here */
+ hang();
+
+ return -1;
+#else
+ return 0;
+#endif
+}
+
+int dram_init(void)
+{
+ /* FIXME: read back ram size from sys_reg2 */
+ gd->ram_size = 0x40000000;
+
+ return 0;
+}
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+void enable_caches(void)
+{
+ /* Enable D-cache. I-cache is already enabled in start.S */
+ dcache_enable();
+}
+#endif
diff --git a/arch/arm/mach-rockchip/rk3188/Kconfig b/arch/arm/mach-rockchip/rk3188/Kconfig
new file mode 100644
index 0000000..f8e1d03
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3188/Kconfig
@@ -0,0 +1,24 @@
+if ROCKCHIP_RK3188
+
+config SYS_SOC
+ default "rockchip"
+
+config SYS_MALLOC_F_LEN
+ default 0x0800
+
+config SPL_LIBCOMMON_SUPPORT
+ default y
+
+config SPL_LIBGENERIC_SUPPORT
+ default y
+
+config SPL_SERIAL_SUPPORT
+ default y
+
+config TPL_LIBCOMMON_SUPPORT
+ default y
+
+config TPL_SERIAL_SUPPORT
+ default y
+
+endif
diff --git a/arch/arm/mach-rockchip/rk3188/Makefile b/arch/arm/mach-rockchip/rk3188/Makefile
new file mode 100644
index 0000000..2dc9511
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3188/Makefile
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2015 Google, Inc
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+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/rk3188/clk_rk3188.c b/arch/arm/mach-rockchip/rk3188/clk_rk3188.c
new file mode 100644
index 0000000..1ec9e1c
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3188/clk_rk3188.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3188.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_GET_DRIVER(rockchip_rk3188_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+ struct rk3188_clk_priv *priv;
+ struct udevice *dev;
+ int ret;
+
+ ret = rockchip_get_clk(&dev);
+ if (ret)
+ return ERR_PTR(ret);
+
+ priv = dev_get_priv(dev);
+
+ return priv->cru;
+}
diff --git a/arch/arm/mach-rockchip/rk3188/sdram_rk3188.c b/arch/arm/mach-rockchip/rk3188/sdram_rk3188.c
new file mode 100644
index 0000000..461cfcd
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3188/sdram_rk3188.c
@@ -0,0 +1,995 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Copyright 2014 Rockchip Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ * Adapted from the very similar rk3288 ddr init.
+ */
+
+#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_rk3188.h>
+#include <asm/arch/ddr_rk3188.h>
+#include <asm/arch/grf_rk3188.h>
+#include <asm/arch/pmu_rk3188.h>
+#include <asm/arch/sdram.h>
+#include <linux/err.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct chan_info {
+ struct rk3288_ddr_pctl *pctl;
+ struct rk3288_ddr_publ *publ;
+ struct rk3188_msch *msch;
+};
+
+struct dram_info {
+ struct chan_info chan[1];
+ struct ram_info info;
+ struct clk ddr_clk;
+ struct rk3188_cru *cru;
+ struct rk3188_grf *grf;
+ struct rk3188_sgrf *sgrf;
+ struct rk3188_pmu *pmu;
+};
+
+struct rk3188_sdram_params {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_rockchip_rk3188_dmc of_plat;
+#endif
+ struct rk3288_sdram_channel ch[2];
+ struct rk3288_sdram_pctl_timing pctl_timing;
+ struct rk3288_sdram_phy_timing phy_timing;
+ struct rk3288_base_params base;
+ int num_channels;
+ struct regmap *map;
+};
+
+const int ddrconf_table[] = {
+ /*
+ * [5:4] row(13+n)
+ * [1:0] col(9+n), assume bw=2
+ * row col,bw
+ */
+ 0,
+ ((2 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
+ ((1 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
+ ((0 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
+ ((2 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
+ ((1 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
+ ((0 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
+ ((1 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT),
+ ((0 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+};
+
+#define TEST_PATTEN 0x5aa5f00f
+#define DQS_GATE_TRAINING_ERROR_RANK0 (1 << 4)
+#define DQS_GATE_TRAINING_ERROR_RANK1 (2 << 4)
+
+#ifdef CONFIG_SPL_BUILD
+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++;
+ }
+}
+
+static void ddr_reset(struct rk3188_cru *cru, u32 ch, u32 ctl, u32 phy)
+{
+ u32 phy_ctl_srstn_shift = 13;
+ u32 ctl_psrstn_shift = 11;
+ u32 ctl_srstn_shift = 10;
+ u32 phy_psrstn_shift = 9;
+ u32 phy_srstn_shift = 8;
+
+ rk_clrsetreg(&cru->cru_softrst_con[5],
+ 1 << phy_ctl_srstn_shift | 1 << ctl_psrstn_shift |
+ 1 << ctl_srstn_shift | 1 << phy_psrstn_shift |
+ 1 << phy_srstn_shift,
+ phy << phy_ctl_srstn_shift | ctl << ctl_psrstn_shift |
+ ctl << ctl_srstn_shift | phy << phy_psrstn_shift |
+ phy << phy_srstn_shift);
+}
+
+static void ddr_phy_ctl_reset(struct rk3188_cru *cru, u32 ch, u32 n)
+{
+ u32 phy_ctl_srstn_shift = 13;
+
+ rk_clrsetreg(&cru->cru_softrst_con[5],
+ 1 << phy_ctl_srstn_shift, n << phy_ctl_srstn_shift);
+}
+
+static void phy_pctrl_reset(struct rk3188_cru *cru,
+ struct rk3288_ddr_publ *publ,
+ int channel)
+{
+ int i;
+
+ ddr_reset(cru, channel, 1, 1);
+ udelay(1);
+ clrbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
+ for (i = 0; i < 4; i++)
+ clrbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
+
+ udelay(10);
+ setbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
+ for (i = 0; i < 4; i++)
+ setbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
+
+ udelay(10);
+ ddr_reset(cru, channel, 1, 0);
+ udelay(10);
+ ddr_reset(cru, channel, 0, 0);
+ udelay(10);
+}
+
+static void phy_dll_bypass_set(struct rk3288_ddr_publ *publ,
+ u32 freq)
+{
+ int i;
+
+ if (freq <= 250000000) {
+ if (freq <= 150000000)
+ clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
+ else
+ setbits_le32(&publ->dllgcr, SBIAS_BYPASS);
+ setbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
+ for (i = 0; i < 4; i++)
+ setbits_le32(&publ->datx8[i].dxdllcr,
+ DXDLLCR_DLLDIS);
+
+ setbits_le32(&publ->pir, PIR_DLLBYP);
+ } else {
+ clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
+ clrbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
+ for (i = 0; i < 4; i++) {
+ clrbits_le32(&publ->datx8[i].dxdllcr,
+ DXDLLCR_DLLDIS);
+ }
+
+ clrbits_le32(&publ->pir, PIR_DLLBYP);
+ }
+}
+
+static void dfi_cfg(struct rk3288_ddr_pctl *pctl, u32 dramtype)
+{
+ writel(DFI_INIT_START, &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(7 << TLP_RESP_TIME_SHIFT | LP_SR_EN | LP_PD_EN,
+ &pctl->dfilpcfg0);
+
+ writel(2 << TCTRL_DELAY_TIME_SHIFT, &pctl->dfitctrldelay);
+ writel(1 << TPHY_WRDATA_TIME_SHIFT, &pctl->dfitphywrdata);
+ writel(0xf << TPHY_RDLAT_TIME_SHIFT, &pctl->dfitphyrdlat);
+ writel(2 << TDRAM_CLK_DIS_TIME_SHIFT, &pctl->dfitdramclkdis);
+ writel(2 << TDRAM_CLK_EN_TIME_SHIFT, &pctl->dfitdramclken);
+ writel(1, &pctl->dfitphyupdtype0);
+
+ /* cs0 and cs1 write odt enable */
+ writel((RANK0_ODT_WRITE_SEL | RANK1_ODT_WRITE_SEL),
+ &pctl->dfiodtcfg);
+ /* odt write length */
+ writel(7 << ODT_LEN_BL8_W_SHIFT, &pctl->dfiodtcfg1);
+ /* phyupd and ctrlupd disabled */
+ writel(0, &pctl->dfiupdcfg);
+}
+
+static void ddr_set_enable(struct rk3188_grf *grf, uint channel, bool enable)
+{
+ uint val = 0;
+
+ if (enable)
+ val = 1 << DDR_16BIT_EN_SHIFT;
+
+ rk_clrsetreg(&grf->ddrc_con0, 1 << DDR_16BIT_EN_SHIFT, val);
+}
+
+static void ddr_set_ddr3_mode(struct rk3188_grf *grf, uint channel,
+ bool ddr3_mode)
+{
+ uint mask, val;
+
+ mask = MSCH4_MAINDDR3_MASK << MSCH4_MAINDDR3_SHIFT;
+ val = ddr3_mode << MSCH4_MAINDDR3_SHIFT;
+ rk_clrsetreg(&grf->soc_con2, mask, val);
+}
+
+static void ddr_rank_2_row15en(struct rk3188_grf *grf, bool enable)
+{
+ uint mask, val;
+
+ mask = RANK_TO_ROW15_EN_MASK << RANK_TO_ROW15_EN_SHIFT;
+ val = enable << RANK_TO_ROW15_EN_SHIFT;
+ rk_clrsetreg(&grf->soc_con2, mask, val);
+}
+
+static void pctl_cfg(int channel, struct rk3288_ddr_pctl *pctl,
+ struct rk3188_sdram_params *sdram_params,
+ struct rk3188_grf *grf)
+{
+ copy_to_reg(&pctl->togcnt1u, &sdram_params->pctl_timing.togcnt1u,
+ sizeof(sdram_params->pctl_timing));
+ switch (sdram_params->base.dramtype) {
+ case DDR3:
+ if (sdram_params->phy_timing.mr[1] & DDR3_DLL_DISABLE) {
+ writel(sdram_params->pctl_timing.tcl - 3,
+ &pctl->dfitrddataen);
+ } else {
+ writel(sdram_params->pctl_timing.tcl - 2,
+ &pctl->dfitrddataen);
+ }
+ writel(sdram_params->pctl_timing.tcwl - 1,
+ &pctl->dfitphywrlat);
+ 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);
+ ddr_set_ddr3_mode(grf, channel, true);
+ ddr_set_enable(grf, channel, true);
+ break;
+ }
+
+ setbits_le32(&pctl->scfg, 1);
+}
+
+static void phy_cfg(const struct chan_info *chan, int channel,
+ struct rk3188_sdram_params *sdram_params)
+{
+ struct rk3288_ddr_publ *publ = chan->publ;
+ struct rk3188_msch *msch = chan->msch;
+ uint ddr_freq_mhz = sdram_params->base.ddr_freq / 1000000;
+ u32 dinit2;
+ int i;
+
+ dinit2 = DIV_ROUND_UP(ddr_freq_mhz * 200000, 1000);
+ /* DDR PHY Timing */
+ copy_to_reg(&publ->dtpr[0], &sdram_params->phy_timing.dtpr0,
+ sizeof(sdram_params->phy_timing));
+ writel(sdram_params->base.noc_timing, &msch->ddrtiming);
+ writel(0x3f, &msch->readlatency);
+ writel(DIV_ROUND_UP(ddr_freq_mhz * 5120, 1000) << PRT_DLLLOCK_SHIFT |
+ DIV_ROUND_UP(ddr_freq_mhz * 50, 1000) << PRT_DLLSRST_SHIFT |
+ 8 << PRT_ITMSRST_SHIFT, &publ->ptr[0]);
+ writel(DIV_ROUND_UP(ddr_freq_mhz * 500000, 1000) << PRT_DINIT0_SHIFT |
+ DIV_ROUND_UP(ddr_freq_mhz * 400, 1000) << PRT_DINIT1_SHIFT,
+ &publ->ptr[1]);
+ writel(min(dinit2, 0x1ffffU) << PRT_DINIT2_SHIFT |
+ DIV_ROUND_UP(ddr_freq_mhz * 1000, 1000) << PRT_DINIT3_SHIFT,
+ &publ->ptr[2]);
+
+ switch (sdram_params->base.dramtype) {
+ case DDR3:
+ clrbits_le32(&publ->pgcr, 0x1f);
+ clrsetbits_le32(&publ->dcr, DDRMD_MASK << DDRMD_SHIFT,
+ DDRMD_DDR3 << DDRMD_SHIFT);
+ break;
+ }
+ if (sdram_params->base.odt) {
+ /*dynamic RTT enable */
+ for (i = 0; i < 4; i++)
+ setbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
+ } else {
+ /*dynamic RTT disable */
+ for (i = 0; i < 4; i++)
+ clrbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
+ }
+}
+
+static void phy_init(struct rk3288_ddr_publ *publ)
+{
+ setbits_le32(&publ->pir, PIR_INIT | PIR_DLLSRST
+ | PIR_DLLLOCK | PIR_ZCAL | PIR_ITMSRST | PIR_CLRSR);
+ udelay(1);
+ while ((readl(&publ->pgsr) &
+ (PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE)) !=
+ (PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE))
+ ;
+}
+
+static void send_command(struct rk3288_ddr_pctl *pctl, u32 rank,
+ u32 cmd, u32 arg)
+{
+ writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd);
+ udelay(1);
+ while (readl(&pctl->mcmd) & START_CMD)
+ ;
+}
+
+static inline void send_command_op(struct rk3288_ddr_pctl *pctl,
+ u32 rank, u32 cmd, u32 ma, u32 op)
+{
+ send_command(pctl, rank, cmd, (ma & LPDDR2_MA_MASK) << LPDDR2_MA_SHIFT |
+ (op & LPDDR2_OP_MASK) << LPDDR2_OP_SHIFT);
+}
+
+static void memory_init(struct rk3288_ddr_publ *publ,
+ u32 dramtype)
+{
+ setbits_le32(&publ->pir,
+ (PIR_INIT | PIR_DRAMINIT | PIR_LOCKBYP
+ | PIR_ZCALBYP | PIR_CLRSR | PIR_ICPC
+ | (dramtype == DDR3 ? PIR_DRAMRST : 0)));
+ udelay(1);
+ while ((readl(&publ->pgsr) & (PGSR_IDONE | PGSR_DLDONE))
+ != (PGSR_IDONE | PGSR_DLDONE))
+ ;
+}
+
+static void move_to_config_state(struct rk3288_ddr_publ *publ,
+ struct rk3288_ddr_pctl *pctl)
+{
+ unsigned int state;
+
+ while (1) {
+ state = readl(&pctl->stat) & PCTL_STAT_MSK;
+
+ switch (state) {
+ case LOW_POWER:
+ writel(WAKEUP_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MSK)
+ != ACCESS)
+ ;
+ /* wait DLL lock */
+ while ((readl(&publ->pgsr) & PGSR_DLDONE)
+ != PGSR_DLDONE)
+ ;
+ /*
+ * 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_MSK) != CONFIG)
+ ;
+ break;
+ case CONFIG:
+ return;
+ default:
+ break;
+ }
+ }
+}
+
+static void set_bandwidth_ratio(const struct chan_info *chan, int channel,
+ u32 n, struct rk3188_grf *grf)
+{
+ struct rk3288_ddr_pctl *pctl = chan->pctl;
+ struct rk3288_ddr_publ *publ = chan->publ;
+ struct rk3188_msch *msch = chan->msch;
+
+ if (n == 1) {
+ setbits_le32(&pctl->ppcfg, 1);
+ ddr_set_enable(grf, channel, 1);
+ setbits_le32(&msch->ddrtiming, 1 << 31);
+ /* Data Byte disable*/
+ clrbits_le32(&publ->datx8[2].dxgcr, 1);
+ clrbits_le32(&publ->datx8[3].dxgcr, 1);
+ /* disable DLL */
+ setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
+ setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
+ } else {
+ clrbits_le32(&pctl->ppcfg, 1);
+ ddr_set_enable(grf, channel, 0);
+ clrbits_le32(&msch->ddrtiming, 1 << 31);
+ /* Data Byte enable*/
+ setbits_le32(&publ->datx8[2].dxgcr, 1);
+ setbits_le32(&publ->datx8[3].dxgcr, 1);
+
+ /* enable DLL */
+ clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
+ clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
+ /* reset DLL */
+ clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
+ clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
+ udelay(10);
+ setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
+ setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
+ }
+ setbits_le32(&pctl->dfistcfg0, 1 << 2);
+}
+
+static int data_training(const struct chan_info *chan, int channel,
+ struct rk3188_sdram_params *sdram_params)
+{
+ unsigned int j;
+ int ret = 0;
+ u32 rank;
+ int i;
+ u32 step[2] = { PIR_QSTRN, PIR_RVTRN };
+ struct rk3288_ddr_publ *publ = chan->publ;
+ struct rk3288_ddr_pctl *pctl = chan->pctl;
+
+ /* disable auto refresh */
+ writel(0, &pctl->trefi);
+
+ if (sdram_params->base.dramtype != LPDDR3)
+ setbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
+ rank = sdram_params->ch[channel].rank | 1;
+ for (j = 0; j < ARRAY_SIZE(step); j++) {
+ /*
+ * trigger QSTRN and RVTRN
+ * clear DTDONE status
+ */
+ setbits_le32(&publ->pir, PIR_CLRSR);
+
+ /* trigger DTT */
+ setbits_le32(&publ->pir,
+ PIR_INIT | step[j] | PIR_LOCKBYP | PIR_ZCALBYP |
+ PIR_CLRSR);
+ udelay(1);
+ /* wait echo byte DTDONE */
+ while ((readl(&publ->datx8[0].dxgsr[0]) & rank)
+ != rank)
+ ;
+ while ((readl(&publ->datx8[1].dxgsr[0]) & rank)
+ != rank)
+ ;
+ if (!(readl(&pctl->ppcfg) & 1)) {
+ while ((readl(&publ->datx8[2].dxgsr[0])
+ & rank) != rank)
+ ;
+ while ((readl(&publ->datx8[3].dxgsr[0])
+ & rank) != rank)
+ ;
+ }
+ if (readl(&publ->pgsr) &
+ (PGSR_DTERR | PGSR_RVERR | PGSR_RVEIRR)) {
+ ret = -1;
+ break;
+ }
+ }
+ /* send some auto refresh to complement the lost while DTT */
+ for (i = 0; i < (rank > 1 ? 8 : 4); i++)
+ send_command(pctl, rank, REF_CMD, 0);
+
+ if (sdram_params->base.dramtype != LPDDR3)
+ clrbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
+
+ /* resume auto refresh */
+ writel(sdram_params->pctl_timing.trefi, &pctl->trefi);
+
+ return ret;
+}
+
+static void move_to_access_state(const struct chan_info *chan)
+{
+ struct rk3288_ddr_publ *publ = chan->publ;
+ struct rk3288_ddr_pctl *pctl = chan->pctl;
+ unsigned int state;
+
+ while (1) {
+ state = readl(&pctl->stat) & PCTL_STAT_MSK;
+
+ switch (state) {
+ case LOW_POWER:
+ if (((readl(&pctl->stat) >> LP_TRIG_SHIFT) &
+ LP_TRIG_MASK) == 1)
+ return;
+
+ writel(WAKEUP_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MSK) != ACCESS)
+ ;
+ /* wait DLL lock */
+ while ((readl(&publ->pgsr) & PGSR_DLDONE)
+ != PGSR_DLDONE)
+ ;
+ break;
+ case INIT_MEM:
+ writel(CFG_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG)
+ ;
+ /* fallthrough */
+ case CONFIG:
+ writel(GO_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MSK) == CONFIG)
+ ;
+ break;
+ case ACCESS:
+ return;
+ default:
+ break;
+ }
+ }
+}
+
+static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum,
+ struct rk3188_sdram_params *sdram_params)
+{
+ struct rk3288_ddr_publ *publ = chan->publ;
+
+ if (sdram_params->ch[chnum].bk == 3)
+ clrsetbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT,
+ 1 << PDQ_SHIFT);
+ else
+ clrbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT);
+
+ writel(sdram_params->base.ddrconfig, &chan->msch->ddrconf);
+}
+
+static void dram_all_config(const struct dram_info *dram,
+ struct rk3188_sdram_params *sdram_params)
+{
+ unsigned int chan;
+ u32 sys_reg = 0;
+
+ sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT;
+ sys_reg |= (sdram_params->num_channels - 1) << SYS_REG_NUM_CH_SHIFT;
+ for (chan = 0; chan < sdram_params->num_channels; chan++) {
+ const struct rk3288_sdram_channel *info =
+ &sdram_params->ch[chan];
+
+ sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(chan);
+ sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(chan);
+ sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(chan);
+ sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(chan);
+ sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(chan);
+ sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(chan);
+ sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(chan);
+ sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(chan);
+ sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(chan);
+
+ dram_cfg_rbc(&dram->chan[chan], chan, sdram_params);
+ }
+ if (sdram_params->ch[0].rank == 2)
+ ddr_rank_2_row15en(dram->grf, 0);
+ else
+ ddr_rank_2_row15en(dram->grf, 1);
+
+ writel(sys_reg, &dram->pmu->sys_reg[2]);
+}
+
+static int sdram_rank_bw_detect(struct dram_info *dram, int channel,
+ struct rk3188_sdram_params *sdram_params)
+{
+ int reg;
+ int need_trainig = 0;
+ const struct chan_info *chan = &dram->chan[channel];
+ struct rk3288_ddr_publ *publ = chan->publ;
+
+ ddr_rank_2_row15en(dram->grf, 0);
+
+ if (data_training(chan, channel, sdram_params) < 0) {
+ printf("first data training fail!\n");
+ reg = readl(&publ->datx8[0].dxgsr[0]);
+ /* Check the result for rank 0 */
+ if ((channel == 0) && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) {
+ printf("data training fail!\n");
+ return -EIO;
+ }
+
+ /* Check the result for rank 1 */
+ if (reg & DQS_GATE_TRAINING_ERROR_RANK1) {
+ sdram_params->ch[channel].rank = 1;
+ clrsetbits_le32(&publ->pgcr, 0xF << 18,
+ sdram_params->ch[channel].rank << 18);
+ need_trainig = 1;
+ }
+ reg = readl(&publ->datx8[2].dxgsr[0]);
+ if (reg & (1 << 4)) {
+ sdram_params->ch[channel].bw = 1;
+ set_bandwidth_ratio(chan, channel,
+ sdram_params->ch[channel].bw,
+ dram->grf);
+ need_trainig = 1;
+ }
+ }
+ /* Assume the Die bit width are the same with the chip bit width */
+ sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw;
+
+ if (need_trainig &&
+ (data_training(chan, channel, sdram_params) < 0)) {
+ if (sdram_params->base.dramtype == LPDDR3) {
+ ddr_phy_ctl_reset(dram->cru, channel, 1);
+ udelay(10);
+ ddr_phy_ctl_reset(dram->cru, channel, 0);
+ udelay(10);
+ }
+ printf("2nd data training failed!");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/*
+ * Detect ram columns and rows.
+ * @dram: dram info struct
+ * @channel: channel number to handle
+ * @sdram_params: sdram parameters, function will fill in col and row values
+ *
+ * Returns 0 or negative on error.
+ */
+static int sdram_col_row_detect(struct dram_info *dram, int channel,
+ struct rk3188_sdram_params *sdram_params)
+{
+ int row, col;
+ unsigned int addr;
+ const struct chan_info *chan = &dram->chan[channel];
+ struct rk3288_ddr_pctl *pctl = chan->pctl;
+ struct rk3288_ddr_publ *publ = chan->publ;
+ int ret = 0;
+
+ /* Detect col */
+ for (col = 11; col >= 9; col--) {
+ writel(0, CONFIG_SYS_SDRAM_BASE);
+ addr = CONFIG_SYS_SDRAM_BASE +
+ (1 << (col + sdram_params->ch[channel].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[channel].col = col;
+ }
+
+ ddr_rank_2_row15en(dram->grf, 1);
+ move_to_config_state(publ, pctl);
+ writel(1, &chan->msch->ddrconf);
+ move_to_access_state(chan);
+ /* Detect row, max 15,min13 in rk3188*/
+ for (row = 16; row >= 13; row--) {
+ writel(0, CONFIG_SYS_SDRAM_BASE);
+ addr = CONFIG_SYS_SDRAM_BASE + (1 << (row + 15 - 1));
+ writel(TEST_PATTEN, addr);
+ if ((readl(addr) == TEST_PATTEN) &&
+ (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+ break;
+ }
+ if (row == 12) {
+ printf("Row detect error\n");
+ ret = -EINVAL;
+ } else {
+ sdram_params->ch[channel].cs1_row = row;
+ sdram_params->ch[channel].row_3_4 = 0;
+ debug("chn %d col %d, row %d\n", channel, col, row);
+ sdram_params->ch[channel].cs0_row = row;
+ }
+
+out:
+ return ret;
+}
+
+static int sdram_get_niu_config(struct rk3188_sdram_params *sdram_params)
+{
+ int i, tmp, size, ret = 0;
+
+ 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);
+ size = sizeof(ddrconf_table)/sizeof(ddrconf_table[0]);
+ for (i = 0; i < size; i++)
+ if (tmp == ddrconf_table[i])
+ break;
+ if (i >= size) {
+ printf("niu config not found\n");
+ ret = -EINVAL;
+ } else {
+ debug("niu config %d\n", i);
+ sdram_params->base.ddrconfig = i;
+ }
+
+ return ret;
+}
+
+static int sdram_init(struct dram_info *dram,
+ struct rk3188_sdram_params *sdram_params)
+{
+ int channel;
+ int zqcr;
+ int ret;
+
+ if ((sdram_params->base.dramtype == DDR3 &&
+ sdram_params->base.ddr_freq > 800000000)) {
+ printf("SDRAM frequency is too high!");
+ return -E2BIG;
+ }
+
+ ret = clk_set_rate(&dram->ddr_clk, sdram_params->base.ddr_freq);
+ if (ret) {
+ printf("Could not set DDR clock\n");
+ return ret;
+ }
+
+ for (channel = 0; channel < 1; channel++) {
+ const struct chan_info *chan = &dram->chan[channel];
+ struct rk3288_ddr_pctl *pctl = chan->pctl;
+ struct rk3288_ddr_publ *publ = chan->publ;
+
+ phy_pctrl_reset(dram->cru, publ, channel);
+ phy_dll_bypass_set(publ, sdram_params->base.ddr_freq);
+
+ dfi_cfg(pctl, sdram_params->base.dramtype);
+
+ pctl_cfg(channel, pctl, sdram_params, dram->grf);
+
+ phy_cfg(chan, channel, sdram_params);
+
+ phy_init(publ);
+
+ writel(POWER_UP_START, &pctl->powctl);
+ while (!(readl(&pctl->powstat) & POWER_UP_DONE))
+ ;
+
+ memory_init(publ, sdram_params->base.dramtype);
+ move_to_config_state(publ, pctl);
+
+ /* Using 32bit bus width for detect */
+ sdram_params->ch[channel].bw = 2;
+ set_bandwidth_ratio(chan, channel,
+ sdram_params->ch[channel].bw, dram->grf);
+ /*
+ * set cs, using n=3 for detect
+ * CS0, n=1
+ * CS1, n=2
+ * CS0 & CS1, n = 3
+ */
+ sdram_params->ch[channel].rank = 2,
+ clrsetbits_le32(&publ->pgcr, 0xF << 18,
+ (sdram_params->ch[channel].rank | 1) << 18);
+
+ /* DS=40ohm,ODT=155ohm */
+ zqcr = 1 << ZDEN_SHIFT | 2 << PU_ONDIE_SHIFT |
+ 2 << PD_ONDIE_SHIFT | 0x19 << PU_OUTPUT_SHIFT |
+ 0x19 << PD_OUTPUT_SHIFT;
+ writel(zqcr, &publ->zq1cr[0]);
+ writel(zqcr, &publ->zq0cr[0]);
+
+ /* Detect the rank and bit-width with data-training */
+ writel(1, &chan->msch->ddrconf);
+ sdram_rank_bw_detect(dram, channel, sdram_params);
+
+ if (sdram_params->base.dramtype == LPDDR3) {
+ u32 i;
+ writel(0, &pctl->mrrcfg0);
+ for (i = 0; i < 17; i++)
+ send_command_op(pctl, 1, MRR_CMD, i, 0);
+ }
+ writel(4, &chan->msch->ddrconf);
+ move_to_access_state(chan);
+ /* DDR3 and LPDDR3 are always 8 bank, no need detect */
+ sdram_params->ch[channel].bk = 3;
+ /* Detect Col and Row number*/
+ ret = sdram_col_row_detect(dram, channel, sdram_params);
+ if (ret)
+ goto error;
+ }
+ /* Find NIU DDR configuration */
+ ret = sdram_get_niu_config(sdram_params);
+ if (ret)
+ goto error;
+
+ dram_all_config(dram, sdram_params);
+ debug("%s done\n", __func__);
+
+ return 0;
+error:
+ printf("DRAM init failed!\n");
+ hang();
+}
+#endif /* CONFIG_SPL_BUILD */
+
+size_t sdram_size_mb(struct rk3188_pmu *pmu)
+{
+ u32 rank, col, bk, cs0_row, cs1_row, bw, row_3_4;
+ size_t chipsize_mb = 0;
+ size_t size_mb = 0;
+ u32 ch;
+ u32 sys_reg = readl(&pmu->sys_reg[2]);
+ u32 chans;
+
+ chans = 1 + ((sys_reg >> SYS_REG_NUM_CH_SHIFT) & SYS_REG_NUM_CH_MASK);
+
+ for (ch = 0; ch < chans; ch++) {
+ rank = 1 + (sys_reg >> SYS_REG_RANK_SHIFT(ch) &
+ SYS_REG_RANK_MASK);
+ col = 9 + (sys_reg >> SYS_REG_COL_SHIFT(ch) & SYS_REG_COL_MASK);
+ bk = 3 - ((sys_reg >> SYS_REG_BK_SHIFT(ch)) & SYS_REG_BK_MASK);
+ cs0_row = 13 + (sys_reg >> SYS_REG_CS0_ROW_SHIFT(ch) &
+ SYS_REG_CS0_ROW_MASK);
+ cs1_row = 13 + (sys_reg >> SYS_REG_CS1_ROW_SHIFT(ch) &
+ SYS_REG_CS1_ROW_MASK);
+ bw = (2 >> ((sys_reg >> SYS_REG_BW_SHIFT(ch)) &
+ SYS_REG_BW_MASK));
+ row_3_4 = sys_reg >> SYS_REG_ROW_3_4_SHIFT(ch) &
+ SYS_REG_ROW_3_4_MASK;
+ chipsize_mb = (1 << (cs0_row + col + bk + bw - 20));
+
+ if (rank > 1)
+ chipsize_mb += chipsize_mb >>
+ (cs0_row - cs1_row);
+ if (row_3_4)
+ chipsize_mb = chipsize_mb * 3 / 4;
+ size_mb += chipsize_mb;
+ }
+
+ /* there can be no more than 2gb of memory */
+ size_mb = min(size_mb, 0x80000000 >> 20);
+
+ return size_mb;
+}
+
+#ifdef CONFIG_SPL_BUILD
+static int setup_sdram(struct udevice *dev)
+{
+ struct dram_info *priv = dev_get_priv(dev);
+ struct rk3188_sdram_params *params = dev_get_platdata(dev);
+
+ return sdram_init(priv, params);
+}
+
+static int rk3188_dmc_ofdata_to_platdata(struct udevice *dev)
+{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct rk3188_sdram_params *params = dev_get_platdata(dev);
+ const void *blob = gd->fdt_blob;
+ int node = dev->of_offset;
+ int ret;
+
+ /* rk3188 supports only one-channel */
+ 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_SPL_BUILD */
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int conv_of_platdata(struct udevice *dev)
+{
+ struct rk3188_sdram_params *plat = dev_get_platdata(dev);
+ struct dtd_rockchip_rk3188_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));
+ /* rk3188 supports dual-channel, set default channel num to 2 */
+ 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 rk3188_dmc_probe(struct udevice *dev)
+{
+#ifdef CONFIG_SPL_BUILD
+ struct rk3188_sdram_params *plat = dev_get_platdata(dev);
+#endif
+ struct dram_info *priv = dev_get_priv(dev);
+ struct regmap *map;
+ int ret;
+ struct udevice *dev_clk;
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ ret = conv_of_platdata(dev);
+ if (ret)
+ return ret;
+#endif
+ map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_NOC);
+ if (IS_ERR(map))
+ return PTR_ERR(map);
+ priv->chan[0].msch = regmap_get_range(map, 0);
+
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
+
+#ifdef CONFIG_SPL_BUILD
+ priv->chan[0].pctl = regmap_get_range(plat->map, 0);
+ priv->chan[0].publ = regmap_get_range(plat->map, 1);
+#endif
+
+ 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);
+#ifdef CONFIG_SPL_BUILD
+ ret = setup_sdram(dev);
+ if (ret)
+ return ret;
+#endif
+ priv->info.base = 0;
+ priv->info.size = sdram_size_mb(priv->pmu) << 20;
+
+ return 0;
+}
+
+static int rk3188_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 rk3188_dmc_ops = {
+ .get_info = rk3188_dmc_get_info,
+};
+
+static const struct udevice_id rk3188_dmc_ids[] = {
+ { .compatible = "rockchip,rk3188-dmc" },
+ { }
+};
+
+U_BOOT_DRIVER(dmc_rk3188) = {
+ .name = "rockchip_rk3188_dmc",
+ .id = UCLASS_RAM,
+ .of_match = rk3188_dmc_ids,
+ .ops = &rk3188_dmc_ops,
+#ifdef CONFIG_SPL_BUILD
+ .ofdata_to_platdata = rk3188_dmc_ofdata_to_platdata,
+#endif
+ .probe = rk3188_dmc_probe,
+ .priv_auto_alloc_size = sizeof(struct dram_info),
+#ifdef CONFIG_SPL_BUILD
+ .platdata_auto_alloc_size = sizeof(struct rk3188_sdram_params),
+#endif
+};
diff --git a/arch/arm/mach-rockchip/rk3188/syscon_rk3188.c b/arch/arm/mach-rockchip/rk3188/syscon_rk3188.c
new file mode 100644
index 0000000..aeee6bf
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3188/syscon_rk3188.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+
+static const struct udevice_id rk3188_syscon_ids[] = {
+ { .compatible = "rockchip,rk3188-noc", .data = ROCKCHIP_SYSCON_NOC },
+ { .compatible = "rockchip,rk3188-grf", .data = ROCKCHIP_SYSCON_GRF },
+ { .compatible = "rockchip,rk3188-pmu", .data = ROCKCHIP_SYSCON_PMU },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_rk3188) = {
+ .name = "rk3188_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3188_syscon_ids,
+};
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int rk3188_syscon_bind_of_platdata(struct udevice *dev)
+{
+ dev->driver_data = dev->driver->of_match->data;
+ debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(rockchip_rk3188_noc) = {
+ .name = "rockchip_rk3188_noc",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3188_syscon_ids,
+ .bind = rk3188_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_rk3188_grf) = {
+ .name = "rockchip_rk3188_grf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3188_syscon_ids + 1,
+ .bind = rk3188_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_rk3188_pmu) = {
+ .name = "rockchip_rk3188_pmu",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3188_syscon_ids + 2,
+ .bind = rk3188_syscon_bind_of_platdata,
+};
+#endif
diff --git a/arch/arm/mach-rockchip/rk3288-board-spl.c b/arch/arm/mach-rockchip/rk3288-board-spl.c
index 930939a..74f3379 100644
--- a/arch/arm/mach-rockchip/rk3288-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3288-board-spl.c
@@ -14,6 +14,7 @@
#include <spl.h>
#include <asm/gpio.h>
#include <asm/io.h>
+#include <asm/arch/bootrom.h>
#include <asm/arch/clock.h>
#include <asm/arch/hardware.h>
#include <asm/arch/periph.h>
@@ -155,7 +156,7 @@ static int configure_emmc(struct udevice *pinctrl)
return 0;
}
#endif
-extern void back_to_bootrom(void);
+
void board_init_f(ulong dummy)
{
struct udevice *pinctrl;
@@ -184,9 +185,9 @@ void board_init_f(ulong dummy)
debug_uart_init();
#endif
- ret = spl_init();
+ ret = spl_early_init();
if (ret) {
- debug("spl_init() failed: %d\n", ret);
+ debug("spl_early_init() failed: %d\n", ret);
hang();
}
diff --git a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
index 89fd8e6..8549b28 100644
--- a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
@@ -57,6 +57,26 @@ struct rk3288_sdram_params {
struct regmap *map;
};
+const int ddrconf_table[] = {
+ /* row col,bw */
+ 0,
+ ((1 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
+ ((2 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
+ ((3 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
+ ((4 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
+ ((1 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
+ ((2 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
+ ((3 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
+ ((1 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT),
+ ((2 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT),
+ ((3 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT),
+ 0,
+ 0,
+ 0,
+ 0,
+ ((4 << 4) | 2),
+};
+
#define TEST_PATTEN 0x5aa5f00f
#define DQS_GATE_TRAINING_ERROR_RANK0 (1 << 4)
#define DQS_GATE_TRAINING_ERROR_RANK1 (2 << 4)
@@ -100,7 +120,7 @@ static void ddr_phy_ctl_reset(struct rk3288_cru *cru, u32 ch, u32 n)
static void phy_pctrl_reset(struct rk3288_cru *cru,
struct rk3288_ddr_publ *publ,
- u32 channel)
+ int channel)
{
int i;
@@ -126,6 +146,7 @@ static void phy_dll_bypass_set(struct rk3288_ddr_publ *publ,
u32 freq)
{
int i;
+
if (freq <= 250000000) {
if (freq <= 150000000)
clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
@@ -217,7 +238,7 @@ static void ddr_set_en_bst_odt(struct rk3288_grf *grf, uint channel,
UPCTL0_LPDDR3_ODT_EN_SHIFT));
}
-static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl *pctl,
+static void pctl_cfg(int channel, struct rk3288_ddr_pctl *pctl,
struct rk3288_sdram_params *sdram_params,
struct rk3288_grf *grf)
{
@@ -267,7 +288,7 @@ static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl *pctl,
setbits_le32(&pctl->scfg, 1);
}
-static void phy_cfg(const struct chan_info *chan, u32 channel,
+static void phy_cfg(const struct chan_info *chan, int channel,
struct rk3288_sdram_params *sdram_params)
{
struct rk3288_ddr_publ *publ = chan->publ;
@@ -392,7 +413,8 @@ static void move_to_config_state(struct rk3288_ddr_publ *publ,
while ((readl(&publ->pgsr) & PGSR_DLDONE)
!= PGSR_DLDONE)
;
- /* if at low power state,need wakeup first,
+ /*
+ * if at low power state,need wakeup first,
* and then enter the config
* so here no break.
*/
@@ -411,7 +433,7 @@ static void move_to_config_state(struct rk3288_ddr_publ *publ,
}
}
-static void set_bandwidth_ratio(const struct chan_info *chan, u32 channel,
+static void set_bandwidth_ratio(const struct chan_info *chan, int channel,
u32 n, struct rk3288_grf *grf)
{
struct rk3288_ddr_pctl *pctl = chan->pctl;
@@ -449,7 +471,7 @@ static void set_bandwidth_ratio(const struct chan_info *chan, u32 channel,
setbits_le32(&pctl->dfistcfg0, 1 << 2);
}
-static int data_training(const struct chan_info *chan, u32 channel,
+static int data_training(const struct chan_info *chan, int channel,
struct rk3288_sdram_params *sdram_params)
{
unsigned int j;
@@ -593,25 +615,6 @@ static void dram_all_config(const struct dram_info *dram,
writel(sys_reg, &dram->pmu->sys_reg[2]);
rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, sdram_params->base.stride);
}
-const int ddrconf_table[] = {
- /* row col,bw */
- 0,
- ((1 << 4) | 1),
- ((2 << 4) | 1),
- ((3 << 4) | 1),
- ((4 << 4) | 1),
- ((1 << 4) | 2),
- ((2 << 4) | 2),
- ((3 << 4) | 2),
- ((1 << 4) | 0),
- ((2 << 4) | 0),
- ((3 << 4) | 0),
- 0,
- 0,
- 0,
- 0,
- ((4 << 4) | 2),
-};
static int sdram_rank_bw_detect(struct dram_info *dram, int channel,
struct rk3288_sdram_params *sdram_params)
@@ -621,12 +624,12 @@ static int sdram_rank_bw_detect(struct dram_info *dram, int channel,
const struct chan_info *chan = &dram->chan[channel];
struct rk3288_ddr_publ *publ = chan->publ;
- if (-1 == data_training(chan, channel, sdram_params)) {
+ if (data_training(chan, channel, sdram_params) < 0) {
reg = readl(&publ->datx8[0].dxgsr[0]);
/* Check the result for rank 0 */
if ((channel == 0) && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) {
debug("data training fail!\n");
- return -EIO;
+ return -EIO;
} else if ((channel == 1) &&
(reg & DQS_GATE_TRAINING_ERROR_RANK0)) {
sdram_params->num_channels = 1;
@@ -652,7 +655,7 @@ static int sdram_rank_bw_detect(struct dram_info *dram, int channel,
sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw;
if (need_trainig &&
- (-1 == data_training(chan, channel, sdram_params))) {
+ (data_training(chan, channel, sdram_params) < 0)) {
if (sdram_params->base.dramtype == LPDDR3) {
ddr_phy_ctl_reset(dram->cru, channel, 1);
udelay(10);
diff --git a/arch/arm/mach-rockchip/rk3328/Kconfig b/arch/arm/mach-rockchip/rk3328/Kconfig
new file mode 100644
index 0000000..43afba2
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3328/Kconfig
@@ -0,0 +1,23 @@
+if ROCKCHIP_RK3328
+
+choice
+ prompt "RK3328 board select"
+
+config TARGET_EVB_RK3328
+ bool "RK3328 evaluation board"
+ help
+ RK3328evb is a evaluation board for Rockchip rk3328,
+ with full function and phisical connectors support like
+ usb2.0 host ports, LVDS, JTAG, MAC, SDcard, HDMI, USB-2-serial...
+
+endchoice
+
+config SYS_SOC
+ default "rockchip"
+
+config SYS_MALLOC_F_LEN
+ default 0x0800
+
+source "board/rockchip/evb_rk3328/Kconfig"
+
+endif
diff --git a/arch/arm/mach-rockchip/rk3328/Makefile b/arch/arm/mach-rockchip/rk3328/Makefile
new file mode 100644
index 0000000..bbab036
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3328/Makefile
@@ -0,0 +1,9 @@
+#
+# (C) Copyright 2016 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += clk_rk3328.o
+obj-y += rk3328.o
+obj-y += syscon_rk3328.o
diff --git a/arch/arm/mach-rockchip/rk3328/clk_rk3328.c b/arch/arm/mach-rockchip/rk3328/clk_rk3328.c
new file mode 100644
index 0000000..1205516
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3328/clk_rk3328.c
@@ -0,0 +1,31 @@
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3328.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_GET_DRIVER(rockchip_rk3328_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+ struct rk3328_clk_priv *priv;
+ struct udevice *dev;
+ int ret;
+
+ ret = rockchip_get_clk(&dev);
+ if (ret)
+ return ERR_PTR(ret);
+
+ priv = dev_get_addr_ptr(dev);
+
+ return priv->cru;
+}
diff --git a/arch/arm/mach-rockchip/rk3328/rk3328.c b/arch/arm/mach-rockchip/rk3328/rk3328.c
new file mode 100644
index 0000000..857f014
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3328/rk3328.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/hardware.h>
+#include <asm/armv8/mmu.h>
+#include <asm/io.h>
+
+static struct mm_region rk3328_mem_map[] = {
+ {
+ .virt = 0x0UL,
+ .phys = 0x0UL,
+ .size = 0x80000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE
+ }, {
+ .virt = 0xf0000000UL,
+ .phys = 0xf0000000UL,
+ .size = 0x10000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* List terminator */
+ 0,
+ }
+};
+
+struct mm_region *mem_map = rk3328_mem_map;
+
+int arch_cpu_init(void)
+{
+ /* We do some SoC one time setting here. */
+
+ return 0;
+}
diff --git a/arch/arm/mach-rockchip/rk3328/syscon_rk3328.c b/arch/arm/mach-rockchip/rk3328/syscon_rk3328.c
new file mode 100644
index 0000000..a1a368f
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3328/syscon_rk3328.c
@@ -0,0 +1,20 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/clock.h>
+#include <dm.h>
+#include <syscon.h>
+
+static const struct udevice_id rk3328_syscon_ids[] = {
+ { .compatible = "rockchip,rk3328-grf", .data = ROCKCHIP_SYSCON_GRF },
+};
+
+U_BOOT_DRIVER(syscon_rk3328) = {
+ .name = "rk3328_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3328_syscon_ids,
+};
diff --git a/arch/arm/mach-rockchip/rk3399-board-spl.c b/arch/arm/mach-rockchip/rk3399-board-spl.c
new file mode 100644
index 0000000..8ae3055
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3399-board-spl.c
@@ -0,0 +1,158 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <led.h>
+#include <malloc.h>
+#include <ram.h>
+#include <spl.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/periph.h>
+#include <asm/arch/sdram.h>
+#include <asm/arch/timer.h>
+#include <dm/pinctrl.h>
+#include <dm/root.h>
+#include <dm/test.h>
+#include <dm/util.h>
+#include <power/regulator.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+u32 spl_boot_device(void)
+{
+ return BOOT_DEVICE_MMC1;
+}
+
+u32 spl_boot_mode(const u32 boot_device)
+{
+ return MMCSD_MODE_RAW;
+}
+
+#define TIMER_CHN10_BASE 0xff8680a0
+#define TIMER_END_COUNT_L 0x00
+#define TIMER_END_COUNT_H 0x04
+#define TIMER_INIT_COUNT_L 0x10
+#define TIMER_INIT_COUNT_H 0x14
+#define TIMER_CONTROL_REG 0x1c
+
+#define TIMER_EN 0x1
+#define TIMER_FMODE (0 << 1)
+#define TIMER_RMODE (1 << 1)
+
+void secure_timer_init(void)
+{
+ writel(0xffffffff, TIMER_CHN10_BASE + TIMER_END_COUNT_L);
+ writel(0xffffffff, TIMER_CHN10_BASE + TIMER_END_COUNT_H);
+ writel(0, TIMER_CHN10_BASE + TIMER_INIT_COUNT_L);
+ writel(0, TIMER_CHN10_BASE + TIMER_INIT_COUNT_H);
+ writel(TIMER_EN | TIMER_FMODE, TIMER_CHN10_BASE + TIMER_CONTROL_REG);
+}
+
+#define GRF_EMMCCORE_CON11 0xff77f02c
+void board_init_f(ulong dummy)
+{
+ struct udevice *pinctrl;
+ struct udevice *dev;
+ int ret;
+
+ /* Example code showing how to enable the debug UART on RK3288 */
+#include <asm/arch/grf_rk3399.h>
+ /* Enable early UART2 channel C on the RK3399 */
+#define GRF_BASE 0xff770000
+ struct rk3399_grf_regs * const grf = (void *)GRF_BASE;
+
+ rk_clrsetreg(&grf->gpio4c_iomux,
+ GRF_GPIO4C3_SEL_MASK,
+ GRF_UART2DGBC_SIN << GRF_GPIO4C3_SEL_SHIFT);
+ rk_clrsetreg(&grf->gpio4c_iomux,
+ GRF_GPIO4C4_SEL_MASK,
+ GRF_UART2DBGC_SOUT << GRF_GPIO4C4_SEL_SHIFT);
+ /* Set channel C as UART2 input */
+ rk_clrsetreg(&grf->soc_con7,
+ GRF_UART_DBG_SEL_MASK,
+ GRF_UART_DBG_SEL_C << GRF_UART_DBG_SEL_SHIFT);
+#define EARLY_UART
+#ifdef EARLY_UART
+ /*
+ * Debug UART can be used from here if required:
+ *
+ * debug_uart_init();
+ * printch('a');
+ * printhex8(0x1234);
+ * printascii("string");
+ */
+ debug_uart_init();
+ printascii("U-Boot SPL board init");
+#endif
+ /* Emmc clock generator: disable the clock multipilier */
+ rk_clrreg(GRF_EMMCCORE_CON11, 0x0ff);
+
+ ret = spl_init();
+ if (ret) {
+ debug("spl_init() failed: %d\n", ret);
+ hang();
+ }
+
+ secure_timer_init();
+
+ ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
+ if (ret) {
+ debug("Pinctrl 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 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();
+#ifdef CONFIG_ROCKCHIP_SPL_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)
+{
+ /* Just empty function now - can't decide what to choose */
+ debug("%s: %s\n", __func__, name);
+
+ return 0;
+}
+#endif
diff --git a/arch/arm/mach-rockchip/rk3399/Makefile b/arch/arm/mach-rockchip/rk3399/Makefile
index 98ebeac..793ce31 100644
--- a/arch/arm/mach-rockchip/rk3399/Makefile
+++ b/arch/arm/mach-rockchip/rk3399/Makefile
@@ -6,4 +6,5 @@
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/rk3399/clk_rk3399.c b/arch/arm/mach-rockchip/rk3399/clk_rk3399.c
index ce706a6..cf5b8c9 100644
--- a/arch/arm/mach-rockchip/rk3399/clk_rk3399.c
+++ b/arch/arm/mach-rockchip/rk3399/clk_rk3399.c
@@ -31,3 +31,24 @@ void *rockchip_get_cru(void)
return priv->cru;
}
+
+static int rockchip_get_pmucruclk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_GET_DRIVER(rockchip_rk3399_pmuclk), devp);
+}
+
+void *rockchip_get_pmucru(void)
+{
+ struct rk3399_pmuclk_priv *priv;
+ struct udevice *dev;
+ int ret;
+
+ ret = rockchip_get_pmucruclk(&dev);
+ if (ret)
+ return ERR_PTR(ret);
+
+ priv = dev_get_priv(dev);
+
+ return priv->pmucru;
+}
diff --git a/arch/arm/mach-rockchip/rk3399/rk3399.c b/arch/arm/mach-rockchip/rk3399/rk3399.c
index 8bb950e..cbfd3fa 100644
--- a/arch/arm/mach-rockchip/rk3399/rk3399.c
+++ b/arch/arm/mach-rockchip/rk3399/rk3399.c
@@ -40,5 +40,6 @@ int arch_cpu_init(void)
/* Emmc clock generator: disable the clock multipilier */
rk_clrreg(GRF_EMMCCORE_CON11, 0x0ff);
+ printf("time %x, %x\n", readl(0xff8680a8), readl(0xff8680ac));
return 0;
}
diff --git a/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c b/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c
new file mode 100644
index 0000000..749b52c
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c
@@ -0,0 +1,1321 @@
+/*
+ * (C) Copyright 2016-2017 Rockchip Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ * Adapted from coreboot.
+ */
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dt-structs.h>
+#include <ram.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sdram_rk3399.h>
+#include <asm/arch/cru_rk3399.h>
+#include <asm/arch/grf_rk3399.h>
+#include <asm/arch/hardware.h>
+#include <linux/err.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+struct chan_info {
+ struct rk3399_ddr_pctl_regs *pctl;
+ struct rk3399_ddr_pi_regs *pi;
+ struct rk3399_ddr_publ_regs *publ;
+ struct rk3399_msch_regs *msch;
+};
+
+struct dram_info {
+#ifdef CONFIG_SPL_BUILD
+ struct chan_info chan[2];
+ struct clk ddr_clk;
+ struct rk3399_cru *cru;
+ struct rk3399_pmucru *pmucru;
+ struct rk3399_pmusgrf_regs *pmusgrf;
+ struct rk3399_ddr_cic_regs *cic;
+#endif
+ struct ram_info info;
+ struct rk3399_pmugrf_regs *pmugrf;
+};
+
+/*
+ * sys_reg bitfield struct
+ * [31] row_3_4_ch1
+ * [30] row_3_4_ch0
+ * [29:28] chinfo
+ * [27] rank_ch1
+ * [26:25] col_ch1
+ * [24] bk_ch1
+ * [23:22] cs0_row_ch1
+ * [21:20] cs1_row_ch1
+ * [19:18] bw_ch1
+ * [17:16] dbw_ch1;
+ * [15:13] ddrtype
+ * [12] channelnum
+ * [11] rank_ch0
+ * [10:9] col_ch0
+ * [8] bk_ch0
+ * [7:6] cs0_row_ch0
+ * [5:4] cs1_row_ch0
+ * [3:2] bw_ch0
+ * [1:0] dbw_ch0
+*/
+#define SYS_REG_DDRTYPE_SHIFT 13
+#define SYS_REG_DDRTYPE_MASK 7
+#define SYS_REG_NUM_CH_SHIFT 12
+#define SYS_REG_NUM_CH_MASK 1
+#define SYS_REG_ROW_3_4_SHIFT(ch) (30 + (ch))
+#define SYS_REG_ROW_3_4_MASK 1
+#define SYS_REG_CHINFO_SHIFT(ch) (28 + (ch))
+#define SYS_REG_RANK_SHIFT(ch) (11 + (ch) * 16)
+#define SYS_REG_RANK_MASK 1
+#define SYS_REG_COL_SHIFT(ch) (9 + (ch) * 16)
+#define SYS_REG_COL_MASK 3
+#define SYS_REG_BK_SHIFT(ch) (8 + (ch) * 16)
+#define SYS_REG_BK_MASK 1
+#define SYS_REG_CS0_ROW_SHIFT(ch) (6 + (ch) * 16)
+#define SYS_REG_CS0_ROW_MASK 3
+#define SYS_REG_CS1_ROW_SHIFT(ch) (4 + (ch) * 16)
+#define SYS_REG_CS1_ROW_MASK 3
+#define SYS_REG_BW_SHIFT(ch) (2 + (ch) * 16)
+#define SYS_REG_BW_MASK 3
+#define SYS_REG_DBW_SHIFT(ch) ((ch) * 16)
+#define SYS_REG_DBW_MASK 3
+
+#define PRESET_SGRF_HOLD(n) ((0x1 << (6 + 16)) | ((n) << 6))
+#define PRESET_GPIO0_HOLD(n) ((0x1 << (7 + 16)) | ((n) << 7))
+#define PRESET_GPIO1_HOLD(n) ((0x1 << (8 + 16)) | ((n) << 8))
+
+#define PHY_DRV_ODT_Hi_Z 0x0
+#define PHY_DRV_ODT_240 0x1
+#define PHY_DRV_ODT_120 0x8
+#define PHY_DRV_ODT_80 0x9
+#define PHY_DRV_ODT_60 0xc
+#define PHY_DRV_ODT_48 0xd
+#define PHY_DRV_ODT_40 0xe
+#define PHY_DRV_ODT_34_3 0xf
+
+#ifdef CONFIG_SPL_BUILD
+
+struct rockchip_dmc_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_rockchip_rk3399_dmc dtplat;
+#else
+ struct rk3399_sdram_params sdram_params;
+#endif
+ struct regmap *map;
+};
+
+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++;
+ }
+}
+
+static void phy_dll_bypass_set(struct rk3399_ddr_publ_regs *ddr_publ_regs,
+ u32 freq)
+{
+ u32 *denali_phy = ddr_publ_regs->denali_phy;
+
+ /* From IP spec, only freq small than 125 can enter dll bypass mode */
+ if (freq <= 125) {
+ /* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8 */
+ setbits_le32(&denali_phy[86], (0x3 << 2) << 8);
+ setbits_le32(&denali_phy[214], (0x3 << 2) << 8);
+ setbits_le32(&denali_phy[342], (0x3 << 2) << 8);
+ setbits_le32(&denali_phy[470], (0x3 << 2) << 8);
+
+ /* phy_adrctl_sw_master_mode PHY_547/675/803 4bits offset_16 */
+ setbits_le32(&denali_phy[547], (0x3 << 2) << 16);
+ setbits_le32(&denali_phy[675], (0x3 << 2) << 16);
+ setbits_le32(&denali_phy[803], (0x3 << 2) << 16);
+ } else {
+ /* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8 */
+ clrbits_le32(&denali_phy[86], (0x3 << 2) << 8);
+ clrbits_le32(&denali_phy[214], (0x3 << 2) << 8);
+ clrbits_le32(&denali_phy[342], (0x3 << 2) << 8);
+ clrbits_le32(&denali_phy[470], (0x3 << 2) << 8);
+
+ /* phy_adrctl_sw_master_mode PHY_547/675/803 4bits offset_16 */
+ clrbits_le32(&denali_phy[547], (0x3 << 2) << 16);
+ clrbits_le32(&denali_phy[675], (0x3 << 2) << 16);
+ clrbits_le32(&denali_phy[803], (0x3 << 2) << 16);
+ }
+}
+
+static void set_memory_map(const struct chan_info *chan, u32 channel,
+ const struct rk3399_sdram_params *sdram_params)
+{
+ const struct rk3399_sdram_channel *sdram_ch =
+ &sdram_params->ch[channel];
+ u32 *denali_ctl = chan->pctl->denali_ctl;
+ u32 *denali_pi = chan->pi->denali_pi;
+ u32 cs_map;
+ u32 reduc;
+ u32 row;
+
+ /* Get row number from ddrconfig setting */
+ if (sdram_ch->ddrconfig < 2 || sdram_ch->ddrconfig == 4)
+ row = 16;
+ else if (sdram_ch->ddrconfig == 3)
+ row = 14;
+ else
+ row = 15;
+
+ cs_map = (sdram_ch->rank > 1) ? 3 : 1;
+ reduc = (sdram_ch->bw == 2) ? 0 : 1;
+
+ /* Set the dram configuration to ctrl */
+ clrsetbits_le32(&denali_ctl[191], 0xF, (12 - sdram_ch->col));
+ clrsetbits_le32(&denali_ctl[190], (0x3 << 16) | (0x7 << 24),
+ ((3 - sdram_ch->bk) << 16) |
+ ((16 - row) << 24));
+
+ clrsetbits_le32(&denali_ctl[196], 0x3 | (1 << 16),
+ cs_map | (reduc << 16));
+
+ /* PI_199 PI_COL_DIFF:RW:0:4 */
+ clrsetbits_le32(&denali_pi[199], 0xF, (12 - sdram_ch->col));
+
+ /* PI_155 PI_ROW_DIFF:RW:24:3 PI_BANK_DIFF:RW:16:2 */
+ clrsetbits_le32(&denali_pi[155], (0x3 << 16) | (0x7 << 24),
+ ((3 - sdram_ch->bk) << 16) |
+ ((16 - row) << 24));
+ /* PI_41 PI_CS_MAP:RW:24:4 */
+ clrsetbits_le32(&denali_pi[41], 0xf << 24, cs_map << 24);
+ if ((sdram_ch->rank == 1) && (sdram_params->base.dramtype == DDR3))
+ writel(0x2EC7FFFF, &denali_pi[34]);
+}
+
+static void set_ds_odt(const struct chan_info *chan,
+ const struct rk3399_sdram_params *sdram_params)
+{
+ u32 *denali_phy = chan->publ->denali_phy;
+
+ u32 tsel_idle_en, tsel_wr_en, tsel_rd_en;
+ u32 tsel_idle_select_p, tsel_wr_select_p, tsel_rd_select_p;
+ u32 ca_tsel_wr_select_p, ca_tsel_wr_select_n;
+ u32 tsel_idle_select_n, tsel_wr_select_n, tsel_rd_select_n;
+ u32 reg_value;
+
+ if (sdram_params->base.dramtype == LPDDR4) {
+ tsel_rd_select_p = PHY_DRV_ODT_Hi_Z;
+ tsel_wr_select_p = PHY_DRV_ODT_40;
+ ca_tsel_wr_select_p = PHY_DRV_ODT_40;
+ tsel_idle_select_p = PHY_DRV_ODT_Hi_Z;
+
+ tsel_rd_select_n = PHY_DRV_ODT_240;
+ tsel_wr_select_n = PHY_DRV_ODT_40;
+ ca_tsel_wr_select_n = PHY_DRV_ODT_40;
+ tsel_idle_select_n = PHY_DRV_ODT_240;
+ } else if (sdram_params->base.dramtype == LPDDR3) {
+ tsel_rd_select_p = PHY_DRV_ODT_240;
+ tsel_wr_select_p = PHY_DRV_ODT_34_3;
+ ca_tsel_wr_select_p = PHY_DRV_ODT_48;
+ tsel_idle_select_p = PHY_DRV_ODT_240;
+
+ tsel_rd_select_n = PHY_DRV_ODT_Hi_Z;
+ tsel_wr_select_n = PHY_DRV_ODT_34_3;
+ ca_tsel_wr_select_n = PHY_DRV_ODT_48;
+ tsel_idle_select_n = PHY_DRV_ODT_Hi_Z;
+ } else {
+ tsel_rd_select_p = PHY_DRV_ODT_240;
+ tsel_wr_select_p = PHY_DRV_ODT_34_3;
+ ca_tsel_wr_select_p = PHY_DRV_ODT_34_3;
+ tsel_idle_select_p = PHY_DRV_ODT_240;
+
+ tsel_rd_select_n = PHY_DRV_ODT_240;
+ tsel_wr_select_n = PHY_DRV_ODT_34_3;
+ ca_tsel_wr_select_n = PHY_DRV_ODT_34_3;
+ tsel_idle_select_n = PHY_DRV_ODT_240;
+ }
+
+ if (sdram_params->base.odt == 1)
+ tsel_rd_en = 1;
+ else
+ tsel_rd_en = 0;
+
+ tsel_wr_en = 0;
+ tsel_idle_en = 0;
+
+ /*
+ * phy_dq_tsel_select_X 24bits DENALI_PHY_6/134/262/390 offset_0
+ * sets termination values for read/idle cycles and drive strength
+ * for write cycles for DQ/DM
+ */
+ reg_value = tsel_rd_select_n | (tsel_rd_select_p << 0x4) |
+ (tsel_wr_select_n << 8) | (tsel_wr_select_p << 12) |
+ (tsel_idle_select_n << 16) | (tsel_idle_select_p << 20);
+ clrsetbits_le32(&denali_phy[6], 0xffffff, reg_value);
+ clrsetbits_le32(&denali_phy[134], 0xffffff, reg_value);
+ clrsetbits_le32(&denali_phy[262], 0xffffff, reg_value);
+ clrsetbits_le32(&denali_phy[390], 0xffffff, reg_value);
+
+ /*
+ * phy_dqs_tsel_select_X 24bits DENALI_PHY_7/135/263/391 offset_0
+ * sets termination values for read/idle cycles and drive strength
+ * for write cycles for DQS
+ */
+ clrsetbits_le32(&denali_phy[7], 0xffffff, reg_value);
+ clrsetbits_le32(&denali_phy[135], 0xffffff, reg_value);
+ clrsetbits_le32(&denali_phy[263], 0xffffff, reg_value);
+ clrsetbits_le32(&denali_phy[391], 0xffffff, reg_value);
+
+ /* phy_adr_tsel_select_ 8bits DENALI_PHY_544/672/800 offset_0 */
+ reg_value = ca_tsel_wr_select_n | (ca_tsel_wr_select_p << 0x4);
+ clrsetbits_le32(&denali_phy[544], 0xff, reg_value);
+ clrsetbits_le32(&denali_phy[672], 0xff, reg_value);
+ clrsetbits_le32(&denali_phy[800], 0xff, reg_value);
+
+ /* phy_pad_addr_drive 8bits DENALI_PHY_928 offset_0 */
+ clrsetbits_le32(&denali_phy[928], 0xff, reg_value);
+
+ /* phy_pad_rst_drive 8bits DENALI_PHY_937 offset_0 */
+ clrsetbits_le32(&denali_phy[937], 0xff, reg_value);
+
+ /* phy_pad_cke_drive 8bits DENALI_PHY_935 offset_0 */
+ clrsetbits_le32(&denali_phy[935], 0xff, reg_value);
+
+ /* phy_pad_cs_drive 8bits DENALI_PHY_939 offset_0 */
+ clrsetbits_le32(&denali_phy[939], 0xff, reg_value);
+
+ /* phy_pad_clk_drive 8bits DENALI_PHY_929 offset_0 */
+ clrsetbits_le32(&denali_phy[929], 0xff, reg_value);
+
+ /* phy_pad_fdbk_drive 23bit DENALI_PHY_924/925 */
+ clrsetbits_le32(&denali_phy[924], 0xff,
+ tsel_wr_select_n | (tsel_wr_select_p << 4));
+ clrsetbits_le32(&denali_phy[925], 0xff,
+ tsel_rd_select_n | (tsel_rd_select_p << 4));
+
+ /* phy_dq_tsel_enable_X 3bits DENALI_PHY_5/133/261/389 offset_16 */
+ reg_value = (tsel_rd_en | (tsel_wr_en << 1) | (tsel_idle_en << 2))
+ << 16;
+ clrsetbits_le32(&denali_phy[5], 0x7 << 16, reg_value);
+ clrsetbits_le32(&denali_phy[133], 0x7 << 16, reg_value);
+ clrsetbits_le32(&denali_phy[261], 0x7 << 16, reg_value);
+ clrsetbits_le32(&denali_phy[389], 0x7 << 16, reg_value);
+
+ /* phy_dqs_tsel_enable_X 3bits DENALI_PHY_6/134/262/390 offset_24 */
+ reg_value = (tsel_rd_en | (tsel_wr_en << 1) | (tsel_idle_en << 2))
+ << 24;
+ clrsetbits_le32(&denali_phy[6], 0x7 << 24, reg_value);
+ clrsetbits_le32(&denali_phy[134], 0x7 << 24, reg_value);
+ clrsetbits_le32(&denali_phy[262], 0x7 << 24, reg_value);
+ clrsetbits_le32(&denali_phy[390], 0x7 << 24, reg_value);
+
+ /* phy_adr_tsel_enable_ 1bit DENALI_PHY_518/646/774 offset_8 */
+ reg_value = tsel_wr_en << 8;
+ clrsetbits_le32(&denali_phy[518], 0x1 << 8, reg_value);
+ clrsetbits_le32(&denali_phy[646], 0x1 << 8, reg_value);
+ clrsetbits_le32(&denali_phy[774], 0x1 << 8, reg_value);
+
+ /* phy_pad_addr_term tsel 1bit DENALI_PHY_933 offset_17 */
+ reg_value = tsel_wr_en << 17;
+ clrsetbits_le32(&denali_phy[933], 0x1 << 17, reg_value);
+ /*
+ * pad_rst/cke/cs/clk_term tsel 1bits
+ * DENALI_PHY_938/936/940/934 offset_17
+ */
+ clrsetbits_le32(&denali_phy[938], 0x1 << 17, reg_value);
+ clrsetbits_le32(&denali_phy[936], 0x1 << 17, reg_value);
+ clrsetbits_le32(&denali_phy[940], 0x1 << 17, reg_value);
+ clrsetbits_le32(&denali_phy[934], 0x1 << 17, reg_value);
+
+ /* phy_pad_fdbk_term 1bit DENALI_PHY_930 offset_17 */
+ clrsetbits_le32(&denali_phy[930], 0x1 << 17, reg_value);
+}
+
+static int phy_io_config(const struct chan_info *chan,
+ const struct rk3399_sdram_params *sdram_params)
+{
+ u32 *denali_phy = chan->publ->denali_phy;
+ u32 vref_mode_dq, vref_value_dq, vref_mode_ac, vref_value_ac;
+ u32 mode_sel;
+ u32 reg_value;
+ u32 drv_value, odt_value;
+ u32 speed;
+
+ /* vref setting */
+ if (sdram_params->base.dramtype == LPDDR4) {
+ /* LPDDR4 */
+ vref_mode_dq = 0x6;
+ vref_value_dq = 0x1f;
+ vref_mode_ac = 0x6;
+ vref_value_ac = 0x1f;
+ } else if (sdram_params->base.dramtype == LPDDR3) {
+ if (sdram_params->base.odt == 1) {
+ vref_mode_dq = 0x5; /* LPDDR3 ODT */
+ drv_value = (readl(&denali_phy[6]) >> 12) & 0xf;
+ odt_value = (readl(&denali_phy[6]) >> 4) & 0xf;
+ if (drv_value == PHY_DRV_ODT_48) {
+ switch (odt_value) {
+ case PHY_DRV_ODT_240:
+ vref_value_dq = 0x16;
+ break;
+ case PHY_DRV_ODT_120:
+ vref_value_dq = 0x26;
+ break;
+ case PHY_DRV_ODT_60:
+ vref_value_dq = 0x36;
+ break;
+ default:
+ debug("Invalid ODT value.\n");
+ return -EINVAL;
+ }
+ } else if (drv_value == PHY_DRV_ODT_40) {
+ switch (odt_value) {
+ case PHY_DRV_ODT_240:
+ vref_value_dq = 0x19;
+ break;
+ case PHY_DRV_ODT_120:
+ vref_value_dq = 0x23;
+ break;
+ case PHY_DRV_ODT_60:
+ vref_value_dq = 0x31;
+ break;
+ default:
+ debug("Invalid ODT value.\n");
+ return -EINVAL;
+ }
+ } else if (drv_value == PHY_DRV_ODT_34_3) {
+ switch (odt_value) {
+ case PHY_DRV_ODT_240:
+ vref_value_dq = 0x17;
+ break;
+ case PHY_DRV_ODT_120:
+ vref_value_dq = 0x20;
+ break;
+ case PHY_DRV_ODT_60:
+ vref_value_dq = 0x2e;
+ break;
+ default:
+ debug("Invalid ODT value.\n");
+ return -EINVAL;
+ }
+ } else {
+ debug("Invalid DRV value.\n");
+ return -EINVAL;
+ }
+ } else {
+ vref_mode_dq = 0x2; /* LPDDR3 */
+ vref_value_dq = 0x1f;
+ }
+ vref_mode_ac = 0x2;
+ vref_value_ac = 0x1f;
+ } else if (sdram_params->base.dramtype == DDR3) {
+ /* DDR3L */
+ vref_mode_dq = 0x1;
+ vref_value_dq = 0x1f;
+ vref_mode_ac = 0x1;
+ vref_value_ac = 0x1f;
+ } else {
+ debug("Unknown DRAM type.\n");
+ return -EINVAL;
+ }
+
+ reg_value = (vref_mode_dq << 9) | (0x1 << 8) | vref_value_dq;
+
+ /* PHY_913 PHY_PAD_VREF_CTRL_DQ_0 12bits offset_8 */
+ clrsetbits_le32(&denali_phy[913], 0xfff << 8, reg_value << 8);
+ /* PHY_914 PHY_PAD_VREF_CTRL_DQ_1 12bits offset_0 */
+ clrsetbits_le32(&denali_phy[914], 0xfff, reg_value);
+ /* PHY_914 PHY_PAD_VREF_CTRL_DQ_2 12bits offset_16 */
+ clrsetbits_le32(&denali_phy[914], 0xfff << 16, reg_value << 16);
+ /* PHY_915 PHY_PAD_VREF_CTRL_DQ_3 12bits offset_0 */
+ clrsetbits_le32(&denali_phy[915], 0xfff, reg_value);
+
+ reg_value = (vref_mode_ac << 9) | (0x1 << 8) | vref_value_ac;
+
+ /* PHY_915 PHY_PAD_VREF_CTRL_AC 12bits offset_16 */
+ clrsetbits_le32(&denali_phy[915], 0xfff << 16, reg_value << 16);
+
+ if (sdram_params->base.dramtype == LPDDR4)
+ mode_sel = 0x6;
+ else if (sdram_params->base.dramtype == LPDDR3)
+ mode_sel = 0x0;
+ else if (sdram_params->base.dramtype == DDR3)
+ mode_sel = 0x1;
+ else
+ return -EINVAL;
+
+ /* PHY_924 PHY_PAD_FDBK_DRIVE */
+ clrsetbits_le32(&denali_phy[924], 0x7 << 15, mode_sel << 15);
+ /* PHY_926 PHY_PAD_DATA_DRIVE */
+ clrsetbits_le32(&denali_phy[926], 0x7 << 6, mode_sel << 6);
+ /* PHY_927 PHY_PAD_DQS_DRIVE */
+ clrsetbits_le32(&denali_phy[927], 0x7 << 6, mode_sel << 6);
+ /* PHY_928 PHY_PAD_ADDR_DRIVE */
+ clrsetbits_le32(&denali_phy[928], 0x7 << 14, mode_sel << 14);
+ /* PHY_929 PHY_PAD_CLK_DRIVE */
+ clrsetbits_le32(&denali_phy[929], 0x7 << 14, mode_sel << 14);
+ /* PHY_935 PHY_PAD_CKE_DRIVE */
+ clrsetbits_le32(&denali_phy[935], 0x7 << 14, mode_sel << 14);
+ /* PHY_937 PHY_PAD_RST_DRIVE */
+ clrsetbits_le32(&denali_phy[937], 0x7 << 14, mode_sel << 14);
+ /* PHY_939 PHY_PAD_CS_DRIVE */
+ clrsetbits_le32(&denali_phy[939], 0x7 << 14, mode_sel << 14);
+
+
+ /* speed setting */
+ if (sdram_params->base.ddr_freq < 400)
+ speed = 0x0;
+ else if (sdram_params->base.ddr_freq < 800)
+ speed = 0x1;
+ else if (sdram_params->base.ddr_freq < 1200)
+ speed = 0x2;
+ else
+ speed = 0x3;
+
+ /* PHY_924 PHY_PAD_FDBK_DRIVE */
+ clrsetbits_le32(&denali_phy[924], 0x3 << 21, speed << 21);
+ /* PHY_926 PHY_PAD_DATA_DRIVE */
+ clrsetbits_le32(&denali_phy[926], 0x3 << 9, speed << 9);
+ /* PHY_927 PHY_PAD_DQS_DRIVE */
+ clrsetbits_le32(&denali_phy[927], 0x3 << 9, speed << 9);
+ /* PHY_928 PHY_PAD_ADDR_DRIVE */
+ clrsetbits_le32(&denali_phy[928], 0x3 << 17, speed << 17);
+ /* PHY_929 PHY_PAD_CLK_DRIVE */
+ clrsetbits_le32(&denali_phy[929], 0x3 << 17, speed << 17);
+ /* PHY_935 PHY_PAD_CKE_DRIVE */
+ clrsetbits_le32(&denali_phy[935], 0x3 << 17, speed << 17);
+ /* PHY_937 PHY_PAD_RST_DRIVE */
+ clrsetbits_le32(&denali_phy[937], 0x3 << 17, speed << 17);
+ /* PHY_939 PHY_PAD_CS_DRIVE */
+ clrsetbits_le32(&denali_phy[939], 0x3 << 17, speed << 17);
+
+ return 0;
+}
+
+static int pctl_cfg(const struct chan_info *chan, u32 channel,
+ const struct rk3399_sdram_params *sdram_params)
+{
+ u32 *denali_ctl = chan->pctl->denali_ctl;
+ u32 *denali_pi = chan->pi->denali_pi;
+ u32 *denali_phy = chan->publ->denali_phy;
+ const u32 *params_ctl = sdram_params->pctl_regs.denali_ctl;
+ const u32 *params_phy = sdram_params->phy_regs.denali_phy;
+ u32 tmp, tmp1, tmp2;
+ u32 pwrup_srefresh_exit;
+ int ret;
+
+ /*
+ * work around controller bug:
+ * Do not program DRAM_CLASS until NO_PHY_IND_TRAIN_INT is programmed
+ */
+ copy_to_reg(&denali_ctl[1], &params_ctl[1],
+ sizeof(struct rk3399_ddr_pctl_regs) - 4);
+ writel(params_ctl[0], &denali_ctl[0]);
+ copy_to_reg(denali_pi, &sdram_params->pi_regs.denali_pi[0],
+ sizeof(struct rk3399_ddr_pi_regs));
+ /* rank count need to set for init */
+ set_memory_map(chan, channel, sdram_params);
+
+ writel(sdram_params->phy_regs.denali_phy[910], &denali_phy[910]);
+ writel(sdram_params->phy_regs.denali_phy[911], &denali_phy[911]);
+ writel(sdram_params->phy_regs.denali_phy[912], &denali_phy[912]);
+
+ pwrup_srefresh_exit = readl(&denali_ctl[68]) & PWRUP_SREFRESH_EXIT;
+ clrbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT);
+
+ /* PHY_DLL_RST_EN */
+ clrsetbits_le32(&denali_phy[957], 0x3 << 24, 1 << 24);
+
+ setbits_le32(&denali_pi[0], START);
+ setbits_le32(&denali_ctl[0], START);
+
+ /* Wating for phy DLL lock */
+ while (1) {
+ tmp = readl(&denali_phy[920]);
+ tmp1 = readl(&denali_phy[921]);
+ tmp2 = readl(&denali_phy[922]);
+ if ((((tmp >> 16) & 0x1) == 0x1) &&
+ (((tmp1 >> 16) & 0x1) == 0x1) &&
+ (((tmp1 >> 0) & 0x1) == 0x1) &&
+ (((tmp2 >> 0) & 0x1) == 0x1))
+ break;
+ }
+
+ copy_to_reg(&denali_phy[896], &params_phy[896], (958 - 895) * 4);
+ copy_to_reg(&denali_phy[0], &params_phy[0], (90 - 0 + 1) * 4);
+ copy_to_reg(&denali_phy[128], &params_phy[128], (218 - 128 + 1) * 4);
+ copy_to_reg(&denali_phy[256], &params_phy[256], (346 - 256 + 1) * 4);
+ copy_to_reg(&denali_phy[384], &params_phy[384], (474 - 384 + 1) * 4);
+ copy_to_reg(&denali_phy[512], &params_phy[512], (549 - 512 + 1) * 4);
+ copy_to_reg(&denali_phy[640], &params_phy[640], (677 - 640 + 1) * 4);
+ copy_to_reg(&denali_phy[768], &params_phy[768], (805 - 768 + 1) * 4);
+ set_ds_odt(chan, sdram_params);
+
+ /*
+ * phy_dqs_tsel_wr_timing_X 8bits DENALI_PHY_84/212/340/468 offset_8
+ * dqs_tsel_wr_end[7:4] add Half cycle
+ */
+ tmp = (readl(&denali_phy[84]) >> 8) & 0xff;
+ clrsetbits_le32(&denali_phy[84], 0xff << 8, (tmp + 0x10) << 8);
+ tmp = (readl(&denali_phy[212]) >> 8) & 0xff;
+ clrsetbits_le32(&denali_phy[212], 0xff << 8, (tmp + 0x10) << 8);
+ tmp = (readl(&denali_phy[340]) >> 8) & 0xff;
+ clrsetbits_le32(&denali_phy[340], 0xff << 8, (tmp + 0x10) << 8);
+ tmp = (readl(&denali_phy[468]) >> 8) & 0xff;
+ clrsetbits_le32(&denali_phy[468], 0xff << 8, (tmp + 0x10) << 8);
+
+ /*
+ * phy_dqs_tsel_wr_timing_X 8bits DENALI_PHY_83/211/339/467 offset_8
+ * dq_tsel_wr_end[7:4] add Half cycle
+ */
+ tmp = (readl(&denali_phy[83]) >> 16) & 0xff;
+ clrsetbits_le32(&denali_phy[83], 0xff << 16, (tmp + 0x10) << 16);
+ tmp = (readl(&denali_phy[211]) >> 16) & 0xff;
+ clrsetbits_le32(&denali_phy[211], 0xff << 16, (tmp + 0x10) << 16);
+ tmp = (readl(&denali_phy[339]) >> 16) & 0xff;
+ clrsetbits_le32(&denali_phy[339], 0xff << 16, (tmp + 0x10) << 16);
+ tmp = (readl(&denali_phy[467]) >> 16) & 0xff;
+ clrsetbits_le32(&denali_phy[467], 0xff << 16, (tmp + 0x10) << 16);
+
+ ret = phy_io_config(chan, sdram_params);
+ if (ret)
+ return ret;
+
+ /* PHY_DLL_RST_EN */
+ clrsetbits_le32(&denali_phy[957], 0x3 << 24, 0x2 << 24);
+
+ /* Wating for PHY and DRAM init complete */
+ tmp = 0;
+ while (!(readl(&denali_ctl[203]) & (1 << 3))) {
+ mdelay(10);
+ tmp++;
+ if (tmp > 10)
+ return -ETIME;
+ }
+
+ clrsetbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT,
+ pwrup_srefresh_exit);
+ return 0;
+}
+
+static void select_per_cs_training_index(const struct chan_info *chan,
+ u32 rank)
+{
+ u32 *denali_phy = chan->publ->denali_phy;
+
+ /* PHY_84 PHY_PER_CS_TRAINING_EN_0 1bit offset_16 */
+ if ((readl(&denali_phy[84])>>16) & 1) {
+ /*
+ * PHY_8/136/264/392
+ * phy_per_cs_training_index_X 1bit offset_24
+ */
+ clrsetbits_le32(&denali_phy[8], 0x1 << 24, rank << 24);
+ clrsetbits_le32(&denali_phy[136], 0x1 << 24, rank << 24);
+ clrsetbits_le32(&denali_phy[264], 0x1 << 24, rank << 24);
+ clrsetbits_le32(&denali_phy[392], 0x1 << 24, rank << 24);
+ }
+}
+
+static void override_write_leveling_value(const struct chan_info *chan)
+{
+ u32 *denali_ctl = chan->pctl->denali_ctl;
+ u32 *denali_phy = chan->publ->denali_phy;
+ u32 byte;
+
+ /* PHY_896 PHY_FREQ_SEL_MULTICAST_EN 1bit offset_0 */
+ setbits_le32(&denali_phy[896], 1);
+
+ /*
+ * PHY_8/136/264/392
+ * phy_per_cs_training_multicast_en_X 1bit offset_16
+ */
+ clrsetbits_le32(&denali_phy[8], 0x1 << 16, 1 << 16);
+ clrsetbits_le32(&denali_phy[136], 0x1 << 16, 1 << 16);
+ clrsetbits_le32(&denali_phy[264], 0x1 << 16, 1 << 16);
+ clrsetbits_le32(&denali_phy[392], 0x1 << 16, 1 << 16);
+
+ for (byte = 0; byte < 4; byte++)
+ clrsetbits_le32(&denali_phy[63 + (128 * byte)], 0xffff << 16,
+ 0x200 << 16);
+
+ /* PHY_896 PHY_FREQ_SEL_MULTICAST_EN 1bit offset_0 */
+ clrbits_le32(&denali_phy[896], 1);
+
+ /* CTL_200 ctrlupd_req 1bit offset_8 */
+ clrsetbits_le32(&denali_ctl[200], 0x1 << 8, 0x1 << 8);
+}
+
+static int data_training_ca(const struct chan_info *chan, u32 channel,
+ const struct rk3399_sdram_params *sdram_params)
+{
+ u32 *denali_pi = chan->pi->denali_pi;
+ u32 *denali_phy = chan->publ->denali_phy;
+ u32 i, tmp;
+ u32 obs_0, obs_1, obs_2, obs_err = 0;
+ u32 rank = sdram_params->ch[channel].rank;
+
+ for (i = 0; i < rank; i++) {
+ select_per_cs_training_index(chan, i);
+ /* PI_100 PI_CALVL_EN:RW:8:2 */
+ clrsetbits_le32(&denali_pi[100], 0x3 << 8, 0x2 << 8);
+ /* PI_92 PI_CALVL_REQ:WR:16:1,PI_CALVL_CS:RW:24:2 */
+ clrsetbits_le32(&denali_pi[92],
+ (0x1 << 16) | (0x3 << 24),
+ (0x1 << 16) | (i << 24));
+
+ /* Waiting for training complete */
+ while (1) {
+ /* PI_174 PI_INT_STATUS:RD:8:18 */
+ tmp = readl(&denali_pi[174]) >> 8;
+ /*
+ * check status obs
+ * PHY_532/660/789 phy_adr_calvl_obs1_:0:32
+ */
+ obs_0 = readl(&denali_phy[532]);
+ obs_1 = readl(&denali_phy[660]);
+ obs_2 = readl(&denali_phy[788]);
+ if (((obs_0 >> 30) & 0x3) ||
+ ((obs_1 >> 30) & 0x3) ||
+ ((obs_2 >> 30) & 0x3))
+ obs_err = 1;
+ if ((((tmp >> 11) & 0x1) == 0x1) &&
+ (((tmp >> 13) & 0x1) == 0x1) &&
+ (((tmp >> 5) & 0x1) == 0x0) &&
+ (obs_err == 0))
+ break;
+ else if ((((tmp >> 5) & 0x1) == 0x1) ||
+ (obs_err == 1))
+ return -EIO;
+ }
+ /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
+ writel(0x00003f7c, (&denali_pi[175]));
+ }
+ clrbits_le32(&denali_pi[100], 0x3 << 8);
+
+ return 0;
+}
+
+static int data_training_wl(const struct chan_info *chan, u32 channel,
+ const struct rk3399_sdram_params *sdram_params)
+{
+ u32 *denali_pi = chan->pi->denali_pi;
+ u32 *denali_phy = chan->publ->denali_phy;
+ u32 i, tmp;
+ u32 obs_0, obs_1, obs_2, obs_3, obs_err = 0;
+ u32 rank = sdram_params->ch[channel].rank;
+
+ for (i = 0; i < rank; i++) {
+ select_per_cs_training_index(chan, i);
+ /* PI_60 PI_WRLVL_EN:RW:8:2 */
+ clrsetbits_le32(&denali_pi[60], 0x3 << 8, 0x2 << 8);
+ /* PI_59 PI_WRLVL_REQ:WR:8:1,PI_WRLVL_CS:RW:16:2 */
+ clrsetbits_le32(&denali_pi[59],
+ (0x1 << 8) | (0x3 << 16),
+ (0x1 << 8) | (i << 16));
+
+ /* Waiting for training complete */
+ while (1) {
+ /* PI_174 PI_INT_STATUS:RD:8:18 */
+ tmp = readl(&denali_pi[174]) >> 8;
+
+ /*
+ * check status obs, if error maybe can not
+ * get leveling done PHY_40/168/296/424
+ * phy_wrlvl_status_obs_X:0:13
+ */
+ obs_0 = readl(&denali_phy[40]);
+ obs_1 = readl(&denali_phy[168]);
+ obs_2 = readl(&denali_phy[296]);
+ obs_3 = readl(&denali_phy[424]);
+ if (((obs_0 >> 12) & 0x1) ||
+ ((obs_1 >> 12) & 0x1) ||
+ ((obs_2 >> 12) & 0x1) ||
+ ((obs_3 >> 12) & 0x1))
+ obs_err = 1;
+ if ((((tmp >> 10) & 0x1) == 0x1) &&
+ (((tmp >> 13) & 0x1) == 0x1) &&
+ (((tmp >> 4) & 0x1) == 0x0) &&
+ (obs_err == 0))
+ break;
+ else if ((((tmp >> 4) & 0x1) == 0x1) ||
+ (obs_err == 1))
+ return -EIO;
+ }
+ /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
+ writel(0x00003f7c, (&denali_pi[175]));
+ }
+
+ override_write_leveling_value(chan);
+ clrbits_le32(&denali_pi[60], 0x3 << 8);
+
+ return 0;
+}
+
+static int data_training_rg(const struct chan_info *chan, u32 channel,
+ const struct rk3399_sdram_params *sdram_params)
+{
+ u32 *denali_pi = chan->pi->denali_pi;
+ u32 *denali_phy = chan->publ->denali_phy;
+ u32 i, tmp;
+ u32 obs_0, obs_1, obs_2, obs_3, obs_err = 0;
+ u32 rank = sdram_params->ch[channel].rank;
+
+ for (i = 0; i < rank; i++) {
+ select_per_cs_training_index(chan, i);
+ /* PI_80 PI_RDLVL_GATE_EN:RW:24:2 */
+ clrsetbits_le32(&denali_pi[80], 0x3 << 24, 0x2 << 24);
+ /*
+ * PI_74 PI_RDLVL_GATE_REQ:WR:16:1
+ * PI_RDLVL_CS:RW:24:2
+ */
+ clrsetbits_le32(&denali_pi[74],
+ (0x1 << 16) | (0x3 << 24),
+ (0x1 << 16) | (i << 24));
+
+ /* Waiting for training complete */
+ while (1) {
+ /* PI_174 PI_INT_STATUS:RD:8:18 */
+ tmp = readl(&denali_pi[174]) >> 8;
+
+ /*
+ * check status obs
+ * PHY_43/171/299/427
+ * PHY_GTLVL_STATUS_OBS_x:16:8
+ */
+ obs_0 = readl(&denali_phy[43]);
+ obs_1 = readl(&denali_phy[171]);
+ obs_2 = readl(&denali_phy[299]);
+ obs_3 = readl(&denali_phy[427]);
+ if (((obs_0 >> (16 + 6)) & 0x3) ||
+ ((obs_1 >> (16 + 6)) & 0x3) ||
+ ((obs_2 >> (16 + 6)) & 0x3) ||
+ ((obs_3 >> (16 + 6)) & 0x3))
+ obs_err = 1;
+ if ((((tmp >> 9) & 0x1) == 0x1) &&
+ (((tmp >> 13) & 0x1) == 0x1) &&
+ (((tmp >> 3) & 0x1) == 0x0) &&
+ (obs_err == 0))
+ break;
+ else if ((((tmp >> 3) & 0x1) == 0x1) ||
+ (obs_err == 1))
+ return -EIO;
+ }
+ /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
+ writel(0x00003f7c, (&denali_pi[175]));
+ }
+ clrbits_le32(&denali_pi[80], 0x3 << 24);
+
+ return 0;
+}
+
+static int data_training_rl(const struct chan_info *chan, u32 channel,
+ const struct rk3399_sdram_params *sdram_params)
+{
+ u32 *denali_pi = chan->pi->denali_pi;
+ u32 i, tmp;
+ u32 rank = sdram_params->ch[channel].rank;
+
+ for (i = 0; i < rank; i++) {
+ select_per_cs_training_index(chan, i);
+ /* PI_80 PI_RDLVL_EN:RW:16:2 */
+ clrsetbits_le32(&denali_pi[80], 0x3 << 16, 0x2 << 16);
+ /* PI_74 PI_RDLVL_REQ:WR:8:1,PI_RDLVL_CS:RW:24:2 */
+ clrsetbits_le32(&denali_pi[74],
+ (0x1 << 8) | (0x3 << 24),
+ (0x1 << 8) | (i << 24));
+
+ /* Waiting for training complete */
+ while (1) {
+ /* PI_174 PI_INT_STATUS:RD:8:18 */
+ tmp = readl(&denali_pi[174]) >> 8;
+
+ /*
+ * make sure status obs not report error bit
+ * PHY_46/174/302/430
+ * phy_rdlvl_status_obs_X:16:8
+ */
+ if ((((tmp >> 8) & 0x1) == 0x1) &&
+ (((tmp >> 13) & 0x1) == 0x1) &&
+ (((tmp >> 2) & 0x1) == 0x0))
+ break;
+ else if (((tmp >> 2) & 0x1) == 0x1)
+ return -EIO;
+ }
+ /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
+ writel(0x00003f7c, (&denali_pi[175]));
+ }
+ clrbits_le32(&denali_pi[80], 0x3 << 16);
+
+ return 0;
+}
+
+static int data_training_wdql(const struct chan_info *chan, u32 channel,
+ const struct rk3399_sdram_params *sdram_params)
+{
+ u32 *denali_pi = chan->pi->denali_pi;
+ u32 i, tmp;
+ u32 rank = sdram_params->ch[channel].rank;
+
+ for (i = 0; i < rank; i++) {
+ select_per_cs_training_index(chan, i);
+ /*
+ * disable PI_WDQLVL_VREF_EN before wdq leveling?
+ * PI_181 PI_WDQLVL_VREF_EN:RW:8:1
+ */
+ clrbits_le32(&denali_pi[181], 0x1 << 8);
+ /* PI_124 PI_WDQLVL_EN:RW:16:2 */
+ clrsetbits_le32(&denali_pi[124], 0x3 << 16, 0x2 << 16);
+ /* PI_121 PI_WDQLVL_REQ:WR:8:1,PI_WDQLVL_CS:RW:16:2 */
+ clrsetbits_le32(&denali_pi[121],
+ (0x1 << 8) | (0x3 << 16),
+ (0x1 << 8) | (i << 16));
+
+ /* Waiting for training complete */
+ while (1) {
+ /* PI_174 PI_INT_STATUS:RD:8:18 */
+ tmp = readl(&denali_pi[174]) >> 8;
+ if ((((tmp >> 12) & 0x1) == 0x1) &&
+ (((tmp >> 13) & 0x1) == 0x1) &&
+ (((tmp >> 6) & 0x1) == 0x0))
+ break;
+ else if (((tmp >> 6) & 0x1) == 0x1)
+ return -EIO;
+ }
+ /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
+ writel(0x00003f7c, (&denali_pi[175]));
+ }
+ clrbits_le32(&denali_pi[124], 0x3 << 16);
+
+ return 0;
+}
+
+static int data_training(const struct chan_info *chan, u32 channel,
+ const struct rk3399_sdram_params *sdram_params,
+ u32 training_flag)
+{
+ u32 *denali_phy = chan->publ->denali_phy;
+
+ /* PHY_927 PHY_PAD_DQS_DRIVE RPULL offset_22 */
+ setbits_le32(&denali_phy[927], (1 << 22));
+
+ if (training_flag == PI_FULL_TRAINING) {
+ if (sdram_params->base.dramtype == LPDDR4) {
+ training_flag = PI_CA_TRAINING | PI_WRITE_LEVELING |
+ PI_READ_GATE_TRAINING |
+ PI_READ_LEVELING | PI_WDQ_LEVELING;
+ } else if (sdram_params->base.dramtype == LPDDR3) {
+ training_flag = PI_CA_TRAINING | PI_WRITE_LEVELING |
+ PI_READ_GATE_TRAINING;
+ } else if (sdram_params->base.dramtype == DDR3) {
+ training_flag = PI_WRITE_LEVELING |
+ PI_READ_GATE_TRAINING |
+ PI_READ_LEVELING;
+ }
+ }
+
+ /* ca training(LPDDR4,LPDDR3 support) */
+ if ((training_flag & PI_CA_TRAINING) == PI_CA_TRAINING)
+ data_training_ca(chan, channel, sdram_params);
+
+ /* write leveling(LPDDR4,LPDDR3,DDR3 support) */
+ if ((training_flag & PI_WRITE_LEVELING) == PI_WRITE_LEVELING)
+ data_training_wl(chan, channel, sdram_params);
+
+ /* read gate training(LPDDR4,LPDDR3,DDR3 support) */
+ if ((training_flag & PI_READ_GATE_TRAINING) == PI_READ_GATE_TRAINING)
+ data_training_rg(chan, channel, sdram_params);
+
+ /* read leveling(LPDDR4,LPDDR3,DDR3 support) */
+ if ((training_flag & PI_READ_LEVELING) == PI_READ_LEVELING)
+ data_training_rl(chan, channel, sdram_params);
+
+ /* wdq leveling(LPDDR4 support) */
+ if ((training_flag & PI_WDQ_LEVELING) == PI_WDQ_LEVELING)
+ data_training_wdql(chan, channel, sdram_params);
+
+ /* PHY_927 PHY_PAD_DQS_DRIVE RPULL offset_22 */
+ clrbits_le32(&denali_phy[927], (1 << 22));
+
+ return 0;
+}
+
+static void set_ddrconfig(const struct chan_info *chan,
+ const struct rk3399_sdram_params *sdram_params,
+ unsigned char channel, u32 ddrconfig)
+{
+ /* only need to set ddrconfig */
+ struct rk3399_msch_regs *ddr_msch_regs = chan->msch;
+ unsigned int cs0_cap = 0;
+ unsigned int cs1_cap = 0;
+
+ cs0_cap = (1 << (sdram_params->ch[channel].cs0_row
+ + sdram_params->ch[channel].col
+ + sdram_params->ch[channel].bk
+ + sdram_params->ch[channel].bw - 20));
+ if (sdram_params->ch[channel].rank > 1)
+ cs1_cap = cs0_cap >> (sdram_params->ch[channel].cs0_row
+ - sdram_params->ch[channel].cs1_row);
+ if (sdram_params->ch[channel].row_3_4) {
+ cs0_cap = cs0_cap * 3 / 4;
+ cs1_cap = cs1_cap * 3 / 4;
+ }
+
+ writel(ddrconfig | (ddrconfig << 8), &ddr_msch_regs->ddrconf);
+ writel(((cs0_cap / 32) & 0xff) | (((cs1_cap / 32) & 0xff) << 8),
+ &ddr_msch_regs->ddrsize);
+}
+
+static void dram_all_config(struct dram_info *dram,
+ const struct rk3399_sdram_params *sdram_params)
+{
+ u32 sys_reg = 0;
+ unsigned int channel, idx;
+
+ sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT;
+ sys_reg |= (sdram_params->base.num_channels - 1)
+ << SYS_REG_NUM_CH_SHIFT;
+ for (channel = 0, idx = 0;
+ (idx < sdram_params->base.num_channels) && (channel < 2);
+ channel++) {
+ const struct rk3399_sdram_channel *info =
+ &sdram_params->ch[channel];
+ struct rk3399_msch_regs *ddr_msch_regs;
+ const struct rk3399_msch_timings *noc_timing;
+
+ if (sdram_params->ch[channel].col == 0)
+ continue;
+ idx++;
+ sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(channel);
+ sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(channel);
+ sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(channel);
+ sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(channel);
+ sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(channel);
+ sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(channel);
+ sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(channel);
+ sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(channel);
+ sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(channel);
+
+ ddr_msch_regs = dram->chan[channel].msch;
+ noc_timing = &sdram_params->ch[channel].noc_timings;
+ writel(noc_timing->ddrtiminga0,
+ &ddr_msch_regs->ddrtiminga0);
+ writel(noc_timing->ddrtimingb0,
+ &ddr_msch_regs->ddrtimingb0);
+ writel(noc_timing->ddrtimingc0,
+ &ddr_msch_regs->ddrtimingc0);
+ writel(noc_timing->devtodev0,
+ &ddr_msch_regs->devtodev0);
+ writel(noc_timing->ddrmode,
+ &ddr_msch_regs->ddrmode);
+
+ /* rank 1 memory clock disable (dfi_dram_clk_disable = 1) */
+ if (sdram_params->ch[channel].rank == 1)
+ setbits_le32(&dram->chan[channel].pctl->denali_ctl[276],
+ 1 << 17);
+ }
+
+ writel(sys_reg, &dram->pmugrf->os_reg2);
+ rk_clrsetreg(&dram->pmusgrf->soc_con4, 0x1f << 10,
+ sdram_params->base.stride << 10);
+
+ /* reboot hold register set */
+ writel(PRESET_SGRF_HOLD(0) | PRESET_GPIO0_HOLD(1) |
+ PRESET_GPIO1_HOLD(1),
+ &dram->pmucru->pmucru_rstnhold_con[1]);
+ clrsetbits_le32(&dram->cru->glb_rst_con, 0x3, 0x3);
+}
+
+static int switch_to_phy_index1(struct dram_info *dram,
+ const struct rk3399_sdram_params *sdram_params)
+{
+ u32 channel;
+ u32 *denali_phy;
+ u32 ch_count = sdram_params->base.num_channels;
+ int ret;
+ int i = 0;
+
+ writel(RK_CLRSETBITS(0x03 << 4 | 1 << 2 | 1,
+ 1 << 4 | 1 << 2 | 1),
+ &dram->cic->cic_ctrl0);
+ while (!(readl(&dram->cic->cic_status0) & (1 << 2))) {
+ mdelay(10);
+ i++;
+ if (i > 10) {
+ debug("index1 frequency change overtime\n");
+ return -ETIME;
+ }
+ }
+
+ i = 0;
+ writel(RK_CLRSETBITS(1 << 1, 1 << 1), &dram->cic->cic_ctrl0);
+ while (!(readl(&dram->cic->cic_status0) & (1 << 0))) {
+ mdelay(10);
+ if (i > 10) {
+ debug("index1 frequency done overtime\n");
+ return -ETIME;
+ }
+ }
+
+ for (channel = 0; channel < ch_count; channel++) {
+ denali_phy = dram->chan[channel].publ->denali_phy;
+ clrsetbits_le32(&denali_phy[896], (0x3 << 8) | 1, 1 << 8);
+ ret = data_training(&dram->chan[channel], channel,
+ sdram_params, PI_FULL_TRAINING);
+ if (ret) {
+ debug("index1 training failed\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int sdram_init(struct dram_info *dram,
+ const struct rk3399_sdram_params *sdram_params)
+{
+ unsigned char dramtype = sdram_params->base.dramtype;
+ unsigned int ddr_freq = sdram_params->base.ddr_freq;
+ int channel;
+
+ debug("Starting SDRAM initialization...\n");
+
+ if ((dramtype == DDR3 && ddr_freq > 800) ||
+ (dramtype == LPDDR3 && ddr_freq > 933) ||
+ (dramtype == LPDDR4 && ddr_freq > 800)) {
+ debug("SDRAM frequency is to high!");
+ return -E2BIG;
+ }
+
+ for (channel = 0; channel < 2; channel++) {
+ const struct chan_info *chan = &dram->chan[channel];
+ struct rk3399_ddr_publ_regs *publ = chan->publ;
+
+ phy_dll_bypass_set(publ, ddr_freq);
+
+ if (channel >= sdram_params->base.num_channels)
+ continue;
+
+ if (pctl_cfg(chan, channel, sdram_params) != 0) {
+ printf("pctl_cfg fail, reset\n");
+ return -EIO;
+ }
+
+ /* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */
+ if (dramtype == LPDDR3)
+ udelay(10);
+
+ if (data_training(chan, channel,
+ sdram_params, PI_FULL_TRAINING)) {
+ printf("SDRAM initialization failed, reset\n");
+ return -EIO;
+ }
+
+ set_ddrconfig(chan, sdram_params, channel,
+ sdram_params->ch[channel].ddrconfig);
+ }
+ dram_all_config(dram, sdram_params);
+ switch_to_phy_index1(dram, sdram_params);
+
+ debug("Finish SDRAM initialization...\n");
+ return 0;
+}
+
+static int rk3399_dmc_ofdata_to_platdata(struct udevice *dev)
+{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct rockchip_dmc_plat *plat = dev_get_platdata(dev);
+ const void *blob = gd->fdt_blob;
+ int node = dev->of_offset;
+ int ret;
+
+ ret = fdtdec_get_int_array(blob, node, "rockchip,sdram-params",
+ (u32 *)&plat->sdram_params,
+ sizeof(plat->sdram_params) / sizeof(u32));
+ if (ret) {
+ printf("%s: Cannot read rockchip,sdram-params %d\n",
+ __func__, ret);
+ return ret;
+ }
+ ret = regmap_init_mem(dev, &plat->map);
+ if (ret)
+ printf("%s: regmap failed %d\n", __func__, ret);
+
+#endif
+ return 0;
+}
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int conv_of_platdata(struct udevice *dev)
+{
+ struct rockchip_dmc_plat *plat = dev_get_platdata(dev);
+ struct dtd_rockchip_rk3399_dmc *dtplat = &plat->dtplat;
+ int ret;
+
+ ret = regmap_init_mem_platdata(dev, dtplat->reg,
+ ARRAY_SIZE(dtplat->reg) / 4,
+ &plat->map);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+#endif
+
+static int rk3399_dmc_init(struct udevice *dev)
+{
+ struct dram_info *priv = dev_get_priv(dev);
+ struct rockchip_dmc_plat *plat = dev_get_platdata(dev);
+ int ret;
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct rk3399_sdram_params *params = &plat->sdram_params;
+#else
+ struct dtd_rockchip_rk3399_dmc *dtplat = &plat->dtplat;
+ struct rk3399_sdram_params *params =
+ (void *)dtplat->rockchip_sdram_params;
+
+ ret = conv_of_platdata(dev);
+ if (ret)
+ return ret;
+#endif
+
+ priv->cic = syscon_get_first_range(ROCKCHIP_SYSCON_CIC);
+ priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
+ priv->pmusgrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUSGRF);
+ priv->pmucru = rockchip_get_pmucru();
+ priv->cru = rockchip_get_cru();
+ priv->chan[0].pctl = regmap_get_range(plat->map, 0);
+ priv->chan[0].pi = regmap_get_range(plat->map, 1);
+ priv->chan[0].publ = regmap_get_range(plat->map, 2);
+ priv->chan[0].msch = regmap_get_range(plat->map, 3);
+ priv->chan[1].pctl = regmap_get_range(plat->map, 4);
+ priv->chan[1].pi = regmap_get_range(plat->map, 5);
+ priv->chan[1].publ = regmap_get_range(plat->map, 6);
+ priv->chan[1].msch = regmap_get_range(plat->map, 7);
+
+ debug("con reg %p %p %p %p %p %p %p %p\n",
+ priv->chan[0].pctl, priv->chan[0].pi,
+ priv->chan[0].publ, priv->chan[0].msch,
+ priv->chan[1].pctl, priv->chan[1].pi,
+ priv->chan[1].publ, priv->chan[1].msch);
+ debug("cru %p, cic %p, grf %p, sgrf %p, pmucru %p\n", priv->cru,
+ priv->cic, priv->pmugrf, priv->pmusgrf, priv->pmucru);
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->ddr_clk);
+#else
+ ret = clk_get_by_index(dev, 0, &priv->ddr_clk);
+#endif
+ if (ret) {
+ printf("%s clk get failed %d\n", __func__, ret);
+ return ret;
+ }
+ ret = clk_set_rate(&priv->ddr_clk, params->base.ddr_freq * MHz);
+ if (ret < 0) {
+ printf("%s clk set failed %d\n", __func__, ret);
+ return ret;
+ }
+ ret = sdram_init(priv, params);
+ if (ret < 0) {
+ printf("%s DRAM init failed%d\n", __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+#endif
+
+size_t sdram_size_mb(struct dram_info *dram)
+{
+ u32 rank, col, bk, cs0_row, cs1_row, bw, row_3_4;
+ size_t chipsize_mb = 0;
+ size_t size_mb = 0;
+ u32 ch;
+
+ u32 sys_reg = readl(&dram->pmugrf->os_reg2);
+ u32 ch_num = 1 + ((sys_reg >> SYS_REG_NUM_CH_SHIFT)
+ & SYS_REG_NUM_CH_MASK);
+
+ for (ch = 0; ch < ch_num; ch++) {
+ rank = 1 + (sys_reg >> SYS_REG_RANK_SHIFT(ch) &
+ SYS_REG_RANK_MASK);
+ col = 9 + (sys_reg >> SYS_REG_COL_SHIFT(ch) & SYS_REG_COL_MASK);
+ bk = 3 - ((sys_reg >> SYS_REG_BK_SHIFT(ch)) & SYS_REG_BK_MASK);
+ cs0_row = 13 + (sys_reg >> SYS_REG_CS0_ROW_SHIFT(ch) &
+ SYS_REG_CS0_ROW_MASK);
+ cs1_row = 13 + (sys_reg >> SYS_REG_CS1_ROW_SHIFT(ch) &
+ SYS_REG_CS1_ROW_MASK);
+ bw = (2 >> ((sys_reg >> SYS_REG_BW_SHIFT(ch)) &
+ SYS_REG_BW_MASK));
+ row_3_4 = sys_reg >> SYS_REG_ROW_3_4_SHIFT(ch) &
+ SYS_REG_ROW_3_4_MASK;
+
+ chipsize_mb = (1 << (cs0_row + col + bk + bw - 20));
+
+ if (rank > 1)
+ chipsize_mb += chipsize_mb >> (cs0_row - cs1_row);
+ if (row_3_4)
+ chipsize_mb = chipsize_mb * 3 / 4;
+ size_mb += chipsize_mb;
+ }
+
+ /*
+ * we use the 0x00000000~0xf7ffffff space
+ * since 0xf8000000~0xffffffff is soc register space
+ * so we reserve it
+ */
+ size_mb = min_t(size_t, size_mb, 0xf8000000/(1<<20));
+
+ return size_mb;
+}
+
+static int rk3399_dmc_probe(struct udevice *dev)
+{
+#ifdef CONFIG_SPL_BUILD
+ if (rk3399_dmc_init(dev))
+ return 0;
+#else
+ struct dram_info *priv = dev_get_priv(dev);
+
+ priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
+ debug("%s: pmugrf=%p\n", __func__, priv->pmugrf);
+#endif
+ return 0;
+}
+
+static int rk3399_dmc_get_info(struct udevice *dev, struct ram_info *info)
+{
+ struct dram_info *priv = dev_get_priv(dev);
+
+ info = &priv->info;
+ priv->info.base = 0;
+ priv->info.size = sdram_size_mb(priv) << 20;
+
+ return 0;
+}
+
+static struct ram_ops rk3399_dmc_ops = {
+ .get_info = rk3399_dmc_get_info,
+};
+
+
+static const struct udevice_id rk3399_dmc_ids[] = {
+ { .compatible = "rockchip,rk3399-dmc" },
+ { }
+};
+
+U_BOOT_DRIVER(dmc_rk3399) = {
+ .name = "rockchip_rk3399_dmc",
+ .id = UCLASS_RAM,
+ .of_match = rk3399_dmc_ids,
+ .ops = &rk3399_dmc_ops,
+#ifdef CONFIG_SPL_BUILD
+ .ofdata_to_platdata = rk3399_dmc_ofdata_to_platdata,
+#endif
+ .probe = rk3399_dmc_probe,
+#ifdef CONFIG_SPL_BUILD
+ .priv_auto_alloc_size = sizeof(struct dram_info),
+ .platdata_auto_alloc_size = sizeof(struct rockchip_dmc_plat),
+#endif
+};
diff --git a/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c b/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c
index 2cef68b..d32985b 100644
--- a/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c
+++ b/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c
@@ -12,6 +12,8 @@
static const struct udevice_id rk3399_syscon_ids[] = {
{ .compatible = "rockchip,rk3399-grf", .data = ROCKCHIP_SYSCON_GRF },
{ .compatible = "rockchip,rk3399-pmugrf", .data = ROCKCHIP_SYSCON_PMUGRF },
+ { .compatible = "rockchip,rk3399-pmusgrf", .data = ROCKCHIP_SYSCON_PMUSGRF },
+ { .compatible = "rockchip,rk3399-cic", .data = ROCKCHIP_SYSCON_CIC },
};
U_BOOT_DRIVER(syscon_rk3399) = {
@@ -19,3 +21,41 @@ U_BOOT_DRIVER(syscon_rk3399) = {
.id = UCLASS_SYSCON,
.of_match = rk3399_syscon_ids,
};
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int rk3399_syscon_bind_of_platdata(struct udevice *dev)
+{
+ dev->driver_data = dev->driver->of_match->data;
+ debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(rockchip_rk3399_grf) = {
+ .name = "rockchip_rk3399_grf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3399_syscon_ids,
+ .bind = rk3399_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_rk3399_pmugrf) = {
+ .name = "rockchip_rk3399_pmugrf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3399_syscon_ids + 1,
+ .bind = rk3399_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_rk3399_pmusgrf) = {
+ .name = "rockchip_rk3399_pmusgrf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3399_syscon_ids + 2,
+ .bind = rk3399_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_rk3399_cic) = {
+ .name = "rockchip_rk3399_cic",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3399_syscon_ids + 3,
+ .bind = rk3399_syscon_bind_of_platdata,
+};
+#endif
diff --git a/board/rockchip/evb_rk3328/Kconfig b/board/rockchip/evb_rk3328/Kconfig
new file mode 100644
index 0000000..ef446b4
--- /dev/null
+++ b/board/rockchip/evb_rk3328/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_EVB_RK3328
+
+config SYS_BOARD
+ default "evb_rk3328"
+
+config SYS_VENDOR
+ default "rockchip"
+
+config SYS_CONFIG_NAME
+ default "evb_rk3328"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+
+endif
diff --git a/board/rockchip/evb_rk3328/MAINTAINERS b/board/rockchip/evb_rk3328/MAINTAINERS
new file mode 100644
index 0000000..9db604f
--- /dev/null
+++ b/board/rockchip/evb_rk3328/MAINTAINERS
@@ -0,0 +1,6 @@
+EVB-RK3328
+M: William Zhang <william.zhang@rock-chips.com>
+S: Maintained
+F: board/rockchip/evb_rk3328
+F: include/configs/evb_rk3328.h
+F: configs/evb-rk3328_defconfig
diff --git a/board/rockchip/evb_rk3328/Makefile b/board/rockchip/evb_rk3328/Makefile
new file mode 100644
index 0000000..81c5de8
--- /dev/null
+++ b/board/rockchip/evb_rk3328/Makefile
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2016 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += evb-rk3328.o
diff --git a/board/rockchip/evb_rk3328/README b/board/rockchip/evb_rk3328/README
new file mode 100644
index 0000000..6cbb66a
--- /dev/null
+++ b/board/rockchip/evb_rk3328/README
@@ -0,0 +1,70 @@
+Introduction
+============
+
+RK3328 key features we might use in U-Boot:
+* CPU: ARMv8 64bit quad-core Cortex-A53
+* IRAM: 36KB
+* DRAM: 4GB-16MB dual-channel
+* eMMC: support eMMC 5.0/5.1, suport HS400, HS200, DDR50
+* SD/MMC: support SD 3.0, MMC 4.51
+* USB: USB2.0 EHCI host port *2
+* Display: RGB/HDMI/DP/MIPI/EDP
+
+evb key features:
+* regulator: pwm regulator for CPU B/L
+* PMIC: rk808
+* debug console: UART2
+
+In order to support Arm Trust Firmware(ATF), we need to use the
+miniloader from rockchip which:
+* do DRAM init
+* load and verify ATF image
+* load and verify U-Boot image
+
+Here is the step-by-step to boot to U-Boot on rk3328.
+
+Get the Source and prebuild binary
+==================================
+
+ > mkdir ~/evb_rk3328
+ > cd ~/evb_rk3328
+ > git clone https://github.com/ARM-software/arm-trusted-firmware.git
+ > git clone https://github.com/rockchip-linux/rkbin
+ > git clone https://github.com/rockchip-linux/rkflashtool
+
+Compile ATF
+===============
+
+ > cd arm-trusted-firmware
+ > make realclean
+ > make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3328 bl31
+
+Compile U-Boot
+==================
+
+ > cd ../u-boot
+ > make CROSS_COMPILE=aarch64-linux-gnu- evb-rk3328_defconfig all
+
+Compile rkflashtool
+=======================
+
+ > cd ../rkflashtool
+ > make
+
+Package image for miniloader
+================================
+ > cd ..
+ > cp arm-trusted-firmware/build/rk3328/release/bl31.bin rkbin/rk33
+ > ./rkbin/tools/trust_merger rkbin/tools/RK3328TRUST.ini
+ > ./rkbin/tools/loaderimage --pack --uboot u-boot/u-boot-dtb.bin uboot.img
+ > mkdir image
+ > mv trust.img ./image/
+ > mv uboot.img ./image/rk3328evb-uboot.bin
+
+Flash image
+===============
+Power on(or reset with RESET KEY) with MASKROM KEY preesed, and then:
+
+ > ./rkflashtool/rkflashloader rk3328evb
+
+You should be able to get U-Boot log message in console/UART2 now.
diff --git a/board/rockchip/evb_rk3328/evb-rk3328.c b/board/rockchip/evb_rk3328/evb-rk3328.c
new file mode 100644
index 0000000..7e70f38
--- /dev/null
+++ b/board/rockchip/evb_rk3328/evb-rk3328.c
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/armv8/mmu.h>
+#include <dwc3-uboot.h>
+#include <usb.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+ return 0;
+}
+
+int dram_init(void)
+{
+ gd->ram_size = 0x80000000;
+ return 0;
+}
+
+void dram_init_banksize(void)
+{
+ /* Reserve 0x200000 for ATF bl31 */
+ gd->bd->bi_dram[0].start = 0x200000;
+ gd->bd->bi_dram[0].size = 0x7e000000;
+}
+
+int usb_gadget_handle_interrupts(void)
+{
+ return 0;
+}
+
+int board_usb_init(int index, enum usb_init_type init)
+{
+ return 0;
+}
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 766fb3d..2bc8b42 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -170,22 +170,20 @@ __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
image_entry();
}
-int spl_init(void)
+static int spl_common_init(bool setup_malloc)
{
int ret;
- debug("spl_init()\n");
-/*
- * with CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN we set malloc_base and
- * malloc_limit in spl_relocate_stack_gd
- */
-#if defined(CONFIG_SYS_MALLOC_F_LEN) && \
- !defined(CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN)
+ debug("spl_early_init()\n");
+
+#if defined(CONFIG_SYS_MALLOC_F_LEN)
+ if (setup_malloc) {
#ifdef CONFIG_MALLOC_F_ADDR
- gd->malloc_base = CONFIG_MALLOC_F_ADDR;
+ gd->malloc_base = CONFIG_MALLOC_F_ADDR;
#endif
- gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN;
- gd->malloc_ptr = 0;
+ gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN;
+ gd->malloc_ptr = 0;
+ }
#endif
if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
ret = fdtdec_setup();
@@ -202,6 +200,32 @@ int spl_init(void)
return ret;
}
}
+
+ return 0;
+}
+
+int spl_early_init(void)
+{
+ int ret;
+
+ ret = spl_common_init(true);
+ if (ret)
+ return ret;
+ gd->flags |= GD_FLG_SPL_EARLY_INIT;
+
+ return 0;
+}
+
+int spl_init(void)
+{
+ int ret;
+
+ if (!(gd->flags & GD_FLG_SPL_EARLY_INIT)) {
+ ret = spl_common_init(
+ !IS_ENABLED(CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN));
+ if (ret)
+ return ret;
+ }
gd->flags |= GD_FLG_SPL_INIT;
return 0;
diff --git a/configs/evb-rk3288_defconfig b/configs/evb-rk3288_defconfig
index a0cc7a7..aad2533 100644
--- a/configs/evb-rk3288_defconfig
+++ b/configs/evb-rk3288_defconfig
@@ -41,8 +41,11 @@ CONFIG_LED=y
CONFIG_LED_GPIO=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_DM_ETH=y
+CONFIG_NETDEVICES=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_FULL is not set
CONFIG_SPL_PINCTRL=y
# CONFIG_SPL_PINCTRL_FULL is not set
CONFIG_ROCKCHIP_RK3288_PINCTRL=y
diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig
new file mode 100644
index 0000000..df22105
--- /dev/null
+++ b/configs/evb-rk3328_defconfig
@@ -0,0 +1,36 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_ROCKCHIP_RK3328=y
+CONFIG_DEFAULT_DEVICE_TREE="rk3328-evb"
+CONFIG_FIT=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_CMD_BOOTZ=y
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TIME=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_PINCTRL=y
+CONFIG_ROCKCHIP_RK3328_PINCTRL=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_RAM=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0xFF130000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
+CONFIG_SYSRESET=y
+CONFIG_USE_TINY_PRINTF=y
+CONFIG_ERRNO_STR=y
diff --git a/configs/evb-rk3399_defconfig b/configs/evb-rk3399_defconfig
index ad51ed2..7ef7cb0 100644
--- a/configs/evb-rk3399_defconfig
+++ b/configs/evb-rk3399_defconfig
@@ -3,7 +3,16 @@ CONFIG_ARCH_ROCKCHIP=y
CONFIG_ROCKCHIP_RK3399=y
CONFIG_DEFAULT_DEVICE_TREE="rk3399-evb"
CONFIG_FIT=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_OF_LIBFDT=y
+CONFIG_SPL_ATF_SUPPORT=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x200
+CONFIG_SPL_ATF_TEXT_BASE=0x00010000
# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_ADDR=0x80000
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x4000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_IMLS is not set
CONFIG_CMD_GPT=y
@@ -12,20 +21,28 @@ CONFIG_CMD_SF=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_TIME=y
+CONFIG_CMD_PXE=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_SPL_OF_PLATDATA=y
CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
CONFIG_CLK=y
+CONFIG_SPL_CLK=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_MMC_DW=y
-CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ROCKCHIP=y
CONFIG_PINCTRL=y
+CONFIG_SPL_PINCTRL=y
CONFIG_ROCKCHIP_RK3399_PINCTRL=y
CONFIG_REGULATOR_PWM=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_PWM_ROCKCHIP=y
CONFIG_RAM=y
+CONFIG_SPL_RAM=y
CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
diff --git a/configs/fennec-rk3288_defconfig b/configs/fennec-rk3288_defconfig
index a42cd9c..d1b0ffc 100644
--- a/configs/fennec-rk3288_defconfig
+++ b/configs/fennec-rk3288_defconfig
@@ -17,6 +17,7 @@ CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
CONFIG_CMD_GPIO=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_CACHE=y
@@ -40,8 +41,11 @@ CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_DM_ETH=y
+CONFIG_NETDEVICES=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_FULL is not set
CONFIG_SPL_PINCTRL=y
# CONFIG_SPL_PINCTRL_FULL is not set
CONFIG_ROCKCHIP_RK3288_PINCTRL=y
@@ -58,6 +62,8 @@ CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550=y
CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_USB_STORAGE=y
CONFIG_USE_TINY_PRINTF=y
CONFIG_CMD_DHRYSTONE=y
CONFIG_ERRNO_STR=y
diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig
index 00bfca0..b0741d7 100644
--- a/configs/firefly-rk3288_defconfig
+++ b/configs/firefly-rk3288_defconfig
@@ -16,6 +16,7 @@ CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
CONFIG_CMD_GPIO=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_CACHE=y
@@ -28,7 +29,6 @@ CONFIG_CMD_REGULATOR=y
CONFIG_SPL_PARTITION_UUIDS=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
-CONFIG_SPL_OF_PLATDATA=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_REGMAP=y
CONFIG_SPL_REGMAP=y
@@ -65,6 +65,8 @@ CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550=y
CONFIG_ROCKCHIP_SERIAL=y
CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_USB_STORAGE=y
CONFIG_DM_VIDEO=y
CONFIG_DISPLAY=y
CONFIG_VIDEO_ROCKCHIP=y
diff --git a/configs/popmetal-rk3288_defconfig b/configs/popmetal-rk3288_defconfig
index 7b5ed94..dfc84b9 100644
--- a/configs/popmetal-rk3288_defconfig
+++ b/configs/popmetal-rk3288_defconfig
@@ -41,6 +41,10 @@ CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_DM_ETH=y
+CONFIG_NETDEVICES=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
CONFIG_PINCTRL=y
CONFIG_SPL_PINCTRL=y
# CONFIG_SPL_PINCTRL_FULL is not set
diff --git a/configs/tinker-rk3288_defconfig b/configs/tinker-rk3288_defconfig
index 7573a2e..cec3938 100644
--- a/configs/tinker-rk3288_defconfig
+++ b/configs/tinker-rk3288_defconfig
@@ -17,6 +17,7 @@ CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
CONFIG_CMD_GPIO=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_CACHE=y
@@ -40,6 +41,10 @@ CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_DM_ETH=y
+CONFIG_NETDEVICES=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
CONFIG_PINCTRL=y
CONFIG_SPL_PINCTRL=y
# CONFIG_SPL_PINCTRL_FULL is not set
@@ -57,6 +62,8 @@ CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550=y
CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_USB_STORAGE=y
CONFIG_USE_TINY_PRINTF=y
CONFIG_CMD_DHRYSTONE=y
CONFIG_ERRNO_STR=y
diff --git a/doc/device-tree-bindings/clock/rockchip,rk3399-dmc.txt b/doc/device-tree-bindings/clock/rockchip,rk3399-dmc.txt
new file mode 100644
index 0000000..a15dc5d
--- /dev/null
+++ b/doc/device-tree-bindings/clock/rockchip,rk3399-dmc.txt
@@ -0,0 +1,42 @@
+Rockchip Dynamic Memory Controller Driver
+Required properties:
+- compatible: "rockchip,rk3399-dmc", "syscon"
+- rockchip,cru: this driver should access cru regs, so need get cru here
+- rockchip,pmucru: this driver should access pmucru regs, so need get pmucru here
+- rockchip,pmugrf: this driver should access pmugrf regs, so need get pmugrf here
+- rockchip,pmusgrf: this driver should access pmusgrf regs, so need get pmusgrf here
+- rockchip,cic: this driver should access cic regs, so need get cic here
+- reg: dynamic ram protocol controller(PCTL) address, PHY Independent(PI) address, phy controller(PHYCTL) address and memory schedule(MSCH) address
+- clock: must include clock specifiers corresponding to entries in the clock-names property.
+ Must contain
+ dmc_clk: for ddr working frequency
+- rockchip,sdram-params: SDRAM parameters, including all the information by ddr driver:
+ Must contain
+ Genarate by vendor tool and adjust for U-Boot dtsi.
+
+Example:
+ dmc: dmc {
+ u-boot,dm-pre-reloc;
+ compatible = "rockchip,rk3399-dmc";
+ devfreq-events = <&dfi>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru SCLK_DDRCLK>;
+ clock-names = "dmc_clk";
+ reg = <0x0 0xffa80000 0x0 0x0800
+ 0x0 0xffa80800 0x0 0x1800
+ 0x0 0xffa82000 0x0 0x2000
+ 0x0 0xffa84000 0x0 0x1000
+ 0x0 0xffa88000 0x0 0x0800
+ 0x0 0xffa88800 0x0 0x1800
+ 0x0 0xffa8a000 0x0 0x2000
+ 0x0 0xffa8c000 0x0 0x1000>;
+ };
+
+ &dmc {
+ rockchip,sdram-params = <
+ 0x2
+ 0xa
+ 0x3
+ ...
+ >;
+ };
diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt
index fea324e..0853477 100644
--- a/doc/driver-model/README.txt
+++ b/doc/driver-model/README.txt
@@ -825,6 +825,10 @@ drivers marked with DM_FLAG_PRE_RELOC or the device tree
'u-boot,dm-pre-reloc' flag are initialised prior to relocation. This helps
to reduce the driver model overhead.
+It is possible to limit this to specific relocation steps, by using
+the more specialized 'u-boot,dm-spl' and 'u-boot,dm-tpl' flags
+in the devicetree.
+
Then post relocation we throw that away and re-init driver model again.
For drivers which require some sort of continuity between pre- and
post-relocation devices, we can provide access to the pre-relocation
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index c73156a..fcd693a 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -10,6 +10,7 @@
#include <dm/device.h>
#include <dm/lists.h>
#include <dm/root.h>
+#include <dm/util.h>
#include "pmc.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -56,7 +57,7 @@ int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name)
offset > 0;
offset = fdt_next_subnode(fdt, offset)) {
if (pre_reloc_only &&
- !fdt_getprop(fdt, offset, "u-boot,dm-pre-reloc", NULL))
+ !dm_fdt_pre_reloc(fdt, offset))
continue;
/*
* If this node has "compatible" property, this is not
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 1f8e417..1091a76 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -5,5 +5,7 @@
#
obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o
+obj-$(CONFIG_ROCKCHIP_RK3188) += clk_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o
+obj-$(CONFIG_ROCKCHIP_RK3328) += clk_rk3328.o
obj-$(CONFIG_ROCKCHIP_RK3399) += clk_rk3399.o
diff --git a/drivers/clk/rockchip/clk_rk3188.c b/drivers/clk/rockchip/clk_rk3188.c
new file mode 100644
index 0000000..459649f
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rk3188.c
@@ -0,0 +1,527 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * (C) Copyright 2016 Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dt-structs.h>
+#include <errno.h>
+#include <mapmem.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3188.h>
+#include <asm/arch/grf_rk3188.h>
+#include <asm/arch/hardware.h>
+#include <dt-bindings/clock/rk3188-cru.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/uclass-internal.h>
+#include <linux/log2.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum rk3188_clk_type {
+ RK3188_CRU,
+ RK3188A_CRU,
+};
+
+struct rk3188_clk_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_rockchip_rk3188_cru dtd;
+#endif
+};
+
+struct pll_div {
+ u32 nr;
+ u32 nf;
+ u32 no;
+};
+
+enum {
+ VCO_MAX_HZ = 2200U * 1000000,
+ VCO_MIN_HZ = 440 * 1000000,
+ OUTPUT_MAX_HZ = 2200U * 1000000,
+ OUTPUT_MIN_HZ = 30 * 1000000,
+ FREF_MAX_HZ = 2200U * 1000000,
+ FREF_MIN_HZ = 30 * 1000,
+};
+
+enum {
+ /* PLL CON0 */
+ PLL_OD_MASK = 0x0f,
+
+ /* PLL CON1 */
+ PLL_NF_MASK = 0x1fff,
+
+ /* PLL CON2 */
+ PLL_BWADJ_MASK = 0x0fff,
+
+ /* PLL CON3 */
+ PLL_RESET_SHIFT = 5,
+
+ /* GRF_SOC_STATUS0 */
+ SOCSTS_DPLL_LOCK = 1 << 5,
+ SOCSTS_APLL_LOCK = 1 << 6,
+ SOCSTS_CPLL_LOCK = 1 << 7,
+ SOCSTS_GPLL_LOCK = 1 << 8,
+};
+
+#define RATE_TO_DIV(input_rate, output_rate) \
+ ((input_rate) / (output_rate) - 1);
+
+#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
+
+#define PLL_DIVISORS(hz, _nr, _no) {\
+ .nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no};\
+ _Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\
+ (_nr * _no) == hz, #hz "Hz cannot be hit with PLL "\
+ "divisors on line " __stringify(__LINE__));
+
+/* Keep divisors as low as possible to reduce jitter and power usage */
+#ifdef CONFIG_SPL_BUILD
+static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2);
+static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
+#endif
+
+static int rkclk_set_pll(struct rk3188_cru *cru, enum rk_clk_id clk_id,
+ const struct pll_div *div, bool has_bwadj)
+{
+ int pll_id = rk_pll_id(clk_id);
+ struct rk3188_pll *pll = &cru->pll[pll_id];
+ /* All PLLs have same VCO and output frequency range restrictions. */
+ uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000;
+ uint output_hz = vco_hz / div->no;
+
+ debug("PLL at %x: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n",
+ (uint)pll, div->nf, div->nr, div->no, vco_hz, output_hz);
+ assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
+ output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ &&
+ (div->no == 1 || !(div->no % 2)));
+
+ /* enter reset */
+ rk_setreg(&pll->con3, 1 << PLL_RESET_SHIFT);
+
+ rk_clrsetreg(&pll->con0,
+ CLKR_MASK << CLKR_SHIFT | PLL_OD_MASK,
+ ((div->nr - 1) << CLKR_SHIFT) | (div->no - 1));
+ rk_clrsetreg(&pll->con1, CLKF_MASK, div->nf - 1);
+
+ if (has_bwadj)
+ rk_clrsetreg(&pll->con2, PLL_BWADJ_MASK, (div->nf >> 1) - 1);
+
+ udelay(10);
+
+ /* return from reset */
+ rk_clrreg(&pll->con3, 1 << PLL_RESET_SHIFT);
+
+ return 0;
+}
+
+static int rkclk_configure_ddr(struct rk3188_cru *cru, struct rk3188_grf *grf,
+ unsigned int hz, bool has_bwadj)
+{
+ static const struct pll_div dpll_cfg[] = {
+ {.nf = 25, .nr = 2, .no = 1},
+ {.nf = 400, .nr = 9, .no = 2},
+ {.nf = 500, .nr = 9, .no = 2},
+ {.nf = 100, .nr = 3, .no = 1},
+ };
+ int cfg;
+
+ switch (hz) {
+ case 300000000:
+ cfg = 0;
+ break;
+ case 533000000: /* actually 533.3P MHz */
+ cfg = 1;
+ break;
+ case 666000000: /* actually 666.6P MHz */
+ cfg = 2;
+ break;
+ case 800000000:
+ cfg = 3;
+ break;
+ default:
+ debug("Unsupported SDRAM frequency");
+ return -EINVAL;
+ }
+
+ /* pll enter slow-mode */
+ rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK << DPLL_MODE_SHIFT,
+ DPLL_MODE_SLOW << DPLL_MODE_SHIFT);
+
+ rkclk_set_pll(cru, CLK_DDR, &dpll_cfg[cfg], has_bwadj);
+
+ /* wait for pll lock */
+ while (!(readl(&grf->soc_status0) & SOCSTS_DPLL_LOCK))
+ udelay(1);
+
+ /* PLL enter normal-mode */
+ rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK << DPLL_MODE_SHIFT,
+ DPLL_MODE_NORMAL << DPLL_MODE_SHIFT);
+
+ return 0;
+}
+
+/* Get pll rate by id */
+static uint32_t rkclk_pll_get_rate(struct rk3188_cru *cru,
+ enum rk_clk_id clk_id)
+{
+ uint32_t nr, no, nf;
+ uint32_t con;
+ int pll_id = rk_pll_id(clk_id);
+ struct rk3188_pll *pll = &cru->pll[pll_id];
+ static u8 clk_shift[CLK_COUNT] = {
+ 0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
+ GPLL_MODE_SHIFT
+ };
+ uint shift;
+
+ con = readl(&cru->cru_mode_con);
+ shift = clk_shift[clk_id];
+ switch ((con >> shift) & APLL_MODE_MASK) {
+ case APLL_MODE_SLOW:
+ return OSC_HZ;
+ case APLL_MODE_NORMAL:
+ /* normal mode */
+ con = readl(&pll->con0);
+ no = ((con >> CLKOD_SHIFT) & CLKOD_MASK) + 1;
+ nr = ((con >> CLKR_SHIFT) & CLKR_MASK) + 1;
+ con = readl(&pll->con1);
+ nf = ((con >> CLKF_SHIFT) & CLKF_MASK) + 1;
+
+ return (24 * nf / (nr * no)) * 1000000;
+ case APLL_MODE_DEEP:
+ default:
+ return 32768;
+ }
+}
+
+static ulong rockchip_mmc_get_clk(struct rk3188_cru *cru, uint gclk_rate,
+ int periph)
+{
+ uint div;
+ u32 con;
+
+ switch (periph) {
+ case HCLK_EMMC:
+ con = readl(&cru->cru_clksel_con[12]);
+ div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK;
+ break;
+ case HCLK_SDMMC:
+ con = readl(&cru->cru_clksel_con[11]);
+ div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK;
+ break;
+ case HCLK_SDIO:
+ con = readl(&cru->cru_clksel_con[12]);
+ div = (con >> SDIO_DIV_SHIFT) & SDIO_DIV_MASK;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return DIV_TO_RATE(gclk_rate, div);
+}
+
+static ulong rockchip_mmc_set_clk(struct rk3188_cru *cru, uint gclk_rate,
+ int periph, uint freq)
+{
+ int src_clk_div;
+
+ debug("%s: gclk_rate=%u\n", __func__, gclk_rate);
+ src_clk_div = RATE_TO_DIV(gclk_rate, freq);
+ assert(src_clk_div <= 0x3f);
+
+ switch (periph) {
+ case HCLK_EMMC:
+ rk_clrsetreg(&cru->cru_clksel_con[12],
+ EMMC_DIV_MASK << EMMC_DIV_SHIFT,
+ src_clk_div << EMMC_DIV_SHIFT);
+ break;
+ case HCLK_SDMMC:
+ rk_clrsetreg(&cru->cru_clksel_con[11],
+ MMC0_DIV_MASK << MMC0_DIV_SHIFT,
+ src_clk_div << MMC0_DIV_SHIFT);
+ break;
+ case HCLK_SDIO:
+ rk_clrsetreg(&cru->cru_clksel_con[12],
+ SDIO_DIV_MASK << SDIO_DIV_SHIFT,
+ src_clk_div << SDIO_DIV_SHIFT);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return rockchip_mmc_get_clk(cru, gclk_rate, periph);
+}
+
+static ulong rockchip_spi_get_clk(struct rk3188_cru *cru, uint gclk_rate,
+ int periph)
+{
+ uint div;
+ u32 con;
+
+ switch (periph) {
+ case SCLK_SPI0:
+ con = readl(&cru->cru_clksel_con[25]);
+ div = (con >> SPI0_DIV_SHIFT) & SPI0_DIV_MASK;
+ break;
+ case SCLK_SPI1:
+ con = readl(&cru->cru_clksel_con[25]);
+ div = (con >> SPI1_DIV_SHIFT) & SPI1_DIV_MASK;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return DIV_TO_RATE(gclk_rate, div);
+}
+
+static ulong rockchip_spi_set_clk(struct rk3188_cru *cru, uint gclk_rate,
+ int periph, uint freq)
+{
+ int src_clk_div = RATE_TO_DIV(gclk_rate, freq);
+
+ switch (periph) {
+ case SCLK_SPI0:
+ assert(src_clk_div <= SPI0_DIV_MASK);
+ rk_clrsetreg(&cru->cru_clksel_con[25],
+ SPI0_DIV_MASK << SPI0_DIV_SHIFT,
+ src_clk_div << SPI0_DIV_SHIFT);
+ break;
+ case SCLK_SPI1:
+ assert(src_clk_div <= SPI1_DIV_MASK);
+ rk_clrsetreg(&cru->cru_clksel_con[25],
+ SPI1_DIV_MASK << SPI1_DIV_SHIFT,
+ src_clk_div << SPI1_DIV_SHIFT);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return rockchip_spi_get_clk(cru, gclk_rate, periph);
+}
+
+#ifdef CONFIG_SPL_BUILD
+static void rkclk_init(struct rk3188_cru *cru, struct rk3188_grf *grf,
+ bool has_bwadj)
+{
+ u32 aclk_div, hclk_div, pclk_div, h2p_div;
+
+ /* pll enter slow-mode */
+ rk_clrsetreg(&cru->cru_mode_con,
+ GPLL_MODE_MASK << GPLL_MODE_SHIFT |
+ CPLL_MODE_MASK << CPLL_MODE_SHIFT,
+ GPLL_MODE_SLOW << GPLL_MODE_SHIFT |
+ CPLL_MODE_SLOW << CPLL_MODE_SHIFT);
+
+ /* init pll */
+ rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg, has_bwadj);
+ rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg, has_bwadj);
+
+ /* waiting for pll lock */
+ while ((readl(&grf->soc_status0) &
+ (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK)) !=
+ (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK))
+ udelay(1);
+
+ /*
+ * cpu clock pll source selection and
+ * reparent aclk_cpu_pre from apll to gpll
+ * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ */
+ aclk_div = RATE_TO_DIV(GPLL_HZ, CPU_ACLK_HZ);
+ assert((aclk_div + 1) * CPU_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
+
+ rk_clrsetreg(&cru->cru_clksel_con[0],
+ CPU_ACLK_PLL_MASK << CPU_ACLK_PLL_SHIFT |
+ A9_CPU_DIV_MASK << A9_CPU_DIV_SHIFT,
+ CPU_ACLK_PLL_SELECT_GPLL << CPU_ACLK_PLL_SHIFT |
+ aclk_div << A9_CPU_DIV_SHIFT);
+
+ hclk_div = ilog2(CPU_ACLK_HZ / CPU_HCLK_HZ);
+ assert((1 << hclk_div) * CPU_HCLK_HZ == CPU_ACLK_HZ && hclk_div < 0x3);
+ pclk_div = ilog2(CPU_ACLK_HZ / CPU_PCLK_HZ);
+ assert((1 << pclk_div) * CPU_PCLK_HZ == CPU_ACLK_HZ && pclk_div < 0x4);
+ h2p_div = ilog2(CPU_HCLK_HZ / CPU_H2P_HZ);
+ assert((1 << h2p_div) * CPU_H2P_HZ == CPU_HCLK_HZ && pclk_div < 0x3);
+
+ rk_clrsetreg(&cru->cru_clksel_con[1],
+ AHB2APB_DIV_MASK << AHB2APB_DIV_SHIFT |
+ CPU_PCLK_DIV_MASK << CPU_PCLK_DIV_SHIFT |
+ CPU_HCLK_DIV_MASK << CPU_HCLK_DIV_SHIFT,
+ h2p_div << AHB2APB_DIV_SHIFT |
+ pclk_div << CPU_PCLK_DIV_SHIFT |
+ hclk_div << CPU_HCLK_DIV_SHIFT);
+
+ /*
+ * peri clock pll source selection and
+ * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ */
+ aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
+ assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
+
+ hclk_div = ilog2(PERI_ACLK_HZ / PERI_HCLK_HZ);
+ assert((1 << hclk_div) * PERI_HCLK_HZ ==
+ PERI_ACLK_HZ && (hclk_div < 0x4));
+
+ pclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ);
+ assert((1 << pclk_div) * PERI_PCLK_HZ ==
+ PERI_ACLK_HZ && (pclk_div < 0x4));
+
+ rk_clrsetreg(&cru->cru_clksel_con[10],
+ PERI_PCLK_DIV_MASK << PERI_PCLK_DIV_SHIFT |
+ PERI_HCLK_DIV_MASK << PERI_HCLK_DIV_SHIFT |
+ PERI_ACLK_DIV_MASK << PERI_ACLK_DIV_SHIFT,
+ PERI_SEL_GPLL << PERI_SEL_PLL_SHIFT |
+ pclk_div << PERI_PCLK_DIV_SHIFT |
+ hclk_div << PERI_HCLK_DIV_SHIFT |
+ aclk_div << PERI_ACLK_DIV_SHIFT);
+
+ /* PLL enter normal-mode */
+ rk_clrsetreg(&cru->cru_mode_con,
+ GPLL_MODE_MASK << GPLL_MODE_SHIFT |
+ CPLL_MODE_MASK << CPLL_MODE_SHIFT,
+ GPLL_MODE_NORMAL << GPLL_MODE_SHIFT |
+ CPLL_MODE_NORMAL << CPLL_MODE_SHIFT);
+
+ rockchip_mmc_set_clk(cru, PERI_HCLK_HZ, HCLK_SDMMC, 16000000);
+}
+#endif
+
+static ulong rk3188_clk_get_rate(struct clk *clk)
+{
+ struct rk3188_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong new_rate, gclk_rate;
+
+ gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL);
+ switch (clk->id) {
+ case 1 ... 4:
+ new_rate = rkclk_pll_get_rate(priv->cru, clk->id);
+ break;
+ case HCLK_EMMC:
+ case HCLK_SDMMC:
+ case HCLK_SDIO:
+ new_rate = rockchip_mmc_get_clk(priv->cru, PERI_HCLK_HZ,
+ clk->id);
+ break;
+ case SCLK_SPI0:
+ case SCLK_SPI1:
+ new_rate = rockchip_spi_get_clk(priv->cru, PERI_PCLK_HZ,
+ clk->id);
+ break;
+ case PCLK_I2C0:
+ case PCLK_I2C1:
+ case PCLK_I2C2:
+ case PCLK_I2C3:
+ case PCLK_I2C4:
+ return gclk_rate;
+ default:
+ return -ENOENT;
+ }
+
+ return new_rate;
+}
+
+static ulong rk3188_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct rk3188_clk_priv *priv = dev_get_priv(clk->dev);
+ struct rk3188_cru *cru = priv->cru;
+ ulong new_rate;
+
+ switch (clk->id) {
+ case CLK_DDR:
+ new_rate = rkclk_configure_ddr(priv->cru, priv->grf, rate,
+ priv->has_bwadj);
+ break;
+ case HCLK_EMMC:
+ case HCLK_SDMMC:
+ case HCLK_SDIO:
+ new_rate = rockchip_mmc_set_clk(cru, PERI_HCLK_HZ,
+ clk->id, rate);
+ break;
+ case SCLK_SPI0:
+ case SCLK_SPI1:
+ new_rate = rockchip_spi_set_clk(cru, PERI_PCLK_HZ,
+ clk->id, rate);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return new_rate;
+}
+
+static struct clk_ops rk3188_clk_ops = {
+ .get_rate = rk3188_clk_get_rate,
+ .set_rate = rk3188_clk_set_rate,
+};
+
+static int rk3188_clk_ofdata_to_platdata(struct udevice *dev)
+{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct rk3188_clk_priv *priv = dev_get_priv(dev);
+
+ priv->cru = (struct rk3188_cru *)dev_get_addr(dev);
+#endif
+
+ return 0;
+}
+
+static int rk3188_clk_probe(struct udevice *dev)
+{
+ struct rk3188_clk_priv *priv = dev_get_priv(dev);
+ enum rk3188_clk_type type = dev_get_driver_data(dev);
+
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ if (IS_ERR(priv->grf))
+ return PTR_ERR(priv->grf);
+ priv->has_bwadj = (type == RK3188A_CRU) ? 1 : 0;
+
+#ifdef CONFIG_SPL_BUILD
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct rk3188_clk_plat *plat = dev_get_platdata(dev);
+
+ priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
+#endif
+
+ rkclk_init(priv->cru, priv->grf, priv->has_bwadj);
+#endif
+
+ return 0;
+}
+
+static int rk3188_clk_bind(struct udevice *dev)
+{
+ int ret;
+
+ /* The reset driver does not have a device node, so bind it here */
+ ret = device_bind_driver(gd->dm_root, "rk3188_sysreset", "reset", &dev);
+ if (ret)
+ debug("Warning: No rk3188 reset driver: ret=%d\n", ret);
+
+ return 0;
+}
+
+static const struct udevice_id rk3188_clk_ids[] = {
+ { .compatible = "rockchip,rk3188-cru", .data = RK3188_CRU },
+ { .compatible = "rockchip,rk3188a-cru", .data = RK3188A_CRU },
+ { }
+};
+
+U_BOOT_DRIVER(rockchip_rk3188_cru) = {
+ .name = "rockchip_rk3188_cru",
+ .id = UCLASS_CLK,
+ .of_match = rk3188_clk_ids,
+ .priv_auto_alloc_size = sizeof(struct rk3188_clk_priv),
+ .platdata_auto_alloc_size = sizeof(struct rk3188_clk_plat),
+ .ops = &rk3188_clk_ops,
+ .bind = rk3188_clk_bind,
+ .ofdata_to_platdata = rk3188_clk_ofdata_to_platdata,
+ .probe = rk3188_clk_probe,
+};
diff --git a/drivers/clk/rockchip/clk_rk3288.c b/drivers/clk/rockchip/clk_rk3288.c
index d15504c..7835676 100644
--- a/drivers/clk/rockchip/clk_rk3288.c
+++ b/drivers/clk/rockchip/clk_rk3288.c
@@ -131,8 +131,10 @@ enum {
/* Keep divisors as low as possible to reduce jitter and power usage */
static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 1);
+#ifdef CONFIG_SPL_BUILD
static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2);
static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
+#endif
static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id,
const struct pll_div *div)
diff --git a/drivers/clk/rockchip/clk_rk3328.c b/drivers/clk/rockchip/clk_rk3328.c
new file mode 100644
index 0000000..0ff1e30
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rk3328.c
@@ -0,0 +1,581 @@
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3328.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/rk3328-cru.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct pll_div {
+ u32 refdiv;
+ u32 fbdiv;
+ u32 postdiv1;
+ u32 postdiv2;
+ u32 frac;
+};
+
+#define RATE_TO_DIV(input_rate, output_rate) \
+ ((input_rate) / (output_rate) - 1);
+#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
+
+#define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\
+ .refdiv = _refdiv,\
+ .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\
+ .postdiv1 = _postdiv1, .postdiv2 = _postdiv2};
+
+static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 1, 4, 1);
+static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 2, 2, 1);
+
+static const struct pll_div apll_816_cfg = PLL_DIVISORS(816 * MHz, 1, 2, 1);
+static const struct pll_div apll_600_cfg = PLL_DIVISORS(600 * MHz, 1, 3, 1);
+
+static const struct pll_div *apll_cfgs[] = {
+ [APLL_816_MHZ] = &apll_816_cfg,
+ [APLL_600_MHZ] = &apll_600_cfg,
+};
+
+enum {
+ /* PLL_CON0 */
+ PLL_POSTDIV1_SHIFT = 12,
+ PLL_POSTDIV1_MASK = 0x7 << PLL_POSTDIV1_SHIFT,
+ PLL_FBDIV_SHIFT = 0,
+ PLL_FBDIV_MASK = 0xfff,
+
+ /* PLL_CON1 */
+ PLL_DSMPD_SHIFT = 12,
+ PLL_DSMPD_MASK = 1 << PLL_DSMPD_SHIFT,
+ PLL_INTEGER_MODE = 1,
+ PLL_LOCK_STATUS_SHIFT = 10,
+ PLL_LOCK_STATUS_MASK = 1 << PLL_LOCK_STATUS_SHIFT,
+ PLL_POSTDIV2_SHIFT = 6,
+ PLL_POSTDIV2_MASK = 0x7 << PLL_POSTDIV2_SHIFT,
+ PLL_REFDIV_SHIFT = 0,
+ PLL_REFDIV_MASK = 0x3f,
+
+ /* PLL_CON2 */
+ PLL_FRACDIV_SHIFT = 0,
+ PLL_FRACDIV_MASK = 0xffffff,
+
+ /* MODE_CON */
+ APLL_MODE_SHIFT = 0,
+ NPLL_MODE_SHIFT = 1,
+ DPLL_MODE_SHIFT = 4,
+ CPLL_MODE_SHIFT = 8,
+ GPLL_MODE_SHIFT = 12,
+ PLL_MODE_SLOW = 0,
+ PLL_MODE_NORM,
+
+ /* CLKSEL_CON0 */
+ CLK_CORE_PLL_SEL_APLL = 0,
+ CLK_CORE_PLL_SEL_GPLL,
+ CLK_CORE_PLL_SEL_DPLL,
+ CLK_CORE_PLL_SEL_NPLL,
+ CLK_CORE_PLL_SEL_SHIFT = 6,
+ CLK_CORE_PLL_SEL_MASK = 3 << CLK_CORE_PLL_SEL_SHIFT,
+ CLK_CORE_DIV_SHIFT = 0,
+ CLK_CORE_DIV_MASK = 0x1f,
+
+ /* CLKSEL_CON1 */
+ ACLKM_CORE_DIV_SHIFT = 4,
+ ACLKM_CORE_DIV_MASK = 0x7 << ACLKM_CORE_DIV_SHIFT,
+ PCLK_DBG_DIV_SHIFT = 0,
+ PCLK_DBG_DIV_MASK = 0xF << PCLK_DBG_DIV_SHIFT,
+
+ /* CLKSEL_CON28 */
+ ACLK_PERIHP_PLL_SEL_CPLL = 0,
+ ACLK_PERIHP_PLL_SEL_GPLL,
+ ACLK_PERIHP_PLL_SEL_HDMIPHY,
+ ACLK_PERIHP_PLL_SEL_SHIFT = 6,
+ ACLK_PERIHP_PLL_SEL_MASK = 3 << ACLK_PERIHP_PLL_SEL_SHIFT,
+ ACLK_PERIHP_DIV_CON_SHIFT = 0,
+ ACLK_PERIHP_DIV_CON_MASK = 0x1f,
+
+ /* CLKSEL_CON29 */
+ PCLK_PERIHP_DIV_CON_SHIFT = 4,
+ PCLK_PERIHP_DIV_CON_MASK = 0x7 << PCLK_PERIHP_DIV_CON_SHIFT,
+ HCLK_PERIHP_DIV_CON_SHIFT = 0,
+ HCLK_PERIHP_DIV_CON_MASK = 3 << HCLK_PERIHP_DIV_CON_SHIFT,
+
+ /* CLKSEL_CON22 */
+ CLK_TSADC_DIV_CON_SHIFT = 0,
+ CLK_TSADC_DIV_CON_MASK = 0x3ff,
+
+ /* CLKSEL_CON23 */
+ CLK_SARADC_DIV_CON_SHIFT = 0,
+ CLK_SARADC_DIV_CON_MASK = 0x3ff << CLK_SARADC_DIV_CON_SHIFT,
+
+ /* CLKSEL_CON24 */
+ CLK_PWM_PLL_SEL_CPLL = 0,
+ CLK_PWM_PLL_SEL_GPLL,
+ CLK_PWM_PLL_SEL_SHIFT = 15,
+ CLK_PWM_PLL_SEL_MASK = 1 << CLK_PWM_PLL_SEL_SHIFT,
+ CLK_PWM_DIV_CON_SHIFT = 8,
+ CLK_PWM_DIV_CON_MASK = 0x7f << CLK_PWM_DIV_CON_SHIFT,
+
+ CLK_SPI_PLL_SEL_CPLL = 0,
+ CLK_SPI_PLL_SEL_GPLL,
+ CLK_SPI_PLL_SEL_SHIFT = 7,
+ CLK_SPI_PLL_SEL_MASK = 1 << CLK_SPI_PLL_SEL_SHIFT,
+ CLK_SPI_DIV_CON_SHIFT = 0,
+ CLK_SPI_DIV_CON_MASK = 0x7f << CLK_SPI_DIV_CON_SHIFT,
+
+ /* CLKSEL_CON30 */
+ CLK_SDMMC_PLL_SEL_CPLL = 0,
+ CLK_SDMMC_PLL_SEL_GPLL,
+ CLK_SDMMC_PLL_SEL_24M,
+ CLK_SDMMC_PLL_SEL_USBPHY,
+ CLK_SDMMC_PLL_SHIFT = 8,
+ CLK_SDMMC_PLL_MASK = 0x3 << CLK_SDMMC_PLL_SHIFT,
+ CLK_SDMMC_DIV_CON_SHIFT = 0,
+ CLK_SDMMC_DIV_CON_MASK = 0xff << CLK_SDMMC_DIV_CON_SHIFT,
+
+ /* CLKSEL_CON32 */
+ CLK_EMMC_PLL_SEL_CPLL = 0,
+ CLK_EMMC_PLL_SEL_GPLL,
+ CLK_EMMC_PLL_SEL_24M,
+ CLK_EMMC_PLL_SEL_USBPHY,
+ CLK_EMMC_PLL_SHIFT = 8,
+ CLK_EMMC_PLL_MASK = 0x3 << CLK_EMMC_PLL_SHIFT,
+ CLK_EMMC_DIV_CON_SHIFT = 0,
+ CLK_EMMC_DIV_CON_MASK = 0xff << CLK_EMMC_DIV_CON_SHIFT,
+
+ /* CLKSEL_CON34 */
+ CLK_I2C_PLL_SEL_CPLL = 0,
+ CLK_I2C_PLL_SEL_GPLL,
+ CLK_I2C_DIV_CON_MASK = 0x7f,
+ CLK_I2C_PLL_SEL_MASK = 1,
+ CLK_I2C1_PLL_SEL_SHIFT = 15,
+ CLK_I2C1_DIV_CON_SHIFT = 8,
+ CLK_I2C0_PLL_SEL_SHIFT = 7,
+ CLK_I2C0_DIV_CON_SHIFT = 0,
+
+ /* CLKSEL_CON35 */
+ CLK_I2C3_PLL_SEL_SHIFT = 15,
+ CLK_I2C3_DIV_CON_SHIFT = 8,
+ CLK_I2C2_PLL_SEL_SHIFT = 7,
+ CLK_I2C2_DIV_CON_SHIFT = 0,
+};
+
+#define VCO_MAX_KHZ (3200 * (MHz / KHz))
+#define VCO_MIN_KHZ (800 * (MHz / KHz))
+#define OUTPUT_MAX_KHZ (3200 * (MHz / KHz))
+#define OUTPUT_MIN_KHZ (16 * (MHz / KHz))
+
+/*
+ * the div restructions of pll in integer mode, these are defined in
+ * * CRU_*PLL_CON0 or PMUCRU_*PLL_CON0
+ */
+#define PLL_DIV_MIN 16
+#define PLL_DIV_MAX 3200
+
+/*
+ * How to calculate the PLL(from TRM V0.3 Part 1 Page 63):
+ * Formulas also embedded within the Fractional PLL Verilog model:
+ * If DSMPD = 1 (DSM is disabled, "integer mode")
+ * FOUTVCO = FREF / REFDIV * FBDIV
+ * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
+ * Where:
+ * FOUTVCO = Fractional PLL non-divided output frequency
+ * FOUTPOSTDIV = Fractional PLL divided output frequency
+ * (output of second post divider)
+ * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input)
+ * REFDIV = Fractional PLL input reference clock divider
+ * FBDIV = Integer value programmed into feedback divide
+ *
+ */
+static void rkclk_set_pll(struct rk3328_cru *cru, enum rk_clk_id clk_id,
+ const struct pll_div *div)
+{
+ u32 *pll_con;
+ u32 mode_shift, mode_mask;
+
+ pll_con = NULL;
+ mode_shift = 0;
+ switch (clk_id) {
+ case CLK_ARM:
+ pll_con = cru->apll_con;
+ mode_shift = APLL_MODE_SHIFT;
+ break;
+ case CLK_DDR:
+ pll_con = cru->dpll_con;
+ mode_shift = DPLL_MODE_SHIFT;
+ break;
+ case CLK_CODEC:
+ pll_con = cru->cpll_con;
+ mode_shift = CPLL_MODE_SHIFT;
+ break;
+ case CLK_GENERAL:
+ pll_con = cru->gpll_con;
+ mode_shift = GPLL_MODE_SHIFT;
+ break;
+ case CLK_NEW:
+ pll_con = cru->npll_con;
+ mode_shift = NPLL_MODE_SHIFT;
+ break;
+ default:
+ break;
+ }
+ mode_mask = 1 << mode_shift;
+
+ /* All 8 PLLs have same VCO and output frequency range restrictions. */
+ u32 vco_khz = OSC_HZ / 1000 * div->fbdiv / div->refdiv;
+ u32 output_khz = vco_khz / div->postdiv1 / div->postdiv2;
+
+ debug("PLL at %p: fbdiv=%d, refdiv=%d, postdiv1=%d, \
+ postdiv2=%d, vco=%u khz, output=%u khz\n",
+ pll_con, div->fbdiv, div->refdiv, div->postdiv1,
+ div->postdiv2, vco_khz, output_khz);
+ assert(vco_khz >= VCO_MIN_KHZ && vco_khz <= VCO_MAX_KHZ &&
+ output_khz >= OUTPUT_MIN_KHZ && output_khz <= OUTPUT_MAX_KHZ &&
+ div->fbdiv >= PLL_DIV_MIN && div->fbdiv <= PLL_DIV_MAX);
+
+ /*
+ * When power on or changing PLL setting,
+ * we must force PLL into slow mode to ensure output stable clock.
+ */
+ rk_clrsetreg(&cru->mode_con, mode_mask, PLL_MODE_SLOW << mode_shift);
+
+ /* use integer mode */
+ rk_clrsetreg(&pll_con[1], PLL_DSMPD_MASK,
+ PLL_INTEGER_MODE << PLL_DSMPD_SHIFT);
+
+ rk_clrsetreg(&pll_con[0],
+ PLL_FBDIV_MASK | PLL_POSTDIV1_MASK,
+ (div->fbdiv << PLL_FBDIV_SHIFT) |
+ (div->postdiv1 << PLL_POSTDIV1_SHIFT));
+ rk_clrsetreg(&pll_con[1],
+ PLL_POSTDIV2_MASK | PLL_REFDIV_MASK,
+ (div->postdiv2 << PLL_POSTDIV2_SHIFT) |
+ (div->refdiv << PLL_REFDIV_SHIFT));
+
+ /* waiting for pll lock */
+ while (!(readl(&pll_con[1]) & (1 << PLL_LOCK_STATUS_SHIFT)))
+ udelay(1);
+
+ /* pll enter normal mode */
+ rk_clrsetreg(&cru->mode_con, mode_mask, PLL_MODE_NORM << mode_shift);
+}
+
+static void rkclk_init(struct rk3328_cru *cru)
+{
+ u32 aclk_div;
+ u32 hclk_div;
+ u32 pclk_div;
+
+ /* configure gpll cpll */
+ rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
+ rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg);
+
+ /* configure perihp aclk, hclk, pclk */
+ aclk_div = GPLL_HZ / PERIHP_ACLK_HZ - 1;
+ hclk_div = PERIHP_ACLK_HZ / PERIHP_HCLK_HZ - 1;
+ pclk_div = PERIHP_ACLK_HZ / PERIHP_PCLK_HZ - 1;
+
+ rk_clrsetreg(&cru->clksel_con[28],
+ ACLK_PERIHP_PLL_SEL_MASK | ACLK_PERIHP_DIV_CON_MASK,
+ ACLK_PERIHP_PLL_SEL_GPLL << ACLK_PERIHP_PLL_SEL_SHIFT |
+ aclk_div << ACLK_PERIHP_DIV_CON_SHIFT);
+ rk_clrsetreg(&cru->clksel_con[29],
+ PCLK_PERIHP_DIV_CON_MASK | HCLK_PERIHP_DIV_CON_MASK,
+ pclk_div << PCLK_PERIHP_DIV_CON_SHIFT |
+ hclk_div << HCLK_PERIHP_DIV_CON_SHIFT);
+}
+
+void rk3328_configure_cpu(struct rk3328_cru *cru,
+ enum apll_frequencies apll_freq)
+{
+ u32 clk_core_div;
+ u32 aclkm_div;
+ u32 pclk_dbg_div;
+
+ rkclk_set_pll(cru, CLK_ARM, apll_cfgs[apll_freq]);
+
+ clk_core_div = APLL_HZ / CLK_CORE_HZ - 1;
+ aclkm_div = APLL_HZ / ACLKM_CORE_HZ / (clk_core_div + 1) - 1;
+ pclk_dbg_div = APLL_HZ / PCLK_DBG_HZ / (clk_core_div + 1) - 1;
+
+ rk_clrsetreg(&cru->clksel_con[0],
+ CLK_CORE_PLL_SEL_MASK | CLK_CORE_DIV_MASK,
+ CLK_CORE_PLL_SEL_APLL << CLK_CORE_PLL_SEL_SHIFT |
+ clk_core_div << CLK_CORE_DIV_SHIFT);
+
+ rk_clrsetreg(&cru->clksel_con[1],
+ PCLK_DBG_DIV_MASK | ACLKM_CORE_DIV_MASK,
+ pclk_dbg_div << PCLK_DBG_DIV_SHIFT |
+ aclkm_div << ACLKM_CORE_DIV_SHIFT);
+}
+
+
+static ulong rk3328_i2c_get_clk(struct rk3328_cru *cru, ulong clk_id)
+{
+ u32 div, con;
+
+ switch (clk_id) {
+ case SCLK_I2C0:
+ con = readl(&cru->clksel_con[34]);
+ div = con >> CLK_I2C0_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
+ break;
+ case SCLK_I2C1:
+ con = readl(&cru->clksel_con[34]);
+ div = con >> CLK_I2C1_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
+ break;
+ case SCLK_I2C2:
+ con = readl(&cru->clksel_con[35]);
+ div = con >> CLK_I2C2_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
+ break;
+ case SCLK_I2C3:
+ con = readl(&cru->clksel_con[35]);
+ div = con >> CLK_I2C3_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
+ break;
+ default:
+ printf("do not support this i2c bus\n");
+ return -EINVAL;
+ }
+
+ return DIV_TO_RATE(GPLL_HZ, div);
+}
+
+static ulong rk3328_i2c_set_clk(struct rk3328_cru *cru, ulong clk_id, uint hz)
+{
+ int src_clk_div;
+
+ src_clk_div = GPLL_HZ / hz;
+ assert(src_clk_div - 1 < 127);
+
+ switch (clk_id) {
+ case SCLK_I2C0:
+ rk_clrsetreg(&cru->clksel_con[34],
+ CLK_I2C_DIV_CON_MASK << CLK_I2C0_DIV_CON_SHIFT |
+ CLK_I2C_PLL_SEL_MASK << CLK_I2C0_PLL_SEL_SHIFT,
+ (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT |
+ CLK_I2C_PLL_SEL_GPLL << CLK_I2C0_PLL_SEL_SHIFT);
+ break;
+ case SCLK_I2C1:
+ rk_clrsetreg(&cru->clksel_con[34],
+ CLK_I2C_DIV_CON_MASK << CLK_I2C1_DIV_CON_SHIFT |
+ CLK_I2C_PLL_SEL_MASK << CLK_I2C1_PLL_SEL_SHIFT,
+ (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT |
+ CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT);
+ break;
+ case SCLK_I2C2:
+ rk_clrsetreg(&cru->clksel_con[35],
+ CLK_I2C_DIV_CON_MASK << CLK_I2C2_DIV_CON_SHIFT |
+ CLK_I2C_PLL_SEL_MASK << CLK_I2C2_PLL_SEL_SHIFT,
+ (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT |
+ CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT);
+ break;
+ case SCLK_I2C3:
+ rk_clrsetreg(&cru->clksel_con[35],
+ CLK_I2C_DIV_CON_MASK << CLK_I2C3_DIV_CON_SHIFT |
+ CLK_I2C_PLL_SEL_MASK << CLK_I2C3_PLL_SEL_SHIFT,
+ (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT |
+ CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT);
+ break;
+ default:
+ printf("do not support this i2c bus\n");
+ return -EINVAL;
+ }
+
+ return DIV_TO_RATE(GPLL_HZ, src_clk_div);
+}
+
+static ulong rk3328_mmc_get_clk(struct rk3328_cru *cru, uint clk_id)
+{
+ u32 div, con, con_id;
+
+ switch (clk_id) {
+ case HCLK_SDMMC:
+ con_id = 30;
+ break;
+ case HCLK_EMMC:
+ con_id = 32;
+ break;
+ default:
+ return -EINVAL;
+ }
+ con = readl(&cru->clksel_con[con_id]);
+ div = (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT;
+
+ if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT
+ == CLK_EMMC_PLL_SEL_24M)
+ return DIV_TO_RATE(OSC_HZ, div);
+ else
+ return DIV_TO_RATE(GPLL_HZ, div);
+}
+
+static ulong rk3328_mmc_set_clk(struct rk3328_cru *cru,
+ ulong clk_id, ulong set_rate)
+{
+ int src_clk_div;
+ u32 con_id;
+
+ switch (clk_id) {
+ case HCLK_SDMMC:
+ con_id = 30;
+ break;
+ case HCLK_EMMC:
+ con_id = 32;
+ break;
+ default:
+ return -EINVAL;
+ }
+ /* Select clk_sdmmc/emmc source from GPLL by default */
+ src_clk_div = GPLL_HZ / set_rate;
+
+ if (src_clk_div > 127) {
+ /* use 24MHz source for 400KHz clock */
+ src_clk_div = OSC_HZ / set_rate;
+ rk_clrsetreg(&cru->clksel_con[con_id],
+ CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
+ CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT |
+ (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
+ } else {
+ rk_clrsetreg(&cru->clksel_con[con_id],
+ CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
+ CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT |
+ (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
+ }
+
+ return rk3328_mmc_get_clk(cru, clk_id);
+}
+
+static ulong rk3328_pwm_get_clk(struct rk3328_cru *cru)
+{
+ u32 div, con;
+
+ con = readl(&cru->clksel_con[24]);
+ div = (con & CLK_PWM_DIV_CON_MASK) >> CLK_PWM_DIV_CON_SHIFT;
+
+ return DIV_TO_RATE(GPLL_HZ, div);
+}
+
+static ulong rk3328_pwm_set_clk(struct rk3328_cru *cru, uint hz)
+{
+ u32 div = GPLL_HZ / hz;
+
+ rk_clrsetreg(&cru->clksel_con[24],
+ CLK_PWM_PLL_SEL_MASK | CLK_PWM_DIV_CON_MASK,
+ CLK_PWM_PLL_SEL_GPLL << CLK_PWM_PLL_SEL_SHIFT |
+ (div - 1) << CLK_PWM_DIV_CON_SHIFT);
+
+ return DIV_TO_RATE(GPLL_HZ, div);
+}
+
+static ulong rk3328_clk_get_rate(struct clk *clk)
+{
+ struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong rate = 0;
+
+ switch (clk->id) {
+ case 0 ... 29:
+ return 0;
+ case HCLK_SDMMC:
+ case HCLK_EMMC:
+ rate = rk3328_mmc_get_clk(priv->cru, clk->id);
+ break;
+ case SCLK_I2C0:
+ case SCLK_I2C1:
+ case SCLK_I2C2:
+ case SCLK_I2C3:
+ rate = rk3328_i2c_get_clk(priv->cru, clk->id);
+ break;
+ case SCLK_PWM:
+ rate = rk3328_pwm_get_clk(priv->cru);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return rate;
+}
+
+static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong ret = 0;
+
+ switch (clk->id) {
+ case 0 ... 29:
+ return 0;
+ case HCLK_SDMMC:
+ case HCLK_EMMC:
+ ret = rk3328_mmc_set_clk(priv->cru, clk->id, rate);
+ break;
+ case SCLK_I2C0:
+ case SCLK_I2C1:
+ case SCLK_I2C2:
+ case SCLK_I2C3:
+ ret = rk3328_i2c_set_clk(priv->cru, clk->id, rate);
+ break;
+ case SCLK_PWM:
+ ret = rk3328_pwm_set_clk(priv->cru, rate);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return ret;
+}
+
+static struct clk_ops rk3328_clk_ops = {
+ .get_rate = rk3328_clk_get_rate,
+ .set_rate = rk3328_clk_set_rate,
+};
+
+static int rk3328_clk_probe(struct udevice *dev)
+{
+ struct rk3328_clk_priv *priv = dev_get_priv(dev);
+
+ rkclk_init(priv->cru);
+
+ return 0;
+}
+
+static int rk3328_clk_ofdata_to_platdata(struct udevice *dev)
+{
+ struct rk3328_clk_priv *priv = dev_get_priv(dev);
+
+ priv->cru = (struct rk3328_cru *)dev_get_addr(dev);
+
+ return 0;
+}
+
+static int rk3328_clk_bind(struct udevice *dev)
+{
+ int ret;
+
+ /* The reset driver does not have a device node, so bind it here */
+ ret = device_bind_driver(gd->dm_root, "rk3328_sysreset", "reset", &dev);
+ if (ret)
+ printf("Warning: No RK3328 reset driver: ret=%d\n", ret);
+
+ return ret;
+}
+
+static const struct udevice_id rk3328_clk_ids[] = {
+ { .compatible = "rockchip,rk3328-cru" },
+ { }
+};
+
+U_BOOT_DRIVER(rockchip_rk3328_cru) = {
+ .name = "rockchip_rk3328_cru",
+ .id = UCLASS_CLK,
+ .of_match = rk3328_clk_ids,
+ .priv_auto_alloc_size = sizeof(struct rk3328_clk_priv),
+ .ofdata_to_platdata = rk3328_clk_ofdata_to_platdata,
+ .ops = &rk3328_clk_ops,
+ .bind = rk3328_clk_bind,
+ .probe = rk3328_clk_probe,
+};
diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
index 2e87e4b..922ce7e 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -7,7 +7,9 @@
#include <common.h>
#include <clk-uclass.h>
#include <dm.h>
+#include <dt-structs.h>
#include <errno.h>
+#include <mapmem.h>
#include <syscon.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
@@ -18,10 +20,16 @@
DECLARE_GLOBAL_DATA_PTR;
-struct rk3399_pmuclk_priv {
- struct rk3399_pmucru *pmucru;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+struct rk3399_clk_plat {
+ struct dtd_rockchip_rk3399_cru dtd;
};
+struct rk3399_pmuclk_plat {
+ struct dtd_rockchip_rk3399_pmucru dtd;
+};
+#endif
+
struct pll_div {
u32 refdiv;
u32 fbdiv;
@@ -381,6 +389,7 @@ static int pll_para_config(u32 freq_hz, struct pll_div *div)
return 0;
}
+#ifdef CONFIG_SPL_BUILD
static void rkclk_init(struct rk3399_cru *cru)
{
u32 aclk_div;
@@ -456,6 +465,7 @@ static void rkclk_init(struct rk3399_cru *cru)
hclk_div << HCLK_PERILP1_DIV_CON_SHIFT |
HCLK_PERILP1_PLL_SEL_GPLL << HCLK_PERILP1_PLL_SEL_SHIFT);
}
+#endif
void rk3399_configure_cpu(struct rk3399_cru *cru,
enum apll_l_frequencies apll_l_freq)
@@ -709,6 +719,44 @@ static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru,
return rk3399_mmc_get_clk(cru, clk_id);
}
+#define PMUSGRF_DDR_RGN_CON16 0xff330040
+static ulong rk3399_ddr_set_clk(struct rk3399_cru *cru,
+ ulong set_rate)
+{
+ struct pll_div dpll_cfg;
+
+ /* IC ECO bug, need to set this register */
+ writel(0xc000c000, PMUSGRF_DDR_RGN_CON16);
+
+ /* clk_ddrc == DPLL = 24MHz / refdiv * fbdiv / postdiv1 / postdiv2 */
+ switch (set_rate) {
+ case 200*MHz:
+ dpll_cfg = (struct pll_div)
+ {.refdiv = 1, .fbdiv = 50, .postdiv1 = 6, .postdiv2 = 1};
+ break;
+ case 300*MHz:
+ dpll_cfg = (struct pll_div)
+ {.refdiv = 2, .fbdiv = 100, .postdiv1 = 4, .postdiv2 = 1};
+ break;
+ case 666*MHz:
+ dpll_cfg = (struct pll_div)
+ {.refdiv = 2, .fbdiv = 111, .postdiv1 = 2, .postdiv2 = 1};
+ break;
+ case 800*MHz:
+ dpll_cfg = (struct pll_div)
+ {.refdiv = 1, .fbdiv = 100, .postdiv1 = 3, .postdiv2 = 1};
+ break;
+ case 933*MHz:
+ dpll_cfg = (struct pll_div)
+ {.refdiv = 1, .fbdiv = 116, .postdiv1 = 3, .postdiv2 = 1};
+ break;
+ default:
+ error("Unsupported SDRAM frequency!,%ld\n", set_rate);
+ }
+ rkclk_set_pll(&cru->dpll_con[0], &dpll_cfg);
+
+ return set_rate;
+}
static ulong rk3399_clk_get_rate(struct clk *clk)
{
struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
@@ -763,6 +811,9 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
case DCLK_VOP1:
ret = rk3399_vop_set_clk(priv->cru, clk->id, rate);
break;
+ case SCLK_DDRCLK:
+ ret = rk3399_ddr_set_clk(priv->cru, rate);
+ break;
default:
return -ENOENT;
}
@@ -777,19 +828,26 @@ static struct clk_ops rk3399_clk_ops = {
static int rk3399_clk_probe(struct udevice *dev)
{
+#ifdef CONFIG_SPL_BUILD
struct rk3399_clk_priv *priv = dev_get_priv(dev);
- rkclk_init(priv->cru);
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct rk3399_clk_plat *plat = dev_get_platdata(dev);
+ priv->cru = map_sysmem(plat->dtd.reg[1], plat->dtd.reg[3]);
+#endif
+ rkclk_init(priv->cru);
+#endif
return 0;
}
static int rk3399_clk_ofdata_to_platdata(struct udevice *dev)
{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3399_clk_priv *priv = dev_get_priv(dev);
priv->cru = (struct rk3399_cru *)dev_get_addr(dev);
-
+#endif
return 0;
}
@@ -811,7 +869,7 @@ static const struct udevice_id rk3399_clk_ids[] = {
};
U_BOOT_DRIVER(clk_rk3399) = {
- .name = "clk_rk3399",
+ .name = "rockchip_rk3399_cru",
.id = UCLASS_CLK,
.of_match = rk3399_clk_ids,
.priv_auto_alloc_size = sizeof(struct rk3399_clk_priv),
@@ -819,6 +877,9 @@ U_BOOT_DRIVER(clk_rk3399) = {
.ops = &rk3399_clk_ops,
.bind = rk3399_clk_bind,
.probe = rk3399_clk_probe,
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ .platdata_auto_alloc_size = sizeof(struct rk3399_clk_plat),
+#endif
};
static ulong rk3399_i2c_get_pmuclk(struct rk3399_pmucru *pmucru, ulong clk_id)
@@ -930,6 +991,7 @@ static struct clk_ops rk3399_pmuclk_ops = {
.set_rate = rk3399_pmuclk_set_rate,
};
+#ifndef CONFIG_SPL_BUILD
static void pmuclk_init(struct rk3399_pmucru *pmucru)
{
u32 pclk_div;
@@ -939,27 +1001,35 @@ static void pmuclk_init(struct rk3399_pmucru *pmucru)
/* configure pmu pclk */
pclk_div = PPLL_HZ / PMU_PCLK_HZ - 1;
- assert((pclk_div + 1) * PMU_PCLK_HZ == PPLL_HZ && pclk_div < 0x1f);
rk_clrsetreg(&pmucru->pmucru_clksel[0],
PMU_PCLK_DIV_CON_MASK,
pclk_div << PMU_PCLK_DIV_CON_SHIFT);
}
+#endif
static int rk3399_pmuclk_probe(struct udevice *dev)
{
struct rk3399_pmuclk_priv *priv = dev_get_priv(dev);
- pmuclk_init(priv->pmucru);
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct rk3399_pmuclk_plat *plat = dev_get_platdata(dev);
+
+ priv->pmucru = map_sysmem(plat->dtd.reg[1], plat->dtd.reg[3]);
+#endif
+#ifndef CONFIG_SPL_BUILD
+ pmuclk_init(priv->pmucru);
+#endif
return 0;
}
static int rk3399_pmuclk_ofdata_to_platdata(struct udevice *dev)
{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3399_pmuclk_priv *priv = dev_get_priv(dev);
priv->pmucru = (struct rk3399_pmucru *)dev_get_addr(dev);
-
+#endif
return 0;
}
@@ -969,11 +1039,14 @@ static const struct udevice_id rk3399_pmuclk_ids[] = {
};
U_BOOT_DRIVER(rockchip_rk3399_pmuclk) = {
- .name = "pmuclk_rk3399",
+ .name = "rockchip_rk3399_pmucru",
.id = UCLASS_CLK,
.of_match = rk3399_pmuclk_ids,
.priv_auto_alloc_size = sizeof(struct rk3399_pmuclk_priv),
.ofdata_to_platdata = rk3399_pmuclk_ofdata_to_platdata,
.ops = &rk3399_pmuclk_ops,
.probe = rk3399_pmuclk_probe,
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ .platdata_auto_alloc_size = sizeof(struct rk3399_pmuclk_plat),
+#endif
};
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 175fd3f..93ab568 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -205,7 +205,7 @@ int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset,
offset > 0;
offset = fdt_next_subnode(blob, offset)) {
if (pre_reloc_only &&
- !fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL))
+ !dm_fdt_pre_reloc(blob, offset))
continue;
if (!fdtdec_get_is_enabled(blob, offset)) {
dm_dbg(" - ignoring disabled device\n");
diff --git a/drivers/core/util.c b/drivers/core/util.c
index e01dd06..5ceac8b 100644
--- a/drivers/core/util.c
+++ b/drivers/core/util.c
@@ -5,6 +5,7 @@
*/
#include <common.h>
+#include <libfdt.h>
#include <vsprintf.h>
void dm_warn(const char *fmt, ...)
@@ -35,3 +36,27 @@ int list_count_items(struct list_head *head)
return count;
}
+
+bool dm_fdt_pre_reloc(const void *blob, int offset)
+{
+ if (fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL))
+ return true;
+
+#ifdef CONFIG_TPL_BUILD
+ if (fdt_getprop(blob, offset, "u-boot,dm-tpl", NULL))
+ return true;
+#elif defined(CONFIG_SPL_BUILD)
+ if (fdt_getprop(blob, offset, "u-boot,dm-spl", NULL))
+ return true;
+#else
+ /*
+ * In regular builds individual spl and tpl handling both
+ * count as handled pre-relocation for later second init.
+ */
+ if (fdt_getprop(blob, offset, "u-boot,dm-spl", NULL) ||
+ fdt_getprop(blob, offset, "u-boot,dm-tpl", NULL))
+ return true;
+#endif
+
+ return false;
+}
diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
index bd91f91..bdde831 100644
--- a/drivers/mmc/rockchip_sdhci.c
+++ b/drivers/mmc/rockchip_sdhci.c
@@ -8,9 +8,11 @@
#include <common.h>
#include <dm.h>
+#include <dt-structs.h>
#include <fdtdec.h>
#include <libfdt.h>
#include <malloc.h>
+#include <mapmem.h>
#include <sdhci.h>
#include <clk.h>
@@ -19,6 +21,9 @@ DECLARE_GLOBAL_DATA_PTR;
#define EMMC_MIN_FREQ 400000
struct rockchip_sdhc_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_rockchip_rk3399_sdhci_5_1 dtplat;
+#endif
struct mmc_config cfg;
struct mmc mmc;
};
@@ -37,10 +42,18 @@ static int arasan_sdhci_probe(struct udevice *dev)
int max_frequency, ret;
struct clk clk;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_rockchip_rk3399_sdhci_5_1 *dtplat = &plat->dtplat;
+ host->name = dev->name;
+ host->ioaddr = map_sysmem(dtplat->reg[1], dtplat->reg[3]);
+ max_frequency = dtplat->max_frequency;
+ ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &clk);
+#else
max_frequency = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"max-frequency", 0);
ret = clk_get_by_index(dev, 0, &clk);
+#endif
if (!ret) {
ret = clk_set_rate(&clk, max_frequency);
if (IS_ERR_VALUE(ret))
@@ -66,10 +79,12 @@ static int arasan_sdhci_probe(struct udevice *dev)
static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct sdhci_host *host = dev_get_priv(dev);
host->name = dev->name;
host->ioaddr = dev_get_addr_ptr(dev);
+#endif
return 0;
}
@@ -87,7 +102,7 @@ static const struct udevice_id arasan_sdhci_ids[] = {
};
U_BOOT_DRIVER(arasan_sdhci_drv) = {
- .name = "arasan_sdhci",
+ .name = "rockchip_rk3399_sdhci_5_1",
.id = UCLASS_MMC,
.of_match = arasan_sdhci_ids,
.ofdata_to_platdata = arasan_sdhci_ofdata_to_platdata,
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index d011dad..f3e3072 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -132,6 +132,15 @@ config ROCKCHIP_RK3036_PINCTRL
definitions and pin control functions for each available multiplex
function.
+config ROCKCHIP_RK3188_PINCTRL
+ bool "Rockchip pin control driver"
+ depends on DM
+ help
+ Support pin multiplexing control on Rockchip rk3188 SoCs. The driver
+ is controlled by a device tree node which contains both the GPIO
+ definitions and pin control functions for each available multiplex
+ function.
+
config ROCKCHIP_RK3288_PINCTRL
bool "Rockchip pin control driver"
depends on DM
@@ -148,6 +157,15 @@ config PINCTRL_AT91PIO4
This option is to enable the AT91 pinctrl driver for AT91 PIO4
controller which is available on SAMA5D2 SoC.
+config ROCKCHIP_RK3328_PINCTRL
+ bool "Rockchip pin control driver"
+ depends on DM
+ help
+ Support pin multiplexing control on Rockchip rk3328 SoCs. The driver
+ is controlled by a device tree node which contains both the GPIO
+ definitions and pin control functions for each available multiplex
+ function.
+
config ROCKCHIP_RK3399_PINCTRL
bool "Rockchip pin control driver"
depends on DM
diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c
index 49afe91..9efad06 100644
--- a/drivers/pinctrl/pinctrl-uclass.c
+++ b/drivers/pinctrl/pinctrl-uclass.c
@@ -12,6 +12,7 @@
#include <dm/lists.h>
#include <dm/pinctrl.h>
#include <dm/uclass.h>
+#include <dm/util.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -131,7 +132,7 @@ static int pinconfig_post_bind(struct udevice *dev)
offset > 0;
offset = fdt_next_subnode(fdt, offset)) {
if (pre_reloc_only &&
- !fdt_getprop(fdt, offset, "u-boot,dm-pre-reloc", NULL))
+ !dm_fdt_pre_reloc(fdt, offset))
continue;
/*
* If this node has "compatible" property, this is not
diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
index 805c833..b0b698a 100644
--- a/drivers/pinctrl/rockchip/Makefile
+++ b/drivers/pinctrl/rockchip/Makefile
@@ -6,5 +6,7 @@
#
obj-$(CONFIG_ROCKCHIP_RK3036_PINCTRL) += pinctrl_rk3036.o
+obj-$(CONFIG_ROCKCHIP_RK3188_PINCTRL) += pinctrl_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK3288_PINCTRL) += pinctrl_rk3288.o
+obj-$(CONFIG_ROCKCHIP_RK3328_PINCTRL) += pinctrl_rk3328.o
obj-$(CONFIG_ROCKCHIP_RK3399_PINCTRL) += pinctrl_rk3399.o
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3188.c b/drivers/pinctrl/rockchip/pinctrl_rk3188.c
new file mode 100644
index 0000000..ef94dab
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3188.c
@@ -0,0 +1,611 @@
+/*
+ * Pinctrl driver for Rockchip RK3188 SoCs
+ * Copyright (c) 2016 Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3188.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/periph.h>
+#include <asm/arch/pmu_rk3188.h>
+#include <dm/pinctrl.h>
+#include <dm/root.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct rk3188_pinctrl_priv {
+ struct rk3188_grf *grf;
+ struct rk3188_pmu *pmu;
+ int num_banks;
+};
+
+/**
+ * Encode variants of iomux registers into a type variable
+ */
+#define IOMUX_GPIO_ONLY BIT(0)
+
+/**
+ * @type: iomux variant using IOMUX_* constants
+ * @offset: if initialized to -1 it will be autocalculated, by specifying
+ * an initial offset value the relevant source offset can be reset
+ * to a new value for autocalculating the following iomux registers.
+ */
+struct rockchip_iomux {
+ u8 type;
+ s16 offset;
+};
+
+/**
+ * @reg: register offset of the gpio bank
+ * @nr_pins: number of pins in this bank
+ * @bank_num: number of the bank, to account for holes
+ * @name: name of the bank
+ * @iomux: array describing the 4 iomux sources of the bank
+ */
+struct rockchip_pin_bank {
+ u16 reg;
+ u8 nr_pins;
+ u8 bank_num;
+ char *name;
+ struct rockchip_iomux iomux[4];
+};
+
+#define PIN_BANK(id, pins, label) \
+ { \
+ .bank_num = id, \
+ .nr_pins = pins, \
+ .name = label, \
+ .iomux = { \
+ { .offset = -1 }, \
+ { .offset = -1 }, \
+ { .offset = -1 }, \
+ { .offset = -1 }, \
+ }, \
+ }
+
+#define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \
+ { \
+ .bank_num = id, \
+ .nr_pins = pins, \
+ .name = label, \
+ .iomux = { \
+ { .type = iom0, .offset = -1 }, \
+ { .type = iom1, .offset = -1 }, \
+ { .type = iom2, .offset = -1 }, \
+ { .type = iom3, .offset = -1 }, \
+ }, \
+ }
+
+#ifndef CONFIG_SPL_BUILD
+static struct rockchip_pin_bank rk3188_pin_banks[] = {
+ PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0),
+ PIN_BANK(1, 32, "gpio1"),
+ PIN_BANK(2, 32, "gpio2"),
+ PIN_BANK(3, 32, "gpio3"),
+};
+#endif
+
+static void pinctrl_rk3188_pwm_config(struct rk3188_grf *grf, int pwm_id)
+{
+ switch (pwm_id) {
+ case PERIPH_ID_PWM0:
+ rk_clrsetreg(&grf->gpio3d_iomux, GPIO3D3_MASK << GPIO3D3_SHIFT,
+ GPIO3D3_PWM_0 << GPIO3D3_SHIFT);
+ break;
+ case PERIPH_ID_PWM1:
+ rk_clrsetreg(&grf->gpio3d_iomux, GPIO3D4_MASK << GPIO3D4_SHIFT,
+ GPIO3D4_PWM_1 << GPIO3D4_SHIFT);
+ break;
+ case PERIPH_ID_PWM2:
+ rk_clrsetreg(&grf->gpio3d_iomux, GPIO3D5_MASK << GPIO3D5_SHIFT,
+ GPIO3D5_PWM_2 << GPIO3D5_SHIFT);
+ break;
+ case PERIPH_ID_PWM3:
+ rk_clrsetreg(&grf->gpio3d_iomux, GPIO3D6_MASK << GPIO3D6_SHIFT,
+ GPIO3D6_PWM_3 << GPIO3D6_SHIFT);
+ break;
+ default:
+ debug("pwm id = %d iomux error!\n", pwm_id);
+ break;
+ }
+}
+
+static void pinctrl_rk3188_i2c_config(struct rk3188_grf *grf,
+ struct rk3188_pmu *pmu, int i2c_id)
+{
+ switch (i2c_id) {
+ case PERIPH_ID_I2C0:
+ rk_clrsetreg(&grf->gpio1d_iomux,
+ GPIO1D1_MASK << GPIO1D1_SHIFT |
+ GPIO1D0_MASK << GPIO1D0_SHIFT,
+ GPIO1D1_I2C0_SCL << GPIO1D1_SHIFT |
+ GPIO1D0_I2C0_SDA << GPIO1D0_SHIFT);
+ /* enable new i2c controller */
+ rk_clrsetreg(&grf->soc_con1, 1 << RKI2C0_SEL_SHIFT,
+ 1 << RKI2C0_SEL_SHIFT);
+ break;
+ case PERIPH_ID_I2C1:
+ rk_clrsetreg(&grf->gpio1d_iomux,
+ GPIO1D3_MASK << GPIO1D3_SHIFT |
+ GPIO1D2_MASK << GPIO1D2_SHIFT,
+ GPIO1D3_I2C1_SCL << GPIO1D2_SHIFT |
+ GPIO1D2_I2C1_SDA << GPIO1D2_SHIFT);
+ rk_clrsetreg(&grf->soc_con1, 1 << RKI2C1_SEL_SHIFT,
+ 1 << RKI2C1_SEL_SHIFT);
+ break;
+ case PERIPH_ID_I2C2:
+ rk_clrsetreg(&grf->gpio1d_iomux,
+ GPIO1D5_MASK << GPIO1D5_SHIFT |
+ GPIO1D4_MASK << GPIO1D4_SHIFT,
+ GPIO1D5_I2C2_SCL << GPIO1D5_SHIFT |
+ GPIO1D4_I2C2_SDA << GPIO1D4_SHIFT);
+ rk_clrsetreg(&grf->soc_con1, 1 << RKI2C2_SEL_SHIFT,
+ 1 << RKI2C2_SEL_SHIFT);
+ break;
+ case PERIPH_ID_I2C3:
+ rk_clrsetreg(&grf->gpio3b_iomux,
+ GPIO3B7_MASK << GPIO3B7_SHIFT |
+ GPIO3B6_MASK << GPIO3B6_SHIFT,
+ GPIO3B7_I2C3_SCL << GPIO3B7_SHIFT |
+ GPIO3B6_I2C3_SDA << GPIO3B6_SHIFT);
+ rk_clrsetreg(&grf->soc_con1, 1 << RKI2C3_SEL_SHIFT,
+ 1 << RKI2C3_SEL_SHIFT);
+ break;
+ case PERIPH_ID_I2C4:
+ rk_clrsetreg(&grf->gpio1d_iomux,
+ GPIO1D7_MASK << GPIO1D7_SHIFT |
+ GPIO1D6_MASK << GPIO1D6_SHIFT,
+ GPIO1D7_I2C4_SCL << GPIO1D7_SHIFT |
+ GPIO1D6_I2C4_SDA << GPIO1D6_SHIFT);
+ rk_clrsetreg(&grf->soc_con1, 1 << RKI2C4_SEL_SHIFT,
+ 1 << RKI2C4_SEL_SHIFT);
+ break;
+ default:
+ debug("i2c id = %d iomux error!\n", i2c_id);
+ break;
+ }
+}
+
+static int pinctrl_rk3188_spi_config(struct rk3188_grf *grf,
+ enum periph_id spi_id, int cs)
+{
+ switch (spi_id) {
+ case PERIPH_ID_SPI0:
+ switch (cs) {
+ case 0:
+ rk_clrsetreg(&grf->gpio1a_iomux,
+ GPIO1A7_MASK << GPIO1A7_SHIFT,
+ GPIO1A7_SPI0_CSN0 << GPIO1A7_SHIFT);
+ break;
+ case 1:
+ rk_clrsetreg(&grf->gpio1b_iomux,
+ GPIO1B7_MASK << GPIO1B7_SHIFT,
+ GPIO1B7_SPI0_CSN1 << GPIO1B7_SHIFT);
+ break;
+ default:
+ goto err;
+ }
+ rk_clrsetreg(&grf->gpio1a_iomux,
+ GPIO1A4_MASK << GPIO1A4_SHIFT |
+ GPIO1A5_MASK << GPIO1A5_SHIFT |
+ GPIO1A6_MASK << GPIO1A6_SHIFT,
+ GPIO1A4_SPI0_RXD << GPIO1A4_SHIFT |
+ GPIO1A5_SPI0_TXD << GPIO1A5_SHIFT |
+ GPIO1A6_SPI0_CLK << GPIO1A6_SHIFT);
+ break;
+ case PERIPH_ID_SPI1:
+ switch (cs) {
+ case 0:
+ rk_clrsetreg(&grf->gpio0d_iomux,
+ GPIO0D7_MASK << GPIO0D7_SHIFT,
+ GPIO0D7_SPI1_CSN0 << GPIO0D7_SHIFT);
+ break;
+ case 1:
+ rk_clrsetreg(&grf->gpio1b_iomux,
+ GPIO1B6_MASK << GPIO1B6_SHIFT,
+ GPIO1B6_SPI1_CSN1 << GPIO1B6_SHIFT);
+ break;
+ default:
+ goto err;
+ }
+ rk_clrsetreg(&grf->gpio0d_iomux,
+ GPIO0D4_MASK << GPIO0D4_SHIFT |
+ GPIO0D5_MASK << GPIO0D5_SHIFT |
+ GPIO0D6_MASK << GPIO0D6_SHIFT,
+ GPIO0D4_SPI0_RXD << GPIO0D4_SHIFT |
+ GPIO0D5_SPI1_TXD << GPIO0D5_SHIFT |
+ GPIO0D6_SPI1_CLK << GPIO0D6_SHIFT);
+ break;
+ default:
+ goto err;
+ }
+
+ return 0;
+err:
+ debug("rkspi: periph%d cs=%d not supported", spi_id, cs);
+ return -ENOENT;
+}
+
+static void pinctrl_rk3188_uart_config(struct rk3188_grf *grf, int uart_id)
+{
+ switch (uart_id) {
+ case PERIPH_ID_UART0:
+ rk_clrsetreg(&grf->gpio1a_iomux,
+ GPIO1A3_MASK << GPIO1A3_SHIFT |
+ GPIO1A2_MASK << GPIO1A2_SHIFT |
+ GPIO1A1_MASK << GPIO1A1_SHIFT |
+ GPIO1A0_MASK << GPIO1A0_SHIFT,
+ GPIO1A3_UART0_RTS_N << GPIO1A3_SHIFT |
+ GPIO1A2_UART0_CTS_N << GPIO1A2_SHIFT |
+ GPIO1A1_UART0_SOUT << GPIO1A1_SHIFT |
+ GPIO1A0_UART0_SIN << GPIO1A0_SHIFT);
+ break;
+ case PERIPH_ID_UART1:
+ rk_clrsetreg(&grf->gpio1a_iomux,
+ GPIO1A7_MASK << GPIO1A7_SHIFT |
+ GPIO1A6_MASK << GPIO1A6_SHIFT |
+ GPIO1A5_MASK << GPIO1A5_SHIFT |
+ GPIO1A4_MASK << GPIO1A4_SHIFT,
+ GPIO1A7_UART1_RTS_N << GPIO1A7_SHIFT |
+ GPIO1A6_UART1_CTS_N << GPIO1A6_SHIFT |
+ GPIO1A5_UART1_SOUT << GPIO1A5_SHIFT |
+ GPIO1A4_UART1_SIN << GPIO1A4_SHIFT);
+ break;
+ case PERIPH_ID_UART2:
+ rk_clrsetreg(&grf->gpio1b_iomux,
+ GPIO1B1_MASK << GPIO1B1_SHIFT |
+ GPIO1B0_MASK << GPIO1B0_SHIFT,
+ GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT |
+ GPIO1B0_UART2_SIN << GPIO1B0_SHIFT);
+ break;
+ case PERIPH_ID_UART3:
+ rk_clrsetreg(&grf->gpio1b_iomux,
+ GPIO1B5_MASK << GPIO1B5_SHIFT |
+ GPIO1B4_MASK << GPIO1B4_SHIFT |
+ GPIO1B3_MASK << GPIO1B3_SHIFT |
+ GPIO1B2_MASK << GPIO1B2_SHIFT,
+ GPIO1B5_UART3_RTS_N << GPIO1B5_SHIFT |
+ GPIO1B4_UART3_CTS_N << GPIO1B4_SHIFT |
+ GPIO1B3_UART3_SOUT << GPIO1B3_SHIFT |
+ GPIO1B2_UART3_SIN << GPIO1B2_SHIFT);
+ break;
+ default:
+ debug("uart id = %d iomux error!\n", uart_id);
+ break;
+ }
+}
+
+static void pinctrl_rk3188_sdmmc_config(struct rk3188_grf *grf, int mmc_id)
+{
+ switch (mmc_id) {
+ case PERIPH_ID_EMMC:
+ rk_clrsetreg(&grf->soc_con0, 1 << EMMC_FLASH_SEL_SHIFT,
+ 1 << EMMC_FLASH_SEL_SHIFT);
+ rk_clrsetreg(&grf->gpio0d_iomux,
+ GPIO0D2_MASK << GPIO0D2_SHIFT |
+ GPIO0D0_MASK << GPIO0D0_SHIFT,
+ GPIO0D2_EMMC_CMD << GPIO0D2_SHIFT |
+ GPIO0D0_EMMC_CLKOUT << GPIO0D0_SHIFT);
+ break;
+ case PERIPH_ID_SDCARD:
+ rk_clrsetreg(&grf->gpio3b_iomux,
+ GPIO3B0_MASK << GPIO3B0_SHIFT,
+ GPIO3B0_SDMMC_DETECT_N << GPIO3B0_SHIFT);
+ rk_clrsetreg(&grf->gpio3a_iomux,
+ GPIO3A7_MASK << GPIO3A7_SHIFT |
+ GPIO3A6_MASK << GPIO3A6_SHIFT |
+ GPIO3A5_MASK << GPIO3A5_SHIFT |
+ GPIO3A4_MASK << GPIO3A4_SHIFT |
+ GPIO3A3_MASK << GPIO3A3_SHIFT |
+ GPIO3A3_MASK << GPIO3A2_SHIFT,
+ GPIO3A7_SDMMC0_DATA3 << GPIO3A7_SHIFT |
+ GPIO3A6_SDMMC0_DATA2 << GPIO3A6_SHIFT |
+ GPIO3A5_SDMMC0_DATA1 << GPIO3A5_SHIFT |
+ GPIO3A4_SDMMC0_DATA0 << GPIO3A4_SHIFT |
+ GPIO3A3_SDMMC0_CMD << GPIO3A3_SHIFT |
+ GPIO3A2_SDMMC0_CLKOUT << GPIO3A2_SHIFT);
+ break;
+ default:
+ debug("mmc id = %d iomux error!\n", mmc_id);
+ break;
+ }
+}
+
+static int rk3188_pinctrl_request(struct udevice *dev, int func, int flags)
+{
+ struct rk3188_pinctrl_priv *priv = dev_get_priv(dev);
+
+ debug("%s: func=%x, flags=%x\n", __func__, func, flags);
+ switch (func) {
+ case PERIPH_ID_PWM0:
+ case PERIPH_ID_PWM1:
+ case PERIPH_ID_PWM2:
+ case PERIPH_ID_PWM3:
+ case PERIPH_ID_PWM4:
+ pinctrl_rk3188_pwm_config(priv->grf, func);
+ break;
+ case PERIPH_ID_I2C0:
+ case PERIPH_ID_I2C1:
+ case PERIPH_ID_I2C2:
+ case PERIPH_ID_I2C3:
+ case PERIPH_ID_I2C4:
+ case PERIPH_ID_I2C5:
+ pinctrl_rk3188_i2c_config(priv->grf, priv->pmu, func);
+ break;
+ case PERIPH_ID_SPI0:
+ case PERIPH_ID_SPI1:
+ case PERIPH_ID_SPI2:
+ pinctrl_rk3188_spi_config(priv->grf, func, flags);
+ break;
+ case PERIPH_ID_UART0:
+ case PERIPH_ID_UART1:
+ case PERIPH_ID_UART2:
+ case PERIPH_ID_UART3:
+ case PERIPH_ID_UART4:
+ pinctrl_rk3188_uart_config(priv->grf, func);
+ break;
+ break;
+ case PERIPH_ID_SDMMC0:
+ case PERIPH_ID_SDMMC1:
+ pinctrl_rk3188_sdmmc_config(priv->grf, func);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rk3188_pinctrl_get_periph_id(struct udevice *dev,
+ struct udevice *periph)
+{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ u32 cell[3];
+ int ret;
+
+ ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
+ "interrupts", cell, ARRAY_SIZE(cell));
+ if (ret < 0)
+ return -EINVAL;
+
+ switch (cell[1]) {
+ case 44:
+ return PERIPH_ID_SPI0;
+ case 45:
+ return PERIPH_ID_SPI1;
+ case 46:
+ return PERIPH_ID_SPI2;
+ case 60:
+ return PERIPH_ID_I2C0;
+ case 62: /* Note strange order */
+ return PERIPH_ID_I2C1;
+ case 61:
+ return PERIPH_ID_I2C2;
+ case 63:
+ return PERIPH_ID_I2C3;
+ case 64:
+ return PERIPH_ID_I2C4;
+ case 65:
+ return PERIPH_ID_I2C5;
+ }
+#endif
+
+ return -ENOENT;
+}
+
+static int rk3188_pinctrl_set_state_simple(struct udevice *dev,
+ struct udevice *periph)
+{
+ int func;
+
+ func = rk3188_pinctrl_get_periph_id(dev, periph);
+ if (func < 0)
+ return func;
+ return rk3188_pinctrl_request(dev, func, 0);
+}
+
+#ifndef CONFIG_SPL_BUILD
+int rk3188_pinctrl_get_pin_info(struct rk3188_pinctrl_priv *priv,
+ int banknum, int ind, u32 **addrp, uint *shiftp,
+ uint *maskp)
+{
+ struct rockchip_pin_bank *bank = &rk3188_pin_banks[banknum];
+ uint muxnum;
+ u32 *addr;
+
+ for (muxnum = 0; muxnum < 4; muxnum++) {
+ struct rockchip_iomux *mux = &bank->iomux[muxnum];
+
+ if (ind >= 8) {
+ ind -= 8;
+ continue;
+ }
+
+ addr = &priv->grf->gpio0c_iomux - 2;
+ addr += mux->offset;
+ *shiftp = ind & 7;
+ *maskp = 3;
+ *shiftp *= 2;
+
+ debug("%s: addr=%p, mask=%x, shift=%x\n", __func__, addr,
+ *maskp, *shiftp);
+ *addrp = addr;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int rk3188_pinctrl_get_gpio_mux(struct udevice *dev, int banknum,
+ int index)
+{
+ struct rk3188_pinctrl_priv *priv = dev_get_priv(dev);
+ uint shift;
+ uint mask;
+ u32 *addr;
+ int ret;
+
+ ret = rk3188_pinctrl_get_pin_info(priv, banknum, index, &addr, &shift,
+ &mask);
+ if (ret)
+ return ret;
+ return (readl(addr) & mask) >> shift;
+}
+
+static int rk3188_pinctrl_set_pins(struct udevice *dev, int banknum, int index,
+ int muxval, int flags)
+{
+ struct rk3188_pinctrl_priv *priv = dev_get_priv(dev);
+ uint shift, ind = index;
+ uint mask;
+ u32 *addr;
+ int ret;
+
+ debug("%s: %x %x %x %x\n", __func__, banknum, index, muxval, flags);
+ ret = rk3188_pinctrl_get_pin_info(priv, banknum, index, &addr, &shift,
+ &mask);
+ if (ret)
+ return ret;
+ rk_clrsetreg(addr, mask << shift, muxval << shift);
+
+ /* Handle pullup/pulldown */
+ if (flags) {
+ uint val = 0;
+
+ if (flags & (1 << PIN_CONFIG_BIAS_PULL_UP))
+ val = 1;
+ else if (flags & (1 << PIN_CONFIG_BIAS_PULL_DOWN))
+ val = 2;
+
+ ind = index >> 3;
+
+ if (banknum == 0 && index < 12) {
+ addr = &priv->pmu->gpio0_p[ind];
+ shift = (index & 7) * 2;
+ } else if (banknum == 0 && index >= 12) {
+ addr = &priv->grf->gpio0_p[ind - 1];
+ /*
+ * The bits in the grf-registers have an inverse
+ * ordering with the lowest pin being in bits 15:14
+ * and the highest pin in bits 1:0 .
+ */
+ shift = (7 - (index & 7)) * 2;
+ } else {
+ addr = &priv->grf->gpio1_p[banknum - 1][ind];
+ shift = (7 - (index & 7)) * 2;
+ }
+ debug("%s: addr=%p, val=%x, shift=%x\n", __func__, addr, val,
+ shift);
+ rk_clrsetreg(addr, 3 << shift, val << shift);
+ }
+
+ return 0;
+}
+
+static int rk3188_pinctrl_set_state(struct udevice *dev, struct udevice *config)
+{
+ const void *blob = gd->fdt_blob;
+ int pcfg_node, ret, flags, count, i;
+ u32 cell[60], *ptr;
+
+ debug("%s: %s %s\n", __func__, dev->name, config->name);
+ ret = fdtdec_get_int_array_count(blob, config->of_offset,
+ "rockchip,pins", cell,
+ ARRAY_SIZE(cell));
+ if (ret < 0) {
+ debug("%s: bad array %d\n", __func__, ret);
+ return -EINVAL;
+ }
+ count = ret;
+ for (i = 0, ptr = cell; i < count; i += 4, ptr += 4) {
+ pcfg_node = fdt_node_offset_by_phandle(blob, ptr[3]);
+ if (pcfg_node < 0)
+ return -EINVAL;
+ flags = pinctrl_decode_pin_config(blob, pcfg_node);
+ if (flags < 0)
+ return flags;
+
+ ret = rk3188_pinctrl_set_pins(dev, ptr[0], ptr[1], ptr[2],
+ flags);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+#endif
+
+static struct pinctrl_ops rk3188_pinctrl_ops = {
+#ifndef CONFIG_SPL_BUILD
+ .set_state = rk3188_pinctrl_set_state,
+ .get_gpio_mux = rk3188_pinctrl_get_gpio_mux,
+#endif
+ .set_state_simple = rk3188_pinctrl_set_state_simple,
+ .request = rk3188_pinctrl_request,
+ .get_periph_id = rk3188_pinctrl_get_periph_id,
+};
+
+#ifndef CONFIG_SPL_BUILD
+static int rk3188_pinctrl_parse_tables(struct rk3188_pinctrl_priv *priv,
+ struct rockchip_pin_bank *banks,
+ int count)
+{
+ struct rockchip_pin_bank *bank;
+ uint reg, muxnum, banknum;
+
+ reg = 0;
+ for (banknum = 0; banknum < count; banknum++) {
+ bank = &banks[banknum];
+ bank->reg = reg;
+ debug("%s: bank %d, reg %x\n", __func__, banknum, reg * 4);
+ for (muxnum = 0; muxnum < 4; muxnum++) {
+ struct rockchip_iomux *mux = &bank->iomux[muxnum];
+
+ mux->offset = reg;
+ reg += 1;
+ }
+ }
+
+ return 0;
+}
+#endif
+
+static int rk3188_pinctrl_probe(struct udevice *dev)
+{
+ struct rk3188_pinctrl_priv *priv = dev_get_priv(dev);
+ int ret = 0;
+
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
+ debug("%s: grf=%p, pmu=%p\n", __func__, priv->grf, priv->pmu);
+#ifndef CONFIG_SPL_BUILD
+ ret = rk3188_pinctrl_parse_tables(priv, rk3188_pin_banks,
+ ARRAY_SIZE(rk3188_pin_banks));
+#endif
+
+ return ret;
+}
+
+static const struct udevice_id rk3188_pinctrl_ids[] = {
+ { .compatible = "rockchip,rk3188-pinctrl" },
+ { }
+};
+
+U_BOOT_DRIVER(pinctrl_rk3188) = {
+ .name = "rockchip_rk3188_pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = rk3188_pinctrl_ids,
+ .priv_auto_alloc_size = sizeof(struct rk3188_pinctrl_priv),
+ .ops = &rk3188_pinctrl_ops,
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ .bind = dm_scan_fdt_dev,
+#endif
+ .probe = rk3188_pinctrl_probe,
+};
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3328.c b/drivers/pinctrl/rockchip/pinctrl_rk3328.c
new file mode 100644
index 0000000..5ca6782
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3328.c
@@ -0,0 +1,419 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/grf_rk3328.h>
+#include <asm/arch/periph.h>
+#include <asm/io.h>
+#include <dm/pinctrl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct rk3328_pinctrl_priv {
+ struct rk3328_grf_regs *grf;
+};
+
+enum {
+ /* GRF_GPIO0A_IOMUX */
+ GRF_GPIO0A5_SEL_SHIFT = 10,
+ GRF_GPIO0A5_SEL_MASK = 3 << GRF_GPIO0A5_SEL_SHIFT,
+ GRF_I2C3_SCL = 2,
+
+ GRF_GPIO0A6_SEL_SHIFT = 12,
+ GRF_GPIO0A6_SEL_MASK = 3 << GRF_GPIO0A6_SEL_SHIFT,
+ GRF_I2C3_SDA = 2,
+
+ GRF_GPIO0A7_SEL_SHIFT = 14,
+ GRF_GPIO0A7_SEL_MASK = 3 << GRF_GPIO0A7_SEL_SHIFT,
+ GRF_EMMC_DATA0 = 2,
+
+ /* GRF_GPIO1A_IOMUX */
+ GRF_GPIO1A0_SEL_SHIFT = 0,
+ GRF_GPIO1A0_SEL_MASK = 0x3fff << GRF_GPIO1A0_SEL_SHIFT,
+ GRF_CARD_DATA_CLK_CMD_DETN = 0x1555,
+
+ /* GRF_GPIO2A_IOMUX */
+ GRF_GPIO2A0_SEL_SHIFT = 0,
+ GRF_GPIO2A0_SEL_MASK = 3 << GRF_GPIO2A0_SEL_SHIFT,
+ GRF_UART2_TX_M1 = 1,
+
+ GRF_GPIO2A1_SEL_SHIFT = 2,
+ GRF_GPIO2A1_SEL_MASK = 3 << GRF_GPIO2A1_SEL_SHIFT,
+ GRF_UART2_RX_M1 = 1,
+
+ GRF_GPIO2A2_SEL_SHIFT = 4,
+ GRF_GPIO2A2_SEL_MASK = 3 << GRF_GPIO2A2_SEL_SHIFT,
+ GRF_PWM_IR = 1,
+
+ GRF_GPIO2A4_SEL_SHIFT = 8,
+ GRF_GPIO2A4_SEL_MASK = 3 << GRF_GPIO2A4_SEL_SHIFT,
+ GRF_PWM_0 = 1,
+ GRF_I2C1_SDA,
+
+ GRF_GPIO2A5_SEL_SHIFT = 10,
+ GRF_GPIO2A5_SEL_MASK = 3 << GRF_GPIO2A5_SEL_SHIFT,
+ GRF_PWM_1 = 1,
+ GRF_I2C1_SCL,
+
+ GRF_GPIO2A6_SEL_SHIFT = 12,
+ GRF_GPIO2A6_SEL_MASK = 3 << GRF_GPIO2A6_SEL_SHIFT,
+ GRF_PWM_2 = 1,
+
+ GRF_GPIO2A7_SEL_SHIFT = 14,
+ GRF_GPIO2A7_SEL_MASK = 3 << GRF_GPIO2A7_SEL_SHIFT,
+ GRF_CARD_PWR_EN_M0 = 1,
+
+ /* GRF_GPIO2BL_IOMUX */
+ GRF_GPIO2BL0_SEL_SHIFT = 0,
+ GRF_GPIO2BL0_SEL_MASK = 0x3f << GRF_GPIO2BL0_SEL_SHIFT,
+ GRF_SPI_CLK_TX_RX_M0 = 0x15,
+
+ GRF_GPIO2BL3_SEL_SHIFT = 6,
+ GRF_GPIO2BL3_SEL_MASK = 3 << GRF_GPIO2BL3_SEL_SHIFT,
+ GRF_SPI_CSN0_M0 = 1,
+
+ GRF_GPIO2BL4_SEL_SHIFT = 8,
+ GRF_GPIO2BL4_SEL_MASK = 3 << GRF_GPIO2BL4_SEL_SHIFT,
+ GRF_SPI_CSN1_M0 = 1,
+
+ GRF_GPIO2BL5_SEL_SHIFT = 10,
+ GRF_GPIO2BL5_SEL_MASK = 3 << GRF_GPIO2BL5_SEL_SHIFT,
+ GRF_I2C2_SDA = 1,
+
+ GRF_GPIO2BL6_SEL_SHIFT = 12,
+ GRF_GPIO2BL6_SEL_MASK = 3 << GRF_GPIO2BL6_SEL_SHIFT,
+ GRF_I2C2_SCL = 1,
+
+ /* GRF_GPIO2D_IOMUX */
+ GRF_GPIO2D0_SEL_SHIFT = 0,
+ GRF_GPIO2D0_SEL_MASK = 3 << GRF_GPIO2D0_SEL_SHIFT,
+ GRF_I2C0_SCL = 1,
+
+ GRF_GPIO2D1_SEL_SHIFT = 2,
+ GRF_GPIO2D1_SEL_MASK = 3 << GRF_GPIO2D1_SEL_SHIFT,
+ GRF_I2C0_SDA = 1,
+
+ GRF_GPIO2D4_SEL_SHIFT = 8,
+ GRF_GPIO2D4_SEL_MASK = 0xff << GRF_GPIO2D4_SEL_SHIFT,
+ GRF_EMMC_DATA123 = 0xaa,
+
+ /* GRF_GPIO3C_IOMUX */
+ GRF_GPIO3C0_SEL_SHIFT = 0,
+ GRF_GPIO3C0_SEL_MASK = 0x3fff << GRF_GPIO3C0_SEL_SHIFT,
+ GRF_EMMC_DATA567_PWR_CLK_RSTN_CMD = 0x2aaa,
+
+ /* GRF_COM_IOMUX */
+ GRF_UART2_IOMUX_SEL_SHIFT = 0,
+ GRF_UART2_IOMUX_SEL_MASK = 3 << GRF_UART2_IOMUX_SEL_SHIFT,
+ GRF_UART2_IOMUX_SEL_M0 = 0,
+ GRF_UART2_IOMUX_SEL_M1,
+
+ GRF_SPI_IOMUX_SEL_SHIFT = 4,
+ GRF_SPI_IOMUX_SEL_MASK = 3 << GRF_SPI_IOMUX_SEL_SHIFT,
+ GRF_SPI_IOMUX_SEL_M0 = 0,
+ GRF_SPI_IOMUX_SEL_M1,
+ GRF_SPI_IOMUX_SEL_M2,
+
+ GRF_CARD_IOMUX_SEL_SHIFT = 7,
+ GRF_CARD_IOMUX_SEL_MASK = 1 << GRF_CARD_IOMUX_SEL_SHIFT,
+ GRF_CARD_IOMUX_SEL_M0 = 0,
+ GRF_CARD_IOMUX_SEL_M1,
+};
+
+static void pinctrl_rk3328_pwm_config(struct rk3328_grf_regs *grf, int pwm_id)
+{
+ switch (pwm_id) {
+ case PERIPH_ID_PWM0:
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GRF_GPIO2A4_SEL_MASK,
+ GRF_PWM_0 << GRF_GPIO2A4_SEL_SHIFT);
+ break;
+ case PERIPH_ID_PWM1:
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GRF_GPIO2A5_SEL_MASK,
+ GRF_PWM_1 << GRF_GPIO2A5_SEL_SHIFT);
+ break;
+ case PERIPH_ID_PWM2:
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GRF_GPIO2A6_SEL_MASK,
+ GRF_PWM_2 << GRF_GPIO2A6_SEL_SHIFT);
+ break;
+ case PERIPH_ID_PWM3:
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GRF_GPIO2A2_SEL_MASK,
+ GRF_PWM_IR << GRF_GPIO2A2_SEL_SHIFT);
+ break;
+ default:
+ debug("pwm id = %d iomux error!\n", pwm_id);
+ break;
+ }
+}
+
+static void pinctrl_rk3328_i2c_config(struct rk3328_grf_regs *grf, int i2c_id)
+{
+ switch (i2c_id) {
+ case PERIPH_ID_I2C0:
+ rk_clrsetreg(&grf->gpio2d_iomux,
+ GRF_GPIO2D0_SEL_MASK | GRF_GPIO2D1_SEL_MASK,
+ GRF_I2C0_SCL << GRF_GPIO2D0_SEL_SHIFT
+ | GRF_I2C0_SDA << GRF_GPIO2D1_SEL_SHIFT);
+ break;
+ case PERIPH_ID_I2C1:
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GRF_GPIO2A4_SEL_MASK | GRF_GPIO2A5_SEL_MASK,
+ GRF_I2C1_SCL << GRF_GPIO2A5_SEL_SHIFT
+ | GRF_I2C1_SDA << GRF_GPIO2A4_SEL_SHIFT);
+ break;
+ case PERIPH_ID_I2C2:
+ rk_clrsetreg(&grf->gpio2bl_iomux,
+ GRF_GPIO2BL5_SEL_MASK | GRF_GPIO2BL6_SEL_MASK,
+ GRF_I2C2_SCL << GRF_GPIO2BL6_SEL_SHIFT
+ | GRF_I2C2_SDA << GRF_GPIO2BL6_SEL_SHIFT);
+ break;
+ case PERIPH_ID_I2C3:
+ rk_clrsetreg(&grf->gpio0a_iomux,
+ GRF_GPIO0A5_SEL_MASK | GRF_GPIO0A6_SEL_MASK,
+ GRF_I2C3_SCL << GRF_GPIO0A5_SEL_SHIFT
+ | GRF_I2C3_SDA << GRF_GPIO0A6_SEL_SHIFT);
+ break;
+ default:
+ debug("i2c id = %d iomux error!\n", i2c_id);
+ break;
+ }
+}
+
+static void pinctrl_rk3328_lcdc_config(struct rk3328_grf_regs *grf, int lcd_id)
+{
+ switch (lcd_id) {
+ case PERIPH_ID_LCDC0:
+ break;
+ default:
+ debug("lcdc id = %d iomux error!\n", lcd_id);
+ break;
+ }
+}
+
+static int pinctrl_rk3328_spi_config(struct rk3328_grf_regs *grf,
+ enum periph_id spi_id, int cs)
+{
+ rk_clrsetreg(&grf->com_iomux,
+ GRF_SPI_IOMUX_SEL_MASK,
+ GRF_SPI_IOMUX_SEL_M0 << GRF_SPI_IOMUX_SEL_SHIFT);
+
+ switch (spi_id) {
+ case PERIPH_ID_SPI0:
+ switch (cs) {
+ case 0:
+ rk_clrsetreg(&grf->gpio2bl_iomux,
+ GRF_GPIO2BL3_SEL_MASK,
+ GRF_SPI_CSN0_M0 << GRF_GPIO2BL3_SEL_SHIFT);
+ break;
+ case 1:
+ rk_clrsetreg(&grf->gpio2bl_iomux,
+ GRF_GPIO2BL4_SEL_MASK,
+ GRF_SPI_CSN1_M0 << GRF_GPIO2BL4_SEL_SHIFT);
+ break;
+ default:
+ goto err;
+ }
+ rk_clrsetreg(&grf->gpio2bl_iomux,
+ GRF_GPIO2BL0_SEL_MASK,
+ GRF_SPI_CLK_TX_RX_M0 << GRF_GPIO2BL0_SEL_SHIFT);
+ break;
+ default:
+ goto err;
+ }
+
+ return 0;
+err:
+ debug("rkspi: periph%d cs=%d not supported", spi_id, cs);
+ return -ENOENT;
+}
+
+static void pinctrl_rk3328_uart_config(struct rk3328_grf_regs *grf, int uart_id)
+{
+ switch (uart_id) {
+ case PERIPH_ID_UART2:
+ break;
+ /* uart2 iomux select m1 */
+ rk_clrsetreg(&grf->com_iomux,
+ GRF_UART2_IOMUX_SEL_MASK,
+ GRF_UART2_IOMUX_SEL_M1
+ << GRF_UART2_IOMUX_SEL_SHIFT);
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GRF_GPIO2A0_SEL_MASK | GRF_GPIO2A1_SEL_MASK,
+ GRF_UART2_TX_M1 << GRF_GPIO2A0_SEL_SHIFT |
+ GRF_UART2_RX_M1 << GRF_GPIO2A1_SEL_SHIFT);
+ break;
+ case PERIPH_ID_UART0:
+ case PERIPH_ID_UART1:
+ case PERIPH_ID_UART3:
+ case PERIPH_ID_UART4:
+ default:
+ debug("uart id = %d iomux error!\n", uart_id);
+ break;
+ }
+}
+
+static void pinctrl_rk3328_sdmmc_config(struct rk3328_grf_regs *grf,
+ int mmc_id)
+{
+ switch (mmc_id) {
+ case PERIPH_ID_EMMC:
+ rk_clrsetreg(&grf->gpio0a_iomux,
+ GRF_GPIO0A7_SEL_MASK,
+ GRF_EMMC_DATA0 << GRF_GPIO0A7_SEL_SHIFT);
+ rk_clrsetreg(&grf->gpio2d_iomux,
+ GRF_GPIO2D4_SEL_MASK,
+ GRF_EMMC_DATA123 << GRF_GPIO2D4_SEL_SHIFT);
+ rk_clrsetreg(&grf->gpio3c_iomux,
+ GRF_GPIO3C0_SEL_MASK,
+ GRF_EMMC_DATA567_PWR_CLK_RSTN_CMD
+ << GRF_GPIO3C0_SEL_SHIFT);
+ break;
+ case PERIPH_ID_SDCARD:
+ /* sdcard iomux select m0 */
+ rk_clrsetreg(&grf->com_iomux,
+ GRF_CARD_IOMUX_SEL_MASK,
+ GRF_CARD_IOMUX_SEL_M0 << GRF_CARD_IOMUX_SEL_SHIFT);
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GRF_GPIO2A7_SEL_MASK,
+ GRF_CARD_PWR_EN_M0 << GRF_GPIO2A7_SEL_SHIFT);
+ rk_clrsetreg(&grf->gpio1a_iomux,
+ GRF_GPIO1A0_SEL_MASK,
+ GRF_CARD_DATA_CLK_CMD_DETN
+ << GRF_GPIO1A0_SEL_SHIFT);
+ break;
+ default:
+ debug("mmc id = %d iomux error!\n", mmc_id);
+ break;
+ }
+}
+
+static int rk3328_pinctrl_request(struct udevice *dev, int func, int flags)
+{
+ struct rk3328_pinctrl_priv *priv = dev_get_priv(dev);
+
+ debug("%s: func=%x, flags=%x\n", __func__, func, flags);
+ switch (func) {
+ case PERIPH_ID_PWM0:
+ case PERIPH_ID_PWM1:
+ case PERIPH_ID_PWM2:
+ case PERIPH_ID_PWM3:
+ pinctrl_rk3328_pwm_config(priv->grf, func);
+ break;
+ case PERIPH_ID_I2C0:
+ case PERIPH_ID_I2C1:
+ case PERIPH_ID_I2C2:
+ case PERIPH_ID_I2C3:
+ pinctrl_rk3328_i2c_config(priv->grf, func);
+ break;
+ case PERIPH_ID_SPI0:
+ pinctrl_rk3328_spi_config(priv->grf, func, flags);
+ break;
+ case PERIPH_ID_UART0:
+ case PERIPH_ID_UART1:
+ case PERIPH_ID_UART2:
+ case PERIPH_ID_UART3:
+ case PERIPH_ID_UART4:
+ pinctrl_rk3328_uart_config(priv->grf, func);
+ break;
+ case PERIPH_ID_LCDC0:
+ case PERIPH_ID_LCDC1:
+ pinctrl_rk3328_lcdc_config(priv->grf, func);
+ break;
+ case PERIPH_ID_SDMMC0:
+ case PERIPH_ID_SDMMC1:
+ pinctrl_rk3328_sdmmc_config(priv->grf, func);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rk3328_pinctrl_get_periph_id(struct udevice *dev,
+ struct udevice *periph)
+{
+ u32 cell[3];
+ int ret;
+
+ ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
+ "interrupts", cell, ARRAY_SIZE(cell));
+ if (ret < 0)
+ return -EINVAL;
+
+ switch (cell[1]) {
+ case 49:
+ return PERIPH_ID_SPI0;
+ case 50:
+ return PERIPH_ID_PWM0;
+ case 36:
+ return PERIPH_ID_I2C0;
+ case 37: /* Note strange order */
+ return PERIPH_ID_I2C1;
+ case 38:
+ return PERIPH_ID_I2C2;
+ case 39:
+ return PERIPH_ID_I2C3;
+ case 12:
+ return PERIPH_ID_SDCARD;
+ case 14:
+ return PERIPH_ID_EMMC;
+ }
+
+ return -ENOENT;
+}
+
+static int rk3328_pinctrl_set_state_simple(struct udevice *dev,
+ struct udevice *periph)
+{
+ int func;
+
+ func = rk3328_pinctrl_get_periph_id(dev, periph);
+ if (func < 0)
+ return func;
+
+ return rk3328_pinctrl_request(dev, func, 0);
+}
+
+static struct pinctrl_ops rk3328_pinctrl_ops = {
+ .set_state_simple = rk3328_pinctrl_set_state_simple,
+ .request = rk3328_pinctrl_request,
+ .get_periph_id = rk3328_pinctrl_get_periph_id,
+};
+
+static int rk3328_pinctrl_probe(struct udevice *dev)
+{
+ struct rk3328_pinctrl_priv *priv = dev_get_priv(dev);
+ int ret = 0;
+
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ debug("%s: grf=%p\n", __func__, priv->grf);
+
+ return ret;
+}
+
+static const struct udevice_id rk3328_pinctrl_ids[] = {
+ { .compatible = "rockchip,rk3328-pinctrl" },
+ { }
+};
+
+U_BOOT_DRIVER(pinctrl_rk3328) = {
+ .name = "rockchip_rk3328_pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = rk3328_pinctrl_ids,
+ .priv_auto_alloc_size = sizeof(struct rk3328_pinctrl_priv),
+ .ops = &rk3328_pinctrl_ops,
+ .bind = dm_scan_fdt_dev,
+ .probe = rk3328_pinctrl_probe,
+};
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3399.c b/drivers/pinctrl/rockchip/pinctrl_rk3399.c
index da30154..a74793a 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3399.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3399.c
@@ -22,112 +22,6 @@ struct rk3399_pinctrl_priv {
struct rk3399_pmugrf_regs *pmugrf;
};
-enum {
- /* GRF_GPIO2B_IOMUX */
- GRF_GPIO2B1_SEL_SHIFT = 0,
- GRF_GPIO2B1_SEL_MASK = 3 << GRF_GPIO2B1_SEL_SHIFT,
- GRF_SPI2TPM_RXD = 1,
- GRF_GPIO2B2_SEL_SHIFT = 2,
- GRF_GPIO2B2_SEL_MASK = 3 << GRF_GPIO2B2_SEL_SHIFT,
- GRF_SPI2TPM_TXD = 1,
- GRF_GPIO2B3_SEL_SHIFT = 6,
- GRF_GPIO2B3_SEL_MASK = 3 << GRF_GPIO2B3_SEL_SHIFT,
- GRF_SPI2TPM_CLK = 1,
- GRF_GPIO2B4_SEL_SHIFT = 8,
- GRF_GPIO2B4_SEL_MASK = 3 << GRF_GPIO2B4_SEL_SHIFT,
- GRF_SPI2TPM_CSN0 = 1,
-
- /* GRF_GPIO3A_IOMUX */
- GRF_GPIO3A4_SEL_SHIFT = 8,
- GRF_GPIO3A4_SEL_MASK = 3 << GRF_GPIO3A4_SEL_SHIFT,
- GRF_SPI0NORCODEC_RXD = 2,
- GRF_GPIO3A5_SEL_SHIFT = 10,
- GRF_GPIO3A5_SEL_MASK = 3 << GRF_GPIO3A5_SEL_SHIFT,
- GRF_SPI0NORCODEC_TXD = 2,
- GRF_GPIO3A6_SEL_SHIFT = 12,
- GRF_GPIO3A6_SEL_MASK = 3 << GRF_GPIO3A6_SEL_SHIFT,
- GRF_SPI0NORCODEC_CLK = 2,
- GRF_GPIO3A7_SEL_SHIFT = 14,
- GRF_GPIO3A7_SEL_MASK = 3 << GRF_GPIO3A7_SEL_SHIFT,
- GRF_SPI0NORCODEC_CSN0 = 2,
-
- /* GRF_GPIO3B_IOMUX */
- GRF_GPIO3B0_SEL_SHIFT = 0,
- GRF_GPIO3B0_SEL_MASK = 3 << GRF_GPIO3B0_SEL_SHIFT,
- GRF_SPI0NORCODEC_CSN1 = 2,
-
- /* GRF_GPIO4B_IOMUX */
- GRF_GPIO4B0_SEL_SHIFT = 0,
- GRF_GPIO4B0_SEL_MASK = 3 << GRF_GPIO4B0_SEL_SHIFT,
- GRF_SDMMC_DATA0 = 1,
- GRF_UART2DBGA_SIN = 2,
- GRF_GPIO4B1_SEL_SHIFT = 2,
- GRF_GPIO4B1_SEL_MASK = 3 << GRF_GPIO4B1_SEL_SHIFT,
- GRF_SDMMC_DATA1 = 1,
- GRF_UART2DBGA_SOUT = 2,
- GRF_GPIO4B2_SEL_SHIFT = 4,
- GRF_GPIO4B2_SEL_MASK = 3 << GRF_GPIO4B2_SEL_SHIFT,
- GRF_SDMMC_DATA2 = 1,
- GRF_GPIO4B3_SEL_SHIFT = 6,
- GRF_GPIO4B3_SEL_MASK = 3 << GRF_GPIO4B3_SEL_SHIFT,
- GRF_SDMMC_DATA3 = 1,
- GRF_GPIO4B4_SEL_SHIFT = 8,
- GRF_GPIO4B4_SEL_MASK = 3 << GRF_GPIO4B4_SEL_SHIFT,
- GRF_SDMMC_CLKOUT = 1,
- GRF_GPIO4B5_SEL_SHIFT = 10,
- GRF_GPIO4B5_SEL_MASK = 3 << GRF_GPIO4B5_SEL_SHIFT,
- GRF_SDMMC_CMD = 1,
-
- /* GRF_GPIO4C_IOMUX */
- GRF_GPIO4C2_SEL_SHIFT = 4,
- GRF_GPIO4C2_SEL_MASK = 3 << GRF_GPIO4C2_SEL_SHIFT,
- GRF_PWM_0 = 1,
- GRF_GPIO4C3_SEL_SHIFT = 6,
- GRF_GPIO4C3_SEL_MASK = 3 << GRF_GPIO4C3_SEL_SHIFT,
- GRF_UART2DGBC_SIN = 1,
- GRF_GPIO4C4_SEL_SHIFT = 8,
- GRF_GPIO4C4_SEL_MASK = 3 << GRF_GPIO4C4_SEL_SHIFT,
- GRF_UART2DBGC_SOUT = 1,
- GRF_GPIO4C6_SEL_SHIFT = 12,
- GRF_GPIO4C6_SEL_MASK = 3 << GRF_GPIO4C6_SEL_SHIFT,
- GRF_PWM_1 = 1,
-
- /* PMUGRF_GPIO0A_IOMUX */
- PMUGRF_GPIO0A6_SEL_SHIFT = 12,
- PMUGRF_GPIO0A6_SEL_MASK = 3 << PMUGRF_GPIO0A6_SEL_SHIFT,
- PMUGRF_PWM_3A = 1,
-
- /* PMUGRF_GPIO1A_IOMUX */
- PMUGRF_GPIO1A7_SEL_SHIFT = 14,
- PMUGRF_GPIO1A7_SEL_MASK = 3 << PMUGRF_GPIO1A7_SEL_SHIFT,
- PMUGRF_SPI1EC_RXD = 2,
-
- /* PMUGRF_GPIO1B_IOMUX */
- PMUGRF_GPIO1B0_SEL_SHIFT = 0,
- PMUGRF_GPIO1B0_SEL_MASK = 3 << PMUGRF_GPIO1B0_SEL_SHIFT,
- PMUGRF_SPI1EC_TXD = 2,
- PMUGRF_GPIO1B1_SEL_SHIFT = 2,
- PMUGRF_GPIO1B1_SEL_MASK = 3 << PMUGRF_GPIO1B1_SEL_SHIFT,
- PMUGRF_SPI1EC_CLK = 2,
- PMUGRF_GPIO1B2_SEL_SHIFT = 4,
- PMUGRF_GPIO1B2_SEL_MASK = 3 << PMUGRF_GPIO1B2_SEL_SHIFT,
- PMUGRF_SPI1EC_CSN0 = 2,
- PMUGRF_GPIO1B6_SEL_SHIFT = 12,
- PMUGRF_GPIO1B6_SEL_MASK = 3 << PMUGRF_GPIO1B6_SEL_SHIFT,
- PMUGRF_PWM_3B = 1,
- PMUGRF_GPIO1B7_SEL_SHIFT = 14,
- PMUGRF_GPIO1B7_SEL_MASK = 3 << PMUGRF_GPIO1B7_SEL_SHIFT,
- PMUGRF_I2C0PMU_SDA = 2,
-
- /* PMUGRF_GPIO1C_IOMUX */
- PMUGRF_GPIO1C0_SEL_SHIFT = 0,
- PMUGRF_GPIO1C0_SEL_MASK = 3 << PMUGRF_GPIO1C0_SEL_SHIFT,
- PMUGRF_I2C0PMU_SCL = 2,
- PMUGRF_GPIO1C3_SEL_SHIFT = 6,
- PMUGRF_GPIO1C3_SEL_MASK = 3 << PMUGRF_GPIO1C3_SEL_SHIFT,
- PMUGRF_PWM_2 = 1,
-
-};
static void pinctrl_rk3399_pwm_config(struct rk3399_grf_regs *grf,
struct rk3399_pmugrf_regs *pmugrf, int pwm_id)
{
@@ -359,6 +253,7 @@ static int rk3399_pinctrl_request(struct udevice *dev, int func, int flags)
static int rk3399_pinctrl_get_periph_id(struct udevice *dev,
struct udevice *periph)
{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
u32 cell[3];
int ret;
@@ -389,7 +284,7 @@ static int rk3399_pinctrl_get_periph_id(struct udevice *dev,
case 65:
return PERIPH_ID_SDMMC1;
}
-
+#endif
return -ENOENT;
}
@@ -434,6 +329,8 @@ U_BOOT_DRIVER(pinctrl_rk3399) = {
.of_match = rk3399_pinctrl_ids,
.priv_auto_alloc_size = sizeof(struct rk3399_pinctrl_priv),
.ops = &rk3399_pinctrl_ops,
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
.bind = dm_scan_fdt_dev,
+#endif
.probe = rk3399_pinctrl_probe,
};
diff --git a/drivers/serial/serial_rockchip.c b/drivers/serial/serial_rockchip.c
index c06afc5..734cee2 100644
--- a/drivers/serial/serial_rockchip.c
+++ b/drivers/serial/serial_rockchip.c
@@ -12,12 +12,19 @@
#include <serial.h>
#include <asm/arch/clock.h>
+#if defined(CONFIG_ROCKCHIP_RK3188)
+struct rockchip_uart_platdata {
+ struct dtd_rockchip_rk3188_uart dtplat;
+ struct ns16550_platdata plat;
+};
+struct dtd_rockchip_rk3188_uart *dtplat, s_dtplat;
+#elif defined(CONFIG_ROCKCHIP_RK3288)
struct rockchip_uart_platdata {
struct dtd_rockchip_rk3288_uart dtplat;
struct ns16550_platdata plat;
};
-
struct dtd_rockchip_rk3288_uart *dtplat, s_dtplat;
+#endif
static int rockchip_serial_probe(struct udevice *dev)
{
@@ -33,6 +40,16 @@ static int rockchip_serial_probe(struct udevice *dev)
return ns16550_serial_probe(dev);
}
+U_BOOT_DRIVER(rockchip_rk3188_uart) = {
+ .name = "rockchip_rk3188_uart",
+ .id = UCLASS_SERIAL,
+ .priv_auto_alloc_size = sizeof(struct NS16550),
+ .platdata_auto_alloc_size = sizeof(struct rockchip_uart_platdata),
+ .probe = rockchip_serial_probe,
+ .ops = &ns16550_serial_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
U_BOOT_DRIVER(rockchip_rk3288_uart) = {
.name = "rockchip_rk3288_uart",
.id = UCLASS_SERIAL,
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index 21bcc21..49b8bb6 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -9,7 +9,9 @@ obj-$(CONFIG_SYSRESET) += sysreset-uclass.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_ROCKCHIP_RK3036) += sysreset_rk3036.o
endif
+obj-$(CONFIG_ROCKCHIP_RK3188) += sysreset_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK3288) += sysreset_rk3288.o
+obj-$(CONFIG_ROCKCHIP_RK3328) += sysreset_rk3328.o
obj-$(CONFIG_ROCKCHIP_RK3399) += sysreset_rk3399.o
obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
obj-$(CONFIG_ARCH_SNAPDRAGON) += sysreset_snapdragon.o
diff --git a/drivers/sysreset/sysreset_rk3188.c b/drivers/sysreset/sysreset_rk3188.c
new file mode 100644
index 0000000..36ae476
--- /dev/null
+++ b/drivers/sysreset/sysreset_rk3188.c
@@ -0,0 +1,47 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3188.h>
+#include <asm/arch/hardware.h>
+#include <linux/err.h>
+
+int rk3188_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+ struct rk3188_cru *cru = rockchip_get_cru();
+
+ if (IS_ERR(cru))
+ return PTR_ERR(cru);
+ switch (type) {
+ case SYSRESET_WARM:
+ rk_clrreg(&cru->cru_mode_con, 0xffff);
+ writel(0xeca8, &cru->cru_glb_srst_snd_value);
+ break;
+ case SYSRESET_COLD:
+ rk_clrreg(&cru->cru_mode_con, 0xffff);
+ writel(0xfdb9, &cru->cru_glb_srst_fst_value);
+ break;
+ default:
+ return -EPROTONOSUPPORT;
+ }
+
+ return -EINPROGRESS;
+}
+
+static struct sysreset_ops rk3188_sysreset = {
+ .request = rk3188_sysreset_request,
+};
+
+U_BOOT_DRIVER(sysreset_rk3188) = {
+ .name = "rk3188_sysreset",
+ .id = UCLASS_SYSRESET,
+ .ops = &rk3188_sysreset,
+};
diff --git a/drivers/sysreset/sysreset_rk3328.c b/drivers/sysreset/sysreset_rk3328.c
new file mode 100644
index 0000000..7b9af09
--- /dev/null
+++ b/drivers/sysreset/sysreset_rk3328.c
@@ -0,0 +1,45 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3328.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <linux/err.h>
+
+int rk3328_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+ struct rk3328_cru *cru = rockchip_get_cru();
+
+ if (IS_ERR(cru))
+ return PTR_ERR(cru);
+ switch (type) {
+ case SYSRESET_WARM:
+ writel(0xeca8, &cru->glb_srst_snd_value);
+ break;
+ case SYSRESET_COLD:
+ writel(0xfdb9, &cru->glb_srst_fst_value);
+ break;
+ default:
+ return -EPROTONOSUPPORT;
+ }
+
+ return -EINPROGRESS;
+}
+
+static struct sysreset_ops rk3328_sysreset = {
+ .request = rk3328_sysreset_request,
+};
+
+U_BOOT_DRIVER(sysreset_rk3328) = {
+ .name = "rk3328_sysreset",
+ .id = UCLASS_SYSRESET,
+ .ops = &rk3328_sysreset,
+};
diff --git a/drivers/video/rockchip/rk_hdmi.c b/drivers/video/rockchip/rk_hdmi.c
index 7b0c43b..c8608db 100644
--- a/drivers/video/rockchip/rk_hdmi.c
+++ b/drivers/video/rockchip/rk_hdmi.c
@@ -32,37 +32,37 @@ struct rk_hdmi_priv {
static const struct tmds_n_cts n_cts_table[] = {
{
- .tmds = 25175, .n = 6144, .cts = 25175,
+ .tmds = 25175000, .n = 6144, .cts = 25175,
}, {
- .tmds = 25200, .n = 6144, .cts = 25200,
+ .tmds = 25200000, .n = 6144, .cts = 25200,
}, {
- .tmds = 27000, .n = 6144, .cts = 27000,
+ .tmds = 27000000, .n = 6144, .cts = 27000,
}, {
- .tmds = 27027, .n = 6144, .cts = 27027,
+ .tmds = 27027000, .n = 6144, .cts = 27027,
}, {
- .tmds = 40000, .n = 6144, .cts = 40000,
+ .tmds = 40000000, .n = 6144, .cts = 40000,
}, {
- .tmds = 54000, .n = 6144, .cts = 54000,
+ .tmds = 54000000, .n = 6144, .cts = 54000,
}, {
- .tmds = 54054, .n = 6144, .cts = 54054,
+ .tmds = 54054000, .n = 6144, .cts = 54054,
}, {
- .tmds = 65000, .n = 6144, .cts = 65000,
+ .tmds = 65000000, .n = 6144, .cts = 65000,
}, {
- .tmds = 74176, .n = 11648, .cts = 140625,
+ .tmds = 74176000, .n = 11648, .cts = 140625,
}, {
- .tmds = 74250, .n = 6144, .cts = 74250,
+ .tmds = 74250000, .n = 6144, .cts = 74250,
}, {
- .tmds = 83500, .n = 6144, .cts = 83500,
+ .tmds = 83500000, .n = 6144, .cts = 83500,
}, {
- .tmds = 106500, .n = 6144, .cts = 106500,
+ .tmds = 106500000, .n = 6144, .cts = 106500,
}, {
- .tmds = 108000, .n = 6144, .cts = 108000,
+ .tmds = 108000000, .n = 6144, .cts = 108000,
}, {
- .tmds = 148352, .n = 5824, .cts = 140625,
+ .tmds = 148352000, .n = 5824, .cts = 140625,
}, {
- .tmds = 148500, .n = 6144, .cts = 148500,
+ .tmds = 148500000, .n = 6144, .cts = 148500,
}, {
- .tmds = 297000, .n = 5120, .cts = 247500,
+ .tmds = 297000000, .n = 5120, .cts = 247500,
}
};
@@ -124,12 +124,6 @@ static const struct hdmi_mpll_config rockchip_mpll_cfg[] = {
}
};
-static const u32 csc_coeff_default[3][4] = {
- { 0x2000, 0x0000, 0x0000, 0x0000 },
- { 0x0000, 0x2000, 0x0000, 0x0000 },
- { 0x0000, 0x0000, 0x2000, 0x0000 }
-};
-
static void hdmi_set_clock_regenerator(struct rk3288_hdmi *regs, u32 n, u32 cts)
{
uint cts3;
@@ -220,37 +214,6 @@ static void hdmi_video_sample(struct rk3288_hdmi *regs)
writel(0x0, &regs->tx_bcbdata1);
}
-static void hdmi_update_csc_coeffs(struct rk3288_hdmi *regs)
-{
- u32 i, j;
- u32 csc_scale = 1;
-
- /* the csc registers are sequential, alternating msb then lsb */
- for (i = 0; i < ARRAY_SIZE(csc_coeff_default); i++) {
- for (j = 0; j < ARRAY_SIZE(csc_coeff_default[0]); j++) {
- u32 coeff = csc_coeff_default[i][j];
- writel(coeff >> 8, &regs->csc_coef[i][j].msb);
- writel(coeff && 0xff, &regs->csc_coef[i][j].lsb);
- }
- }
-
- clrsetbits_le32(&regs->csc_scale, HDMI_CSC_SCALE_CSCSCALE_MASK,
- csc_scale);
-}
-
-static void hdmi_video_csc(struct rk3288_hdmi *regs)
-{
- u32 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP;
- u32 interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
-
- /* configure the csc registers */
- writel(interpolation, &regs->csc_cfg);
- clrsetbits_le32(&regs->csc_scale,
- HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK, color_depth);
-
- hdmi_update_csc_coeffs(regs);
-}
-
static void hdmi_video_packetize(struct rk3288_hdmi *regs)
{
u32 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
@@ -467,7 +430,6 @@ static int hdmi_phy_init(struct rk3288_hdmi *regs, uint mpixelclock)
hdmi_phy_enable_tmds(regs, 0);
hdmi_phy_enable_power(regs, 0);
- /* enable csc */
ret = hdmi_phy_configure(regs, mpixelclock);
if (ret) {
debug("hdmi phy config failure %d\n", ret);
@@ -837,7 +799,6 @@ static int rk_hdmi_enable(struct udevice *dev, int panel_bpp,
hdmi_audio_set_samplerate(regs, edid->pixelclock.typ);
hdmi_video_packetize(regs);
- hdmi_video_csc(regs);
hdmi_video_sample(regs);
hdmi_clear_overflow(regs);
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index e02863d..5b356dd 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -127,5 +127,6 @@ typedef struct global_data {
#define GD_FLG_SKIP_RELOC 0x00800 /* Don't relocate */
#define GD_FLG_RECORD 0x01000 /* Record console */
#define GD_FLG_ENV_DEFAULT 0x02000 /* Default variable flag */
+#define GD_FLG_SPL_EARLY_INIT 0x04000 /* Early SPL init is done */
#endif /* __ASM_GENERIC_GBL_DATA_H */
diff --git a/include/configs/evb_rk3328.h b/include/configs/evb_rk3328.h
new file mode 100644
index 0000000..3a39a1b
--- /dev/null
+++ b/include/configs/evb_rk3328.h
@@ -0,0 +1,26 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __EVB_RK3328_H
+#define __EVB_RK3328_H
+
+#include <configs/rk3328_common.h>
+
+#define CONFIG_ENV_IS_IN_MMC
+#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)
+
+#define CONFIG_SYS_WHITE_ON_BLACK
+#define CONFIG_CONSOLE_SCROLL_LINES 10
+
+#endif
diff --git a/include/configs/rk3188_common.h b/include/configs/rk3188_common.h
new file mode 100644
index 0000000..2ff7cd7
--- /dev/null
+++ b/include/configs/rk3188_common.h
@@ -0,0 +1,120 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_RK3188_COMMON_H
+#define __CONFIG_RK3188_COMMON_H
+
+#define CONFIG_SYS_CACHELINE_SIZE 64
+
+#include <asm/arch/hardware.h>
+#include "rockchip-common.h"
+
+#define CONFIG_SKIP_LOWLEVEL_INIT_ONLY
+#define CONFIG_NR_DRAM_BANKS 1
+#define CONFIG_ENV_SIZE 0x2000
+#define CONFIG_SYS_MAXARGS 16
+#define CONFIG_BAUDRATE 115200
+#define CONFIG_SYS_MALLOC_LEN (32 << 20)
+#define CONFIG_SYS_CBSIZE 1024
+#define CONFIG_SYS_THUMB_BUILD
+
+#define CONFIG_SYS_TIMER_RATE (24 * 1000 * 1000)
+#define CONFIG_SYS_TIMER_BASE 0x2000e000 /* TIMER3 */
+#define CONFIG_SYS_TIMER_COUNTER (CONFIG_SYS_TIMER_BASE + 8)
+#define CONFIG_SYS_TIMER_COUNTS_DOWN
+
+#define CONFIG_SYS_NS16550_MEM32
+#define CONFIG_SPL_BOARD_INIT
+
+#ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
+/* Bootrom will load u-boot binary to 0x60000000 once return from SPL */
+#define CONFIG_SYS_TEXT_BASE 0x60000000
+#else
+#define CONFIG_SYS_TEXT_BASE 0x60100000
+#endif
+#define CONFIG_SYS_INIT_SP_ADDR 0x60100000
+#define CONFIG_SYS_LOAD_ADDR 0x60800800
+
+#define CONFIG_ROCKCHIP_MAX_INIT_SIZE (0x8000 - 0x800)
+#define CONFIG_ROCKCHIP_CHIP_TAG "RK31"
+
+#ifdef CONFIG_TPL_BUILD
+#define CONFIG_SPL_TEXT_BASE 0x10080804
+/* tpl size 1kb - 4byte RK31 header */
+#define CONFIG_SPL_MAX_SIZE (0x400 - 0x4)
+#elif defined(CONFIG_SPL_BUILD)
+/* spl size 32kb sram - 2kb bootrom - 1kb spl */
+#define CONFIG_SPL_MAX_SIZE (0x8000 - 0xC00)
+#define CONFIG_SPL_TEXT_BASE 0x10080C00
+#define CONFIG_SPL_FRAMEWORK 1
+#define CONFIG_SPL_CLK 1
+#define CONFIG_SPL_PINCTRL 1
+#define CONFIG_SPL_REGMAP 1
+#define CONFIG_SPL_SYSCON 1
+#define CONFIG_SPL_RAM 1
+#define CONFIG_SPL_DRIVERS_MISC_SUPPORT 1
+#define CONFIG_ROCKCHIP_SERIAL 1
+#endif
+
+#define CONFIG_SPL_STACK 0x10087fff
+
+/* MMC/SD IP block */
+#define CONFIG_BOUNCE_BUFFER
+
+#define CONFIG_FAT_WRITE
+
+#define CONFIG_SYS_SDRAM_BASE 0x60000000
+#define CONFIG_NR_DRAM_BANKS 1
+#define SDRAM_BANK_SIZE (2UL << 30)
+
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI
+#define CONFIG_SF_DEFAULT_SPEED 20000000
+
+#ifndef CONFIG_SPL_BUILD
+/* usb otg */
+#define CONFIG_USB_GADGET
+#define CONFIG_USB_GADGET_DUALSPEED
+#define CONFIG_USB_GADGET_DWC2_OTG
+#define CONFIG_ROCKCHIP_USB2_PHY
+#define CONFIG_USB_GADGET_VBUS_DRAW 0
+
+#define CONFIG_USB_GADGET_DOWNLOAD
+#define CONFIG_G_DNL_MANUFACTURER "Rockchip"
+#define CONFIG_G_DNL_VENDOR_NUM 0x2207
+#define CONFIG_G_DNL_PRODUCT_NUM 0x310a
+
+/* usb host support */
+#ifdef CONFIG_CMD_USB
+#define CONFIG_USB_DWC2
+#define CONFIG_USB_HOST_ETHER
+#define CONFIG_USB_ETHER_SMSC95XX
+#define CONFIG_USB_ETHER_ASIX
+#endif
+#define ENV_MEM_LAYOUT_SETTINGS \
+ "scriptaddr=0x60000000\0" \
+ "pxefile_addr_r=0x60100000\0" \
+ "fdt_addr_r=0x61f00000\0" \
+ "kernel_addr_r=0x62000000\0" \
+ "ramdisk_addr_r=0x64000000\0"
+
+#include <config_distro_bootcmd.h>
+
+/* Linux fails to load the fdt if it's loaded above 256M on a Rock board,
+ * so limit the fdt reallocation to that */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "fdt_high=0x6fffffff\0" \
+ "initrd_high=0x6fffffff\0" \
+ "partitions=" PARTS_DEFAULT \
+ ENV_MEM_LAYOUT_SETTINGS \
+ ROCKCHIP_DEVICE_SETTINGS \
+ BOOTENV
+
+#endif /* CONFIG_SPL_BUILD */
+
+#define CONFIG_PREBOOT
+
+#endif
diff --git a/include/configs/rk3328_common.h b/include/configs/rk3328_common.h
new file mode 100644
index 0000000..eacf716
--- /dev/null
+++ b/include/configs/rk3328_common.h
@@ -0,0 +1,65 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_RK3328_COMMON_H
+#define __CONFIG_RK3328_COMMON_H
+
+#include "rockchip-common.h"
+
+#define CONFIG_NR_DRAM_BANKS 1
+#define CONFIG_ENV_SIZE 0x2000
+#define CONFIG_SYS_MAXARGS 16
+#define CONFIG_BAUDRATE 1500000
+#define CONFIG_SYS_MALLOC_LEN (32 << 20)
+#define CONFIG_SYS_CBSIZE 1024
+#define CONFIG_SKIP_LOWLEVEL_INIT
+
+#define CONFIG_SYS_NS16550_MEM32
+
+#define CONFIG_SYS_TEXT_BASE 0x00200000
+#define CONFIG_SYS_INIT_SP_ADDR 0x00300000
+#define CONFIG_SYS_LOAD_ADDR 0x00800800
+
+#define CONFIG_SYS_BOOTM_LEN (64 << 20) /* 64M */
+
+/* MMC/SD IP block */
+#define CONFIG_BOUNCE_BUFFER
+
+#define CONFIG_SUPPORT_VFAT
+#define CONFIG_FS_FAT
+#define CONFIG_FAT_WRITE
+#define CONFIG_FS_EXT4
+
+/* RAW SD card / eMMC locations. */
+#define CONFIG_SYS_SPI_U_BOOT_OFFS (128 << 10)
+
+/* FAT sd card locations. */
+#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1
+#define CONFIG_SYS_SDRAM_BASE 0
+#define CONFIG_NR_DRAM_BANKS 1
+
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI
+#define CONFIG_SF_DEFAULT_SPEED 20000000
+
+#ifndef CONFIG_SPL_BUILD
+
+#define ENV_MEM_LAYOUT_SETTINGS \
+ "scriptaddr=0x00500000\0" \
+ "pxefile_addr_r=0x00600000\0" \
+ "fdt_addr_r=0x01f00000\0" \
+ "kernel_addr_r=0x02000000\0" \
+ "ramdisk_addr_r=0x04000000\0"
+
+#include <config_distro_bootcmd.h>
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ ENV_MEM_LAYOUT_SETTINGS \
+ "partitions=" PARTS_DEFAULT \
+ BOOTENV
+
+#endif
+
+#endif
diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h
index ce64476..eb38376 100644
--- a/include/configs/rk3399_common.h
+++ b/include/configs/rk3399_common.h
@@ -16,12 +16,23 @@
#define CONFIG_SYS_MALLOC_LEN (32 << 20)
#define CONFIG_SYS_CBSIZE 1024
#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_DRIVERS_MISC_SUPPORT
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
#define CONFIG_SYS_NS16550_MEM32
#define CONFIG_SYS_TEXT_BASE 0x00200000
#define CONFIG_SYS_INIT_SP_ADDR 0x00300000
#define CONFIG_SYS_LOAD_ADDR 0x00800800
+#define CONFIG_SPL_STACK 0xff8effff
+#define CONFIG_SPL_TEXT_BASE 0xff8c2008
+#define CONFIG_SPL_MAX_SIZE 0x30000
+/* BSS setup */
+#define CONFIG_SPL_BSS_START_ADDR 0xff8e0000
+#define CONFIG_SPL_BSS_MAX_SIZE 0x10000
#define CONFIG_SYS_BOOTM_LEN (64 << 20) /* 64M */
diff --git a/include/configs/tinker_rk3288.h b/include/configs/tinker_rk3288.h
index 860eb40..c398e07 100644
--- a/include/configs/tinker_rk3288.h
+++ b/include/configs/tinker_rk3288.h
@@ -13,7 +13,7 @@
#undef BOOT_TARGET_DEVICES
#define BOOT_TARGET_DEVICES(func) \
- func(MMC, mmc, 0)
+ func(MMC, mmc, 1)
#define CONFIG_ENV_IS_IN_MMC
#define CONFIG_SYS_MMC_ENV_DEV 0
diff --git a/include/dm/util.h b/include/dm/util.h
index 15daa3d..45529ce 100644
--- a/include/dm/util.h
+++ b/include/dm/util.h
@@ -48,4 +48,30 @@ static inline void dm_dump_devres(void)
}
#endif
+/**
+ * Check if a dt node should be or was bound before relocation.
+ *
+ * Devicetree nodes can be marked as needed to be bound
+ * in the loader stages via special devicetree properties.
+ *
+ * Before relocation this function can be used to check if nodes
+ * are required in either SPL or TPL stages.
+ *
+ * After relocation and jumping into the real U-Boot binary
+ * it is possible to determine if a node was bound in one of
+ * SPL/TPL stages.
+ *
+ * There are 3 settings currently in use
+ * -
+ * - u-boot,dm-pre-reloc: legacy and indicates any of TPL or SPL
+ * Existing platforms only use it to indicate nodes needee in
+ * SPL. Should probably be replaced by u-boot,dm-spl for
+ * existing platforms.
+ * @blob: devicetree
+ * @offset: node offset
+ *
+ * Returns true if node is needed in SPL/TL, false otherwise.
+ */
+bool dm_fdt_pre_reloc(const void *blob, int offset);
+
#endif
diff --git a/include/dt-bindings/clock/rk3066a-cru.h b/include/dt-bindings/clock/rk3066a-cru.h
new file mode 100644
index 0000000..549ae6a
--- /dev/null
+++ b/include/dt-bindings/clock/rk3066a-cru.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3066A_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3066A_H
+
+#include <dt-bindings/clock/rk3188-cru-common.h>
+
+/* soft-reset indices */
+#define SRST_SRST1 0
+#define SRST_SRST2 1
+
+#define SRST_L2MEM 18
+#define SRST_I2S0 23
+#define SRST_I2S1 24
+#define SRST_I2S2 25
+#define SRST_TIMER2 29
+
+#define SRST_GPIO4 36
+#define SRST_GPIO6 38
+
+#define SRST_TSADC 92
+
+#define SRST_HDMI 96
+#define SRST_HDMI_APB 97
+#define SRST_CIF1 111
+
+#endif
diff --git a/include/dt-bindings/clock/rk3188-cru-common.h b/include/dt-bindings/clock/rk3188-cru-common.h
new file mode 100644
index 0000000..8fc818b
--- /dev/null
+++ b/include/dt-bindings/clock/rk3188-cru-common.h
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3188_COMMON_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3188_COMMON_H
+
+/* core clocks from */
+#define PLL_APLL 1
+#define PLL_DPLL 2
+#define PLL_CPLL 3
+#define PLL_GPLL 4
+#define CORE_PERI 5
+#define CORE_L2C 6
+#define ARMCLK 7
+
+/* sclk gates (special clocks) */
+#define SCLK_UART0 64
+#define SCLK_UART1 65
+#define SCLK_UART2 66
+#define SCLK_UART3 67
+#define SCLK_MAC 68
+#define SCLK_SPI0 69
+#define SCLK_SPI1 70
+#define SCLK_SARADC 71
+#define SCLK_SDMMC 72
+#define SCLK_SDIO 73
+#define SCLK_EMMC 74
+#define SCLK_I2S0 75
+#define SCLK_I2S1 76
+#define SCLK_I2S2 77
+#define SCLK_SPDIF 78
+#define SCLK_CIF0 79
+#define SCLK_CIF1 80
+#define SCLK_OTGPHY0 81
+#define SCLK_OTGPHY1 82
+#define SCLK_HSADC 83
+#define SCLK_TIMER0 84
+#define SCLK_TIMER1 85
+#define SCLK_TIMER2 86
+#define SCLK_TIMER3 87
+#define SCLK_TIMER4 88
+#define SCLK_TIMER5 89
+#define SCLK_TIMER6 90
+#define SCLK_JTAG 91
+#define SCLK_SMC 92
+#define SCLK_TSADC 93
+
+#define DCLK_LCDC0 190
+#define DCLK_LCDC1 191
+
+/* aclk gates */
+#define ACLK_DMA1 192
+#define ACLK_DMA2 193
+#define ACLK_GPS 194
+#define ACLK_LCDC0 195
+#define ACLK_LCDC1 196
+#define ACLK_GPU 197
+#define ACLK_SMC 198
+#define ACLK_CIF 199
+#define ACLK_IPP 200
+#define ACLK_RGA 201
+#define ACLK_CIF0 202
+#define ACLK_CPU 203
+#define ACLK_PERI 204
+
+/* pclk gates */
+#define PCLK_GRF 320
+#define PCLK_PMU 321
+#define PCLK_TIMER0 322
+#define PCLK_TIMER1 323
+#define PCLK_TIMER2 324
+#define PCLK_TIMER3 325
+#define PCLK_PWM01 326
+#define PCLK_PWM23 327
+#define PCLK_SPI0 328
+#define PCLK_SPI1 329
+#define PCLK_SARADC 330
+#define PCLK_WDT 331
+#define PCLK_UART0 332
+#define PCLK_UART1 333
+#define PCLK_UART2 334
+#define PCLK_UART3 335
+#define PCLK_I2C0 336
+#define PCLK_I2C1 337
+#define PCLK_I2C2 338
+#define PCLK_I2C3 339
+#define PCLK_I2C4 340
+#define PCLK_GPIO0 341
+#define PCLK_GPIO1 342
+#define PCLK_GPIO2 343
+#define PCLK_GPIO3 344
+#define PCLK_GPIO4 345
+#define PCLK_GPIO6 346
+#define PCLK_EFUSE 347
+#define PCLK_TZPC 348
+#define PCLK_TSADC 349
+#define PCLK_CPU 350
+#define PCLK_PERI 351
+#define PCLK_DDRUPCTL 352
+#define PCLK_PUBL 353
+
+/* hclk gates */
+#define HCLK_SDMMC 448
+#define HCLK_SDIO 449
+#define HCLK_EMMC 450
+#define HCLK_OTG0 451
+#define HCLK_EMAC 452
+#define HCLK_SPDIF 453
+#define HCLK_I2S0 454
+#define HCLK_I2S1 455
+#define HCLK_I2S2 456
+#define HCLK_OTG1 457
+#define HCLK_HSIC 458
+#define HCLK_HSADC 459
+#define HCLK_PIDF 460
+#define HCLK_LCDC0 461
+#define HCLK_LCDC1 462
+#define HCLK_ROM 463
+#define HCLK_CIF0 464
+#define HCLK_IPP 465
+#define HCLK_RGA 466
+#define HCLK_NANDC0 467
+#define HCLK_CPU 468
+#define HCLK_PERI 469
+
+#define CLK_NR_CLKS (HCLK_PERI + 1)
+
+/* soft-reset indices */
+#define SRST_MCORE 2
+#define SRST_CORE0 3
+#define SRST_CORE1 4
+#define SRST_MCORE_DBG 7
+#define SRST_CORE0_DBG 8
+#define SRST_CORE1_DBG 9
+#define SRST_CORE0_WDT 12
+#define SRST_CORE1_WDT 13
+#define SRST_STRC_SYS 14
+#define SRST_L2C 15
+
+#define SRST_CPU_AHB 17
+#define SRST_AHB2APB 19
+#define SRST_DMA1 20
+#define SRST_INTMEM 21
+#define SRST_ROM 22
+#define SRST_SPDIF 26
+#define SRST_TIMER0 27
+#define SRST_TIMER1 28
+#define SRST_EFUSE 30
+
+#define SRST_GPIO0 32
+#define SRST_GPIO1 33
+#define SRST_GPIO2 34
+#define SRST_GPIO3 35
+
+#define SRST_UART0 39
+#define SRST_UART1 40
+#define SRST_UART2 41
+#define SRST_UART3 42
+#define SRST_I2C0 43
+#define SRST_I2C1 44
+#define SRST_I2C2 45
+#define SRST_I2C3 46
+#define SRST_I2C4 47
+
+#define SRST_PWM0 48
+#define SRST_PWM1 49
+#define SRST_DAP_PO 50
+#define SRST_DAP 51
+#define SRST_DAP_SYS 52
+#define SRST_TPIU_ATB 53
+#define SRST_PMU_APB 54
+#define SRST_GRF 55
+#define SRST_PMU 56
+#define SRST_PERI_AXI 57
+#define SRST_PERI_AHB 58
+#define SRST_PERI_APB 59
+#define SRST_PERI_NIU 60
+#define SRST_CPU_PERI 61
+#define SRST_EMEM_PERI 62
+#define SRST_USB_PERI 63
+
+#define SRST_DMA2 64
+#define SRST_SMC 65
+#define SRST_MAC 66
+#define SRST_NANC0 68
+#define SRST_USBOTG0 69
+#define SRST_USBPHY0 70
+#define SRST_OTGC0 71
+#define SRST_USBOTG1 72
+#define SRST_USBPHY1 73
+#define SRST_OTGC1 74
+#define SRST_HSADC 76
+#define SRST_PIDFILTER 77
+#define SRST_DDR_MSCH 79
+
+#define SRST_TZPC 80
+#define SRST_SDMMC 81
+#define SRST_SDIO 82
+#define SRST_EMMC 83
+#define SRST_SPI0 84
+#define SRST_SPI1 85
+#define SRST_WDT 86
+#define SRST_SARADC 87
+#define SRST_DDRPHY 88
+#define SRST_DDRPHY_APB 89
+#define SRST_DDRCTL 90
+#define SRST_DDRCTL_APB 91
+#define SRST_DDRPUB 93
+
+#define SRST_VIO0_AXI 98
+#define SRST_VIO0_AHB 99
+#define SRST_LCDC0_AXI 100
+#define SRST_LCDC0_AHB 101
+#define SRST_LCDC0_DCLK 102
+#define SRST_LCDC1_AXI 103
+#define SRST_LCDC1_AHB 104
+#define SRST_LCDC1_DCLK 105
+#define SRST_IPP_AXI 106
+#define SRST_IPP_AHB 107
+#define SRST_RGA_AXI 108
+#define SRST_RGA_AHB 109
+#define SRST_CIF0 110
+
+#define SRST_VCODEC_AXI 112
+#define SRST_VCODEC_AHB 113
+#define SRST_VIO1_AXI 114
+#define SRST_VCODEC_CPU 115
+#define SRST_VCODEC_NIU 116
+#define SRST_GPU 120
+#define SRST_GPU_NIU 122
+#define SRST_TFUN_ATB 125
+#define SRST_TFUN_APB 126
+#define SRST_CTI4_APB 127
+
+#define SRST_TPIU_APB 128
+#define SRST_TRACE 129
+#define SRST_CORE_DBG 130
+#define SRST_DBG_APB 131
+#define SRST_CTI0 132
+#define SRST_CTI0_APB 133
+#define SRST_CTI1 134
+#define SRST_CTI1_APB 135
+#define SRST_PTM_CORE0 136
+#define SRST_PTM_CORE1 137
+#define SRST_PTM0 138
+#define SRST_PTM0_ATB 139
+#define SRST_PTM1 140
+#define SRST_PTM1_ATB 141
+#define SRST_CTM 142
+#define SRST_TS 143
+
+#endif
diff --git a/include/dt-bindings/clock/rk3188-cru.h b/include/dt-bindings/clock/rk3188-cru.h
new file mode 100644
index 0000000..b6960b0
--- /dev/null
+++ b/include/dt-bindings/clock/rk3188-cru.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3188_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3188_H
+
+#include <dt-bindings/clock/rk3188-cru-common.h>
+
+/* soft-reset indices */
+#define SRST_PTM_CORE2 0
+#define SRST_PTM_CORE3 1
+#define SRST_CORE2 5
+#define SRST_CORE3 6
+#define SRST_CORE2_DBG 10
+#define SRST_CORE3_DBG 11
+
+#define SRST_TIMER2 16
+#define SRST_TIMER4 23
+#define SRST_I2S0 24
+#define SRST_TIMER5 25
+#define SRST_TIMER3 29
+#define SRST_TIMER6 31
+
+#define SRST_PTM3 36
+#define SRST_PTM3_ATB 37
+
+#define SRST_GPS 67
+#define SRST_HSICPHY 75
+#define SRST_TIMER 78
+
+#define SRST_PTM2 92
+#define SRST_CORE2_WDT 94
+#define SRST_CORE3_WDT 95
+
+#define SRST_PTM2_ATB 111
+
+#define SRST_HSIC 117
+#define SRST_CTI2 118
+#define SRST_CTI2_APB 119
+#define SRST_GPU_BRIDGE 121
+#define SRST_CTI3 123
+#define SRST_CTI3_APB 124
+
+#endif
diff --git a/include/dt-bindings/clock/rk3328-cru.h b/include/dt-bindings/clock/rk3328-cru.h
new file mode 100644
index 0000000..6d8bf13
--- /dev/null
+++ b/include/dt-bindings/clock/rk3328-cru.h
@@ -0,0 +1,394 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3328_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3328_H
+
+/* core clocks */
+#define PLL_APLL 1
+#define PLL_DPLL 2
+#define PLL_CPLL 3
+#define PLL_GPLL 4
+#define PLL_NPLL 5
+#define ARMCLK 6
+
+/* sclk gates (special clocks) */
+#define SCLK_RTC32K 30
+#define SCLK_SDMMC_EXT 31
+#define SCLK_SPI 32
+#define SCLK_SDMMC 33
+#define SCLK_SDIO 34
+#define SCLK_EMMC 35
+#define SCLK_TSADC 36
+#define SCLK_SARADC 37
+#define SCLK_UART0 38
+#define SCLK_UART1 39
+#define SCLK_UART2 40
+#define SCLK_I2S0 41
+#define SCLK_I2S1 42
+#define SCLK_I2S2 43
+#define SCLK_I2S1_OUT 44
+#define SCLK_I2S2_OUT 45
+#define SCLK_SPDIF 46
+#define SCLK_TIMER0 47
+#define SCLK_TIMER1 48
+#define SCLK_TIMER2 49
+#define SCLK_TIMER3 50
+#define SCLK_TIMER4 51
+#define SCLK_TIMER5 52
+#define SCLK_WIFI 53
+#define SCLK_CIF_OUT 54
+#define SCLK_I2C0 55
+#define SCLK_I2C1 56
+#define SCLK_I2C2 57
+#define SCLK_I2C3 58
+#define SCLK_CRYPTO 59
+#define SCLK_PWM 60
+#define SCLK_PDM 61
+#define SCLK_EFUSE 62
+#define SCLK_OTP 63
+#define SCLK_DDRCLK 64
+#define SCLK_VDEC_CABAC 65
+#define SCLK_VDEC_CORE 66
+#define SCLK_VENC_DSP 67
+#define SCLK_VENC_CORE 68
+#define SCLK_RGA 69
+#define SCLK_HDMI_SFC 70
+#define SCLK_HDMI_CEC 71
+#define SCLK_USB3_REF 72
+#define SCLK_USB3_SUSPEND 73
+#define SCLK_SDMMC_DRV 74
+#define SCLK_SDIO_DRV 75
+#define SCLK_EMMC_DRV 76
+#define SCLK_SDMMC_EXT_DRV 77
+#define SCLK_SDMMC_SAMPLE 78
+#define SCLK_SDIO_SAMPLE 79
+#define SCLK_EMMC_SAMPLE 80
+#define SCLK_SDMMC_EXT_SAMPLE 81
+#define SCLK_VOP 82
+#define SCLK_MAC2PHY_RXTX 83
+#define SCLK_MAC2PHY_SRC 84
+#define SCLK_MAC2PHY_REF 85
+#define SCLK_MAC2PHY_OUT 86
+#define SCLK_MAC2IO_RX 87
+#define SCLK_MAC2IO_TX 88
+#define SCLK_MAC2IO_REFOUT 89
+#define SCLK_MAC2IO_REF 90
+#define SCLK_MAC2IO_OUT 91
+#define SCLK_TSP 92
+#define SCLK_HSADC_TSP 93
+#define SCLK_USB3PHY_REF 94
+#define SCLK_REF_USB3OTG 95
+#define SCLK_USB3OTG_REF 96
+#define SCLK_USB3OTG_SUSPEND 97
+#define SCLK_REF_USB3OTG_SRC 98
+#define SCLK_MAC2IO_SRC 99
+
+/* dclk gates */
+#define DCLK_LCDC 180
+#define DCLK_HDMIPHY 181
+#define HDMIPHY 182
+#define USB480M 183
+#define DCLK_LCDC_SRC 184
+
+/* aclk gates */
+#define ACLK_AXISRAM 190
+#define ACLK_VOP_PRE 191
+#define ACLK_USB3OTG 192
+#define ACLK_RGA_PRE 193
+#define ACLK_DMAC 194
+#define ACLK_GPU 195
+#define ACLK_BUS_PRE 196
+#define ACLK_PERI_PRE 197
+#define ACLK_RKVDEC_PRE 198
+#define ACLK_RKVDEC 199
+#define ACLK_RKVENC 200
+#define ACLK_VPU_PRE 201
+#define ACLK_VIO_PRE 202
+#define ACLK_VPU 203
+#define ACLK_VIO 204
+#define ACLK_VOP 205
+#define ACLK_GMAC 206
+#define ACLK_H265 207
+#define ACLK_H264 208
+#define ACLK_MAC2PHY 209
+#define ACLK_MAC2IO 210
+#define ACLK_DCF 211
+#define ACLK_TSP 212
+#define ACLK_PERI 213
+#define ACLK_RGA 214
+#define ACLK_IEP 215
+#define ACLK_CIF 216
+#define ACLK_HDCP 217
+
+/* pclk gates */
+#define PCLK_GPIO0 300
+#define PCLK_GPIO1 301
+#define PCLK_GPIO2 302
+#define PCLK_GPIO3 303
+#define PCLK_GRF 304
+#define PCLK_I2C0 305
+#define PCLK_I2C1 306
+#define PCLK_I2C2 307
+#define PCLK_I2C3 308
+#define PCLK_SPI 309
+#define PCLK_UART0 310
+#define PCLK_UART1 311
+#define PCLK_UART2 312
+#define PCLK_TSADC 313
+#define PCLK_PWM 314
+#define PCLK_TIMER 315
+#define PCLK_BUS_PRE 316
+#define PCLK_PERI_PRE 317
+#define PCLK_HDMI_CTRL 318
+#define PCLK_HDMI_PHY 319
+#define PCLK_GMAC 320
+#define PCLK_H265 321
+#define PCLK_MAC2PHY 322
+#define PCLK_MAC2IO 323
+#define PCLK_USB3PHY_OTG 324
+#define PCLK_USB3PHY_PIPE 325
+#define PCLK_USB3_GRF 326
+#define PCLK_USB2_GRF 327
+#define PCLK_HDMIPHY 328
+#define PCLK_DDR 329
+#define PCLK_PERI 330
+#define PCLK_HDMI 331
+#define PCLK_HDCP 332
+#define PCLK_DCF 333
+#define PCLK_SARADC 334
+
+/* hclk gates */
+#define HCLK_PERI 408
+#define HCLK_TSP 409
+#define HCLK_GMAC 410
+#define HCLK_I2S0_8CH 411
+#define HCLK_I2S1_8CH 413
+#define HCLK_I2S2_2CH 413
+#define HCLK_SPDIF_8CH 414
+#define HCLK_VOP 415
+#define HCLK_NANDC 416
+#define HCLK_SDMMC 417
+#define HCLK_SDIO 418
+#define HCLK_EMMC 419
+#define HCLK_SDMMC_EXT 420
+#define HCLK_RKVDEC_PRE 421
+#define HCLK_RKVDEC 422
+#define HCLK_RKVENC 423
+#define HCLK_VPU_PRE 424
+#define HCLK_VIO_PRE 425
+#define HCLK_VPU 426
+#define HCLK_VIO 427
+#define HCLK_BUS_PRE 428
+#define HCLK_PERI_PRE 429
+#define HCLK_H264 430
+#define HCLK_CIF 431
+#define HCLK_OTG_PMU 432
+#define HCLK_OTG 433
+#define HCLK_HOST0 434
+#define HCLK_HOST0_ARB 435
+#define HCLK_CRYPTO_MST 436
+#define HCLK_CRYPTO_SLV 437
+#define HCLK_PDM 438
+#define HCLK_IEP 439
+#define HCLK_RGA 440
+#define HCLK_HDCP 441
+
+#define CLK_NR_CLKS (HCLK_HDCP + 1)
+
+#define SCLK_MAC2IO 0
+#define SCLK_MAC2PHY 1
+
+#define CLKGRF_NR_CLKS (SCLK_MAC2PHY + 1)
+
+/* soft-reset indices */
+#define SRST_CORE0_PO 0
+#define SRST_CORE1_PO 1
+#define SRST_CORE2_PO 2
+#define SRST_CORE3_PO 3
+#define SRST_CORE0 4
+#define SRST_CORE1 5
+#define SRST_CORE2 6
+#define SRST_CORE3 7
+#define SRST_CORE0_DBG 8
+#define SRST_CORE1_DBG 9
+#define SRST_CORE2_DBG 10
+#define SRST_CORE3_DBG 11
+#define SRST_TOPDBG 12
+#define SRST_CORE_NIU 13
+#define SRST_STRC_A 14
+#define SRST_L2C 15
+
+#define SRST_A53_GIC 18
+#define SRST_DAP 19
+#define SRST_PMU_P 21
+#define SRST_EFUSE 22
+#define SRST_BUSSYS_H 23
+#define SRST_BUSSYS_P 24
+#define SRST_SPDIF 25
+#define SRST_INTMEM 26
+#define SRST_ROM 27
+#define SRST_GPIO0 28
+#define SRST_GPIO1 29
+#define SRST_GPIO2 30
+#define SRST_GPIO3 31
+
+#define SRST_I2S0 32
+#define SRST_I2S1 33
+#define SRST_I2S2 34
+#define SRST_I2S0_H 35
+#define SRST_I2S1_H 36
+#define SRST_I2S2_H 37
+#define SRST_UART0 38
+#define SRST_UART1 39
+#define SRST_UART2 40
+#define SRST_UART0_P 41
+#define SRST_UART1_P 42
+#define SRST_UART2_P 43
+#define SRST_I2C0 44
+#define SRST_I2C1 45
+#define SRST_I2C2 46
+#define SRST_I2C3 47
+
+#define SRST_I2C0_P 48
+#define SRST_I2C1_P 49
+#define SRST_I2C2_P 50
+#define SRST_I2C3_P 51
+#define SRST_EFUSE_SE_P 52
+#define SRST_EFUSE_NS_P 53
+#define SRST_PWM0 54
+#define SRST_PWM0_P 55
+#define SRST_DMA 56
+#define SRST_TSP_A 57
+#define SRST_TSP_H 58
+#define SRST_TSP 59
+#define SRST_TSP_HSADC 60
+#define SRST_DCF_A 61
+#define SRST_DCF_P 62
+
+#define SRST_SCR 64
+#define SRST_SPI 65
+#define SRST_TSADC 66
+#define SRST_TSADC_P 67
+#define SRST_CRYPTO 68
+#define SRST_SGRF 69
+#define SRST_GRF 70
+#define SRST_USB_GRF 71
+#define SRST_TIMER_6CH_P 72
+#define SRST_TIMER0 73
+#define SRST_TIMER1 74
+#define SRST_TIMER2 75
+#define SRST_TIMER3 76
+#define SRST_TIMER4 77
+#define SRST_TIMER5 78
+#define SRST_USB3GRF 79
+
+#define SRST_PHYNIU 80
+#define SRST_HDMIPHY 81
+#define SRST_VDAC 82
+#define SRST_ACODEC_p 83
+#define SRST_SARADC 85
+#define SRST_SARADC_P 86
+#define SRST_GRF_DDR 87
+#define SRST_DFIMON 88
+#define SRST_MSCH 89
+#define SRST_DDRMSCH 91
+#define SRST_DDRCTRL 92
+#define SRST_DDRCTRL_P 93
+#define SRST_DDRPHY 94
+#define SRST_DDRPHY_P 95
+
+#define SRST_GMAC_NIU_A 96
+#define SRST_GMAC_NIU_P 97
+#define SRST_GMAC2PHY_A 98
+#define SRST_GMAC2IO_A 99
+#define SRST_MACPHY 100
+#define SRST_OTP_PHY 101
+#define SRST_GPU_A 102
+#define SRST_GPU_NIU_A 103
+#define SRST_SDMMCEXT 104
+#define SRST_PERIPH_NIU_A 105
+#define SRST_PERIHP_NIU_H 106
+#define SRST_PERIHP_P 107
+#define SRST_PERIPHSYS_H 108
+#define SRST_MMC0 109
+#define SRST_SDIO 110
+#define SRST_EMMC 111
+
+#define SRST_USB2OTG_H 112
+#define SRST_USB2OTG 113
+#define SRST_USB2OTG_ADP 114
+#define SRST_USB2HOST_H 115
+#define SRST_USB2HOST_ARB 116
+#define SRST_USB2HOST_AUX 117
+#define SRST_USB2HOST_EHCIPHY 118
+#define SRST_USB2HOST_UTMI 119
+#define SRST_USB3OTG 120
+#define SRST_USBPOR 121
+#define SRST_USB2OTG_UTMI 122
+#define SRST_USB2HOST_PHY_UTMI 123
+#define SRST_USB3OTG_UTMI 124
+#define SRST_USB3PHY_U2 125
+#define SRST_USB3PHY_U3 126
+#define SRST_USB3PHY_PIPE 127
+
+#define SRST_VIO_A 128
+#define SRST_VIO_BUS_H 129
+#define SRST_VIO_H2P_H 130
+#define SRST_VIO_ARBI_H 131
+#define SRST_VOP_NIU_A 132
+#define SRST_VOP_A 133
+#define SRST_VOP_H 134
+#define SRST_VOP_D 135
+#define SRST_RGA 136
+#define SRST_RGA_NIU_A 137
+#define SRST_RGA_A 138
+#define SRST_RGA_H 139
+#define SRST_IEP_A 140
+#define SRST_IEP_H 141
+#define SRST_HDMI 142
+#define SRST_HDMI_P 143
+
+#define SRST_HDCP_A 144
+#define SRST_HDCP 145
+#define SRST_HDCP_H 146
+#define SRST_CIF_A 147
+#define SRST_CIF_H 148
+#define SRST_CIF_P 149
+#define SRST_OTP_P 150
+#define SRST_OTP_SBPI 151
+#define SRST_OTP_USER 152
+#define SRST_DDRCTRL_A 153
+#define SRST_DDRSTDY_P 154
+#define SRST_DDRSTDY 155
+#define SRST_PDM_H 156
+#define SRST_PDM 157
+#define SRST_USB3PHY_OTG_P 158
+#define SRST_USB3PHY_PIPE_P 159
+
+#define SRST_VCODEC_A 160
+#define SRST_VCODEC_NIU_A 161
+#define SRST_VCODEC_H 162
+#define SRST_VCODEC_NIU_H 163
+#define SRST_VDEC_A 164
+#define SRST_VDEC_NIU_A 165
+#define SRST_VDEC_H 166
+#define SRST_VDEC_NIU_H 167
+#define SRST_VDEC_CORE 168
+#define SRST_VDEC_CABAC 169
+#define SRST_DDRPHYDIV 175
+
+#define SRST_RKVENC_NIU_A 176
+#define SRST_RKVENC_NIU_H 177
+#define SRST_RKVENC_H265_A 178
+#define SRST_RKVENC_H265_P 179
+#define SRST_RKVENC_H265_CORE 180
+#define SRST_RKVENC_H265_DSP 181
+#define SRST_RKVENC_H264_A 182
+#define SRST_RKVENC_H264_H 183
+#define SRST_RKVENC_INTMEM 184
+
+#endif
diff --git a/include/dt-bindings/clock/rk3399-cru.h b/include/dt-bindings/clock/rk3399-cru.h
index 0a86aec..d4bdcc6 100644
--- a/include/dt-bindings/clock/rk3399-cru.h
+++ b/include/dt-bindings/clock/rk3399-cru.h
@@ -122,6 +122,10 @@
#define SCLK_DPHY_RX0_CFG 165
#define SCLK_RMII_SRC 166
#define SCLK_PCIEPHY_REF100M 167
+#define SCLK_USBPHY0_480M_SRC 168
+#define SCLK_USBPHY1_480M_SRC 169
+#define SCLK_DDRCLK 170
+#define SCLK_TESTOUT2 171
#define DCLK_VOP0 180
#define DCLK_VOP1 181
@@ -589,13 +593,13 @@
#define SRST_P_SPI0 214
#define SRST_P_SPI1 215
#define SRST_P_SPI2 216
-#define SRST_P_SPI3 217
-#define SRST_P_SPI4 218
+#define SRST_P_SPI4 217
+#define SRST_P_SPI5 218
#define SRST_SPI0 219
#define SRST_SPI1 220
#define SRST_SPI2 221
-#define SRST_SPI3 222
-#define SRST_SPI4 223
+#define SRST_SPI4 222
+#define SRST_SPI5 223
/* cru_softrst_con14 */
#define SRST_I2S0_8CH 224
@@ -717,8 +721,8 @@
#define SRST_H_CM0S_NOC 3
#define SRST_DBG_CM0S 4
#define SRST_PO_CM0S 5
-#define SRST_P_SPI6 6
-#define SRST_SPI6 7
+#define SRST_P_SPI3 6
+#define SRST_SPI3 7
#define SRST_P_TIMER_0_1 8
#define SRST_P_TIMER_0 9
#define SRST_P_TIMER_1 10
diff --git a/include/dt-bindings/pinctrl/rockchip.h b/include/dt-bindings/pinctrl/rockchip.h
index 56887e1..ecb76c7 100644
--- a/include/dt-bindings/pinctrl/rockchip.h
+++ b/include/dt-bindings/pinctrl/rockchip.h
@@ -22,5 +22,7 @@
#define RK_FUNC_2 2
#define RK_FUNC_3 3
#define RK_FUNC_4 4
+#define RK_FUNC_5 5
+#define RK_FUNC_6 6
#endif
diff --git a/include/spl.h b/include/spl.h
index bde4437..cdd196d 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -213,11 +213,29 @@ int spl_load_image_ext_os(struct spl_image_info *spl_image,
struct blk_desc *block_dev, int partition);
/**
- * spl_init() - Set up device tree and driver model in SPL if enabled
+ * spl_early_init() - Set up device tree and driver model in SPL if enabled
*
* Call this function in board_init_f() if you want to use device tree and
- * driver model early, before board_init_r() is called. This function will
- * be called from board_init_r() if not called earlier.
+ * driver model early, before board_init_r() is called.
+ *
+ * If this is not called, then driver model will be inactive in SPL's
+ * board_init_f(), and no device tree will be available.
+ */
+int spl_early_init(void);
+
+/**
+ * spl_init() - Set up device tree and driver model in SPL if enabled
+ *
+ * You can optionally call spl_early_init(), then optionally call spl_init().
+ * This function will be called from board_init_r() if not called earlier.
+ *
+ * Both spl_early_init() and spl_init() perform a similar function except that
+ * the latter will not set up the malloc() area if
+ * CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN is enabled, since it is assumed to
+ * already be done by a calll to spl_relocate_stack_gd() before board_init_r()
+ * is reached.
+ *
+ * This function will be called from board_init_r() if not called earlier.
*
* If this is not called, then driver model will be inactive in SPL's
* board_init_f(), and no device tree will be available.
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index b52f996..5370648 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -215,8 +215,13 @@ $(obj)/$(SPL_BIN)-pad.bin: $(obj)/$(SPL_BIN)
# 'u-boot,dm-pre-reloc' property and thus are not needed by SPL. The second
# pass removes various unused properties from the remaining nodes.
# The output is typically a much smaller device tree file.
+ifeq ($(CONFIG_TPL_BUILD),y)
+fdtgrep_props := -b u-boot,dm-pre-reloc -b u-boot,dm-tpl
+else
+fdtgrep_props := -b u-boot,dm-pre-reloc -b u-boot,dm-spl
+endif
quiet_cmd_fdtgrep = FDTGREP $@
- cmd_fdtgrep = $(objtree)/tools/fdtgrep -b u-boot,dm-pre-reloc -RT $< \
+ cmd_fdtgrep = $(objtree)/tools/fdtgrep $(fdtgrep_props) -RT $< \
-n /chosen -O dtb | \
$(objtree)/tools/fdtgrep -r -O dtb - -o $@ \
$(addprefix -P ,$(subst $\",,$(CONFIG_OF_SPL_REMOVE_PROPS)))
diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
index 6df7b0d..bf67ec8 100755
--- a/tools/dtoc/dtoc.py
+++ b/tools/dtoc/dtoc.py
@@ -30,6 +30,8 @@ PROP_IGNORE_LIST = [
"status",
'phandle',
'u-boot,dm-pre-reloc',
+ 'u-boot,dm-tpl',
+ 'u-boot,dm-spl',
]
# C type declarations for the tyues we support
diff --git a/tools/rkcommon.c b/tools/rkcommon.c
index 0a072aa..6595e02 100644
--- a/tools/rkcommon.c
+++ b/tools/rkcommon.c
@@ -46,17 +46,20 @@ struct header0_info {
* @imagename: Image name(passed by "mkimage -n")
* @spl_hdr: Boot ROM requires a 4-bytes spl header
* @spl_size: Spl size(include extra 4-bytes spl header)
+ * @spl_rc4: RC4 encode the SPL binary (same key as header)
*/
struct spl_info {
const char *imagename;
const char *spl_hdr;
const uint32_t spl_size;
+ const bool spl_rc4;
};
static struct spl_info spl_infos[] = {
- { "rk3036", "RK30", 0x1000 },
- { "rk3288", "RK32", 0x8000 },
- { "rk3399", "RK33", 0x20000 },
+ { "rk3036", "RK30", 0x1000, false },
+ { "rk3188", "RK31", 0x8000 - 0x800, true },
+ { "rk3288", "RK32", 0x8000, false },
+ { "rk3399", "RK33", 0x20000, false },
};
static unsigned char rc4_key[16] = {
@@ -113,6 +116,16 @@ int rkcommon_get_spl_size(struct image_tool_params *params)
return info->spl_size;
}
+bool rkcommon_need_rc4_spl(struct image_tool_params *params)
+{
+ struct spl_info *info = rkcommon_get_spl_info(params->imagename);
+
+ /*
+ * info would not be NULL, because of we checked params before.
+ */
+ return info->spl_rc4;
+}
+
int rkcommon_set_header(void *buf, uint file_size,
struct image_tool_params *params)
{
@@ -124,7 +137,7 @@ int rkcommon_set_header(void *buf, uint file_size,
memset(buf, '\0', RK_INIT_OFFSET * RK_BLK_SIZE);
hdr = (struct header0_info *)buf;
hdr->signature = RK_SIGNATURE;
- hdr->disable_rc4 = 1;
+ hdr->disable_rc4 = !rkcommon_need_rc4_spl(params);
hdr->init_offset = RK_INIT_OFFSET;
hdr->init_size = (file_size + RK_BLK_SIZE - 1) / RK_BLK_SIZE;
@@ -135,3 +148,16 @@ int rkcommon_set_header(void *buf, uint file_size,
return 0;
}
+
+void rkcommon_rc4_encode_spl(void *buf, unsigned int offset, unsigned int size)
+{
+ unsigned int remaining = size;
+
+ while (remaining > 0) {
+ int step = (remaining > RK_BLK_SIZE) ? RK_BLK_SIZE : remaining;
+
+ rc4_encode(buf + offset, step, rc4_key);
+ offset += RK_BLK_SIZE;
+ remaining -= step;
+ }
+}
diff --git a/tools/rkcommon.h b/tools/rkcommon.h
index c69540f..b4f6f32 100644
--- a/tools/rkcommon.h
+++ b/tools/rkcommon.h
@@ -55,4 +55,26 @@ int rkcommon_get_spl_size(struct image_tool_params *params);
int rkcommon_set_header(void *buf, uint file_size,
struct image_tool_params *params);
+/**
+ * rkcommon_need_rc4_spl() - check if rc4 encoded spl is required
+ *
+ * Some socs cannot disable the rc4-encryption of the spl binary.
+ * rc4 encryption is disabled normally except on socs that cannot
+ * handle unencrypted binaries.
+ * @return true or false depending on rc4 being required.
+ */
+bool rkcommon_need_rc4_spl(struct image_tool_params *params);
+
+/**
+ * rkcommon_rc4_encode_spl() - encode the spl binary
+ *
+ * Encrypts the SPL binary using the generic rc4 key as required
+ * by some socs.
+ *
+ * @buf: Pointer to the SPL data (header and SPL binary)
+ * @offset: offset inside buf to start at
+ * @size: number of bytes to encode
+ */
+void rkcommon_rc4_encode_spl(void *buf, unsigned int offset, unsigned int size);
+
#endif
diff --git a/tools/rkimage.c b/tools/rkimage.c
index ef31cb6..44d098c 100644
--- a/tools/rkimage.c
+++ b/tools/rkimage.c
@@ -28,6 +28,9 @@ static void rkimage_set_header(void *buf, struct stat *sbuf, int ifd,
{
memcpy(buf + RK_SPL_HDR_START, rkcommon_get_spl_hdr(params),
RK_SPL_HDR_SIZE);
+
+ if (rkcommon_need_rc4_spl(params))
+ rkcommon_rc4_encode_spl(buf, 4, params->file_size);
}
static int rkimage_extract_subimage(void *buf, struct image_tool_params *params)
diff --git a/tools/rksd.c b/tools/rksd.c
index a2baa74..ff2233f 100644
--- a/tools/rksd.c
+++ b/tools/rksd.c
@@ -41,6 +41,10 @@ static void rksd_set_header(void *buf, struct stat *sbuf, int ifd,
memcpy(buf + RK_SPL_HDR_START, rkcommon_get_spl_hdr(params),
RK_SPL_HDR_SIZE);
+
+ if (rkcommon_need_rc4_spl(params))
+ rkcommon_rc4_encode_spl(buf, RK_SPL_START - 4,
+ params->file_size - RK_SPL_START + 4);
}
static int rksd_extract_subimage(void *buf, struct image_tool_params *params)
diff --git a/tools/rkspi.c b/tools/rkspi.c
index a0b0051..0271d2e 100644
--- a/tools/rkspi.c
+++ b/tools/rkspi.c
@@ -48,6 +48,10 @@ static void rkspi_set_header(void *buf, struct stat *sbuf, int ifd,
memcpy(buf + RK_SPL_HDR_START, rkcommon_get_spl_hdr(params),
RK_SPL_HDR_SIZE);
+ if (rkcommon_need_rc4_spl(params))
+ rkcommon_rc4_encode_spl(buf, RK_SPL_START - 4,
+ params->file_size - RK_SPL_START + 4);
+
/*
* Spread the image out so we only use the first 2KB of each 4KB
* region. This is a feature of the SPI format required by the Rockchip