All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Fitzsimmons <fitzsim@fitzsim.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 1/1] board: arm: Add support for Broadcom BCM7445D0
Date: Sun,  6 May 2018 07:09:22 -0400	[thread overview]
Message-ID: <20180506110922.32469-2-fitzsim@fitzsim.org> (raw)
In-Reply-To: <20180506110922.32469-1-fitzsim@fitzsim.org>

Add support for loading U-Boot on the Broadcom 7445D0 SoC.  This port
assumes Broadcom's BOLT bootloader is acting as the second stage
bootloader, and U-Boot is acting as the third stage bootloader, loaded
as an ELF program by BOLT.

Signed-off-by: Thomas Fitzsimmons <fitzsim@fitzsim.org>
Cc: Stefan Roese <sr@denx.de>
---
 arch/arm/Kconfig                                |  12 +
 arch/arm/cpu/armv7/Makefile                     |   1 +
 arch/arm/cpu/armv7/bcm7445d0/Makefile           |  11 +
 arch/arm/cpu/armv7/bcm7445d0/lowlevel_init.S    |  24 ++
 arch/arm/lib/crt0.S                             |   2 +
 arch/arm/mach-bcm7445d0/include/mach/gpio.h     |  12 +
 arch/arm/mach-bcm7445d0/include/mach/hardware.h |  12 +
 arch/arm/mach-bcm7445d0/include/mach/sdhci.h    |  15 +
 board/broadcom/bcm7445d0/Kconfig                | 132 ++++++++
 board/broadcom/bcm7445d0/Makefile               |  11 +
 board/broadcom/bcm7445d0/bcm7445d0.c            | 147 ++++++++
 common/fdt_support.c                            |   9 +-
 common/image-fit.c                              |   2 +
 configs/bcm7445d0_defconfig                     |  21 ++
 drivers/mmc/Makefile                            |   1 +
 drivers/mmc/bcmstb_sdhci.c                      |  59 ++++
 drivers/spi/Kconfig                             |   7 +
 drivers/spi/Makefile                            |   1 +
 drivers/spi/bcmstb_spi.c                        | 428 ++++++++++++++++++++++++
 dts/Kconfig                                     |   6 +
 include/configs/bcm7445d0.h                     | 227 +++++++++++++
 include/configs/bcmstb.h                        |  57 ++++
 lib/fdtdec.c                                    |   8 +
 23 files changed, 1204 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/cpu/armv7/bcm7445d0/Makefile
 create mode 100644 arch/arm/cpu/armv7/bcm7445d0/lowlevel_init.S
 create mode 100644 arch/arm/mach-bcm7445d0/include/mach/gpio.h
 create mode 100644 arch/arm/mach-bcm7445d0/include/mach/hardware.h
 create mode 100644 arch/arm/mach-bcm7445d0/include/mach/sdhci.h
 create mode 100644 board/broadcom/bcm7445d0/Kconfig
 create mode 100644 board/broadcom/bcm7445d0/Makefile
 create mode 100644 board/broadcom/bcm7445d0/bcm7445d0.c
 create mode 100644 configs/bcm7445d0_defconfig
 create mode 100644 drivers/mmc/bcmstb_sdhci.c
 create mode 100644 drivers/spi/bcmstb_spi.c
 create mode 100644 include/configs/bcm7445d0.h
 create mode 100644 include/configs/bcmstb.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9bd70f4..b2df30a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -498,6 +498,17 @@ config TARGET_VEXPRESS_CA15_TC2
 	select CPU_V7_HAS_VIRT
 	select PL011_SERIAL
 
+config TARGET_BCM7445D0
+	bool "Broadcom 7445D0 TSBL"
+	select CPU_V7
+	select SUPPORT_SPL
+	help
+	  Support for the Broadcom 7445D0 SoC.  This port assumes Bolt
+	  is acting as the second stage bootloader, and U-Boot is
+	  acting as the third stage bootloader (TSBL), loaded by Bolt.
+	  This port may work on other BCM7xxx boards with
+	  configuration changes.
+
 config TARGET_VEXPRESS_CA5X2
 	bool "Support vexpress_ca5x2"
 	select CPU_V7
@@ -1320,6 +1331,7 @@ source "board/armltd/vexpress/Kconfig"
 source "board/armltd/vexpress64/Kconfig"
 source "board/broadcom/bcm23550_w1d/Kconfig"
 source "board/broadcom/bcm28155_ap/Kconfig"
+source "board/broadcom/bcm7445d0/Kconfig"
 source "board/broadcom/bcmcygnus/Kconfig"
 source "board/broadcom/bcmnsp/Kconfig"
 source "board/broadcom/bcmns2/Kconfig"
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile
index b14ee54..7183d4d 100644
--- a/arch/arm/cpu/armv7/Makefile
+++ b/arch/arm/cpu/armv7/Makefile
@@ -30,6 +30,7 @@ endif
 
 obj-$(if $(filter bcm235xx,$(SOC)),y) += bcm235xx/
 obj-$(if $(filter bcm281xx,$(SOC)),y) += bcm281xx/
+obj-$(if $(filter bcm7445d0,$(SOC)),y) += bcm7445d0/
 obj-$(if $(filter bcmcygnus,$(SOC)),y) += bcmcygnus/
 obj-$(if $(filter bcmnsp,$(SOC)),y) += bcmnsp/
 obj-$(if $(filter ls102xa,$(SOC)),y) += ls102xa/
diff --git a/arch/arm/cpu/armv7/bcm7445d0/Makefile b/arch/arm/cpu/armv7/bcm7445d0/Makefile
new file mode 100644
index 0000000..796f482
--- /dev/null
+++ b/arch/arm/cpu/armv7/bcm7445d0/Makefile
@@ -0,0 +1,11 @@
+#
+# (C) Copyright 2018
+# Cisco Systems, Inc. <www.cisco.com>
+#
+# Author :
+#	Thomas Fitzsimmons <fitzsim@fitzsim.org>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	:= lowlevel_init.o
diff --git a/arch/arm/cpu/armv7/bcm7445d0/lowlevel_init.S b/arch/arm/cpu/armv7/bcm7445d0/lowlevel_init.S
new file mode 100644
index 0000000..1eb67a0
--- /dev/null
+++ b/arch/arm/cpu/armv7/bcm7445d0/lowlevel_init.S
@@ -0,0 +1,24 @@
+/*
+ * (C) Copyright 2018
+ * Cisco Systems, Inc. <www.cisco.com>
+ *
+ * Author :
+ *	Thomas Fitzsimmons <fitzsim@fitzsim.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <linux/linkage.h>
+
+ENTRY(save_boot_params)
+	ldr	r6, =bcm7445d0_boot_parameters
+	str	r0, [r6, #0]
+	str	r1, [r6, #4]
+	str	r2, [r6, #8]
+	str	r3, [r6, #12]
+	str	sp, [r6, #16]
+	str	lr, [r6, #20]
+	ldr	r6, =prior_stage_fdt_address
+	str	r2, [r6]
+	b	save_boot_params_ret
+ENDPROC(save_boot_params)
diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S
index fa81317..f1a6f35 100644
--- a/arch/arm/lib/crt0.S
+++ b/arch/arm/lib/crt0.S
@@ -94,6 +94,7 @@ ENTRY(_main)
  * 'here' but relocated.
  */
 
