summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/boards/rockchip.rst1
-rw-r--r--Documentation/user/booting-linux.rst10
-rw-r--r--arch/arm/boards/Makefile1
-rw-r--r--arch/arm/boards/pine64-quartz64/lowlevel.c26
-rw-r--r--arch/arm/boards/radxa-cm3/.gitignore1
-rw-r--r--arch/arm/boards/radxa-cm3/Makefile3
-rw-r--r--arch/arm/boards/radxa-cm3/board.c56
-rw-r--r--arch/arm/boards/radxa-cm3/lowlevel.c32
-rw-r--r--arch/arm/boards/radxa-rock3/lowlevel.c25
-rw-r--r--arch/arm/boards/rockchip-rk3568-bpi-r2pro/lowlevel.c25
-rw-r--r--arch/arm/boards/rockchip-rk3568-evb/lowlevel.c26
-rw-r--r--arch/arm/dts/Makefile1
-rw-r--r--arch/arm/dts/rk3566-cm3-io.dts50
-rw-r--r--arch/arm/dts/rk356x.dtsi5
-rw-r--r--arch/arm/mach-rockchip/Kconfig6
-rw-r--r--arch/arm/mach-rockchip/Makefile3
-rw-r--r--arch/arm/mach-rockchip/atf.c34
-rw-r--r--arch/arm/mach-rockchip/bootrom.c51
-rw-r--r--arch/arm/mach-rockchip/dmc.c219
-rw-r--r--arch/arm/mach-rockchip/rk3568.c29
-rw-r--r--images/Makefile.rockchip7
-rw-r--r--include/bootsource.h1
-rw-r--r--include/linux/sizes.h3
-rw-r--r--include/mach/rockchip/atf.h2
-rw-r--r--include/mach/rockchip/bootrom.h32
-rw-r--r--include/mach/rockchip/dmc.h86
-rw-r--r--include/mach/rockchip/rk3399-regs.h1
-rw-r--r--include/mach/rockchip/rk3568-regs.h1
28 files changed, 621 insertions, 116 deletions
diff --git a/Documentation/boards/rockchip.rst b/Documentation/boards/rockchip.rst
index 0e8738bbf1..583b4f1720 100644
--- a/Documentation/boards/rockchip.rst
+++ b/Documentation/boards/rockchip.rst
@@ -60,6 +60,7 @@ Supported Boards
- Rockchip RK3568 Bananapi R2 Pro
- Pine64 Quartz64 Model A
- Radxa ROCK3 Model A
+- Radxa CM3 (RK3566) IO Board
The steps described in the following target the RK3568 and the RK3568 EVB but
generally apply to both SoCs and all boards.
diff --git a/Documentation/user/booting-linux.rst b/Documentation/user/booting-linux.rst
index 1a95f87e77..6fa8cd911e 100644
--- a/Documentation/user/booting-linux.rst
+++ b/Documentation/user/booting-linux.rst
@@ -19,8 +19,10 @@ architecture the bootm command handles different image types. On ARM the
following images are supported:
* ARM Linux zImage
+* ARM64 Linux Image, plain or compressed
* U-Boot uImage
* barebox images
+* FIT images, containing a zImage or Image
The images can either be passed directly to the bootm command as argument or
in the ``global.bootm.image`` variable:
@@ -48,6 +50,14 @@ variable:
global.bootm.image=/path/to/zImage
bootm
+FIT image configurations will be matched by comparing the ``compatible`` property
+inside the configuration node with the barebox live tree's ``/compatible``.
+It's also possible to select a specific configuration explicitly:
+
+.. code-block:: sh
+
+ global.bootm.image=/dev/mmc0.fit@conf-imx8mm-evk.dtb
+
**NOTE:** it may happen that barebox is probed from the devicetree, but you have
want to start a Kernel without passing a devicetree. In this case set the
``global.bootm.boot_atag`` variable to ``true``.
diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile
index 37b1650e63..b204c257f6 100644
--- a/arch/arm/boards/Makefile
+++ b/arch/arm/boards/Makefile
@@ -190,3 +190,4 @@ obj-$(CONFIG_MACH_RK3568_BPI_R2PRO) += rockchip-rk3568-bpi-r2pro/
obj-$(CONFIG_MACH_PINE64_QUARTZ64) += pine64-quartz64/
obj-$(CONFIG_MACH_RADXA_ROCK3) += radxa-rock3/
obj-$(CONFIG_MACH_VARISCITE_DT8MCUSTOMBOARD_IMX8MP) += variscite-dt8mcustomboard-imx8mp/
+obj-$(CONFIG_MACH_RADXA_CM3) += radxa-cm3/
diff --git a/arch/arm/boards/pine64-quartz64/lowlevel.c b/arch/arm/boards/pine64-quartz64/lowlevel.c
index 1e63c0e698..7723d47860 100644
--- a/arch/arm/boards/pine64-quartz64/lowlevel.c
+++ b/arch/arm/boards/pine64-quartz64/lowlevel.c
@@ -1,35 +1,17 @@
// SPDX-License-Identifier: GPL-2.0-only
+
#include <common.h>
-#include <linux/sizes.h>
-#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
#include <mach/rockchip/hardware.h>
#include <mach/rockchip/atf.h>
#include <debug_ll.h>
-#include <mach/rockchip/rockchip.h>
extern char __dtb_rk3566_quartz64_a_start[];
-static noinline void start_quartz64(void)
-{
- void *fdt = __dtb_rk3566_quartz64_a_start;
-
- if (current_el() == 3) {
- rk3568_lowlevel_init();
- rk3568_atf_load_bl31(fdt);
- /* not reached */
- }
-
- barebox_arm_entry(RK3568_DRAM_BOTTOM, 0x80000000 - RK3568_DRAM_BOTTOM,
- fdt);
-}
-
ENTRY_FUNCTION(start_quartz64a, r0, r1, r2)
{
- /*
- * Image execution starts at 0x0, but this is used for ATF and
- * OP-TEE later, so move away from here.
- */
+ putc_ll('>');
+
if (current_el() == 3)
relocate_to_adr_full(RK3568_BAREBOX_LOAD_ADDRESS);
else
@@ -37,5 +19,5 @@ ENTRY_FUNCTION(start_quartz64a, r0, r1, r2)
setup_c();
- start_quartz64();
+ rk3568_barebox_entry(__dtb_rk3566_quartz64_a_start);
}
diff --git a/arch/arm/boards/radxa-cm3/.gitignore b/arch/arm/boards/radxa-cm3/.gitignore
new file mode 100644
index 0000000000..f458f794b5
--- /dev/null
+++ b/arch/arm/boards/radxa-cm3/.gitignore
@@ -0,0 +1 @@
+sdram-init.bin
diff --git a/arch/arm/boards/radxa-cm3/Makefile b/arch/arm/boards/radxa-cm3/Makefile
new file mode 100644
index 0000000000..b37b6c870b
--- /dev/null
+++ b/arch/arm/boards/radxa-cm3/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-y += board.o
+lwl-y += lowlevel.o
diff --git a/arch/arm/boards/radxa-cm3/board.c b/arch/arm/boards/radxa-cm3/board.c
new file mode 100644
index 0000000000..14b6784179
--- /dev/null
+++ b/arch/arm/boards/radxa-cm3/board.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <bootsource.h>
+#include <common.h>
+#include <deep-probe.h>
+#include <init.h>
+#include <mach/rockchip/bbu.h>
+
+struct cm3_model {
+ const char *name;
+ const char *shortname;
+};
+
+static int cm3_probe(struct device *dev)
+{
+ enum bootsource bootsource = bootsource_get();
+ int instance = bootsource_get_instance();
+ const struct cm3_model *model;
+
+ model = device_get_match_data(dev);
+
+ barebox_set_model(model->name);
+ barebox_set_hostname(model->shortname);
+
+ if (bootsource == BOOTSOURCE_MMC && instance == 1)
+ of_device_enable_path("/chosen/environment-sd");
+ else
+ of_device_enable_path("/chosen/environment-emmc");
+
+ rk3568_bbu_mmc_register("emmc", BBU_HANDLER_FLAG_DEFAULT,
+ "/dev/mmc0");
+ rk3568_bbu_mmc_register("sd", 0, "/dev/mmc1");
+
+ return 0;
+}
+
+static const struct cm3_model cm3_io = {
+ .name = "Radxa CM3 on IO Board",
+ .shortname = "cm3-io",
+};
+
+static const struct of_device_id cm3_of_match[] = {
+ {
+ .compatible = "radxa,cm3-io",
+ .data = &cm3_io,
+ },
+ { /* sentinel */ },
+};
+
+static struct driver cm3_io_board_driver = {
+ .name = "board-cm3-io",
+ .probe = cm3_probe,
+ .of_compatible = cm3_of_match,
+};
+coredevice_platform_driver(cm3_io_board_driver);
+
+BAREBOX_DEEP_PROBE_ENABLE(cm3_of_match);
diff --git a/arch/arm/boards/radxa-cm3/lowlevel.c b/arch/arm/boards/radxa-cm3/lowlevel.c
new file mode 100644
index 0000000000..e1b453f21f
--- /dev/null
+++ b/arch/arm/boards/radxa-cm3/lowlevel.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <common.h>
+#include <asm/barebox-arm.h>
+#include <mach/rockchip/hardware.h>
+#include <mach/rockchip/atf.h>
+#include <debug_ll.h>
+
+extern char __dtb_rk3566_cm3_io_start[];
+
+ENTRY_FUNCTION(start_radxa_cm3_io, r0, r1, r2)
+{
+ /*
+ * Enable vccio4 1.8V and vccio6 1.8V
+ * Needed for GMAC to work.
+ * FIXME: This is done by the io-domain driver as well, but there
+ * currently is no mechanism to make sure the driver gets probed
+ * before its consumers. Remove this setup once this issue is
+ * resolved.
+ */
+ writel(RK_SETBITS(0x50), 0xfdc20140);
+
+ putc_ll('>');
+
+ if (current_el() == 3)
+ relocate_to_adr_full(RK3568_BAREBOX_LOAD_ADDRESS);
+ else
+ relocate_to_current_adr();
+
+ setup_c();
+
+ rk3568_barebox_entry(__dtb_rk3566_cm3_io_start);
+}
diff --git a/arch/arm/boards/radxa-rock3/lowlevel.c b/arch/arm/boards/radxa-rock3/lowlevel.c
index a8226749d4..ec407404b9 100644
--- a/arch/arm/boards/radxa-rock3/lowlevel.c
+++ b/arch/arm/boards/radxa-rock3/lowlevel.c
@@ -1,19 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-only
+
#include <common.h>
-#include <linux/sizes.h>
-#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
#include <mach/rockchip/hardware.h>
#include <mach/rockchip/atf.h>
#include <debug_ll.h>
-#include <mach/rockchip/rockchip.h>
extern char __dtb_rk3568_rock_3a_start[];
-static noinline void rk3568_start(void)
+ENTRY_FUNCTION(start_rock3a, r0, r1, r2)
{
- void *fdt = __dtb_rk3568_rock_3a_start;
-
/*
* Enable vccio4 1.8V and vccio6 1.8V
* Needed for GMAC to work.
@@ -24,21 +20,8 @@ static noinline void rk3568_start(void)
*/
writel(RK_SETBITS(0x50), 0xfdc20140);
- if (current_el() == 3) {
- rk3568_lowlevel_init();
- rk3568_atf_load_bl31(fdt);
- /* not reached */
- }
-
- barebox_arm_entry(RK3568_DRAM_BOTTOM, 0x80000000 - RK3568_DRAM_BOTTOM, fdt);
-}
+ putc_ll('>');
-ENTRY_FUNCTION(start_rock3a, r0, r1, r2)
-{
- /*
- * Image execution starts at 0x0, but this is used for ATF and
- * OP-TEE later, so move away from here.
- */
if (current_el() == 3)
relocate_to_adr_full(RK3568_BAREBOX_LOAD_ADDRESS);
else
@@ -46,5 +29,5 @@ ENTRY_FUNCTION(start_rock3a, r0, r1, r2)
setup_c();
- rk3568_start();
+ rk3568_barebox_entry(__dtb_rk3568_rock_3a_start);
}
diff --git a/arch/arm/boards/rockchip-rk3568-bpi-r2pro/lowlevel.c b/arch/arm/boards/rockchip-rk3568-bpi-r2pro/lowlevel.c
index 23bacc91d9..12c2445287 100644
--- a/arch/arm/boards/rockchip-rk3568-bpi-r2pro/lowlevel.c
+++ b/arch/arm/boards/rockchip-rk3568-bpi-r2pro/lowlevel.c
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <common.h>
-#include <linux/sizes.h>
-#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
#include <mach/rockchip/hardware.h>
#include <mach/rockchip/atf.h>
@@ -11,9 +9,9 @@
extern char __dtb_rk3568_bpi_r2_pro_start[];
-static noinline void rk3568_start(void)
+ENTRY_FUNCTION(start_rk3568_bpi_r2pro, r0, r1, r2)
{
- void *fdt;
+ putc_ll('>');
/*
* set iodomain vccio6 to 1.8V needed for GMAC1 to work.
@@ -28,23 +26,6 @@ static noinline void rk3568_start(void)
//clear bit 6 for 3v3 as it was set to 1v8
writel(RK_CLRBITS(BIT(6)), PMU_GRF_IO_VSEL1);
- fdt = __dtb_rk3568_bpi_r2_pro_start;
-
- if (current_el() == 3) {
- rk3568_lowlevel_init();
- rk3568_atf_load_bl31(fdt);
- /* not reached */
- }
-
- barebox_arm_entry(RK3568_DRAM_BOTTOM, 0x80000000 - RK3568_DRAM_BOTTOM, fdt);
-}
-
-ENTRY_FUNCTION(start_rk3568_bpi_r2pro, r0, r1, r2)
-{
- /*
- * Image execution starts at 0x0, but this is used for ATF and
- * OP-TEE later, so move away from here.
- */
if (current_el() == 3)
relocate_to_adr_full(RK3568_BAREBOX_LOAD_ADDRESS);
else
@@ -52,5 +33,5 @@ ENTRY_FUNCTION(start_rk3568_bpi_r2pro, r0, r1, r2)
setup_c();
- rk3568_start();
+ rk3568_barebox_entry(__dtb_rk3568_bpi_r2_pro_start);
}
diff --git a/arch/arm/boards/rockchip-rk3568-evb/lowlevel.c b/arch/arm/boards/rockchip-rk3568-evb/lowlevel.c
index 8720e6d9ae..d5ae70049e 100644
--- a/arch/arm/boards/rockchip-rk3568-evb/lowlevel.c
+++ b/arch/arm/boards/rockchip-rk3568-evb/lowlevel.c
@@ -1,20 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <common.h>
-#include <linux/sizes.h>
-#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
#include <mach/rockchip/hardware.h>
#include <mach/rockchip/atf.h>
#include <debug_ll.h>
-#include <mach/rockchip/rockchip.h>
extern char __dtb_rk3568_evb1_v10_start[];
-static noinline void rk3568_start(void)
+ENTRY_FUNCTION(start_rk3568_evb, r0, r1, r2)
{
- void *fdt;
-
/*
* Enable vccio4 1.8V and vccio6 1.8V
* Needed for GMAC to work.
@@ -25,23 +20,8 @@ static noinline void rk3568_start(void)
*/
writel(RK_SETBITS(0x50), 0xfdc20140);
- fdt = __dtb_rk3568_evb1_v10_start;
-
- if (current_el() == 3) {
- rk3568_lowlevel_init();
- rk3568_atf_load_bl31(fdt);
- /* not reached */
- }
-
- barebox_arm_entry(RK3568_DRAM_BOTTOM, 0x80000000 - RK3568_DRAM_BOTTOM, fdt);
-}
+ putc_ll('>');
-ENTRY_FUNCTION(start_rk3568_evb, r0, r1, r2)
-{
- /*
- * Image execution starts at 0x0, but this is used for ATF and
- * OP-TEE later, so move away from here.
- */
if (current_el() == 3)
relocate_to_adr_full(RK3568_BAREBOX_LOAD_ADDRESS);
else
@@ -49,5 +29,5 @@ ENTRY_FUNCTION(start_rk3568_evb, r0, r1, r2)
setup_c();
- rk3568_start();
+ rk3568_barebox_entry(__dtb_rk3568_evb1_v10_start);
}
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 0a7cceb461..220e1617e3 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -109,6 +109,7 @@ lwl-$(CONFIG_MACH_PROTONIC_STM32MP1) += \
stm32mp151-prtt1s.dtb.o
lwl-$(CONFIG_MACH_RADXA_ROCK) += rk3188-radxarock.dtb.o
lwl-$(CONFIG_MACH_RADXA_ROCK3) += rk3568-rock-3a.dtb.o
+lwl-$(CONFIG_MACH_RADXA_CM3) += rk3566-cm3-io.dtb.o
lwl-$(CONFIG_MACH_PHYTEC_SOM_RK3288) += rk3288-phycore-som.dtb.o
lwl-$(CONFIG_MACH_REALQ7) += imx6q-dmo-edmqmx6.dtb.o
lwl-$(CONFIG_MACH_RK3568_EVB) += rk3568-evb1-v10.dtb.o
diff --git a/arch/arm/dts/rk3566-cm3-io.dts b/arch/arm/dts/rk3566-cm3-io.dts
new file mode 100644
index 0000000000..39cef5e797
--- /dev/null
+++ b/arch/arm/dts/rk3566-cm3-io.dts
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <arm64/rockchip/rk3566-radxa-cm3-io.dts>
+#include "rk356x.dtsi"
+
+/ {
+ chosen: chosen {
+ environment-sd {
+ compatible = "barebox,environment";
+ device-path = &environment_sd;
+ status = "disabled";
+ };
+
+ environment-emmc {
+ compatible = "barebox,environment";
+ device-path = &environment_emmc;
+ status = "disabled";
+ };
+ };
+};
+
+&sdhci {
+ no-sd;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ environment_emmc: partition@408000 {
+ label = "barebox-environment";
+ reg = <0x0 0x408000 0x0 0x8000>;
+ };
+ };
+};
+
+&sdmmc0 {
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ environment_sd: partition@408000 {
+ label = "barebox-environment";
+ reg = <0x0 0x408000 0x0 0x8000>;
+ };
+ };
+};
diff --git a/arch/arm/dts/rk356x.dtsi b/arch/arm/dts/rk356x.dtsi
index 6a9cd14d2d..4de2404b50 100644
--- a/arch/arm/dts/rk356x.dtsi
+++ b/arch/arm/dts/rk356x.dtsi
@@ -6,4 +6,9 @@
barebox,bootsource-mmc1 = &sdmmc0;
barebox,bootsource-mmc2 = &sdmmc1;
};
+
+ dmc: memory-controller {
+ compatible = "rockchip,rk3568-dmc";
+ rockchip,pmu = <&pmugrf>;
+ };
};
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 9b4913d5da..0bce83ecee 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -91,6 +91,12 @@ config MACH_RADXA_ROCK3
help
Say Y here if you are using a Radxa ROCK3
+config MACH_RADXA_CM3
+ select ARCH_RK3568
+ bool "Radxa CM3"
+ help
+ Say Y here if you are using a Radxa CM3
+
endif
comment "select board features:"
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 2529af7c7e..04d75ce287 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -1,9 +1,10 @@
# SPDX-License-Identifier: GPL-2.0-only
-obj-y += rockchip.o
+obj-y += rockchip.o bootrom.o
pbl-$(CONFIG_ARCH_ROCKCHIP_ATF) += atf.o
obj-$(CONFIG_ARCH_RK3188) += rk3188.o
obj-$(CONFIG_ARCH_RK3288) += rk3288.o
obj-pbl-$(CONFIG_ARCH_RK3568) += rk3568.o
obj-$(CONFIG_ARCH_ROCKCHIP_V8) += bootm.o
+obj-pbl-$(CONFIG_ARCH_ROCKCHIP_V8) += dmc.o
obj-$(CONFIG_BAREBOX_UPDATE) += bbu.o
diff --git a/arch/arm/mach-rockchip/atf.c b/arch/arm/mach-rockchip/atf.c
index 93025faf68..d1431cc526 100644
--- a/arch/arm/mach-rockchip/atf.c
+++ b/arch/arm/mach-rockchip/atf.c
@@ -5,6 +5,11 @@
#include <mach/rockchip/atf.h>
#include <elf.h>
#include <asm/atf_common.h>
+#include <asm/barebox-arm.h>
+#include <mach/rockchip/dmc.h>
+#include <mach/rockchip/rockchip.h>
+#include <mach/rockchip/bootrom.h>
+#include <mach/rockchip/rk3568-regs.h>
static unsigned long load_elf64_image_phdr(const void *elf)
{
@@ -69,3 +74,32 @@ void rk3568_atf_load_bl31(void *fdt)
{
rockchip_atf_load_bl31(RK3568, rk3568_bl31_bin, rk3568_op_tee_bin, fdt);
}
+
+void __noreturn rk3568_barebox_entry(void *fdt)
+{
+ unsigned long membase, memsize;
+
+ membase = RK3568_DRAM_BOTTOM;
+ memsize = rk3568_ram0_size() - RK3568_DRAM_BOTTOM;
+
+ if (current_el() == 3) {
+ rk3568_lowlevel_init();
+ rockchip_store_bootrom_iram(membase, memsize, IOMEM(RK3568_IRAM_BASE));
+
+ /*
+ * The downstream TF-A doesn't cope with our device tree when
+ * CONFIG_OF_OVERLAY_LIVE is enabled, supposedly because it is
+ * too big for some reason. Otherwise it doesn't have any visible
+ * effect if we pass a device tree or not, except that the TF-A
+ * fills in the ethernet MAC address into the device tree.
+ * The upstream TF-A doesn't use the device tree at all.
+ *
+ * Pass NULL for now until we have a good reason to pass a real
+ * device tree.
+ */
+ rk3568_atf_load_bl31(NULL);
+ /* not reached when CONFIG_ARCH_ROCKCHIP_ATF */
+ }
+
+ barebox_arm_entry(membase, memsize, fdt);
+}
diff --git a/arch/arm/mach-rockchip/bootrom.c b/arch/arm/mach-rockchip/bootrom.c
new file mode 100644
index 0000000000..cdd0536cda
--- /dev/null
+++ b/arch/arm/mach-rockchip/bootrom.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <mach/rockchip/bootrom.h>
+#include <io.h>
+#include <bootsource.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <errno.h>
+
+#define BROM_BOOTSOURCE_ID 0x10
+#define BROM_BOOTSOURCE_SLOT 0x14
+#define BROM_BOOTSOURCE_SLOT_ACTIVE GENMASK(12, 10)
+
+static const void __iomem *rk_iram;
+
+int rockchip_bootsource_get_active_slot(void)
+{
+ if (!rk_iram)
+ return -EINVAL;
+
+ return FIELD_GET(BROM_BOOTSOURCE_SLOT_ACTIVE,
+ readl(IOMEM(rk_iram) + BROM_BOOTSOURCE_SLOT));
+}
+
+struct rk_bootsource {
+ enum bootsource src;
+ int instance;
+};
+
+static struct rk_bootsource bootdev_map[] = {
+ [0x1] = { .src = BOOTSOURCE_NAND, .instance = 0 },
+ [0x2] = { .src = BOOTSOURCE_MMC, .instance = 0 },
+ [0x3] = { .src = BOOTSOURCE_SPI_NOR, .instance = 0 },
+ [0x4] = { .src = BOOTSOURCE_SPI_NAND, .instance = 0 },
+ [0x5] = { .src = BOOTSOURCE_MMC, .instance = 1 },
+ [0xa] = { .src = BOOTSOURCE_USB, .instance = 0 },
+};
+
+void rockchip_parse_bootrom_iram(const void *iram)
+{
+ u32 v;
+
+ rk_iram = iram;
+
+ v = readl(iram + BROM_BOOTSOURCE_ID);
+
+ if (v >= ARRAY_SIZE(bootdev_map))
+ return;
+
+ bootsource_set(bootdev_map[v].src, bootdev_map[v].instance);
+}
diff --git a/arch/arm/mach-rockchip/dmc.c b/arch/arm/mach-rockchip/dmc.c
new file mode 100644
index 0000000000..dd60db5830
--- /dev/null
+++ b/arch/arm/mach-rockchip/dmc.c
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#define pr_fmt(fmt) "rockchip-dmc: " fmt
+
+#include <common.h>
+#include <init.h>
+#include <asm/barebox-arm.h>
+#include <asm/memory.h>
+#include <pbl.h>
+#include <io.h>
+#include <regmap.h>
+#include <mfd/syscon.h>
+#include <mach/rockchip/dmc.h>
+#include <mach/rockchip/rk3399-regs.h>
+#include <mach/rockchip/rk3568-regs.h>
+
+#define RK3399_PMUGRF_OS_REG2 0x308
+#define RK3399_PMUGRF_OS_REG3 0x30C
+
+#define RK3568_PMUGRF_OS_REG2 0x208
+#define RK3568_PMUGRF_OS_REG3 0x20c
+
+#define RK3399_INT_REG_START 0xf0000000
+#define RK3568_INT_REG_START RK3399_INT_REG_START
+
+struct rockchip_dmc_drvdata {
+ unsigned int os_reg2;
+ unsigned int os_reg3;
+ resource_size_t internal_registers_start;
+};
+
+static resource_size_t rockchip_sdram_size(u32 sys_reg2, u32 sys_reg3)
+{
+ u32 rank, cs0_col, bk, cs0_row, cs1_row, bw, row_3_4;
+ resource_size_t chipsize_mb, size_mb = 0;
+ u32 ch;
+ u32 cs1_col;
+ u32 bg = 0;
+ u32 dbw, dram_type;
+ u32 ch_num = 1 + FIELD_GET(SYS_REG_NUM_CH, sys_reg2);
+ u32 version = FIELD_GET(SYS_REG_VERSION, sys_reg3);
+
+ pr_debug("%s(reg2=%x, reg3=%x)\n", __func__, sys_reg2, sys_reg3);
+
+ dram_type = FIELD_GET(SYS_REG_DDRTYPE, sys_reg2);
+
+ if (version >= 3)
+ dram_type |= FIELD_GET(SYS_REG_EXTEND_DDRTYPE, sys_reg3) << 3;
+
+ for (ch = 0; ch < ch_num; ch++) {
+ rank = 1 + (sys_reg2 >> SYS_REG_RANK_SHIFT(ch) & SYS_REG_RANK_MASK);
+ cs0_col = 9 + (sys_reg2 >> SYS_REG_COL_SHIFT(ch) & SYS_REG_COL_MASK);
+ cs1_col = cs0_col;
+
+ bk = 3 - ((sys_reg2 >> SYS_REG_BK_SHIFT(ch)) & SYS_REG_BK_MASK);
+
+ cs0_row = sys_reg2 >> SYS_REG_CS0_ROW_SHIFT(ch) & SYS_REG_CS0_ROW_MASK;
+ cs1_row = sys_reg2 >> SYS_REG_CS1_ROW_SHIFT(ch) & SYS_REG_CS1_ROW_MASK;
+
+ if (version >= 2) {
+ cs1_col = 9 + (sys_reg3 >> SYS_REG_CS1_COL_SHIFT(ch) &
+ SYS_REG_CS1_COL_MASK);
+
+ cs0_row |= (sys_reg3 >> SYS_REG_EXTEND_CS0_ROW_SHIFT(ch) &
+ SYS_REG_EXTEND_CS0_ROW_MASK) << 2;
+
+ if (cs0_row == 7)
+ cs0_row = 12;
+ else
+ cs0_row += 13;
+
+ cs1_row |= (sys_reg3 >> SYS_REG_EXTEND_CS1_ROW_SHIFT(ch) &
+ SYS_REG_EXTEND_CS1_ROW_MASK) << 2;
+
+ if (cs1_row == 7)
+ cs1_row = 12;
+ else
+ cs1_row += 13;
+ } else {
+ cs0_row += 13;
+ cs1_row += 13;
+ }
+
+ bw = (2 >> ((sys_reg2 >> SYS_REG_BW_SHIFT(ch)) & SYS_REG_BW_MASK));
+ row_3_4 = sys_reg2 >> SYS_REG_ROW_3_4_SHIFT(ch) & SYS_REG_ROW_3_4_MASK;
+
+ if (dram_type == DDR4) {
+ dbw = (sys_reg2 >> SYS_REG_DBW_SHIFT(ch)) & SYS_REG_DBW_MASK;
+ bg = (dbw == 2) ? 2 : 1;
+ }
+
+ chipsize_mb = (1 << (cs0_row + cs0_col + bk + bg + bw - 20));
+
+ if (rank > 1)
+ chipsize_mb += chipsize_mb >> ((cs0_row - cs1_row) +
+ (cs0_col - cs1_col));
+ if (row_3_4)
+ chipsize_mb = chipsize_mb * 3 / 4;
+
+ size_mb += chipsize_mb;
+
+ if (rank > 1)
+ pr_debug("rank %d cs0_col %d cs1_col %d bk %d cs0_row %d "
+ "cs1_row %d bw %d row_3_4 %d\n",
+ rank, cs0_col, cs1_col, bk, cs0_row,
+ cs1_row, bw, row_3_4);
+ else
+ pr_debug("rank %d cs0_col %d bk %d cs0_row %d "
+ "bw %d row_3_4 %d\n",
+ rank, cs0_col, bk, cs0_row,
+ bw, row_3_4);
+ }
+
+ return (resource_size_t)size_mb << 20;
+}
+
+resource_size_t rk3399_ram0_size(void)
+{
+ void __iomem *pmugrf = IOMEM(RK3399_PMUGRF_BASE);
+ u32 sys_reg2, sys_reg3;
+ resource_size_t size;
+
+ sys_reg2 = readl(pmugrf + RK3399_PMUGRF_OS_REG2);
+ sys_reg3 = readl(pmugrf + RK3399_PMUGRF_OS_REG3);
+
+ size = rockchip_sdram_size(sys_reg2, sys_reg3);
+ size = min_t(resource_size_t, RK3399_INT_REG_START, size);
+
+ pr_debug("%s() = %llu\n", __func__, (u64)size);
+
+ return size;
+}
+
+resource_size_t rk3568_ram0_size(void)
+{
+ void __iomem *pmugrf = IOMEM(RK3568_PMUGRF_BASE);
+ u32 sys_reg2, sys_reg3;
+ resource_size_t size;
+
+ sys_reg2 = readl(pmugrf + RK3568_PMUGRF_OS_REG2);
+ sys_reg3 = readl(pmugrf + RK3568_PMUGRF_OS_REG3);
+
+ size = rockchip_sdram_size(sys_reg2, sys_reg3);
+ size = min_t(resource_size_t, RK3568_INT_REG_START, size);
+
+ pr_debug("%s() = %llu\n", __func__, (u64)size);
+
+ return size;
+}
+
+static int rockchip_dmc_probe(struct device *dev)
+{
+ const struct rockchip_dmc_drvdata *drvdata;
+ resource_size_t membase, memsize;
+ struct regmap *regmap;
+ u32 sys_reg2, sys_reg3;
+
+ regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pmu");
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ drvdata = device_get_match_data(dev);
+ if (!drvdata)
+ return -ENOENT;
+
+ regmap_read(regmap, drvdata->os_reg2, &sys_reg2);
+ regmap_read(regmap, drvdata->os_reg3, &sys_reg3);
+
+ memsize = rockchip_sdram_size(sys_reg2, sys_reg3);
+
+ dev_info(dev, "Detected memory size: %pa\n", &memsize);
+
+ /* lowest 10M are shaved off for secure world firmware */
+ membase = 0xa00000;
+
+ /* ram0, from 0xa00000 up to SoC internal register space start */
+ arm_add_mem_device("ram0", membase,
+ min_t(resource_size_t, drvdata->internal_registers_start, memsize) - membase);
+
+ /* ram1, remaining RAM beyond 32bit space */
+ if (memsize > SZ_4G)
+ arm_add_mem_device("ram1", SZ_4G, memsize - SZ_4G);
+
+ return 0;
+}
+
+static const struct rockchip_dmc_drvdata rk3399_drvdata = {
+ .os_reg2 = RK3399_PMUGRF_OS_REG2,
+ .os_reg3 = RK3399_PMUGRF_OS_REG3,
+ .internal_registers_start = RK3399_INT_REG_START,
+};
+
+static const struct rockchip_dmc_drvdata rk3568_drvdata = {
+ .os_reg2 = RK3568_PMUGRF_OS_REG2,
+ .os_reg3 = RK3568_PMUGRF_OS_REG3,
+ .internal_registers_start = RK3568_INT_REG_START,
+};
+
+static struct of_device_id rockchip_dmc_dt_ids[] = {
+ {
+ .compatible = "rockchip,rk3399-dmc",
+ .data = &rk3399_drvdata,
+ },
+ {
+ .compatible = "rockchip,rk3568-dmc",
+ .data = &rk3568_drvdata,
+ },
+ { /* sentinel */ }
+};
+
+static struct driver rockchip_dmc_driver = {
+ .name = "rockchip-dmc",
+ .probe = rockchip_dmc_probe,
+ .of_compatible = rockchip_dmc_dt_ids,
+};
+mem_platform_driver(rockchip_dmc_driver);
diff --git a/arch/arm/mach-rockchip/rk3568.c b/arch/arm/mach-rockchip/rk3568.c
index 39bd4772a6..c0453ea0c4 100644
--- a/arch/arm/mach-rockchip/rk3568.c
+++ b/arch/arm/mach-rockchip/rk3568.c
@@ -2,6 +2,7 @@
#include <common.h>
#include <io.h>
#include <bootsource.h>
+#include <mach/rockchip/bootrom.h>
#include <mach/rockchip/rk3568-regs.h>
#include <mach/rockchip/rockchip.h>
@@ -137,35 +138,9 @@ void rk3568_lowlevel_init(void)
qos_priority_init();
}
-struct rk_bootsource {
- enum bootsource src;
- int instance;
-};
-
-static struct rk_bootsource bootdev_map[] = {
- [0x1] = { .src = BOOTSOURCE_NAND, .instance = 0 },
- [0x2] = { .src = BOOTSOURCE_MMC, .instance = 0 },
- [0x3] = { .src = BOOTSOURCE_SPI_NOR, .instance = 0 },
- [0x4] = { .src = BOOTSOURCE_SPI_NAND, .instance = 0 },
- [0x5] = { .src = BOOTSOURCE_MMC, .instance = 1 },
- [0xa] = { .src = BOOTSOURCE_USB, .instance = 0 },
-};
-
-static void rk3568_bootsource(void)
-{
- u32 v;
-
- v = readl(RK3568_IRAM_BASE + 0x10);
-
- if (v >= ARRAY_SIZE(bootdev_map))
- return;
-
- bootsource_set(bootdev_map[v].src, bootdev_map[v].instance);
-}
-
int rk3568_init(void)
{
- rk3568_bootsource();
+ rockchip_parse_bootrom_iram(rockchip_scratch_space());
return 0;
}
diff --git a/images/Makefile.rockchip b/images/Makefile.rockchip
index 33c76caf79..490e1ddb4d 100644
--- a/images/Makefile.rockchip
+++ b/images/Makefile.rockchip
@@ -23,6 +23,9 @@ image-$(CONFIG_MACH_PINE64_QUARTZ64) += barebox-quartz64a.img
pblb-$(CONFIG_MACH_RADXA_ROCK3) += start_rock3a
image-$(CONFIG_MACH_RADXA_ROCK3) += barebox-rock3a.img
+pblb-$(CONFIG_MACH_RADXA_CM3) += start_radxa-cm3-io.img
+image-$(CONFIG_MACH_RADXA_CM3) += barebox-radxa-cm3-io.img
+
quiet_cmd_rkimg_image = RK-IMG $@
cmd_rkimg_image = $(objtree)/scripts/rkimage -o $@ $(word 2,$^) $(word 1,$^)
@@ -41,3 +44,7 @@ $(obj)/barebox-quartz64a.img: $(obj)/start_quartz64a.pblb \
$(obj)/barebox-rock3a.img: $(obj)/start_rock3a.pblb \
$(board)/radxa-rock3/sdram-init.bin
$(call if_changed,rkimg_image)
+
+$(obj)/barebox-radxa-cm3-io.img: $(obj)/start_radxa_cm3_io.pblb \
+ $(board)/radxa-cm3/sdram-init.bin
+ $(call if_changed,rkimg_image)
diff --git a/include/bootsource.h b/include/bootsource.h
index 05935b64a7..f2ab3a2ad4 100644
--- a/include/bootsource.h
+++ b/include/bootsource.h
@@ -26,6 +26,7 @@ enum bootsource {
#define BOOTSOURCE_INSTANCE_UNKNOWN -1
enum bootsource bootsource_get(void);
+enum bootsource bootsource_get_device(void);
int bootsource_get_instance(void);
void bootsource_set_alias_name(const char *name);
char *bootsource_get_alias_name(void);
diff --git a/include/linux/sizes.h b/include/linux/sizes.h
index fbde0bc7e8..1d222daeab 100644
--- a/include/linux/sizes.h
+++ b/include/linux/sizes.h
@@ -47,5 +47,8 @@
#define SZ_2G 0x80000000
#define SZ_4G _AC(0x100000000, ULL)
+#define SZ_8G _AC(0x200000000, ULL)
+#define SZ_16G _AC(0x400000000, ULL)
+#define SZ_32G _AC(0x800000000, ULL)
#endif /* __LINUX_SIZES_H__ */
diff --git a/include/mach/rockchip/atf.h b/include/mach/rockchip/atf.h
index e5d55af3d7..e1e68825d1 100644
--- a/include/mach/rockchip/atf.h
+++ b/include/mach/rockchip/atf.h
@@ -28,4 +28,6 @@ static inline void rk3568_atf_load_bl31(void *fdt) { }
#endif
#endif
+void __noreturn rk3568_barebox_entry(void *fdt);
+
#endif /* __MACH_ATF_H */
diff --git a/include/mach/rockchip/bootrom.h b/include/mach/rockchip/bootrom.h
new file mode 100644
index 0000000000..96eb147ae4
--- /dev/null
+++ b/include/mach/rockchip/bootrom.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __MACH_ROCKCHIP_BOOTROM_H
+#define __MACH_ROCKCHIP_BOOTROM_H
+
+#include <linux/compiler.h>
+#include <linux/string.h>
+#include <asm/barebox-arm.h>
+
+struct rockchip_scratch_space {
+ u32 irom[16];
+};
+
+static inline void rockchip_store_bootrom_iram(ulong membase,
+ ulong memsize,
+ const void *iram)
+{
+ void *dst = (void *)__arm_mem_scratch(membase + memsize);
+ memcpy(dst, iram, sizeof(struct rockchip_scratch_space));
+}
+
+static inline const struct rockchip_scratch_space *rockchip_scratch_space(void)
+{
+ return arm_mem_scratch_get();
+}
+
+void rockchip_parse_bootrom_iram(const void *iram);
+
+int rockchip_bootsource_get_active_slot(void);
+
+
+#endif
diff --git a/include/mach/rockchip/dmc.h b/include/mach/rockchip/dmc.h
new file mode 100644
index 0000000000..ff197d50a0
--- /dev/null
+++ b/include/mach/rockchip/dmc.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef _MACH_ROCKCHIP_DMC_H
+#define _MACH_ROCKCHIP_DMC_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <linux/bitfield.h>
+
+enum {
+ DDR4 = 0,
+ DDR3 = 0x3,
+ LPDDR2 = 0x5,
+ LPDDR3 = 0x6,
+ LPDDR4 = 0x7,
+ UNUSED = 0xFF
+};
+
+/*
+ * sys_reg2 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] low bits of cs0_row_ch1
+ * [21:20] low bits of 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] low bits of cs0_row_ch0
+ * [5:4] low bits of cs1_row_ch0
+ * [3:2] bw_ch0
+ * [1:0] dbw_ch0
+ */
+
+#define SYS_REG_DDRTYPE GENMASK(15, 13)
+#define SYS_REG_NUM_CH BIT(12)
+#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
+
+/*
+ * sys_reg3 bitfield struct
+ * [7] high bit of cs0_row_ch1
+ * [6] high bit of cs1_row_ch1
+ * [5] high bit of cs0_row_ch0
+ * [4] high bit of cs1_row_ch0
+ * [3:2] cs1_col_ch1
+ * [1:0] cs1_col_ch0
+ */
+#define SYS_REG_VERSION GENMASK(31, 28)
+#define SYS_REG_EXTEND_DDRTYPE GENMASK(13, 12)
+#define SYS_REG_EXTEND_CS0_ROW_SHIFT(ch) (5 + (ch) * 2)
+#define SYS_REG_EXTEND_CS0_ROW_MASK 1
+#define SYS_REG_EXTEND_CS1_ROW_SHIFT(ch) (4 + (ch) * 2)
+#define SYS_REG_EXTEND_CS1_ROW_MASK 1
+#define SYS_REG_CS1_COL_SHIFT(ch) (0 + (ch) * 2)
+#define SYS_REG_CS1_COL_MASK 3
+
+resource_size_t rk3399_ram0_size(void);
+resource_size_t rk3568_ram0_size(void);
+
+#endif
diff --git a/include/mach/rockchip/rk3399-regs.h b/include/mach/rockchip/rk3399-regs.h
index 57033b6510..6db082da9b 100644
--- a/include/mach/rockchip/rk3399-regs.h
+++ b/include/mach/rockchip/rk3399-regs.h
@@ -10,6 +10,7 @@
#define RK3399_UART3_BASE 0xff1b0000
#define RK3399_UART4_BASE 0xff370000
+#define RK3399_PMUGRF_BASE 0xff320000
#define RK3399_IRAM_BASE 0xff8c0000
#define RK3399_STIMER_BASE 0xff8680a0
diff --git a/include/mach/rockchip/rk3568-regs.h b/include/mach/rockchip/rk3568-regs.h
index edd5ee268d..55d28790dd 100644
--- a/include/mach/rockchip/rk3568-regs.h
+++ b/include/mach/rockchip/rk3568-regs.h
@@ -16,5 +16,6 @@
#define RK3568_UART9_BASE 0xfe6d0000
#define RK3568_IRAM_BASE 0xfdcc0000
+#define RK3568_PMUGRF_BASE 0xfdc20000
#endif /* __MACH_RK3568_REGS_H */