Merge tag 'rpi-next-2020.01' of https://github.com/mbgg/u-boot

- add RPi4 upstream compatible to pinctrl
- fix boot banner on RPi3/4
- add support for one binary on RPi3/4
diff --git a/arch/arm/dts/bcm283x-uboot.dtsi b/arch/arm/dts/bcm283x-u-boot.dtsi
similarity index 90%
rename from arch/arm/dts/bcm283x-uboot.dtsi
rename to arch/arm/dts/bcm283x-u-boot.dtsi
index 6cc1aa3..36548da 100644
--- a/arch/arm/dts/bcm283x-uboot.dtsi
+++ b/arch/arm/dts/bcm283x-u-boot.dtsi
@@ -6,10 +6,6 @@
  * (C) Copyright 2016 Fabian Vogt <fvogt@suse.com>
  */
 
-&soc {
-	u-boot,dm-pre-reloc;
-};
-
 &uart0 {
 	skip-init;
 	u-boot,dm-pre-reloc;
diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig
index b08275f..00419bf 100644
--- a/arch/arm/mach-bcm283x/Kconfig
+++ b/arch/arm/mach-bcm283x/Kconfig
@@ -188,6 +188,13 @@
 	  This option creates a build targeting the ARMv8/AArch64 ISA.
 	select BCM2711_64B
 
+config TARGET_RPI_ARM64
+	bool "Raspberry Pi one binary 64-bit build"
+	help
+	  Support for all armv8 based Raspberry Pi variants, such as
+	  the RPi 4 model B, in AArch64 (64-bit) mode.
+	select ARM64
+
 endchoice
 
 config SYS_BOARD
@@ -202,10 +209,4 @@
 config SYS_CONFIG_NAME
 	default "rpi"
 
-config BCM283x_BASE
-	hex
-	default "0x20000000" if BCM2835
-	default "0x3f000000" if BCM2836 || BCM2837
-	default "0xfe000000" if BCM2711
-
 endmenu
diff --git a/arch/arm/mach-bcm283x/include/mach/base.h b/arch/arm/mach-bcm283x/include/mach/base.h
new file mode 100644
index 0000000..c4ae398
--- /dev/null
+++ b/arch/arm/mach-bcm283x/include/mach/base.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * (C) Copyright 2019 Matthias Brugger
+ */
+
+#ifndef _BCM283x_BASE_H_
+#define _BCM283x_BASE_H_
+
+extern unsigned long rpi_bcm283x_base;
+
+#endif
diff --git a/arch/arm/mach-bcm283x/include/mach/mbox.h b/arch/arm/mach-bcm283x/include/mach/mbox.h
index 0b6c254..60e226c 100644
--- a/arch/arm/mach-bcm283x/include/mach/mbox.h
+++ b/arch/arm/mach-bcm283x/include/mach/mbox.h
@@ -7,6 +7,7 @@
 #define _BCM2835_MBOX_H
 
 #include <linux/compiler.h>
+#include <asm/arch/base.h>
 
 /*
  * The BCM2835 SoC contains (at least) two CPUs; the VideoCore (a/k/a "GPU")
@@ -37,7 +38,8 @@
 
 /* Raw mailbox HW */
 
-#define BCM2835_MBOX_PHYSADDR	(CONFIG_BCM283x_BASE + 0x0000b880)
+#define BCM2835_MBOX_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \
+				 rpi_bcm283x_base + 0x0000b880; })
 
 struct bcm2835_mbox_regs {
 	u32 read;
diff --git a/arch/arm/mach-bcm283x/include/mach/sdhci.h b/arch/arm/mach-bcm283x/include/mach/sdhci.h
index b443c37..7323690 100644
--- a/arch/arm/mach-bcm283x/include/mach/sdhci.h
+++ b/arch/arm/mach-bcm283x/include/mach/sdhci.h
@@ -6,7 +6,10 @@
 #ifndef _BCM2835_SDHCI_H_
 #define _BCM2835_SDHCI_H_
 
-#define BCM2835_SDHCI_BASE (CONFIG_BCM283x_BASE + 0x00300000)
+#include <asm/arch/base.h>
+
+#define BCM2835_SDHCI_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \
+				  rpi_bcm283x_base + 0x00300000; })
 
 int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq);
 