+#if !defined(CONFIG_OF_PRIOR_STAGE)
 	ldr	r0, [r9, #GD_START_ADDR_SP]	/* sp = gd->start_addr_sp */
 	bic	r0, r0, #7	/* 8-byte alignment for ABI compliance */
 	mov	sp, r0
@@ -108,6 +109,7 @@ ENTRY(_main)
 #endif
 	ldr	r0, [r9, #GD_RELOCADDR]		/* r0 = gd->relocaddr */
 	b	relocate_code
+#endif
 here:
 /*
  * now relocate vectors
diff --git a/arch/arm/mach-bcm7445d0/include/mach/gpio.h b/arch/arm/mach-bcm7445d0/include/mach/gpio.h
new file mode 100644
index 0000000..f7163e4
--- /dev/null
+++ b/arch/arm/mach-bcm7445d0/include/mach/gpio.h
@@ -0,0 +1,12 @@
+/*
+ * (C) Copyright 2018
+ * Cisco Systems, Inc. <www.cisco.com>
+ *
+ * Author :
+ *	Thomas Fitzsimmons <fitzsim@fitzsim.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _BCM7445D0_GPIO_H
+#define _BCM7445D0_GPIO_H
+#endif /* _BCM7445D0_GPIO_H */
diff --git a/arch/arm/mach-bcm7445d0/include/mach/hardware.h b/arch/arm/mach-bcm7445d0/include/mach/hardware.h
new file mode 100644
index 0000000..28418bf
--- /dev/null
+++ b/arch/arm/mach-bcm7445d0/include/mach/hardware.h
@@ -0,0 +1,12 @@
+/*
+ * (C) Copyright 2018
+ * Cisco Systems, Inc. <www.cisco.com>
+ *
+ * Author :
+ *	Thomas Fitzsimmons <fitzsim@fitzsim.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _BCM7445D0_HARDWARE_H
+#define _BCM7445D0_HARDWARE_H
+#endif /* _BCM7445D0_HARDWARE_H */
diff --git a/arch/arm/mach-bcm7445d0/include/mach/sdhci.h b/arch/arm/mach-bcm7445d0/include/mach/sdhci.h
new file mode 100644
index 0000000..2c7fb09
--- /dev/null
+++ b/arch/arm/mach-bcm7445d0/include/mach/sdhci.h
@@ -0,0 +1,15 @@
+/*
+ * (C) Copyright 2018
+ * Cisco Systems, Inc. <www.cisco.com>
+ *
+ * Author :
+ *	Thomas Fitzsimmons <fitzsim@fitzsim.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _BCM7445D0_SDHCI_H
+#define _BCM7445D0_SDHCI_H
+
+int bcmstb_sdhci_init(phys_addr_t regbase);
+
+#endif /* _BCM7445D0_SDHCI_H */
diff --git a/board/broadcom/bcm7445d0/Kconfig b/board/broadcom/bcm7445d0/Kconfig
new file mode 100644
index 0000000..d710503
--- /dev/null
+++ b/board/broadcom/bcm7445d0/Kconfig
@@ -0,0 +1,132 @@
+if TARGET_BCM7445D0
+
+config SYS_BOARD
+	default "bcm7445d0"
+
+config SYS_VENDOR
+	default "broadcom"
+
+config SYS_CONFIG_NAME
+	default "bcm7445d0"
+
+config SYS_SOC
+	default "bcm7445d0"
+
+config BCHP_BSPI_MAST_N_BOOT_CTRL
+	hex ""
+	default 0x003e3208
+
+config BCHP_EBI_CS_SPI_SELECT
+	hex ""
+	default 0x003e0920
+
+config BCHP_HIF_MSPI_SPCR2_CONT_AFTER_CMD_MASK
+	hex ""
+	default 0x00000080
+
+config BCHP_HIF_MSPI_SPCR2_SPE_MASK
+	hex ""
+	default 0x00000040
+
+config BCHP_HIF_MSPI_SPCR2_SPIFIE_MASK
+	hex ""
+	default 0x00000020
+
+config BCHP_HIF_MSPI_WRITE_LOCK
+	hex ""
+	default 0x003e3580
+
+config BCHP_HIF_MSPI_WRITE_LOCK_WRITE_LOCK_DEFAULT
+	hex ""
+	default 0x00000000
+
+config BCHP_HIF_MSPI_WRITE_LOCK_WRITE_LOCK_MASK
+	hex ""
+	default 0x00000001
+
+config BCHP_HIF_MSPI_WRITE_LOCK_WRITE_LOCK_SHIFT
+	hex ""
+	default 0
+
+config BCHP_HIF_SPI_INTR2_CPU_CLEAR
+	hex ""
+	default 0x003e1a08
+
+config BCHP_HIF_SPI_INTR2_CPU_MASK_CLEAR
+	hex ""
+	default 0x003e1a14
+
+config BCHP_HIF_SPI_INTR2_CPU_MASK_SET
+	hex ""
+	default 0x003e1a10
+
+config BCHP_HIF_SPI_INTR2_CPU_SET_MSPI_DONE_MASK
+	hex ""
+	default 0x00000020
+
+config BCMSTB_ACCOMMODATE_STBLINUX
+	bool ""
+	default y
+	help
+	  This prevents U-Boot from adding memory reservations for the
+          lengths of initramfs and DTB.  Without skipping these,
+          stblinux's "contiguous memory allocator" (CMA) Linux driver
+          (cma_driver) will allocate memory ranges smaller than what
+          are actually available, because it only checks reservation
+          sizes.  It doesn't check if the reserved range overlaps the
+          range it allocates.  stblinux also tries to move the DTB to
+          a lower memory location early in the Linux boot.  If the FIT
+          image specifies a load address for the initramfs then
+          sometimes the DTB is moved into the range where the
+          initramfs image is loaded.  Defining this will mean that
+          FIT-provided initramfs load addresses are ignored.
+
+config BCMSTB_SDHCI
+	bool ""
+	default y
+
+config BCMSTB_SDHCI_BASE
+	hex ""
+	default 0xf03e0200
+
+config BCMSTB_SPI_BASE
+	hex ""
+	default 0xf03e3400
+
+config CMD_FDT_MAX_DUMP
+	int ""
+	default 256
+
+config GENERIC_MMC
+	bool ""
+	default y
+
+config MMC_SDMA
+	bool ""
+	default y
+
+config SDHCI
+	bool ""
+	default y
+
+config SYS_BCMSTB_SPI_WAIT
+	int ""
+	default 10
+
+config SYS_FDT_SAVE_ADDRESS
+	hex ""
+	default 0x1f00000
+
+config SYS_NO_FLASH
+	bool ""
+	default y
+
+config TIMER_FREQUENCY_REGISTER_ADDRESS
+	hex ""
+	default 0xf0412020
+
+config TIMER_LOW_REGISTER_ADDRESS
+	hex ""
+	default 0xf0412008
+
+endif
diff --git a/board/broadcom/bcm7445d0/Makefile b/board/broadcom/bcm7445d0/Makefile
new file mode 100644
index 0000000..265bc74
--- /dev/null
+++ b/board/broadcom/bcm7445d0/Makefile
@@ -0,0 +1,11 @@
+#
+# (C) Copyright 2018
+# Cisco Systems, Inc. <www.cisco.com>
+#
+# Author :
+#	Thomas Fitzsimmons <fitzsim@fitzsim.org>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	:= bcm7445d0.o
diff --git a/board/broadcom/bcm7445d0/bcm7445d0.c b/board/broadcom/bcm7445d0/bcm7445d0.c
new file mode 100644
index 0000000..7f8e1f6
--- /dev/null
+++ b/board/broadcom/bcm7445d0/bcm7445d0.c
@@ -0,0 +1,147 @@
+/*
+ * (C) Copyright 2018
+ * Cisco Systems, Inc. <www.cisco.com>
+ *
+ * Author :
+ *	Thomas Fitzsimmons <fitzsim@fitzsim.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <linux/types.h>
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/sdhci.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct bcm7445d0_boot_parameters {
+	u32 r0;
+	u32 r1;
+	u32 r2;
+	u32 r3;
+	u32 sp;
+	u32 lr;
+};
+
+struct bcm7445d0_boot_parameters bcm7445d0_boot_parameters \
+__attribute__((section(".data")));
+
+phys_addr_t prior_stage_fdt_address __attribute__((section(".data")));
+
+union reg_value_union {
+	const char *data;
+	const phys_addr_t *address;
+};
+
+int board_init(void)
+{
+	return 0;
+}
+
+u32 get_board_rev(void)
+{
+	return 0;
+}
+
+void reset_cpu(ulong ignored)
+{
+}
+
+int print_cpuinfo(void)
+{
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = 0xc0000000;
+
+	return 0;
+}
+
+int dram_init_banksize(void)
+{
+	bd_t *bd = gd->bd;
+
+	bd->bi_dram[0].start = 0x00000000;
+	bd->bi_dram[0].size  = 0x40000000;
+	bd->bi_dram[1].start = 0x40000000;
+	bd->bi_dram[1].size  = 0x40000000;
+	bd->bi_dram[2].start = 0x80000000;
+	bd->bi_dram[2].size  = 0x40000000;
+
+	return 0;
+}
+
+void enable_caches(void)
+{
+	/*
+	 * Nothing required here, since the prior stage bootloader has
+	 * enabled I-cache and D-cache already.  Implementing this
+	 * function silences the warning in the default function.
+	 */
+}
+
+int board_mmc_init(bd_t *bis)
+{
+	/* Just use the hard-coded SDHCI base address, though it could
+	 * be determined from the DTB provided by the prior stage
+	 * bootloader.
+	 */
+	bcmstb_sdhci_init(CONFIG_BCMSTB_SDHCI_BASE);
+
+	return 0;
+}
+
+int timer_init(void)
+{
+	gd->arch.timer_rate_hz = readl(CONFIG_TIMER_FREQUENCY_REGISTER_ADDRESS);
+
+	return 0;
+}
+
+ulong get_tbclk(void)
+{
+	return gd->arch.timer_rate_hz;
+}
+
+unsigned long timer_read_counter(void)
+{
+	return readl(CONFIG_TIMER_LOW_REGISTER_ADDRESS);
+}
+
+int board_late_init(void)
+{
+	printf("Arguments from prior stage bootloader:\n");
+	printf("General Purpose Register 0: 0x%x\n",
+	       bcm7445d0_boot_parameters.r0);
+	printf("General Purpose Register 1: 0x%x\n",
+	       bcm7445d0_boot_parameters.r1);
+	printf("General Purpose Register 2: 0x%x\n",
+	       bcm7445d0_boot_parameters.r2);
+	printf("General Purpose Register 3: 0x%x\n",
+	       bcm7445d0_boot_parameters.r3);
+	printf("Stack Pointer Register:     0x%x\n",
+	       bcm7445d0_boot_parameters.sp);
+	printf("Link Register:              0x%x\n",
+	       bcm7445d0_boot_parameters.lr);
+	printf("Assuming timer frequency register at: 0x%x\n",
+	       CONFIG_TIMER_FREQUENCY_REGISTER_ADDRESS);
+	printf("Read timer frequency (in Hz): %ld\n", gd->arch.timer_rate_hz);
+	printf("Prior stage provided DTB at: 0x%p\n",
+	       (void *)prior_stage_fdt_address);
+	/*
+	 * Set fdtcontroladdr in the environment so that scripts can
+	 * refer to it, for example, to reuse it for fdtaddr.
+	 */
+	env_set_hex("fdtcontroladdr", prior_stage_fdt_address);
+	/*
+	 * Do not set machid to the machine identifier value provided
+	 * by the prior stage bootloader
+	 * (bcm7445d0_boot_parameters.r1) because we're using a device
+	 * tree to boot Linux.
+	 */
+
+	return 0;
+}
diff --git a/common/fdt_support.c b/common/fdt_support.c
index 66a313e..f07dfe3 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -242,11 +242,13 @@ int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end)
 		}
 	}
 
+#if !defined(CONFIG_BCMSTB_ACCOMMODATE_STBLINUX)
 	err = fdt_add_mem_rsv(fdt, initrd_start, initrd_end - initrd_start);
 	if (err < 0) {
 		printf("fdt_initrd: %s\n", fdt_strerror(err));
 		return err;
 	}
+#endif
 
 	is_u64 = (fdt_address_cells(fdt, 0) == 2);
 
@@ -602,7 +604,10 @@ int fdt_shrink_to_minimum(void *blob, uint extrasize)
 {
 	int i;
 	uint64_t addr, size;
-	int total, ret;
+	int total;
+#if !defined(CONFIG_BCMSTB_ACCOMMODATE_STBLINUX)
+	int ret;
+#endif
 	uint actualsize;
 
 	if (!blob)
@@ -635,9 +640,11 @@ int fdt_shrink_to_minimum(void *blob, uint extrasize)
 	fdt_set_totalsize(blob, actualsize);
 
 	/* Add the new reservation */
+#if !defined(CONFIG_BCMSTB_ACCOMMODATE_STBLINUX)
 	ret = fdt_add_mem_rsv(blob, (uintptr_t)blob, actualsize);
 	if (ret < 0)
 		return ret;
+#endif
 
 	return actualsize;
 }
diff --git a/common/image-fit.c b/common/image-fit.c
index 030a3e5..a346f8c 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -1905,6 +1905,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
 			return -EBADF;
 		}
 	} else if (load_op != FIT_LOAD_OPTIONAL_NON_ZERO || load) {
+#if !defined(CONFIG_BCMSTB_ACCOMMODATE_STBLINUX)
 		ulong image_start, image_end;
 		ulong load_end;
 		void *dst;
@@ -1929,6 +1930,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
 		dst = map_sysmem(load, len);
 		memmove(dst, buf, len);
 		data = load;
+#endif
 	}
 	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
 
diff --git a/configs/bcm7445d0_defconfig b/configs/bcm7445d0_defconfig
new file mode 100644
index 0000000..1e1162e
--- /dev/null
+++ b/configs/bcm7445d0_defconfig
@@ -0,0 +1,21 @@
+CONFIG_ARM=y
+CONFIG_SYS_TEXT_BASE=0x80100000
+CONFIG_TARGET_BCM7445D0=y
+CONFIG_USE_PRIVATE_LIBGCC=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_PRIOR_STAGE=y
+CONFIG_DM=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI=y
+CONFIG_SPI_FLASH=y
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_FIT=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_RSA=y
+CONFIG_BLK=n
+CONFIG_MMC_SDHCI=y
+CONFIG_CONS_INDEX=3
+CONFIG_BOOTDELAY=1
+CONFIG_SYS_PROMPT="U-Boot>"
+CONFIG_HUSH_PARSER=y
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index cf46c33..959f410 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_MMC_DW_EXYNOS)		+= exynos_dw_mmc.o
 obj-$(CONFIG_MMC_DW_K3)			+= hi6220_dw_mmc.o
 obj-$(CONFIG_MMC_DW_ROCKCHIP)		+= rockchip_dw_mmc.o
 obj-$(CONFIG_MMC_DW_SOCFPGA)		+= socfpga_dw_mmc.o
+obj-$(CONFIG_BCMSTB_SDHCI) += bcmstb_sdhci.o
 obj-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
 obj-$(CONFIG_FTSDC010) += ftsdc010_mci.o
 obj-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o