diff --git a/arch/arm/mach-bcm283x/include/mach/timer.h b/arch/arm/mach-bcm283x/include/mach/timer.h
index 61beb1a..01c0eba 100644
--- a/arch/arm/mach-bcm283x/include/mach/timer.h
+++ b/arch/arm/mach-bcm283x/include/mach/timer.h
@@ -6,7 +6,12 @@
 #ifndef _BCM2835_TIMER_H
 #define _BCM2835_TIMER_H
 
-#define BCM2835_TIMER_PHYSADDR	(CONFIG_BCM283x_BASE + 0x00003000)
+#ifndef __ASSEMBLY__
+#include <asm/arch/base.h>
+#endif
+
+#define BCM2835_TIMER_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \
+				  rpi_bcm283x_base + 0x00003000; })
 
 #define BCM2835_TIMER_CS_M3	(1 << 3)
 #define BCM2835_TIMER_CS_M2	(1 << 2)
diff --git a/arch/arm/mach-bcm283x/include/mach/wdog.h b/arch/arm/mach-bcm283x/include/mach/wdog.h
index 8292b3c..9942666 100644
--- a/arch/arm/mach-bcm283x/include/mach/wdog.h
+++ b/arch/arm/mach-bcm283x/include/mach/wdog.h
@@ -6,7 +6,10 @@
 #ifndef _BCM2835_WDOG_H
 #define _BCM2835_WDOG_H
 