diff --git a/drivers/mmc/bcmstb_sdhci.c b/drivers/mmc/bcmstb_sdhci.c
new file mode 100644
index 0000000..933c546
--- /dev/null
+++ b/drivers/mmc/bcmstb_sdhci.c
@@ -0,0 +1,59 @@
+#include <common.h>
+#include <malloc.h>
+#include <sdhci.h>
+
+/*
+ * The BCMSTB SDHCI has a quirk in that its actual maximum frequency
+ * capability is 100 MHz.  The divisor that is eventually written to
+ * SDHCI_CLOCK_CONTROL is calculated based on what the MMC device
+ * reports, and relative to this maximum frequency.
+ *
+ * This define used to be set to 52000000 (52 MHz), the desired
+ * maximum frequency, but that would result in the communication
+ * actually running at 100 MHz (seemingly without issue), which is
+ * out-of-spec.
+ *
+ * Now, by setting this to 0 (auto-detect), 100 MHz will be read from
+ * the capabilities register, and the resulting divisor will be
+ * doubled, meaning that the clock control register will be set to the
+ * in-spec 52 MHz value.
+ */
+#define BCMSTB_SDHCI_MAXIMUM_CLOCK_FREQUENCY	0
+/*
+ * When the minimum clock frequency is set to 0 (auto-detect), U-Boot
+ * sets it to 100 MHz divided by SDHCI_MAX_DIV_SPEC_300, or 48,875 Hz,
+ * which results in the controller timing out when trying to
+ * communicate with the MMC device.  Hard-code this value to 400000
+ * (400 kHz) to prevent this.
+ */
+#define BCMSTB_SDHCI_MINIMUM_CLOCK_FREQUENCY	400000
+
+static char *BCMSTB_SDHCI_NAME = "bcmstb-sdhci";
+
+/*
+ * This driver has only been tested with eMMC devices; SD devices may
+ * not work.
+ */
+int bcmstb_sdhci_init(phys_addr_t regbase)
+{
+	struct sdhci_host *host = NULL;
+
+	host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host));
+	if (!host) {
+		printf("bcmstb-sdhci malloc fail!\n");
+		return 1;
+	}
+	memset(host, 0, sizeof(*host));
+
+	host->name = BCMSTB_SDHCI_NAME;
+	host->ioaddr = (void *)regbase;
+	host->quirks = 0;
+
+	host->cfg.part_type = PART_TYPE_DOS;
+
+	host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
+
+	return add_sdhci(host,
+			 BCMSTB_SDHCI_MAXIMUM_CLOCK_FREQUENCY,
+			 BCMSTB_SDHCI_MINIMUM_CLOCK_FREQUENCY);
+}
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 6667f73..c4a6c8d 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -66,6 +66,13 @@ config BCM63XX_SPI
 	  access the SPI NOR flash on platforms embedding these Broadcom
 	  SPI cores.
 
+config BCMSTB_SPI
+	bool "Broadcom Set Top Box SPI driver"
+	help
+	  Enable the Broadcom Set Top Box SPI driver. This driver can
+	  be used to access the SPI flash on platforms embedding this
+	  Broadcom SPI core.
+
 config CADENCE_QSPI
 	bool "Cadence QSPI driver"
 	help
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 176bfa0..0f864be 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_ATH79_SPI) += ath79_spi.o
 obj-$(CONFIG_ATMEL_SPI) += atmel_spi.o
 obj-$(CONFIG_BCM63XX_HSSPI) += bcm63xx_hsspi.o
 obj-$(CONFIG_BCM63XX_SPI) += bcm63xx_spi.o
+obj-$(CONFIG_BCMSTB_SPI) += bcmstb_spi.o
 obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o
 obj-$(CONFIG_CF_SPI) += cf_spi.o
 obj-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
diff --git a/drivers/spi/bcmstb_spi.c b/drivers/spi/bcmstb_spi.c
new file mode 100644
index 0000000..183a547
--- /dev/null
+++ b/drivers/spi/bcmstb_spi.c
@@ -0,0 +1,428 @@
+/*
+ * (C) Copyright 2018
+ * Cisco Systems, Inc. <www.cisco.com>
+ *
+ * Author :
+ *	Thomas Fitzsimmons <fitzsim@fitzsim.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/io.h>
+#include <common.h>
+#include <config.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <spi.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define SPBR_MIN		8
+#define BITS_PER_WORD		8
+
+#define NUM_TXRAM		32
+#define NUM_RXRAM		32
+#define NUM_CDRAM		16
+
+#ifdef DEBUG
+static int debug_tx_rx;
+#define D(fmt, args...) debug_cond(debug_tx_rx, fmt, ##args)
+#else
+#define D(fmt, args...)
+#endif
+
+/* MSPI registers.  BSPI is disabled. */
+struct bcmstb_spi_regs {
+	u32 spcr0_lsb;		/* 0x000 */
+	u32 spcr0_msb;		/* 0x004 */
+	u32 spcr1_lsb;		/* 0x008 */
+	u32 spcr1_msb;		/* 0x00c */
+	u32 newqp;		/* 0x010 */
+	u32 endqp;		/* 0x014 */
+	u32 spcr2;		/* 0x018 */
+	u32 reserved0;		/* 0x01c */
+	u32 mspi_status;	/* 0x020 */
+	u32 cptqp;		/* 0x024 */
+	u32 spcr3;		/* 0x028 */
+	u32 revision;		/* 0x02c */
+	u32 reserved1[4];	/* 0x030 */
+	u32 txram[NUM_TXRAM];	/* 0x040 */
+	u32 rxram[NUM_RXRAM];	/* 0x0c0 */
+	u32 cdram[NUM_CDRAM];	/* 0x140 */
+};
+
+struct bcmstb_spi_platdata {
+	struct bcmstb_spi_regs *regs;
+};
+
+struct bcmstb_spi_priv {
+	struct bcmstb_spi_regs *regs;
+	int default_cs;
+	int curr_cs;
+	uint tx_slot;
+	uint rx_slot;
+	u8 saved_cmd[NUM_CDRAM];
+	uint saved_cmd_len;
+	void *saved_din_addr;
+};
+
+/*
+ * If we could rely on the prior stage bootloader to insert a "spi0"
+ * alias, we could enable CONFIG_DM_SEQ_ALIAS and omit
+ * bcmstb_spi_bind.  We cannot rely on this behaviour, so we have to
+ * handle binding explicitly.
+ */
+static int bcmstb_spi_bind(struct udevice *bus)
+{
+	char spi0_name[30];
+	int node = dev_of_offset(bus);
+
+	memset(spi0_name, 0, sizeof(spi0_name));
+
+	debug("bcmstb_spi_bind: %s, ", bus->name);
+
+	snprintf(spi0_name, sizeof(spi0_name), "spi@%08x",
+		 CONFIG_BCMSTB_SPI_BASE);
+	if (strcmp(fdt_get_name(gd->fdt_blob, node, NULL),
+		   spi0_name) == 0) {
+		bus->req_seq = 0;
+	}
+
+	debug("%d\n", bus->req_seq);
+
+	return 0;
+}
+
+static int bcmstb_spi_ofdata_to_platdata(struct udevice *bus)
+{
+	struct bcmstb_spi_platdata *plat = dev_get_platdata(bus);
+	const void *blob = gd->fdt_blob;
+	int node = dev_of_offset(bus);
+	u32 address = 0;
+	int code = 0;
+
+	code = fdtdec_get_int_array(blob, node, "reg", &address, 1);
+	if (code != 0) {
+		printf("bcmstb_spi_ofdata_to_platdata:"
+		       " Failed to read reg property\n");
+		return code;
+	}
+
+	plat->regs = (struct bcmstb_spi_regs *)address;
+	D("spi_xfer: tx regs: %p\n", &plat->regs->txram[0]);
+	D("spi_xfer: rx regs: %p\n", &plat->regs->rxram[0]);
+
+	return 0;
+}
+
+static void bcmstb_spi_hw_set_parms(struct bcmstb_spi_priv *priv)
+{
+	writel(SPBR_MIN, &priv->regs->spcr0_lsb);
+	writel(BITS_PER_WORD << 2 | SPI_MODE_3, &priv->regs->spcr0_msb);
+}
+
+static void bcmstb_spi_enable_interrupt(u32 mask)
+{
+	BDEV_SET_RB(CONFIG_BCHP_HIF_SPI_INTR2_CPU_MASK_CLEAR, mask);
+}
+
+static void bcmstb_spi_disable_interrupt(u32 mask)
+{
+	BDEV_SET_RB(CONFIG_BCHP_HIF_SPI_INTR2_CPU_MASK_SET, mask);
+}
+
+static void bcmstb_spi_clear_interrupt(u32 mask)
+{
+	BDEV_SET_RB(CONFIG_BCHP_HIF_SPI_INTR2_CPU_CLEAR, mask);
+}
+
+static int bcmstb_spi_probe(struct udevice *bus)
+{
+	struct bcmstb_spi_platdata *plat = dev_get_platdata(bus);
+	struct bcmstb_spi_priv *priv = dev_get_priv(bus);
+
+	priv->regs = plat->regs;
+	priv->default_cs = 0;
+	priv->curr_cs = -1;
+	priv->tx_slot = 0;
+	priv->rx_slot = 0;
+	memset(priv->saved_cmd, 0, NUM_CDRAM);
+	priv->saved_cmd_len = 0;
+	priv->saved_din_addr = NULL;
+
+	/* Disable BSPI. */
+	BDEV_WR_RB(CONFIG_BCHP_BSPI_MAST_N_BOOT_CTRL, 1);
+
+	/* Set up interrupts. */
+	bcmstb_spi_disable_interrupt(0xffffffff);
+	bcmstb_spi_clear_interrupt(0xffffffff);
+	bcmstb_spi_enable_interrupt(
+		CONFIG_BCHP_HIF_SPI_INTR2_CPU_SET_MSPI_DONE_MASK);
+
+	/* Set up control registers. */
+	writel(0, &priv->regs->spcr1_lsb);
+	writel(0, &priv->regs->spcr1_msb);
+	writel(0, &priv->regs->newqp);
+	writel(0, &priv->regs->endqp);
+	writel(CONFIG_BCHP_HIF_MSPI_SPCR2_SPIFIE_MASK, &priv->regs->spcr2);
+	writel(0, &priv->regs->spcr3);
+
+	bcmstb_spi_hw_set_parms(priv);
+
+	return 0;
+}
+
+static int bcmstb_spi_remove(struct udevice *dev)
+{
+	return 0;
+}
+
+static int bcmstb_spi_claim_bus(struct udevice *dev)
+{
+	return 0;
+}
+
+static int bcmstb_spi_release_bus(struct udevice *dev)
+{
+	return 0;
+}
+
+static void bcmstb_spi_submit(struct bcmstb_spi_priv *priv, bool done)
+{
+	D("WR NEWQP: %d\n", 0);
+	writel(0, &priv->regs->newqp);
+
+	D("WR ENDQP: %d\n", priv->tx_slot - 1);
+	writel(priv->tx_slot - 1, &priv->regs->endqp);
+
+	if (done) {
+		D("WR CDRAM[%d]: %02x\n", priv->tx_slot - 1,
+		  readl(&priv->regs->cdram[priv->tx_slot - 1]) & ~0x80);
+		writel(readl(&priv->regs->cdram[priv->tx_slot - 1]) & ~0x80,
+		       &priv->regs->cdram[priv->tx_slot - 1]);
+	}
+
+	/* Force chip select first time. */
+	if (priv->curr_cs != priv->default_cs) {
+		D("spi_xfer: switching chip select to %d\n",
+		  priv->default_cs);
+		BDEV_WR_RB(CONFIG_BCHP_EBI_CS_SPI_SELECT,
+			   (BDEV_RD(CONFIG_BCHP_EBI_CS_SPI_SELECT) &
+			    ~0xff) | (1 << priv->default_cs));
+		udelay(10);
+		priv->curr_cs = priv->default_cs;
+	}
+
+	D("WR WRITE_LOCK: %02x\n", 1);
+	BDEV_WR_F_RB(HIF_MSPI_WRITE_LOCK, WRITE_LOCK, 1);
+
+	D("WR SPCR2: %02x\n",
+	  CONFIG_BCHP_HIF_MSPI_SPCR2_SPIFIE_MASK |
+	  CONFIG_BCHP_HIF_MSPI_SPCR2_SPE_MASK |
+	  CONFIG_BCHP_HIF_MSPI_SPCR2_CONT_AFTER_CMD_MASK);
+	writel(CONFIG_BCHP_HIF_MSPI_SPCR2_SPIFIE_MASK |
+	       CONFIG_BCHP_HIF_MSPI_SPCR2_SPE_MASK |
+	       CONFIG_BCHP_HIF_MSPI_SPCR2_CONT_AFTER_CMD_MASK,
+	       &priv->regs->spcr2);
+}
+
+static int bcmstb_spi_wait(struct bcmstb_spi_regs *regs)
+{
+	u32 start_time = get_timer(0);
+	u32 status = readl(&regs->mspi_status);
+
+	while (!(status & 1)) {
+		if (get_timer(start_time) >
+		    CONFIG_SYS_BCMSTB_SPI_WAIT) {
+			return -ETIMEDOUT;
+		}
+		status = readl(&regs->mspi_status);
+	}
+
+	writel(readl(&regs->mspi_status) & ~1, &regs->mspi_status);
+	bcmstb_spi_clear_interrupt(
+		CONFIG_BCHP_HIF_SPI_INTR2_CPU_SET_MSPI_DONE_MASK);
+
+	return 0;
+}
+
+static int bcmstb_spi_xfer(struct udevice *dev, unsigned int bitlen,
+			   const void *dout, void *din, unsigned long flags)
+{
+	uint len = bitlen / 8;
+	uint tx_len = len;
+	uint rx_len = len;
+	const u8 *out_bytes = (u8 *)dout;
+	u8 *in_bytes = (u8 *)din;
+	struct udevice *bus = dev_get_parent(dev);
+	struct bcmstb_spi_priv *priv = dev_get_priv(bus);
+	struct bcmstb_spi_regs *regs = priv->regs;
+
+	D("spi_xfer: %d, t: %p, r: %p, f: %lx\n", len, dout, din, flags);
+	D("spi_xfer: chip select: %x\n",
+	  readl(CONFIG_BCHP_EBI_CS_SPI_SELECT) & 0xff);
+	D("spi_xfer: tx addr: %p\n", &regs->txram[0]);
+	D("spi_xfer: rx addr: %p\n", &regs->rxram[0]);
+	D("spi_xfer: cd addr: %p\n", &regs->cdram[0]);
+
+	if (flags & SPI_XFER_END) {
+		D("spi_xfer: clearing saved din address: %p\n",
+		  priv->saved_din_addr);
+		priv->saved_din_addr = NULL;
+		priv->saved_cmd_len = 0;
+		memset(priv->saved_cmd, 0, NUM_CDRAM);
+	}
+
+	if (bitlen == 0)
+		return 0;
+
+	if (bitlen % 8) {
+		printf("bcmstb_spi_xfer: Non-byte-aligned transfer\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (flags & ~(SPI_XFER_BEGIN | SPI_XFER_END)) {
+		printf("bcmstb_spi_xfer: Unsupported flags: %lx\n", flags);
+		return -EOPNOTSUPP;
+	}
+
+	if (flags & SPI_XFER_BEGIN) {
+		priv->tx_slot = 0;
+		priv->rx_slot = 0;
+
+		if (out_bytes && len > NUM_CDRAM) {
+			printf("bcmstb_spi_xfer: Unable to save transfer\n");
+			return -EOPNOTSUPP;
+		}
+
+		if (out_bytes && !(flags & SPI_XFER_END)) {
+			/*
+			 * This is the start of a transmit operation
+			 * that will need repeating if the calling
+			 * code polls for the result.  Save it for
+			 * subsequent transmission.
+			 */
+			D("spi_xfer: saving command: %x, %d\n",
+			  out_bytes[0], len);
+			priv->saved_cmd_len = len;
+			memcpy(priv->saved_cmd, out_bytes, priv->saved_cmd_len);
+		}
+	}
+
+	if (!(flags & (SPI_XFER_BEGIN | SPI_XFER_END))) {
+		if (priv->saved_din_addr == din) {
+			/*
+			 * The caller is polling for status.  Repeat
+			 * the last transmission.
+			 */
+			int code = 0;
+
+			D("spi_xfer: Making recursive call\n");
+			code = bcmstb_spi_xfer(dev, priv->saved_cmd_len * 8,
+					       priv->saved_cmd, NULL,
+					       SPI_XFER_BEGIN);
+			if (code) {
+				printf("bcmstb_spi_xfer:"
+				       " Recursive call failed\n");
+				return code;
+			}
+		} else {
+			D("spi_xfer: saving din address: %p\n", din);
+			priv->saved_din_addr = din;
+		}
+	}
+
+	while (rx_len > 0) {
+		priv->rx_slot = priv->tx_slot;
+
+		while (priv->tx_slot < NUM_CDRAM && tx_len > 0) {
+			bcmstb_spi_hw_set_parms(priv);
+			D("WR TXRAM[%d]: %02x\n", priv->tx_slot,
+			  out_bytes ? out_bytes[len - tx_len] : 0xff);
+			writel(out_bytes ? out_bytes[len - tx_len] : 0xff,
+			       &regs->txram[priv->tx_slot << 1]);
+			D("WR CDRAM[%d]: %02x\n", priv->tx_slot, 0x8e);
+			writel(0x8e, &regs->cdram[priv->tx_slot]);
+			priv->tx_slot++;
+			tx_len--;
+			if (!in_bytes)
+				rx_len--;
+		}
+
+		D("spi_xfer: early return clauses: %d, %d, %d\n",
+		  len <= NUM_CDRAM,
+		  !in_bytes,
+		  (flags & (SPI_XFER_BEGIN | SPI_XFER_END)) == SPI_XFER_BEGIN);
+		if (len <= NUM_CDRAM &&
+		    !in_bytes &&
+		    (flags & (SPI_XFER_BEGIN | SPI_XFER_END)) == SPI_XFER_BEGIN)
+			return 0;
+
+		bcmstb_spi_submit(priv, tx_len == 0);
+
+		if (bcmstb_spi_wait(regs) == -ETIMEDOUT) {
+			printf("bcmstb_spi_xfer: Timed out\n");
+			return -ETIMEDOUT;
+		}
+
+		priv->tx_slot %= NUM_CDRAM;
+
+		if (in_bytes) {
+			while (priv->rx_slot < NUM_CDRAM && rx_len > 0) {
+				in_bytes[len - rx_len] =
+					readl(&regs->rxram[(priv->rx_slot << 1)
+							   + 1])
+					& 0xff;
+				D("RD RXRAM[%d]: %02x\n",
+				  priv->rx_slot, in_bytes[len - rx_len]);
+				priv->rx_slot++;
+				rx_len--;
+			}
+		}
+	}
+
+	if (flags & SPI_XFER_END) {
+		D("WR WRITE_LOCK: %02x\n", 0);
+		BDEV_WR_F_RB(HIF_MSPI_WRITE_LOCK, WRITE_LOCK, 0);
+	}
+
+	return 0;
+}
+
+static int bcmstb_spi_set_speed(struct udevice *dev, uint speed)
+{
+	return 0;
+}
+
+static int bcmstb_spi_set_mode(struct udevice *dev, uint mode)
+{
+	return 0;
+}
+
+static const struct dm_spi_ops bcmstb_spi_ops = {
+	.claim_bus	= bcmstb_spi_claim_bus,
+	.release_bus	= bcmstb_spi_release_bus,
+	.xfer		= bcmstb_spi_xfer,
+	.set_speed	= bcmstb_spi_set_speed,
+	.set_mode	= bcmstb_spi_set_mode,
+};
+
+static const struct udevice_id bcmstb_spi_ids[] = {
+	{ .compatible = "brcm,spi-brcmstb" },
+	{ }
+};
+
+U_BOOT_DRIVER(bcmstb_spi) = {
+	.name				= "bcmstb_spi",
+	.id				= UCLASS_SPI,
+	.of_match			= bcmstb_spi_ids,
+	.ops				= &bcmstb_spi_ops,
+	.ofdata_to_platdata		= bcmstb_spi_ofdata_to_platdata,
+	.probe				= bcmstb_spi_probe,
+	.remove				= bcmstb_spi_remove,
+	.platdata_auto_alloc_size	= sizeof(struct bcmstb_spi_platdata),
+	.priv_auto_alloc_size		= sizeof(struct bcmstb_spi_priv),
+	.bind				= bcmstb_spi_bind,
+};
diff --git a/dts/Kconfig b/dts/Kconfig
index 0cef225..074784b 100644
--- a/dts/Kconfig
+++ b/dts/Kconfig
@@ -101,6 +101,12 @@ config OF_HOSTFILE
 	  This is only useful for Sandbox.  Use the -d flag to U-Boot to
 	  specify the file to read.
 
+config OF_PRIOR_STAGE
+	bool "Prior stage bootloader DTB for DT control"
+	help
+	  If this option is enabled, DTB will be read from a memory
+	  location passed to U-Boot by the prior stage bootloader.
+
 endchoice
 
 config DEFAULT_DEVICE_TREE
diff --git a/include/configs/bcm7445d0.h b/include/configs/bcm7445d0.h
new file mode 100644
index 0000000..36155c7
--- /dev/null
+++ b/include/configs/bcm7445d0.h
@@ -0,0 +1,227 @@
+/*
+ * (C) Copyright 2018
+ * Cisco Systems, Inc. <www.cisco.com>
+ *
+ * Author :
+ *	Thomas Fitzsimmons <fitzsim@fitzsim.org>
+ *
+ * Configuration settings for the Broadcom BCM7445D0 SoC.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include "bcmstb.h"
+#include "version.h"
+
+/*
+ * Generic board configuration.
+ */
+#define CONFIG_SYS_GENERIC_BOARD
+
+/*
+ * CPU configuration.
+ */
+#define CONFIG_SKIP_LOWLEVEL_INIT
+
+/*
+ * Memory configuration.
+ *
+ * The prior stage BOLT bootloader sets up memory for us.  An example
+ * invocation is:
+ *
+ * BOLT> boot -bsu -elf flash0.u-boot1
+ *
+ * An example boot memory layout after loading everything is:
+ *
+ *	 0x0000 8000	vmlinux.bin.gz
+ *	       :	[31 MiB uncompressed max]
+ *	 0x01ef f000	FIT containing signed public key
+ *	       :	[~2 KiB in size]
+ *	 0x01f0 0000	DTB copied from prior-stage-provided region
+ *	       :	[~1 MiB max]
+ *	~0x01ff 4000	DTB modified by U-Boot (fdt_high - DTB size)
+ *	       :	[~40 KiB in size]
+ *	 0x0200 0000	FIT containing initramfs.cpio.gz
+ *	       :	[208 MiB uncompressed max, to CMA low address]
+ *	       :	[80 MiB compressed max, to PSB low address]
+ *	 0x0700 0000	Prior stage bootloader (PSB)
+ *	       :
+ *	 0x0761 7000	Prior-stage-provided device tree blob (DTB)
+ *	       :	[~40 KiB in size]
+ *	 0x0f00 0000	Contiguous memory allocator (CMA) low address
+ *	       :
+ *	 0x8010 0000	U-Boot code at ELF load address
+ *	       :	[~500 KiB in size, stripped]
+ *	 0xc000 0000	Top of RAM
+ *
+ * CONFIG_OF_PRIOR_STAGE=y prevents U-Boot from relocating itself when
+ * it is run as an ELF program by the prior stage bootloader.
+ *
+ * The maximum value for fdt_high is the lowest physical address from
+ * which stblinux's CMA driver starts allocating, which is 0x0f000000.
+ * But a good setting for fdt_high is the default load address.
+ *
+ * Relocating the prior stage DTB prevents it from being overwritten
+ * when large initramfs images are loaded.  Then the upper limit for
+ * the initramfs load region becomes the CMA low address.
+ *
+ * Overwriting the prior stage bootloader causes memory instability,
+ * so the compressed initramfs needs to fit between the load address
+ * and the PSB low address.  In BOLT's default configuration this
+ * limits the compressed size of the initramfs to approximately 80
+ * MiB.  However, BOLT can be configured to allow loading larger
+ * initramfs images, in which case this limitation is eliminated.
+ *
+ * Newer versions of stblinux use the bmem mechanism for reserving
+ * physical regions of memory.  In practice CMA/bmem values require
+ * experimentation and tuning to achieve a stable U-Boot memory layout
+ * and the desired Linux memory layout (see also
+ * BCMSTB_ACCOMMODATE_STBLINUX).
+ */
+#define CONFIG_NR_DRAM_BANKS		3
+
+#define CONFIG_SYS_SDRAM_BASE		0x00000000
+#define CONFIG_SYS_TEXT_BASE		0x80100000
+#define CONFIG_SYS_INIT_RAM_ADDR	0x80200000
+#define CONFIG_SYS_INIT_RAM_SIZE	0x100000
+#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_INIT_RAM_ADDR + \
+					 CONFIG_SYS_INIT_RAM_SIZE - \
+					 GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_MALLOC_LEN		((10 * 1024) << 10) /* 10 MiB */
+#define CONFIG_SYS_LOAD_ADDR		0x2000000
+/*
+ * CONFIG_SYS_LOAD_ADDR - 1 MiB.
+ */
+#define CONFIG_SYS_FDT_SAVE_ADDRESS	0x1f00000
+#define CONFIG_SYS_CBSIZE		512
+#define CONFIG_SYS_MAXARGS		32
+
+/*
+ * Timer configuration.
+ */
+#define CONFIG_TIMER_FREQUENCY_REGISTER_ADDRESS	0xf0412020
+#define CONFIG_TIMER_LOW_REGISTER_ADDRESS	0xf0412008
+
+/*
+ * NS16550 configuration.
+ */
+#define V_NS16550_CLK			81000000
+
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_REG_SIZE	(-4)
+#define CONFIG_SYS_NS16550_CLK		V_NS16550_CLK
+
+/*
+ * Serial console configuration.
+ */
+#define CONFIG_SERIAL3			3
+/*
+ * For now, this must be a pre-defined macro, not looked up from the
+ * prior-stage-provided DTB.
+ */
+#define CONFIG_SYS_NS16550_COM3		0xf040ab00
+#define CONFIG_BAUDRATE			115200
+#define CONFIG_SYS_BAUDRATE_TABLE	{4800, 9600, 19200, 38400, 57600,\
+					115200}
+
+/*
+ * Informational display configuration.
+ */
+#define CONFIG_REVISION_TAG
+
+/*
+ * Command configuration.
+ */
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_SPI
+#define CONFIG_CMD_SF_TEST
+#define CONFIG_CMD_MMC
+
+/*
+ * Flattened device tree configuration.
+ */
+#define CONFIG_CMD_FDT_MAX_DUMP		256
+
+/*
+ * Flash configuration.
+ */
+#define CONFIG_ST_SMI
+#define CONFIG_BCMSTB_SPI
+#define CONFIG_SPI_FLASH_STMICRO
+#define CONFIG_SPI_FLASH_MACRONIX
+
+#define CONFIG_BCMSTB_SPI_BASE		0xf03e3400
+
+/*
+ * Copied from stblinux, include/linux/brcmstb/7445d0/bchp_hif_mspi.h.
+ */
+#define CONFIG_BCHP_HIF_MSPI_SPCR2_SPIFIE_MASK			0x00000020
+#define CONFIG_BCHP_HIF_MSPI_SPCR2_SPE_MASK			0x00000040
+#define CONFIG_BCHP_HIF_MSPI_SPCR2_CONT_AFTER_CMD_MASK		0x00000080
+#define CONFIG_BCHP_HIF_MSPI_WRITE_LOCK				0x003e3580
+#define CONFIG_BCHP_HIF_MSPI_WRITE_LOCK_WRITE_LOCK_MASK		0x00000001
+#define CONFIG_BCHP_HIF_MSPI_WRITE_LOCK_WRITE_LOCK_DEFAULT	0x00000000
+
+/*
+ * Copied from stblinux, include/linux/brcmstb/7445d0/bchp_hif_spi_intr2.h.
+ */
+#define CONFIG_BCHP_HIF_SPI_INTR2_CPU_CLEAR			0x003e1a08
+#define CONFIG_BCHP_HIF_SPI_INTR2_CPU_MASK_SET			0x003e1a10
+#define CONFIG_BCHP_HIF_SPI_INTR2_CPU_MASK_CLEAR		0x003e1a14
+#define CONFIG_BCHP_HIF_SPI_INTR2_CPU_SET_MSPI_DONE_MASK	0x00000020
+
+/*
+ * Copied from stblinux, include/linux/brcmstb/7445d0/bchp_ebi.h.
+ */
+#define CONFIG_BCHP_EBI_CS_SPI_SELECT				0x003e0920
+
+/*
+ * Copied from stblinux, include/linux/brcmstb/7445d0/bchp_bspi.h.
+ */
+#define CONFIG_BCHP_BSPI_MAST_N_BOOT_CTRL			0x003e3208
+
+/*
+ * Filesystem configuration.
+ */
+#define CONFIG_DOS_PARTITION
+#define CONFIG_CMD_EXT4
+#define CONFIG_FS_EXT4
+#define CONFIG_CMD_FS_GENERIC
+
+/*
+ * Environment configuration.
+ */
+#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
+
+#define CONFIG_ENV_IS_IN_SPI_FLASH      1
+#define CONFIG_ENV_OFFSET		0x1e0000
+#define CONFIG_ENV_SIZE			(64 << 10) /* 64 KiB */
+#define CONFIG_ENV_SECT_SIZE		CONFIG_ENV_SIZE
+#define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_PREBOOT					\
+	"fdt addr ${fdtcontroladdr};"			\
+	"fdt move ${fdtcontroladdr} ${fdtsaveaddr};"	\
+	"fdt addr ${fdtsaveaddr};"
+#define CONFIG_EXTRA_ENV_SETTINGS					\
+	"fdtsaveaddr=" __stringify(CONFIG_SYS_FDT_SAVE_ADDRESS) "\0"
+
+/*
+ * Set fdtaddr to prior stage-provided DTB in board_late_init, when
+ * writeable environment is available.
+ */
+#define CONFIG_BOARD_LATE_INIT
+
+#define CONFIG_SYS_MAX_FLASH_BANKS 1
+
+#define CONFIG_DM_SPI 1
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/bcmstb.h b/include/configs/bcmstb.h
new file mode 100644
index 0000000..33d1efc
--- /dev/null
+++ b/include/configs/bcmstb.h
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2009
+ * Broadcom Corporation
+ *
+ * Author :
+ *	Thomas Fitzsimmons <fitzsim@fitzsim.org>
+ *
+ * Macros imported from Broadcom stblinux.
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef __BCMSTB_H
+#define __BCMSTB_H
+
+/* Copied from stblinux, include/linux/brcmstb/brcmstb.h. */
+#define DEV_RD(x) (readl((x)))
+#define DEV_WR(x, y) do { writel((y), (x)); } while (0)
+#define DEV_UNSET(x, y) do { DEV_WR((x), DEV_RD(x) & ~(y)); } while (0)
+#define DEV_SET(x, y) do { DEV_WR((x), DEV_RD(x) | (y)); } while (0)
+
+#define DEV_WR_RB(x, y) do { DEV_WR((x), (y)); DEV_RD(x); } while (0)
+#define DEV_SET_RB(x, y) do { DEV_SET((x), (y)); DEV_RD(x); } while (0)
+#define DEV_UNSET_RB(x, y) do { DEV_UNSET((x), (y)); DEV_RD(x); } while (0)
+
+/* Adjusted for U-Boot. */
+#define BRCMSTB_PERIPH_VIRT	0xf0000000
+
+#define BVIRTADDR(x)		(BRCMSTB_PERIPH_VIRT + ((x) & 0x0fffffff))
+
+#define BDEV_RD(x) (DEV_RD(BVIRTADDR(x)))
+#define BDEV_WR(x, y) do { DEV_WR(BVIRTADDR(x), (y)); } while (0)
+#define BDEV_UNSET(x, y) do { BDEV_WR((x), BDEV_RD(x) & ~(y)); } while (0)
+#define BDEV_SET(x, y) do { BDEV_WR((x), BDEV_RD(x) | (y)); } while (0)
+
+#define BDEV_SET_RB(x, y) do { BDEV_SET((x), (y)); BDEV_RD(x); } while (0)
+#define BDEV_UNSET_RB(x, y) do { BDEV_UNSET((x), (y)); BDEV_RD(x); } while (0)
+#define BDEV_WR_RB(x, y) do { BDEV_WR((x), (y)); BDEV_RD(x); } while (0)
+
+#define BDEV_RD_F(reg, field) \
+	((BDEV_RD(BCHP_##reg) & BCHP_##reg##_##field##_MASK) >> \
+	 BCHP_##reg##_##field##_SHIFT)
+#define BDEV_WR_F(reg, field, val) do { \
+	BDEV_WR(BCHP_##reg, \
+	(BDEV_RD(BCHP_##reg) & ~BCHP_##reg##_##field##_MASK) | \
+	(((val) << BCHP_##reg##_##field##_SHIFT) & \
+	 BCHP_##reg##_##field##_MASK)); \
+	} while (0)
+#define BDEV_WR_F_RB(reg, field, val) do { \
+	BDEV_WR(CONFIG_BCHP_##reg, \
+	(BDEV_RD(CONFIG_BCHP_##reg) & ~CONFIG_BCHP_##reg##_##field##_MASK) | \
+	(((val) << CONFIG_BCHP_##reg##_##field##_SHIFT) & \
+	 CONFIG_BCHP_##reg##_##field##_MASK)); \
+	BDEV_RD(CONFIG_BCHP_##reg); \
+	} while (0)
+
+#endif /* __BCMSTB_H */
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 320ee1d..aec12f2 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -1299,6 +1299,10 @@ __weak void *board_fdt_blob_setup(void)
 }
 #endif
 
+#if defined(CONFIG_OF_PRIOR_STAGE)
+extern phys_addr_t prior_stage_fdt_address;
+#endif
+
 int fdtdec_setup(void)
 {
 #if CONFIG_IS_ENABLED(OF_CONTROL)
@@ -1323,8 +1327,12 @@ int fdtdec_setup(void)
 # endif
 # ifndef CONFIG_SPL_BUILD
 	/* Allow the early environment to override the fdt address */
+#  if defined(CONFIG_OF_PRIOR_STAGE)
+	gd->fdt_blob = (void *)prior_stage_fdt_address;
+#  else
 	gd->fdt_blob = (void *)env_get_ulong("fdtcontroladdr", 16,
 						(uintptr_t)gd->fdt_blob);
+#  endif
 # endif
 
 # if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
-- 
1.8.3.1

  reply	other threads:[~2018-05-06 11:09 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-06 11:09 [U-Boot] [PATCH 0/1] board: arm: Add support for Broadcom BCM7445D0 Thomas Fitzsimmons
2018-05-06 11:09 ` Thomas Fitzsimmons [this message]
2018-05-07 23:48   ` [U-Boot] [PATCH 1/1] " Tom Rini
2018-05-24  0:47     ` Thomas Fitzsimmons
2018-05-08 17:44   ` Florian Fainelli
2018-05-10 13:04     ` Thomas Fitzsimmons
2018-05-10 17:43       ` Florian Fainelli
2018-06-06 20:39         ` Thomas Fitzsimmons
2018-06-06 22:06           ` Florian Fainelli
2018-05-24  1:24 ` [U-Boot] [PATCH v2 0/1] board: arm: Add support for Broadcom BCM7445 Thomas Fitzsimmons
2018-05-24  1:24   ` [U-Boot] [PATCH v2 1/1] " Thomas Fitzsimmons
2018-06-06 11:16     ` [U-Boot] [U-Boot, v2, " Tom Rini
2018-06-06 19:32       ` Thomas Fitzsimmons
2018-06-06 18:35   ` [U-Boot] [PATCH v3 0/1] " Thomas Fitzsimmons
2018-06-06 18:35     ` [U-Boot] [PATCH v3 1/1] " Thomas Fitzsimmons
2018-06-07 16:54       ` Florian Fainelli
2018-06-08 22:25         ` Thomas Fitzsimmons
2018-06-08 21:59     ` [U-Boot] [PATCH v4 0/1] " Thomas Fitzsimmons
2018-06-08 21:59       ` [U-Boot] [PATCH v4 1/1] " Thomas Fitzsimmons
2018-07-11 12:42         ` [U-Boot] [U-Boot, v4, " Tom Rini
2019-08-26 15:54         ` [U-Boot] [PATCH v4 " Bin Meng
2019-08-27 22:31           ` Thomas Fitzsimmons
2019-08-28 10:19             ` Bin Meng
2019-08-28 17:24               ` Thomas Fitzsimmons
2019-08-29 15:24                 ` Bin Meng
2019-09-05 12:10                   ` Bin Meng
2019-09-17  5:48                     ` Simon Glass
2019-09-06 11:51                   ` [U-Boot] [PATCH 0/2] dm: CONFIG_OF_PRIOR_STAGE request number fixes Thomas Fitzsimmons
2019-09-06 11:51                     ` [U-Boot] [PATCH 1/2] dm: device: Request next sequence number Thomas Fitzsimmons
2019-09-06 13:24                       ` Bin Meng
2019-09-14 13:41                         ` Thomas Fitzsimmons
2019-09-27  1:49                           ` Simon Glass
2019-09-27 23:28                             ` sjg at google.com
2019-09-06 11:51                     ` [U-Boot] [PATCH 2/2] dm: spi: Do not assume first SPI bus Thomas Fitzsimmons
2019-09-27  1:49                       ` Simon Glass
2019-09-27 23:28                         ` sjg at google.com
2019-08-26 15:50   ` [U-Boot] [PATCH v2 0/1] board: arm: Add support for Broadcom BCM7445 Bin Meng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180506110922.32469-2-fitzsim@fitzsim.org \
    --to=fitzsim@fitzsim.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.