-#define BCM2835_WDOG_PHYSADDR	(CONFIG_BCM283x_BASE + 0x00100000)
+#include <asm/arch/base.h>
+
+#define BCM2835_WDOG_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \
+				 rpi_bcm283x_base + 0x00100000; })
 
 struct bcm2835_wdog_regs {
 	u32 unknown0[7];
diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c
index 9741441..6fb41a9 100644
--- a/arch/arm/mach-bcm283x/init.c
+++ b/arch/arm/mach-bcm283x/init.c
@@ -7,6 +7,100 @@
  */
 
 #include <common.h>
+#include <dm/device.h>
+#include <fdt_support.h>
+
+#ifdef CONFIG_ARM64
+#include <asm/armv8/mmu.h>
+
+static struct mm_region bcm283x_mem_map[] = {
+	{
+		.virt = 0x00000000UL,
+		.phys = 0x00000000UL,
+		.size = 0x3f000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			 PTE_BLOCK_INNER_SHARE
+	}, {
+		.virt = 0x3f000000UL,
+		.phys = 0x3f000000UL,
+		.size = 0x01000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* List terminator */
+		0,
+	}
+};
+
+static struct mm_region bcm2711_mem_map[] = {
+	{
+		.virt = 0x00000000UL,
+		.phys = 0x00000000UL,
+		.size = 0xfe000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			 PTE_BLOCK_INNER_SHARE
+	}, {
+		.virt = 0xfe000000UL,
+		.phys = 0xfe000000UL,
+		.size = 0x01800000UL,
+		.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 = bcm283x_mem_map;
+
+/*
+ * I/O address space varies on different chip versions.
+ * We set the base address by inspecting the DTB.
+ */
+static const struct udevice_id board_ids[] = {
+	{ .compatible = "brcm,bcm2837", .data = (ulong)&bcm283x_mem_map},
+	{ .compatible = "brcm,bcm2838", .data = (ulong)&bcm2711_mem_map},
+	{ .compatible = "brcm,bcm2711", .data = (ulong)&bcm2711_mem_map},
+	{ },
+};
+
+static void _rpi_update_mem_map(struct mm_region *pd)
+{
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		mem_map[i].virt = pd[i].virt;
+		mem_map[i].phys = pd[i].phys;
+		mem_map[i].size = pd[i].size;
+		mem_map[i].attrs = pd[i].attrs;
+	}
+}
+
+static void rpi_update_mem_map(void)
+{
+	int ret;
+	struct mm_region *mm;
+	const struct udevice_id *of_match = board_ids;
+
+	while (of_match->compatible) {
+		ret = fdt_node_check_compatible(gd->fdt_blob, 0,
+						of_match->compatible);
+		if (!ret) {
+			mm = (struct mm_region *)of_match->data;
+			_rpi_update_mem_map(mm);
+			break;
+		}
+
+		of_match++;
+	}
+}
+#else
+static void rpi_update_mem_map(void) {}
+#endif
+
+unsigned long rpi_bcm283x_base = 0x3f000000;
 
 int arch_cpu_init(void)
 {
@@ -15,6 +109,28 @@
 	return 0;
 }
 
+int mach_cpu_init(void)
+{
+	int ret, soc_offset;
+	u64 io_base, size;
+
+	rpi_update_mem_map();
+
+	/* Get IO base from device tree */
+	soc_offset = fdt_path_offset(gd->fdt_blob, "/soc");
+	if (soc_offset < 0)
+		return soc_offset;
+
+	ret = fdt_read_range((void *)gd->fdt_blob, soc_offset, 0, NULL,
+				&io_base, &size);
+	if (ret)
+		return ret;
+
+	rpi_bcm283x_base = io_base;
+
+	return 0;
+}
+
 #ifdef CONFIG_ARMV7_LPAE
 void enable_caches(void)
 {
diff --git a/arch/arm/mach-bcm283x/mbox.c b/arch/arm/mach-bcm283x/mbox.c
index 3c67f68..467d0d5 100644
--- a/arch/arm/mach-bcm283x/mbox.c
+++ b/arch/arm/mach-bcm283x/mbox.c
@@ -5,6 +5,7 @@
 
 #include <common.h>
 #include <asm/io.h>
+#include <asm/arch/base.h>
 #include <asm/arch/mbox.h>
 #include <phys2bus.h>
 
diff --git a/arch/arm/mach-bcm283x/reset.c b/arch/arm/mach-bcm283x/reset.c
index b3da0c7..cd8138d 100644
--- a/arch/arm/mach-bcm283x/reset.c
+++ b/arch/arm/mach-bcm283x/reset.c
@@ -8,6 +8,7 @@
 
 #include <common.h>
 #include <asm/io.h>
+#include <asm/arch/base.h>
 #include <asm/arch/wdog.h>
 #include <efi_loader.h>
 
@@ -25,10 +26,10 @@
 
 void hw_watchdog_disable(void) {}
 
-__efi_runtime_data struct bcm2835_wdog_regs *wdog_regs =
-	(struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR;
+__efi_runtime_data struct bcm2835_wdog_regs *wdog_regs;
 
-void __efi_runtime reset_cpu(ulong ticks)
+static void __efi_runtime
+__reset_cpu(struct bcm2835_wdog_regs *wdog_regs, ulong ticks)
 {
 	uint32_t rstc, timeout;
 
@@ -46,6 +47,14 @@
 	writel(BCM2835_WDOG_PASSWORD | rstc, &wdog_regs->rstc);
 }
 
+void reset_cpu(ulong ticks)
+{
+	struct bcm2835_wdog_regs *regs =
+		(struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR;
+
+	__reset_cpu(regs, 0);
+}
+
 #ifdef CONFIG_EFI_LOADER
 
 void __efi_runtime EFIAPI efi_reset_system(
@@ -58,7 +67,7 @@
 	if (reset_type == EFI_RESET_COLD ||
 	    reset_type == EFI_RESET_WARM ||
 	    reset_type == EFI_RESET_PLATFORM_SPECIFIC) {
-		reset_cpu(0);
+		__reset_cpu(wdog_regs, 0);
 	} else if (reset_type == EFI_RESET_SHUTDOWN) {
 		/*
 		 * We set the watchdog hard reset bit here to distinguish this reset
@@ -69,7 +78,7 @@
 		val |= BCM2835_WDOG_PASSWORD;
 		val |= BCM2835_WDOG_RSTS_RASPBERRYPI_HALT;
 		writel(val, &wdog_regs->rsts);
-		reset_cpu(0);
+		__reset_cpu(wdog_regs, 0);
 	}
 
 	while (1) { }
@@ -77,6 +86,7 @@
 
 efi_status_t efi_reset_system_init(void)
 {
+	wdog_regs = (struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR;
 	return efi_add_runtime_mmio(&wdog_regs, sizeof(*wdog_regs));
 }
 
diff --git a/board/raspberrypi/rpi/lowlevel_init.S b/board/raspberrypi/rpi/lowlevel_init.S
index 435eed5..8c39b3e 100644
--- a/board/raspberrypi/rpi/lowlevel_init.S
+++ b/board/raspberrypi/rpi/lowlevel_init.S
@@ -6,15 +6,6 @@
 
 #include <config.h>
 
-.align 8
-.global fw_dtb_pointer
-fw_dtb_pointer:
-#ifdef CONFIG_ARM64
-	.dword 0x0
-#else
-	.word 0x0
-#endif
-
 /*
  * Routine: save_boot_params (called after reset from start.S)
  * Description: save ATAG/FDT address provided by the firmware at boot time
@@ -28,7 +19,8 @@
 	adr	x8, fw_dtb_pointer
 	str	x0, [x8]
 #else
-	str	r2, fw_dtb_pointer
+	ldr	r8, =fw_dtb_pointer
+	str	r2, [r8]
 #endif
 
 	/* Returns */
diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index 9e0abdd..3d4afaf 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -27,8 +27,11 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* From lowlevel_init.S */
-extern unsigned long fw_dtb_pointer;
+/* Assigned in lowlevel_init.S
+ * Push the variable into the .data section so that it
+ * does not get cleared later.
+ */
+unsigned long __section(".data") fw_dtb_pointer;
 
 /* TODO(sjg@chromium.org): Move these to the msg.c file */
 struct msg_get_arm_mem {
@@ -248,51 +251,6 @@
 static uint32_t rev_type;
 static const struct rpi_model *model;
 
-#ifdef CONFIG_ARM64
-#ifndef CONFIG_BCM2711
-static struct mm_region bcm283x_mem_map[] = {
-	{
-		.virt = 0x00000000UL,
-		.phys = 0x00000000UL,
-		.size = 0x3f000000UL,
-		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
-			 PTE_BLOCK_INNER_SHARE
-	}, {
-		.virt = 0x3f000000UL,
-		.phys = 0x3f000000UL,
-		.size = 0x01000000UL,
-		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
-			 PTE_BLOCK_NON_SHARE |
-			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
-	}, {
-		/* List terminator */
-		0,
-	}
-};
-#else
-static struct mm_region bcm283x_mem_map[] = {
-	{
-		.virt = 0x00000000UL,
-		.phys = 0x00000000UL,
-		.size = 0xfe000000UL,
-		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
-			 PTE_BLOCK_INNER_SHARE
-	}, {
-		.virt = 0xfe000000UL,
-		.phys = 0xfe000000UL,
-		.size = 0x01800000UL,
-		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
-			 PTE_BLOCK_NON_SHARE |
-			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
-	}, {
-		/* List terminator */
-		0,
-	}
-};
-#endif
-struct mm_region *mem_map = bcm283x_mem_map;
-#endif
-
 int dram_init(void)
 {
 	ALLOC_CACHE_ALIGN_BUFFER(struct msg_get_arm_mem, msg, 1);
diff --git a/configs/rpi_arm64_defconfig b/configs/rpi_arm64_defconfig
new file mode 100644
index 0000000..f4e113f
--- /dev/null
+++ b/configs/rpi_arm64_defconfig
@@ -0,0 +1,45 @@
+CONFIG_ARM=y
+CONFIG_ARM64=y
+CONFIG_TARGET_RPI_ARM64=y
+CONFIG_ARCH_BCM283X=y
+CONFIG_SYS_TEXT_BASE=0x00080000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_USE_PREBOOT=y
+CONFIG_PREBOOT="usb start"
+CONFIG_MISC_INIT_R=y
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_SYS_PROMPT="U-Boot> "
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_FS_UUID=y
+CONFIG_OF_BOARD=y
+CONFIG_ENV_FAT_INTERFACE="mmc"
+CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_DM_KEYBOARD=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_BCM2835=y
+CONFIG_PHYLIB=y
+CONFIG_DM_ETH=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_GENERIC is not set
+# CONFIG_REQUIRE_SERIAL_CONSOLE is not set
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_USB_HOST_ETHER=y
+CONFIG_USB_ETHER_LAN78XX=y
+CONFIG_USB_ETHER_SMSC95XX=y
+CONFIG_DM_VIDEO=y
+CONFIG_SYS_WHITE_ON_BLACK=y
+CONFIG_CONSOLE_SCROLL_LINES=10
+CONFIG_PHYS_TO_BUS=y
+CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/drivers/pinctrl/broadcom/pinctrl-bcm283x.c b/drivers/pinctrl/broadcom/pinctrl-bcm283x.c
index 3be080d..eb720f0 100644
--- a/drivers/pinctrl/broadcom/pinctrl-bcm283x.c
+++ b/drivers/pinctrl/broadcom/pinctrl-bcm283x.c
@@ -99,6 +99,7 @@
 
 static const struct udevice_id bcm2835_pinctrl_id[] = {
 	{.compatible = "brcm,bcm2835-gpio"},
+	{.compatible = "brcm,bcm2711-gpio"},
 	{}
 };
 
@@ -148,7 +149,7 @@
 	.priv_auto_alloc_size = sizeof(struct bcm283x_pinctrl_priv),
 	.ops		= &bcm283x_pinctrl_ops,
 	.probe		= bcm283x_pinctl_probe,
-#if !CONFIG_IS_ENABLED(OF_CONTROL)
+#if !CONFIG_IS_ENABLED(OF_CONTROL) || CONFIG_IS_ENABLED(OF_BOARD)
 	.flags		= DM_FLAG_PRE_RELOC,
 #endif
 };
diff --git a/drivers/serial/serial_bcm283x_mu.c b/drivers/serial/serial_bcm283x_mu.c
index bd1d89e..a6ffc84 100644
--- a/drivers/serial/serial_bcm283x_mu.c
+++ b/drivers/serial/serial_bcm283x_mu.c
@@ -199,7 +199,7 @@
 	.platdata_auto_alloc_size = sizeof(struct bcm283x_mu_serial_platdata),
 	.probe = bcm283x_mu_serial_probe,
 	.ops = &bcm283x_mu_serial_ops,
-#if !CONFIG_IS_ENABLED(OF_CONTROL)
+#if !CONFIG_IS_ENABLED(OF_CONTROL) || CONFIG_IS_ENABLED(OF_BOARD)
 	.flags = DM_FLAG_PRE_RELOC,
 #endif
 	.priv_auto_alloc_size = sizeof(struct bcm283x_mu_priv),
diff --git a/drivers/serial/serial_bcm283x_pl011.c b/drivers/serial/serial_bcm283x_pl011.c
index 2527bb8..7d8ab7b 100644
--- a/drivers/serial/serial_bcm283x_pl011.c
+++ b/drivers/serial/serial_bcm283x_pl011.c
@@ -90,7 +90,7 @@
 	.platdata_auto_alloc_size = sizeof(struct pl01x_serial_platdata),
 	.probe	= pl01x_serial_probe,
 	.ops	= &bcm283x_pl011_serial_ops,
-#if !CONFIG_IS_ENABLED(OF_CONTROL)
+#if !CONFIG_IS_ENABLED(OF_CONTROL) || CONFIG_IS_ENABLED(OF_BOARD)
 	.flags	= DM_FLAG_PRE_RELOC,
 #endif
 	.priv_auto_alloc_size = sizeof(struct pl01x_priv),
diff --git a/include/configs/rpi.h b/include/configs/rpi.h
index c03bad8..83e258a 100644
--- a/include/configs/rpi.h
+++ b/include/configs/rpi.h
@@ -9,6 +9,10 @@
 #include <linux/sizes.h>
 #include <asm/arch/timer.h>
 
+#ifndef __ASSEMBLY__
+#include <asm/arch/base.h>
+#endif
+
 #if defined(CONFIG_TARGET_RPI_2) || defined(CONFIG_TARGET_RPI_3_32B)
 #define CONFIG_SKIP_LOWLEVEL_INIT
 #endif