Przeglądaj źródła

u-boot: Update the bbappend to apply to 2019.07

Update the bbappend to apply to 2019.07 and backport the new device tree
bindings and SPI/MMC support.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Alistair Francis 4 lat temu
rodzic
commit
4a6f008cec
40 zmienionych plików z 4687 dodań i 1894 usunięć
  1. 0 286
      recipes-bsp/u-boot/files/0001-riscv-add-infrastructure-for-calling-functions-on-ot.patch
  2. 975 0
      recipes-bsp/u-boot/files/0002-net-macb-sync-header-definitions-as-taken-from-Linux.patch
  3. 0 122
      recipes-bsp/u-boot/files/0002-riscv-import-the-supervisor-binary-interface-header-.patch
  4. 48 0
      recipes-bsp/u-boot/files/0003-net-macb-add-support-for-faster-clk-rates.patch
  5. 0 85
      recipes-bsp/u-boot/files/0003-riscv-implement-IPI-platform-functions-using-SBI.patch
  6. 152 0
      recipes-bsp/u-boot/files/0004-net-macb-use-bit-access-macro-from-header-file.patch
  7. 0 62
      recipes-bsp/u-boot/files/0004-riscv-delay-initialization-of-caches-and-debug-UART.patch
  8. 36 0
      recipes-bsp/u-boot/files/0005-net-macb-add-support-for-SGMII-phy-interface.patch
  9. 0 44
      recipes-bsp/u-boot/files/0005-riscv-save-hart-ID-in-register-tp-instead-of-s0.patch
  10. 86 0
      recipes-bsp/u-boot/files/0006-net-macb-add-dma_burst_length-config.patch
  11. 0 283
      recipes-bsp/u-boot/files/0006-riscv-add-support-for-multi-hart-systems.patch
  12. 71 0
      recipes-bsp/u-boot/files/0007-net-macb-apply-sane-DMA-configuration.patch
  13. 0 55
      recipes-bsp/u-boot/files/0007-riscv-boot-images-passed-to-bootm-on-all-harts.patch
  14. 135 0
      recipes-bsp/u-boot/files/0008-clk-sifive-Factor-out-PLL-library-as-separate-module.patch
  15. 0 44
      recipes-bsp/u-boot/files/0008-riscv-do-not-rely-on-hart-ID-passed-by-previous-boot.patch
  16. 581 0
      recipes-bsp/u-boot/files/0009-clk-sifive-Sync-up-WRPLL-library-with-upstream-Linux.patch
  17. 0 51
      recipes-bsp/u-boot/files/0009-riscv-hang-if-relocation-of-secondary-harts-fails.patch
  18. 95 0
      recipes-bsp/u-boot/files/0010-clk-sifive-Sync-up-DT-bindings-header-with-upstream-.patch
  19. 0 26
      recipes-bsp/u-boot/files/0010-riscv-fu540-enable-SMP.patch
  20. 246 0
      recipes-bsp/u-boot/files/0011-clk-sifive-Sync-up-main-driver-with-upstream-Linux.patch
  21. 0 27
      recipes-bsp/u-boot/files/0011-riscv-qemu-enable-SMP.patch
  22. 127 0
      recipes-bsp/u-boot/files/0012-clk-sifive-Drop-GEMGXL-clock-driver.patch
  23. 0 209
      recipes-bsp/u-boot/files/0012-riscv-Add-a-SYSCON-driver-for-Andestech-s-PLIC.patch
  24. 171 0
      recipes-bsp/u-boot/files/0013-net-macb-Extend-MACB-driver-for-SiFive-Unleashed-boa.patch
  25. 0 145
      recipes-bsp/u-boot/files/0013-riscv-Add-a-SYSCON-driver-for-Andestech-s-PLMT.patch
  26. 0 56
      recipes-bsp/u-boot/files/0014-riscv-ax25-Add-platform-specific-Kconfig-options.patch
  27. 163 0
      recipes-bsp/u-boot/files/0014-riscv-sifive-fu540-Setup-ethaddr-env-variable-using-.patch
  28. 460 0
      recipes-bsp/u-boot/files/0015-doc-sifive-fu540-Update-README-for-steps-to-create-F.patch
  29. 0 32
      recipes-bsp/u-boot/files/0015-riscv-ax25-Andes-specific-cache-shall-only-support-i.patch
  30. 60 0
      recipes-bsp/u-boot/files/0016-net-macb-Fix-check-for-little-endian-system-in.patch
  31. 0 257
      recipes-bsp/u-boot/files/0016-riscv-dts-ae350-support-SMP.patch
  32. 0 27
      recipes-bsp/u-boot/files/0017-riscv-ae350-enable-SMP.patch
  33. 469 0
      recipes-bsp/u-boot/files/0017-spi-Add-SiFive-SPI-driver.patch
  34. 50 0
      recipes-bsp/u-boot/files/0018-mmc-skip-select_mode_and_width-for-MMC-SPI-host.patch
  35. 0 35
      recipes-bsp/u-boot/files/0018-riscv-dts-fix-CONFIG_DEFAULT_DEVICE_TREE-failure.patch
  36. 641 0
      recipes-bsp/u-boot/files/0019-mmc-mmc_spi-Re-write-driver-using-DM-framework.patch
  37. 38 0
      recipes-bsp/u-boot/files/0020-riscv-sifive-fu540-Enable-SiFive-SPI-and-MMC-SPI-dri.patch
  38. 33 0
      recipes-bsp/u-boot/files/0021-doc-sifive-fu540-Update-README-for-SiFive-SPI-and-MM.patch
  39. 0 48
      recipes-bsp/u-boot/u-boot_2019.04.bbappend
  40. 50 0
      recipes-bsp/u-boot/u-boot_2019.07.bbappend

+ 0 - 286
recipes-bsp/u-boot/files/0001-riscv-add-infrastructure-for-calling-functions-on-ot.patch

@@ -1,286 +0,0 @@
-From fa33f08fd657b8568ede929df8a79bd113e9c5b1 Mon Sep 17 00:00:00 2001
-From: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Date: Sun, 17 Mar 2019 19:28:32 +0100
-Subject: [PATCH 01/18] riscv: add infrastructure for calling functions on
- other harts
-
-Harts on RISC-V boot independently, U-Boot is responsible for managing
-them. Functions are called on other harts with smp_call_function(),
-which sends inter-processor interrupts (IPIs) to all other available
-harts. Available harts are those marked as available in the device tree
-and present in the available_harts mask stored in global data. The
-available_harts mask is used to register all harts that have entered
-U-Boot. Functions are specified with their address and two function
-arguments (argument 2 and 3). The first function argument is always the
-hart ID of the hart calling the function. On the other harts, the IPI
-interrupt handler handle_ipi() must be called on software interrupts to
-handle the request and call the specified function.
-
-Functions are stored in the ipi_data data structure. Every hart has its
-own data structure in global data. While this is not required at the
-moment (all harts are expected to boot Linux), this does allow future
-expansion, where other harts may be used for monitoring or other tasks.
-
-Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Reviewed-by: Anup Patel <anup.patel@wdc.com>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-Tested-by: Bin Meng <bmeng.cn@gmail.com>
----
- arch/riscv/Kconfig                   |  19 +++++
- arch/riscv/include/asm/global_data.h |   6 ++
- arch/riscv/include/asm/smp.h         |  53 ++++++++++++
- arch/riscv/lib/Makefile              |   1 +
- arch/riscv/lib/smp.c                 | 118 +++++++++++++++++++++++++++
- 5 files changed, 197 insertions(+)
- create mode 100644 arch/riscv/include/asm/smp.h
- create mode 100644 arch/riscv/lib/smp.c
-
-diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
-index 36512a8995..4d7a115569 100644
---- a/arch/riscv/Kconfig
-+++ b/arch/riscv/Kconfig
-@@ -120,4 +120,23 @@ config RISCV_RDTIME
- config SYS_MALLOC_F_LEN
- 	default 0x1000
- 
-+config SMP
-+	bool "Symmetric Multi-Processing"
-+	help
-+	  This enables support for systems with more than one CPU. If
-+	  you say N here, U-Boot will run on single and multiprocessor
-+	  machines, but will use only one CPU of a multiprocessor
-+	  machine. If you say Y here, U-Boot will run on many, but not
-+	  all, single processor machines.
-+
-+config NR_CPUS
-+	int "Maximum number of CPUs (2-32)"
-+	range 2 32
-+	depends on SMP
-+	default 8
-+	help
-+	  On multiprocessor machines, U-Boot sets up a stack for each CPU.
-+	  Stack memory is pre-allocated. U-Boot must therefore know the
-+	  maximum number of CPUs that may be present.
-+
- endmenu
-diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
-index a3a342c6e1..80e3165e39 100644
---- a/arch/riscv/include/asm/global_data.h
-+++ b/arch/riscv/include/asm/global_data.h
-@@ -10,12 +10,18 @@
- #ifndef	__ASM_GBL_DATA_H
- #define __ASM_GBL_DATA_H
- 
-+#include <asm/smp.h>
-+
- /* Architecture-specific global data */
- struct arch_global_data {
- 	long boot_hart;		/* boot hart id */
- #ifdef CONFIG_SIFIVE_CLINT
- 	void __iomem *clint;	/* clint base address */
- #endif
-+#ifdef CONFIG_SMP
-+	struct ipi_data ipi[CONFIG_NR_CPUS];
-+#endif
-+	ulong available_harts;
- };
- 
- #include <asm-generic/global_data.h>
-diff --git a/arch/riscv/include/asm/smp.h b/arch/riscv/include/asm/smp.h
-new file mode 100644
-index 0000000000..bc863fdbaf
---- /dev/null
-+++ b/arch/riscv/include/asm/smp.h
-@@ -0,0 +1,53 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * Copyright (C) 2019 Fraunhofer AISEC,
-+ * Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-+ */
-+
-+#ifndef _ASM_RISCV_SMP_H
-+#define _ASM_RISCV_SMP_H
-+
-+/**
-+ * struct ipi_data - Inter-processor interrupt (IPI) data structure
-+ *
-+ * IPIs are used for SMP support to communicate to other harts what function to
-+ * call. Functions are in the form
-+ * void (*addr)(ulong hart, ulong arg0, ulong arg1).
-+ *
-+ * The function address and the two arguments, arg0 and arg1, are stored in the
-+ * IPI data structure. The hart ID is inserted by the hart handling the IPI and
-+ * calling the function.
-+ *
-+ * @addr: Address of function
-+ * @arg0: First argument of function
-+ * @arg1: Second argument of function
-+ */
-+struct ipi_data {
-+	ulong addr;
-+	ulong arg0;
-+	ulong arg1;
-+};
-+
-+/**
-+ * handle_ipi() - interrupt handler for software interrupts
-+ *
-+ * The IPI interrupt handler must be called to handle software interrupts. It
-+ * calls the function specified in the hart's IPI data structure.
-+ *
-+ * @hart: Hart ID of the current hart
-+ */
-+void handle_ipi(ulong hart);
-+
-+/**
-+ * smp_call_function() - Call a function on all other harts
-+ *
-+ * Send IPIs with the specified function call to all harts.
-+ *
-+ * @addr: Address of function
-+ * @arg0: First argument of function
-+ * @arg1: Second argument of function
-+ * @return 0 if OK, -ve on error
-+ */
-+int smp_call_function(ulong addr, ulong arg0, ulong arg1);
-+
-+#endif
-diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
-index edfa61690c..19370f9749 100644
---- a/arch/riscv/lib/Makefile
-+++ b/arch/riscv/lib/Makefile
-@@ -14,6 +14,7 @@ obj-$(CONFIG_SIFIVE_CLINT) += sifive_clint.o
- obj-y	+= interrupts.o
- obj-y	+= reset.o
- obj-y   += setjmp.o
-+obj-$(CONFIG_SMP) += smp.o
- 
- # For building EFI apps
- CFLAGS_$(EFI_CRT0) := $(CFLAGS_EFI)
-diff --git a/arch/riscv/lib/smp.c b/arch/riscv/lib/smp.c
-new file mode 100644
-index 0000000000..caa292ccd2
---- /dev/null
-+++ b/arch/riscv/lib/smp.c
-@@ -0,0 +1,118 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright (C) 2019 Fraunhofer AISEC,
-+ * Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-+ */
-+
-+#include <common.h>
-+#include <dm.h>
-+#include <asm/barrier.h>
-+#include <asm/smp.h>
-+
-+DECLARE_GLOBAL_DATA_PTR;
-+
-+/**
-+ * riscv_send_ipi() - Send inter-processor interrupt (IPI)
-+ *
-+ * Platform code must provide this function.
-+ *
-+ * @hart: Hart ID of receiving hart
-+ * @return 0 if OK, -ve on error
-+ */
-+extern int riscv_send_ipi(int hart);
-+
-+/**
-+ * riscv_clear_ipi() - Clear inter-processor interrupt (IPI)
-+ *
-+ * Platform code must provide this function.
-+ *
-+ * @hart: Hart ID of hart to be cleared
-+ * @return 0 if OK, -ve on error
-+ */
-+extern int riscv_clear_ipi(int hart);
-+
-+static int send_ipi_many(struct ipi_data *ipi)
-+{
-+	ofnode node, cpus;
-+	u32 reg;
-+	int ret;
-+
-+	cpus = ofnode_path("/cpus");
-+	if (!ofnode_valid(cpus)) {
-+		pr_err("Can't find cpus node!\n");
-+		return -EINVAL;
-+	}
-+
-+	ofnode_for_each_subnode(node, cpus) {
-+		/* skip if hart is marked as not available in the device tree */
-+		if (!ofnode_is_available(node))
-+			continue;
-+
-+		/* read hart ID of CPU */
-+		ret = ofnode_read_u32(node, "reg", &reg);
-+		if (ret)
-+			continue;
-+
-+		/* skip if it is the hart we are running on */
-+		if (reg == gd->arch.boot_hart)
-+			continue;
-+
-+		if (reg >= CONFIG_NR_CPUS) {
-+			pr_err("Hart ID %d is out of range, increase CONFIG_NR_CPUS\n",
-+			       reg);
-+			continue;
-+		}
-+
-+		/* skip if hart is not available */
-+		if (!(gd->arch.available_harts & (1 << reg)))
-+			continue;
-+
-+		gd->arch.ipi[reg].addr = ipi->addr;
-+		gd->arch.ipi[reg].arg0 = ipi->arg0;
-+		gd->arch.ipi[reg].arg1 = ipi->arg1;
-+
-+		ret = riscv_send_ipi(reg);
-+		if (ret) {
-+			pr_err("Cannot send IPI to hart %d\n", reg);
-+			return ret;
-+		}
-+	}
-+
-+	return 0;
-+}
-+
-+void handle_ipi(ulong hart)
-+{
-+	int ret;
-+	void (*smp_function)(ulong hart, ulong arg0, ulong arg1);
-+
-+	if (hart >= CONFIG_NR_CPUS)
-+		return;
-+
-+	ret = riscv_clear_ipi(hart);
-+	if (ret) {
-+		pr_err("Cannot clear IPI of hart %ld\n", hart);
-+		return;
-+	}
-+
-+	__smp_mb();
-+
-+	smp_function = (void (*)(ulong, ulong, ulong))gd->arch.ipi[hart].addr;
-+	invalidate_icache_all();
-+
-+	smp_function(hart, gd->arch.ipi[hart].arg0, gd->arch.ipi[hart].arg1);
-+}
-+
-+int smp_call_function(ulong addr, ulong arg0, ulong arg1)
-+{
-+	int ret = 0;
-+	struct ipi_data ipi;
-+
-+	ipi.addr = addr;
-+	ipi.arg0 = arg0;
-+	ipi.arg1 = arg1;
-+
-+	ret = send_ipi_many(&ipi);
-+
-+	return ret;
-+}
--- 
-2.21.0
-

+ 975 - 0
recipes-bsp/u-boot/files/0002-net-macb-sync-header-definitions-as-taken-from-Linux.patch

@@ -0,0 +1,975 @@
+From 360d640a0355062a4f8506dced435b2e37db16fc Mon Sep 17 00:00:00 2001
+From: Ramon Fried <rfried.dev@gmail.com>
+Date: Tue, 11 Jun 2019 18:19:25 +0300
+Subject: [PATCH 02/21] net: macb: sync header definitions as taken from Linux
+
+Few registers and bits were added by Cadence and
+they were not updated in the headers.
+Take the latest definitions as defined in Linux
+header (5.1) that also includes some comments
+about existing registers.
+
+One register was improperly named (UR), fix that.
+
+Signed-off-by: Ramon Fried <rfried.dev@gmail.com>
+Upstream-Status: Submitted
+---
+ drivers/net/macb.c |   4 +-
+ drivers/net/macb.h | 868 ++++++++++++++++++++++++++++++++++-----------
+ 2 files changed, 660 insertions(+), 212 deletions(-)
+
+diff --git a/drivers/net/macb.c b/drivers/net/macb.c
+index c5560a7111..5858004858 100644
+--- a/drivers/net/macb.c
++++ b/drivers/net/macb.c
+@@ -772,9 +772,9 @@ static int _macb_init(struct macb_device *macb, const char *name)
+ #ifdef CONFIG_DM_ETH
+ 		if ((macb->phy_interface == PHY_INTERFACE_MODE_RMII) ||
+ 		    (macb->phy_interface == PHY_INTERFACE_MODE_RGMII))
+-			gem_writel(macb, UR, GEM_BIT(RGMII));
++			gem_writel(macb, USRIO, GEM_BIT(RGMII));
+ 		else
+-			gem_writel(macb, UR, 0);
++			gem_writel(macb, USRIO, 0);
+ #else
+ #if defined(CONFIG_RGMII) || defined(CONFIG_RMII)
+ 		gem_writel(macb, UR, GEM_BIT(RGMII));
+diff --git a/drivers/net/macb.h b/drivers/net/macb.h
+index 3cc27f8560..8966c793a7 100644
+--- a/drivers/net/macb.h
++++ b/drivers/net/macb.h
+@@ -5,221 +5,410 @@
+ #ifndef __DRIVERS_MACB_H__
+ #define __DRIVERS_MACB_H__
+ 
++#define MACB_GREGS_NBR 16
++#define MACB_GREGS_VERSION 2
++#define MACB_MAX_QUEUES 8
++
+ /* MACB register offsets */
+-#define MACB_NCR				0x0000
+-#define MACB_NCFGR				0x0004
+-#define MACB_NSR				0x0008
+-#define GEM_UR					0x000c
+-#define MACB_DMACFG				0x0010
+-#define MACB_TSR				0x0014
+-#define MACB_RBQP				0x0018
+-#define MACB_TBQP				0x001c
+-#define MACB_RSR				0x0020
+-#define MACB_ISR				0x0024
+-#define MACB_IER				0x0028
+-#define MACB_IDR				0x002c
+-#define MACB_IMR				0x0030
+-#define MACB_MAN				0x0034
+-#define MACB_PTR				0x0038
+-#define MACB_PFR				0x003c
+-#define MACB_FTO				0x0040
+-#define MACB_SCF				0x0044
+-#define MACB_MCF				0x0048
+-#define MACB_FRO				0x004c
+-#define MACB_FCSE				0x0050
+-#define MACB_ALE				0x0054
+-#define MACB_DTF				0x0058
+-#define MACB_LCOL				0x005c
+-#define MACB_EXCOL				0x0060
+-#define MACB_TUND				0x0064
+-#define MACB_CSE				0x0068
+-#define MACB_RRE				0x006c
+-#define MACB_ROVR				0x0070
+-#define MACB_RSE				0x0074
+-#define MACB_ELE				0x0078
+-#define MACB_RJA				0x007c
+-#define MACB_USF				0x0080
+-#define MACB_STE				0x0084
+-#define MACB_RLE				0x0088
+-#define MACB_TPF				0x008c
+-#define MACB_HRB				0x0090
+-#define MACB_HRT				0x0094
+-#define MACB_SA1B				0x0098
+-#define MACB_SA1T				0x009c
+-#define MACB_SA2B				0x00a0
+-#define MACB_SA2T				0x00a4
+-#define MACB_SA3B				0x00a8
+-#define MACB_SA3T				0x00ac
+-#define MACB_SA4B				0x00b0
+-#define MACB_SA4T				0x00b4
+-#define MACB_TID				0x00b8
+-#define MACB_TPQ				0x00bc
+-#define MACB_USRIO				0x00c0
+-#define MACB_WOL				0x00c4
+-#define MACB_MID				0x00fc
+-
+-/* GEM specific register offsets */
+-#define GEM_DCFG1				0x0280
+-#define GEM_DCFG6				0x0294
+-
+-#define MACB_MAX_QUEUES				8
+-
+-/* GEM specific multi queues register offset */
+-/* hw_q can be 0~7 */
+-#define GEM_TBQP(hw_q)				(0x0440 + ((hw_q) << 2))
++#define MACB_NCR		0x0000 /* Network Control */
++#define MACB_NCFGR		0x0004 /* Network Config */
++#define MACB_NSR		0x0008 /* Network Status */
++#define MACB_TAR		0x000c /* AT91RM9200 only */
++#define MACB_TCR		0x0010 /* AT91RM9200 only */
++#define MACB_TSR		0x0014 /* Transmit Status */
++#define MACB_RBQP		0x0018 /* RX Q Base Address */
++#define MACB_TBQP		0x001c /* TX Q Base Address */
++#define MACB_RSR		0x0020 /* Receive Status */
++#define MACB_ISR		0x0024 /* Interrupt Status */
++#define MACB_IER		0x0028 /* Interrupt Enable */
++#define MACB_IDR		0x002c /* Interrupt Disable */
++#define MACB_IMR		0x0030 /* Interrupt Mask */
++#define MACB_MAN		0x0034 /* PHY Maintenance */
++#define MACB_PTR		0x0038
++#define MACB_PFR		0x003c
++#define MACB_FTO		0x0040
++#define MACB_SCF		0x0044
++#define MACB_MCF		0x0048
++#define MACB_FRO		0x004c
++#define MACB_FCSE		0x0050
++#define MACB_ALE		0x0054
++#define MACB_DTF		0x0058
++#define MACB_LCOL		0x005c
++#define MACB_EXCOL		0x0060
++#define MACB_TUND		0x0064
++#define MACB_CSE		0x0068
++#define MACB_RRE		0x006c
++#define MACB_ROVR		0x0070
++#define MACB_RSE		0x0074
++#define MACB_ELE		0x0078
++#define MACB_RJA		0x007c
++#define MACB_USF		0x0080
++#define MACB_STE		0x0084
++#define MACB_RLE		0x0088
++#define MACB_TPF		0x008c
++#define MACB_HRB		0x0090
++#define MACB_HRT		0x0094
++#define MACB_SA1B		0x0098
++#define MACB_SA1T		0x009c
++#define MACB_SA2B		0x00a0
++#define MACB_SA2T		0x00a4
++#define MACB_SA3B		0x00a8
++#define MACB_SA3T		0x00ac
++#define MACB_SA4B		0x00b0
++#define MACB_SA4T		0x00b4
++#define MACB_TID		0x00b8
++#define MACB_TPQ		0x00bc
++#define MACB_USRIO		0x00c0
++#define MACB_WOL		0x00c4
++#define MACB_MID		0x00fc
++#define MACB_TBQPH		0x04C8
++#define MACB_RBQPH		0x04D4
++
++/* GEM register offsets. */
++#define GEM_NCFGR		0x0004 /* Network Config */
++#define GEM_USRIO		0x000c /* User IO */
++#define GEM_DMACFG		0x0010 /* DMA Configuration */
++#define GEM_JML			0x0048 /* Jumbo Max Length */
++#define GEM_HRB			0x0080 /* Hash Bottom */
++#define GEM_HRT			0x0084 /* Hash Top */
++#define GEM_SA1B		0x0088 /* Specific1 Bottom */
++#define GEM_SA1T		0x008C /* Specific1 Top */
++#define GEM_SA2B		0x0090 /* Specific2 Bottom */
++#define GEM_SA2T		0x0094 /* Specific2 Top */
++#define GEM_SA3B		0x0098 /* Specific3 Bottom */
++#define GEM_SA3T		0x009C /* Specific3 Top */
++#define GEM_SA4B		0x00A0 /* Specific4 Bottom */
++#define GEM_SA4T		0x00A4 /* Specific4 Top */
++#define GEM_EFTSH		0x00e8 /* PTP Event Frame Transmitted Seconds Register 47:32 */
++#define GEM_EFRSH		0x00ec /* PTP Event Frame Received Seconds Register 47:32 */
++#define GEM_PEFTSH		0x00f0 /* PTP Peer Event Frame Transmitted Seconds Register 47:32 */
++#define GEM_PEFRSH		0x00f4 /* PTP Peer Event Frame Received Seconds Register 47:32 */
++#define GEM_OTX			0x0100 /* Octets transmitted */
++#define GEM_OCTTXL		0x0100 /* Octets transmitted [31:0] */
++#define GEM_OCTTXH		0x0104 /* Octets transmitted [47:32] */
++#define GEM_TXCNT		0x0108 /* Frames Transmitted counter */
++#define GEM_TXBCCNT		0x010c /* Broadcast Frames counter */
++#define GEM_TXMCCNT		0x0110 /* Multicast Frames counter */
++#define GEM_TXPAUSECNT		0x0114 /* Pause Frames Transmitted Counter */
++#define GEM_TX64CNT		0x0118 /* 64 byte Frames TX counter */
++#define GEM_TX65CNT		0x011c /* 65-127 byte Frames TX counter */
++#define GEM_TX128CNT		0x0120 /* 128-255 byte Frames TX counter */
++#define GEM_TX256CNT		0x0124 /* 256-511 byte Frames TX counter */
++#define GEM_TX512CNT		0x0128 /* 512-1023 byte Frames TX counter */
++#define GEM_TX1024CNT		0x012c /* 1024-1518 byte Frames TX counter */
++#define GEM_TX1519CNT		0x0130 /* 1519+ byte Frames TX counter */
++#define GEM_TXURUNCNT		0x0134 /* TX under run error counter */
++#define GEM_SNGLCOLLCNT		0x0138 /* Single Collision Frame Counter */
++#define GEM_MULTICOLLCNT	0x013c /* Multiple Collision Frame Counter */
++#define GEM_EXCESSCOLLCNT	0x0140 /* Excessive Collision Frame Counter */
++#define GEM_LATECOLLCNT		0x0144 /* Late Collision Frame Counter */
++#define GEM_TXDEFERCNT		0x0148 /* Deferred Transmission Frame Counter */
++#define GEM_TXCSENSECNT		0x014c /* Carrier Sense Error Counter */
++#define GEM_ORX			0x0150 /* Octets received */
++#define GEM_OCTRXL		0x0150 /* Octets received [31:0] */
++#define GEM_OCTRXH		0x0154 /* Octets received [47:32] */
++#define GEM_RXCNT		0x0158 /* Frames Received Counter */
++#define GEM_RXBROADCNT		0x015c /* Broadcast Frames Received Counter */
++#define GEM_RXMULTICNT		0x0160 /* Multicast Frames Received Counter */
++#define GEM_RXPAUSECNT		0x0164 /* Pause Frames Received Counter */
++#define GEM_RX64CNT		0x0168 /* 64 byte Frames RX Counter */
++#define GEM_RX65CNT		0x016c /* 65-127 byte Frames RX Counter */
++#define GEM_RX128CNT		0x0170 /* 128-255 byte Frames RX Counter */
++#define GEM_RX256CNT		0x0174 /* 256-511 byte Frames RX Counter */
++#define GEM_RX512CNT		0x0178 /* 512-1023 byte Frames RX Counter */
++#define GEM_RX1024CNT		0x017c /* 1024-1518 byte Frames RX Counter */
++#define GEM_RX1519CNT		0x0180 /* 1519+ byte Frames RX Counter */
++#define GEM_RXUNDRCNT		0x0184 /* Undersize Frames Received Counter */
++#define GEM_RXOVRCNT		0x0188 /* Oversize Frames Received Counter */
++#define GEM_RXJABCNT		0x018c /* Jabbers Received Counter */
++#define GEM_RXFCSCNT		0x0190 /* Frame Check Sequence Error Counter */
++#define GEM_RXLENGTHCNT		0x0194 /* Length Field Error Counter */
++#define GEM_RXSYMBCNT		0x0198 /* Symbol Error Counter */
++#define GEM_RXALIGNCNT		0x019c /* Alignment Error Counter */
++#define GEM_RXRESERRCNT		0x01a0 /* Receive Resource Error Counter */
++#define GEM_RXORCNT		0x01a4 /* Receive Overrun Counter */
++#define GEM_RXIPCCNT		0x01a8 /* IP header Checksum Error Counter */
++#define GEM_RXTCPCCNT		0x01ac /* TCP Checksum Error Counter */
++#define GEM_RXUDPCCNT		0x01b0 /* UDP Checksum Error Counter */
++#define GEM_TISUBN		0x01bc /* 1588 Timer Increment Sub-ns */
++#define GEM_TSH			0x01c0 /* 1588 Timer Seconds High */
++#define GEM_TSL			0x01d0 /* 1588 Timer Seconds Low */
++#define GEM_TN			0x01d4 /* 1588 Timer Nanoseconds */
++#define GEM_TA			0x01d8 /* 1588 Timer Adjust */
++#define GEM_TI			0x01dc /* 1588 Timer Increment */
++#define GEM_EFTSL		0x01e0 /* PTP Event Frame Tx Seconds Low */
++#define GEM_EFTN		0x01e4 /* PTP Event Frame Tx Nanoseconds */
++#define GEM_EFRSL		0x01e8 /* PTP Event Frame Rx Seconds Low */
++#define GEM_EFRN		0x01ec /* PTP Event Frame Rx Nanoseconds */
++#define GEM_PEFTSL		0x01f0 /* PTP Peer Event Frame Tx Secs Low */
++#define GEM_PEFTN		0x01f4 /* PTP Peer Event Frame Tx Ns */
++#define GEM_PEFRSL		0x01f8 /* PTP Peer Event Frame Rx Sec Low */
++#define GEM_PEFRN		0x01fc /* PTP Peer Event Frame Rx Ns */
++#define GEM_DCFG1		0x0280 /* Design Config 1 */
++#define GEM_DCFG2		0x0284 /* Design Config 2 */
++#define GEM_DCFG3		0x0288 /* Design Config 3 */
++#define GEM_DCFG4		0x028c /* Design Config 4 */
++#define GEM_DCFG5		0x0290 /* Design Config 5 */
++#define GEM_DCFG6		0x0294 /* Design Config 6 */
++#define GEM_DCFG7		0x0298 /* Design Config 7 */
++#define GEM_DCFG8		0x029C /* Design Config 8 */
++#define GEM_DCFG10		0x02A4 /* Design Config 10 */
++
++#define GEM_TXBDCTRL	0x04cc /* TX Buffer Descriptor control register */
++#define GEM_RXBDCTRL	0x04d0 /* RX Buffer Descriptor control register */
++
++/* Screener Type 2 match registers */
++#define GEM_SCRT2		0x540
++
++/* EtherType registers */
++#define GEM_ETHT		0x06E0
++
++/* Type 2 compare registers */
++#define GEM_T2CMPW0		0x0700
++#define GEM_T2CMPW1		0x0704
++#define T2CMP_OFST(t2idx)	(t2idx * 2)
++
++/* type 2 compare registers
++ * each location requires 3 compare regs
++ */
++#define GEM_IP4SRC_CMP(idx)		(idx * 3)
++#define GEM_IP4DST_CMP(idx)		(idx * 3 + 1)
++#define GEM_PORT_CMP(idx)		(idx * 3 + 2)
++
++/* Which screening type 2 EtherType register will be used (0 - 7) */
++#define SCRT2_ETHT		0
++
++#define GEM_ISR(hw_q)		(0x0400 + ((hw_q) << 2))
++#define GEM_TBQP(hw_q)		(0x0440 + ((hw_q) << 2))
++#define GEM_TBQPH(hw_q)		(0x04C8)
++#define GEM_RBQP(hw_q)		(0x0480 + ((hw_q) << 2))
++#define GEM_RBQS(hw_q)		(0x04A0 + ((hw_q) << 2))
++#define GEM_RBQPH(hw_q)		(0x04D4)
++#define GEM_IER(hw_q)		(0x0600 + ((hw_q) << 2))
++#define GEM_IDR(hw_q)		(0x0620 + ((hw_q) << 2))
++#define GEM_IMR(hw_q)		(0x0640 + ((hw_q) << 2))
+ 
+ /* Bitfields in NCR */
+-#define MACB_LB_OFFSET				0
+-#define MACB_LB_SIZE				1
+-#define MACB_LLB_OFFSET				1
+-#define MACB_LLB_SIZE				1
+-#define MACB_RE_OFFSET				2
+-#define MACB_RE_SIZE				1
+-#define MACB_TE_OFFSET				3
+-#define MACB_TE_SIZE				1
+-#define MACB_MPE_OFFSET				4
+-#define MACB_MPE_SIZE				1
+-#define MACB_CLRSTAT_OFFSET			5
+-#define MACB_CLRSTAT_SIZE			1
+-#define MACB_INCSTAT_OFFSET			6
+-#define MACB_INCSTAT_SIZE			1
+-#define MACB_WESTAT_OFFSET			7
+-#define MACB_WESTAT_SIZE			1
+-#define MACB_BP_OFFSET				8
+-#define MACB_BP_SIZE				1
+-#define MACB_TSTART_OFFSET			9
+-#define MACB_TSTART_SIZE			1
+-#define MACB_THALT_OFFSET			10
+-#define MACB_THALT_SIZE				1
+-#define MACB_NCR_TPF_OFFSET			11
+-#define MACB_NCR_TPF_SIZE			1
+-#define MACB_TZQ_OFFSET				12
+-#define MACB_TZQ_SIZE				1
++#define MACB_LB_OFFSET		0 /* reserved */
++#define MACB_LB_SIZE		1
++#define MACB_LLB_OFFSET		1 /* Loop back local */
++#define MACB_LLB_SIZE		1
++#define MACB_RE_OFFSET		2 /* Receive enable */
++#define MACB_RE_SIZE		1
++#define MACB_TE_OFFSET		3 /* Transmit enable */
++#define MACB_TE_SIZE		1
++#define MACB_MPE_OFFSET		4 /* Management port enable */
++#define MACB_MPE_SIZE		1
++#define MACB_CLRSTAT_OFFSET	5 /* Clear stats regs */
++#define MACB_CLRSTAT_SIZE	1
++#define MACB_INCSTAT_OFFSET	6 /* Incremental stats regs */
++#define MACB_INCSTAT_SIZE	1
++#define MACB_WESTAT_OFFSET	7 /* Write enable stats regs */
++#define MACB_WESTAT_SIZE	1
++#define MACB_BP_OFFSET		8 /* Back pressure */
++#define MACB_BP_SIZE		1
++#define MACB_TSTART_OFFSET	9 /* Start transmission */
++#define MACB_TSTART_SIZE	1
++#define MACB_THALT_OFFSET	10 /* Transmit halt */
++#define MACB_THALT_SIZE		1
++#define MACB_NCR_TPF_OFFSET	11 /* Transmit pause frame */
++#define MACB_NCR_TPF_SIZE	1
++#define MACB_TZQ_OFFSET		12 /* Transmit zero quantum pause frame */
++#define MACB_TZQ_SIZE		1
++#define MACB_SRTSM_OFFSET	15
++#define MACB_OSSMODE_OFFSET 24 /* Enable One Step Synchro Mode */
++#define MACB_OSSMODE_SIZE	1
+ 
+ /* Bitfields in NCFGR */
+-#define MACB_SPD_OFFSET				0
+-#define MACB_SPD_SIZE				1
+-#define MACB_FD_OFFSET				1
+-#define MACB_FD_SIZE				1
+-#define MACB_BIT_RATE_OFFSET			2
+-#define MACB_BIT_RATE_SIZE			1
+-#define MACB_JFRAME_OFFSET			3
+-#define MACB_JFRAME_SIZE			1
+-#define MACB_CAF_OFFSET				4
+-#define MACB_CAF_SIZE				1
+-#define MACB_NBC_OFFSET				5
+-#define MACB_NBC_SIZE				1
+-#define MACB_NCFGR_MTI_OFFSET			6
+-#define MACB_NCFGR_MTI_SIZE			1
+-#define MACB_UNI_OFFSET				7
+-#define MACB_UNI_SIZE				1
+-#define MACB_BIG_OFFSET				8
+-#define MACB_BIG_SIZE				1
+-#define MACB_EAE_OFFSET				9
+-#define MACB_EAE_SIZE				1
+-#define MACB_CLK_OFFSET				10
+-#define MACB_CLK_SIZE				2
+-#define MACB_RTY_OFFSET				12
+-#define MACB_RTY_SIZE				1
+-#define MACB_PAE_OFFSET				13
+-#define MACB_PAE_SIZE				1
+-#define MACB_RBOF_OFFSET			14
+-#define MACB_RBOF_SIZE				2
+-#define MACB_RLCE_OFFSET			16
+-#define MACB_RLCE_SIZE				1
+-#define MACB_DRFCS_OFFSET			17
+-#define MACB_DRFCS_SIZE				1
+-#define MACB_EFRHD_OFFSET			18
+-#define MACB_EFRHD_SIZE				1
+-#define MACB_IRXFCS_OFFSET			19
+-#define MACB_IRXFCS_SIZE			1
+-
+-#define GEM_GBE_OFFSET				10
+-#define GEM_GBE_SIZE				1
+-#define GEM_CLK_OFFSET				18
+-#define GEM_CLK_SIZE				3
+-#define GEM_DBW_OFFSET				21
+-#define GEM_DBW_SIZE				2
++#define MACB_SPD_OFFSET		0 /* Speed */
++#define MACB_SPD_SIZE		1
++#define MACB_FD_OFFSET		1 /* Full duplex */
++#define MACB_FD_SIZE		1
++#define MACB_BIT_RATE_OFFSET	2 /* Discard non-VLAN frames */
++#define MACB_BIT_RATE_SIZE	1
++#define MACB_JFRAME_OFFSET	3 /* reserved */
++#define MACB_JFRAME_SIZE	1
++#define MACB_CAF_OFFSET		4 /* Copy all frames */
++#define MACB_CAF_SIZE		1
++#define MACB_NBC_OFFSET		5 /* No broadcast */
++#define MACB_NBC_SIZE		1
++#define MACB_NCFGR_MTI_OFFSET	6 /* Multicast hash enable */
++#define MACB_NCFGR_MTI_SIZE	1
++#define MACB_UNI_OFFSET		7 /* Unicast hash enable */
++#define MACB_UNI_SIZE		1
++#define MACB_BIG_OFFSET		8 /* Receive 1536 byte frames */
++#define MACB_BIG_SIZE		1
++#define MACB_EAE_OFFSET		9 /* External address match enable */
++#define MACB_EAE_SIZE		1
++#define MACB_CLK_OFFSET		10
++#define MACB_CLK_SIZE		2
++#define MACB_RTY_OFFSET		12 /* Retry test */
++#define MACB_RTY_SIZE		1
++#define MACB_PAE_OFFSET		13 /* Pause enable */
++#define MACB_PAE_SIZE		1
++#define MACB_RM9200_RMII_OFFSET	13 /* AT91RM9200 only */
++#define MACB_RM9200_RMII_SIZE	1  /* AT91RM9200 only */
++#define MACB_RBOF_OFFSET	14 /* Receive buffer offset */
++#define MACB_RBOF_SIZE		2
++#define MACB_RLCE_OFFSET	16 /* Length field error frame discard */
++#define MACB_RLCE_SIZE		1
++#define MACB_DRFCS_OFFSET	17 /* FCS remove */
++#define MACB_DRFCS_SIZE		1
++#define MACB_EFRHD_OFFSET	18
++#define MACB_EFRHD_SIZE		1
++#define MACB_IRXFCS_OFFSET	19
++#define MACB_IRXFCS_SIZE	1
++
++/* GEM specific NCFGR bitfields. */
++#define GEM_GBE_OFFSET		10 /* Gigabit mode enable */
++#define GEM_GBE_SIZE		1
++#define GEM_PCSSEL_OFFSET	11
++#define GEM_PCSSEL_SIZE		1
++#define GEM_CLK_OFFSET		18 /* MDC clock division */
++#define GEM_CLK_SIZE		3
++#define GEM_DBW_OFFSET		21 /* Data bus width */
++#define GEM_DBW_SIZE		2
++#define GEM_RXCOEN_OFFSET	24
++#define GEM_RXCOEN_SIZE		1
++#define GEM_SGMIIEN_OFFSET	27
++#define GEM_SGMIIEN_SIZE	1
++
++
++/* Constants for data bus width. */
++#define GEM_DBW32		0 /* 32 bit AMBA AHB data bus width */
++#define GEM_DBW64		1 /* 64 bit AMBA AHB data bus width */
++#define GEM_DBW128		2 /* 128 bit AMBA AHB data bus width */
++
++/* Bitfields in DMACFG. */
++#define GEM_FBLDO_OFFSET	0 /* fixed burst length for DMA */
++#define GEM_FBLDO_SIZE		5
++#define GEM_ENDIA_DESC_OFFSET	6 /* endian swap mode for management descriptor access */
++#define GEM_ENDIA_DESC_SIZE	1
++#define GEM_ENDIA_PKT_OFFSET	7 /* endian swap mode for packet data access */
++#define GEM_ENDIA_PKT_SIZE	1
++#define GEM_RXBMS_OFFSET	8 /* RX packet buffer memory size select */
++#define GEM_RXBMS_SIZE		2
++#define GEM_TXPBMS_OFFSET	10 /* TX packet buffer memory size select */
++#define GEM_TXPBMS_SIZE		1
++#define GEM_TXCOEN_OFFSET	11 /* TX IP/TCP/UDP checksum gen offload */
++#define GEM_TXCOEN_SIZE		1
++#define GEM_RXBS_OFFSET		16 /* DMA receive buffer size */
++#define GEM_RXBS_SIZE		8
++#define GEM_DDRP_OFFSET		24 /* disc_when_no_ahb */
++#define GEM_DDRP_SIZE		1
++#define GEM_RXEXT_OFFSET	28 /* RX extended Buffer Descriptor mode */
++#define GEM_RXEXT_SIZE		1
++#define GEM_TXEXT_OFFSET	29 /* TX extended Buffer Descriptor mode */
++#define GEM_TXEXT_SIZE		1
++#define GEM_ADDR64_OFFSET	30 /* Address bus width - 64b or 32b */
++#define GEM_ADDR64_SIZE		1
++
+ 
+ /* Bitfields in NSR */
+-#define MACB_NSR_LINK_OFFSET			0
+-#define MACB_NSR_LINK_SIZE			1
+-#define MACB_MDIO_OFFSET			1
+-#define MACB_MDIO_SIZE				1
+-#define MACB_IDLE_OFFSET			2
+-#define MACB_IDLE_SIZE				1
+-
+-/* Bitfields in UR */
+-#define GEM_RGMII_OFFSET			0
+-#define GEM_RGMII_SIZE				1
++#define MACB_NSR_LINK_OFFSET	0 /* pcs_link_state */
++#define MACB_NSR_LINK_SIZE	1
++#define MACB_MDIO_OFFSET	1 /* status of the mdio_in pin */
++#define MACB_MDIO_SIZE		1
++#define MACB_IDLE_OFFSET	2 /* The PHY management logic is idle */
++#define MACB_IDLE_SIZE		1
+ 
+ /* Bitfields in TSR */
+-#define MACB_UBR_OFFSET				0
+-#define MACB_UBR_SIZE				1
+-#define MACB_COL_OFFSET				1
+-#define MACB_COL_SIZE				1
+-#define MACB_TSR_RLE_OFFSET			2
+-#define MACB_TSR_RLE_SIZE			1
+-#define MACB_TGO_OFFSET				3
+-#define MACB_TGO_SIZE				1
+-#define MACB_BEX_OFFSET				4
+-#define MACB_BEX_SIZE				1
+-#define MACB_COMP_OFFSET			5
+-#define MACB_COMP_SIZE				1
+-#define MACB_UND_OFFSET				6
+-#define MACB_UND_SIZE				1
++#define MACB_UBR_OFFSET		0 /* Used bit read */
++#define MACB_UBR_SIZE		1
++#define MACB_COL_OFFSET		1 /* Collision occurred */
++#define MACB_COL_SIZE		1
++#define MACB_TSR_RLE_OFFSET	2 /* Retry limit exceeded */
++#define MACB_TSR_RLE_SIZE	1
++#define MACB_TGO_OFFSET		3 /* Transmit go */
++#define MACB_TGO_SIZE		1
++#define MACB_BEX_OFFSET		4 /* TX frame corruption due to AHB error */
++#define MACB_BEX_SIZE		1
++#define MACB_RM9200_BNQ_OFFSET	4 /* AT91RM9200 only */
++#define MACB_RM9200_BNQ_SIZE	1 /* AT91RM9200 only */
++#define MACB_COMP_OFFSET	5 /* Trnasmit complete */
++#define MACB_COMP_SIZE		1
++#define MACB_UND_OFFSET		6 /* Trnasmit under run */
++#define MACB_UND_SIZE		1
+ 
+ /* Bitfields in RSR */
+-#define MACB_BNA_OFFSET				0
+-#define MACB_BNA_SIZE				1
+-#define MACB_REC_OFFSET				1
+-#define MACB_REC_SIZE				1
+-#define MACB_OVR_OFFSET				2
+-#define MACB_OVR_SIZE				1
++#define MACB_BNA_OFFSET		0 /* Buffer not available */
++#define MACB_BNA_SIZE		1
++#define MACB_REC_OFFSET		1 /* Frame received */
++#define MACB_REC_SIZE		1
++#define MACB_OVR_OFFSET		2 /* Receive overrun */
++#define MACB_OVR_SIZE		1
+ 
+ /* Bitfields in ISR/IER/IDR/IMR */
+-#define MACB_MFD_OFFSET				0
+-#define MACB_MFD_SIZE				1
+-#define MACB_RCOMP_OFFSET			1
+-#define MACB_RCOMP_SIZE				1
+-#define MACB_RXUBR_OFFSET			2
+-#define MACB_RXUBR_SIZE				1
+-#define MACB_TXUBR_OFFSET			3
+-#define MACB_TXUBR_SIZE				1
+-#define MACB_ISR_TUND_OFFSET			4
+-#define MACB_ISR_TUND_SIZE			1
+-#define MACB_ISR_RLE_OFFSET			5
+-#define MACB_ISR_RLE_SIZE			1
+-#define MACB_TXERR_OFFSET			6
+-#define MACB_TXERR_SIZE				1
+-#define MACB_TCOMP_OFFSET			7
+-#define MACB_TCOMP_SIZE				1
+-#define MACB_ISR_LINK_OFFSET			9
+-#define MACB_ISR_LINK_SIZE			1
+-#define MACB_ISR_ROVR_OFFSET			10
+-#define MACB_ISR_ROVR_SIZE			1
+-#define MACB_HRESP_OFFSET			11
+-#define MACB_HRESP_SIZE				1
+-#define MACB_PFR_OFFSET				12
+-#define MACB_PFR_SIZE				1
+-#define MACB_PTZ_OFFSET				13
+-#define MACB_PTZ_SIZE				1
++#define MACB_MFD_OFFSET		0 /* Management frame sent */
++#define MACB_MFD_SIZE		1
++#define MACB_RCOMP_OFFSET	1 /* Receive complete */
++#define MACB_RCOMP_SIZE		1
++#define MACB_RXUBR_OFFSET	2 /* RX used bit read */
++#define MACB_RXUBR_SIZE		1
++#define MACB_TXUBR_OFFSET	3 /* TX used bit read */
++#define MACB_TXUBR_SIZE		1
++#define MACB_ISR_TUND_OFFSET	4 /* Enable TX buffer under run interrupt */
++#define MACB_ISR_TUND_SIZE	1
++#define MACB_ISR_RLE_OFFSET	5 /* EN retry exceeded/late coll interrupt */
++#define MACB_ISR_RLE_SIZE	1
++#define MACB_TXERR_OFFSET	6 /* EN TX frame corrupt from error interrupt */
++#define MACB_TXERR_SIZE		1
++#define MACB_TCOMP_OFFSET	7 /* Enable transmit complete interrupt */
++#define MACB_TCOMP_SIZE		1
++#define MACB_ISR_LINK_OFFSET	9 /* Enable link change interrupt */
++#define MACB_ISR_LINK_SIZE	1
++#define MACB_ISR_ROVR_OFFSET	10 /* Enable receive overrun interrupt */
++#define MACB_ISR_ROVR_SIZE	1
++#define MACB_HRESP_OFFSET	11 /* Enable hrsep not OK interrupt */
++#define MACB_HRESP_SIZE		1
++#define MACB_PFR_OFFSET		12 /* Enable pause frame w/ quantum interrupt */
++#define MACB_PFR_SIZE		1
++#define MACB_PTZ_OFFSET		13 /* Enable pause time zero interrupt */
++#define MACB_PTZ_SIZE		1
++#define MACB_WOL_OFFSET		14 /* Enable wake-on-lan interrupt */
++#define MACB_WOL_SIZE		1
++#define MACB_DRQFR_OFFSET	18 /* PTP Delay Request Frame Received */
++#define MACB_DRQFR_SIZE		1
++#define MACB_SFR_OFFSET		19 /* PTP Sync Frame Received */
++#define MACB_SFR_SIZE		1
++#define MACB_DRQFT_OFFSET	20 /* PTP Delay Request Frame Transmitted */
++#define MACB_DRQFT_SIZE		1
++#define MACB_SFT_OFFSET		21 /* PTP Sync Frame Transmitted */
++#define MACB_SFT_SIZE		1
++#define MACB_PDRQFR_OFFSET	22 /* PDelay Request Frame Received */
++#define MACB_PDRQFR_SIZE	1
++#define MACB_PDRSFR_OFFSET	23 /* PDelay Response Frame Received */
++#define MACB_PDRSFR_SIZE	1
++#define MACB_PDRQFT_OFFSET	24 /* PDelay Request Frame Transmitted */
++#define MACB_PDRQFT_SIZE	1
++#define MACB_PDRSFT_OFFSET	25 /* PDelay Response Frame Transmitted */
++#define MACB_PDRSFT_SIZE	1
++#define MACB_SRI_OFFSET		26 /* TSU Seconds Register Increment */
++#define MACB_SRI_SIZE		1
++
++/* Timer increment fields */
++#define MACB_TI_CNS_OFFSET	0
++#define MACB_TI_CNS_SIZE	8
++#define MACB_TI_ACNS_OFFSET	8
++#define MACB_TI_ACNS_SIZE	8
++#define MACB_TI_NIT_OFFSET	16
++#define MACB_TI_NIT_SIZE	8
+ 
+ /* Bitfields in MAN */
+-#define MACB_DATA_OFFSET			0
+-#define MACB_DATA_SIZE				16
+-#define MACB_CODE_OFFSET			16
+-#define MACB_CODE_SIZE				2
+-#define MACB_REGA_OFFSET			18
+-#define MACB_REGA_SIZE				5
+-#define MACB_PHYA_OFFSET			23
+-#define MACB_PHYA_SIZE				5
+-#define MACB_RW_OFFSET				28
+-#define MACB_RW_SIZE				2
+-#define MACB_SOF_OFFSET				30
+-#define MACB_SOF_SIZE				2
+-
+-/* Bitfields in USRIO */
++#define MACB_DATA_OFFSET	0 /* data */
++#define MACB_DATA_SIZE		16
++#define MACB_CODE_OFFSET	16 /* Must be written to 10 */
++#define MACB_CODE_SIZE		2
++#define MACB_REGA_OFFSET	18 /* Register address */
++#define MACB_REGA_SIZE		5
++#define MACB_PHYA_OFFSET	23 /* PHY address */
++#define MACB_PHYA_SIZE		5
++#define MACB_RW_OFFSET		28 /* Operation. 10 is read. 01 is write. */
++#define MACB_RW_SIZE		2
++#define MACB_SOF_OFFSET		30 /* Must be written to 1 for Clause 22 */
++#define MACB_SOF_SIZE		2
++
++/* Bitfields in USRIO (AVR32) */
+ #define MACB_MII_OFFSET				0
+ #define MACB_MII_SIZE				1
+ #define MACB_EAM_OFFSET				1
+@@ -232,6 +421,8 @@
+ /* Bitfields in USRIO (AT91) */
+ #define MACB_RMII_OFFSET			0
+ #define MACB_RMII_SIZE				1
++#define GEM_RGMII_OFFSET			0 /* GEM gigabit mode */
++#define GEM_RGMII_SIZE				1
+ #define MACB_CLKEN_OFFSET			1
+ #define MACB_CLKEN_SIZE				1
+ 
+@@ -249,17 +440,166 @@
+ 
+ /* Bitfields in MID */
+ #define MACB_IDNUM_OFFSET			16
+-#define MACB_IDNUM_SIZE				16
++#define MACB_IDNUM_SIZE				12
++#define MACB_REV_OFFSET				0
++#define MACB_REV_SIZE				16
+ 
+-/* Bitfields in DCFG1 */
++/* Bitfields in DCFG1. */
++#define GEM_IRQCOR_OFFSET			23
++#define GEM_IRQCOR_SIZE				1
+ #define GEM_DBWDEF_OFFSET			25
+ #define GEM_DBWDEF_SIZE				3
+ 
+-/* constants for data bus width */
+-#define GEM_DBW32				0
+-#define GEM_DBW64				1
+-#define GEM_DBW128				2
++/* Bitfields in DCFG2. */
++#define GEM_RX_PKT_BUFF_OFFSET			20
++#define GEM_RX_PKT_BUFF_SIZE			1
++#define GEM_TX_PKT_BUFF_OFFSET			21
++#define GEM_TX_PKT_BUFF_SIZE			1
++
++
++/* Bitfields in DCFG5. */
++#define GEM_TSU_OFFSET				8
++#define GEM_TSU_SIZE				1
++
++/* Bitfields in DCFG6. */
++#define GEM_PBUF_LSO_OFFSET			27
++#define GEM_PBUF_LSO_SIZE			1
++#define GEM_DAW64_OFFSET			23
++#define GEM_DAW64_SIZE				1
++
++/* Bitfields in DCFG8. */
++#define GEM_T1SCR_OFFSET			24
++#define GEM_T1SCR_SIZE				8
++#define GEM_T2SCR_OFFSET			16
++#define GEM_T2SCR_SIZE				8
++#define GEM_SCR2ETH_OFFSET			8
++#define GEM_SCR2ETH_SIZE			8
++#define GEM_SCR2CMP_OFFSET			0
++#define GEM_SCR2CMP_SIZE			8
++
++/* Bitfields in DCFG10 */
++#define GEM_TXBD_RDBUFF_OFFSET			12
++#define GEM_TXBD_RDBUFF_SIZE			4
++#define GEM_RXBD_RDBUFF_OFFSET			8
++#define GEM_RXBD_RDBUFF_SIZE			4
++
++/* Bitfields in TISUBN */
++#define GEM_SUBNSINCR_OFFSET			0
++#define GEM_SUBNSINCR_SIZE			16
++
++/* Bitfields in TI */
++#define GEM_NSINCR_OFFSET			0
++#define GEM_NSINCR_SIZE				8
++
++/* Bitfields in TSH */
++#define GEM_TSH_OFFSET				0 /* TSU timer value (s). MSB [47:32] of seconds timer count */
++#define GEM_TSH_SIZE				16
++
++/* Bitfields in TSL */
++#define GEM_TSL_OFFSET				0 /* TSU timer value (s). LSB [31:0] of seconds timer count */
++#define GEM_TSL_SIZE				32
+ 
++/* Bitfields in TN */
++#define GEM_TN_OFFSET				0 /* TSU timer value (ns) */
++#define GEM_TN_SIZE					30
++
++/* Bitfields in TXBDCTRL */
++#define GEM_TXTSMODE_OFFSET			4 /* TX Descriptor Timestamp Insertion mode */
++#define GEM_TXTSMODE_SIZE			2
++
++/* Bitfields in RXBDCTRL */
++#define GEM_RXTSMODE_OFFSET			4 /* RX Descriptor Timestamp Insertion mode */
++#define GEM_RXTSMODE_SIZE			2
++
++/* Bitfields in SCRT2 */
++#define GEM_QUEUE_OFFSET			0 /* Queue Number */
++#define GEM_QUEUE_SIZE				4
++#define GEM_VLANPR_OFFSET			4 /* VLAN Priority */
++#define GEM_VLANPR_SIZE				3
++#define GEM_VLANEN_OFFSET			8 /* VLAN Enable */
++#define GEM_VLANEN_SIZE				1
++#define GEM_ETHT2IDX_OFFSET			9 /* Index to screener type 2 EtherType register */
++#define GEM_ETHT2IDX_SIZE			3
++#define GEM_ETHTEN_OFFSET			12 /* EtherType Enable */
++#define GEM_ETHTEN_SIZE				1
++#define GEM_CMPA_OFFSET				13 /* Compare A - Index to screener type 2 Compare register */
++#define GEM_CMPA_SIZE				5
++#define GEM_CMPAEN_OFFSET			18 /* Compare A Enable */
++#define GEM_CMPAEN_SIZE				1
++#define GEM_CMPB_OFFSET				19 /* Compare B - Index to screener type 2 Compare register */
++#define GEM_CMPB_SIZE				5
++#define GEM_CMPBEN_OFFSET			24 /* Compare B Enable */
++#define GEM_CMPBEN_SIZE				1
++#define GEM_CMPC_OFFSET				25 /* Compare C - Index to screener type 2 Compare register */
++#define GEM_CMPC_SIZE				5
++#define GEM_CMPCEN_OFFSET			30 /* Compare C Enable */
++#define GEM_CMPCEN_SIZE				1
++
++/* Bitfields in ETHT */
++#define GEM_ETHTCMP_OFFSET			0 /* EtherType compare value */
++#define GEM_ETHTCMP_SIZE			16
++
++/* Bitfields in T2CMPW0 */
++#define GEM_T2CMP_OFFSET			16 /* 0xFFFF0000 compare value */
++#define GEM_T2CMP_SIZE				16
++#define GEM_T2MASK_OFFSET			0 /* 0x0000FFFF compare value or mask */
++#define GEM_T2MASK_SIZE				16
++
++/* Bitfields in T2CMPW1 */
++#define GEM_T2DISMSK_OFFSET			9 /* disable mask */
++#define GEM_T2DISMSK_SIZE			1
++#define GEM_T2CMPOFST_OFFSET			7 /* compare offset */
++#define GEM_T2CMPOFST_SIZE			2
++#define GEM_T2OFST_OFFSET			0 /* offset value */
++#define GEM_T2OFST_SIZE				7
++
++/* Offset for screener type 2 compare values (T2CMPOFST).
++ * Note the offset is applied after the specified point,
++ * e.g. GEM_T2COMPOFST_ETYPE denotes the EtherType field, so an offset
++ * of 12 bytes from this would be the source IP address in an IP header
++ */
++#define GEM_T2COMPOFST_SOF		0
++#define GEM_T2COMPOFST_ETYPE	1
++#define GEM_T2COMPOFST_IPHDR	2
++#define GEM_T2COMPOFST_TCPUDP	3
++
++/* offset from EtherType to IP address */
++#define ETYPE_SRCIP_OFFSET			12
++#define ETYPE_DSTIP_OFFSET			16
++
++/* offset from IP header to port */
++#define IPHDR_SRCPORT_OFFSET		0
++#define IPHDR_DSTPORT_OFFSET		2
++
++/* Transmit DMA buffer descriptor Word 1 */
++#define GEM_DMA_TXVALID_OFFSET		23 /* timestamp has been captured in the Buffer Descriptor */
++#define GEM_DMA_TXVALID_SIZE		1
++
++/* Receive DMA buffer descriptor Word 0 */
++#define GEM_DMA_RXVALID_OFFSET		2 /* indicates a valid timestamp in the Buffer Descriptor */
++#define GEM_DMA_RXVALID_SIZE		1
++
++/* DMA buffer descriptor Word 2 (32 bit addressing) or Word 4 (64 bit addressing) */
++#define GEM_DMA_SECL_OFFSET			30 /* Timestamp seconds[1:0]  */
++#define GEM_DMA_SECL_SIZE			2
++#define GEM_DMA_NSEC_OFFSET			0 /* Timestamp nanosecs [29:0] */
++#define GEM_DMA_NSEC_SIZE			30
++
++/* DMA buffer descriptor Word 3 (32 bit addressing) or Word 5 (64 bit addressing) */
++
++/* New hardware supports 12 bit precision of timestamp in DMA buffer descriptor.
++ * Old hardware supports only 6 bit precision but it is enough for PTP.
++ * Less accuracy is used always instead of checking hardware version.
++ */
++#define GEM_DMA_SECH_OFFSET			0 /* Timestamp seconds[5:2] */
++#define GEM_DMA_SECH_SIZE			4
++#define GEM_DMA_SEC_WIDTH			(GEM_DMA_SECH_SIZE + GEM_DMA_SECL_SIZE)
++#define GEM_DMA_SEC_TOP				(1 << GEM_DMA_SEC_WIDTH)
++#define GEM_DMA_SEC_MASK			(GEM_DMA_SEC_TOP - 1)
++
++/* Bitfields in ADJ */
++#define GEM_ADDSUB_OFFSET			31
++#define GEM_ADDSUB_SIZE				1
+ /* Constants for CLK */
+ #define MACB_CLK_DIV8				0
+ #define MACB_CLK_DIV16				1
+@@ -280,19 +620,38 @@
+ #define MACB_MAN_READ				2
+ #define MACB_MAN_CODE				2
+ 
++/* Capability mask bits */
++#define MACB_CAPS_ISR_CLEAR_ON_WRITE		0x00000001
++#define MACB_CAPS_USRIO_HAS_CLKEN		0x00000002
++#define MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII	0x00000004
++#define MACB_CAPS_NO_GIGABIT_HALF		0x00000008
++#define MACB_CAPS_USRIO_DISABLED		0x00000010
++#define MACB_CAPS_JUMBO				0x00000020
++#define MACB_CAPS_GEM_HAS_PTP			0x00000040
++#define MACB_CAPS_BD_RD_PREFETCH		0x00000080
++#define MACB_CAPS_NEEDS_RSTONUBR		0x00000100
++#define MACB_CAPS_FIFO_MODE			0x10000000
++#define MACB_CAPS_GIGABIT_MODE_AVAILABLE	0x20000000
++#define MACB_CAPS_SG_DISABLED			0x40000000
++#define MACB_CAPS_MACB_IS_GEM			0x80000000
++
++/* LSO settings */
++#define MACB_LSO_UFO_ENABLE			0x01
++#define MACB_LSO_TSO_ENABLE			0x02
++
+ /* Bit manipulation macros */
+ #define MACB_BIT(name)					\
+ 	(1 << MACB_##name##_OFFSET)
+-#define MACB_BF(name, value)				\
++#define MACB_BF(name,value)				\
+ 	(((value) & ((1 << MACB_##name##_SIZE) - 1))	\
+ 	 << MACB_##name##_OFFSET)
+-#define MACB_BFEXT(name, value)\
++#define MACB_BFEXT(name,value)\
+ 	(((value) >> MACB_##name##_OFFSET)		\
+ 	 & ((1 << MACB_##name##_SIZE) - 1))
+-#define MACB_BFINS(name, value, old)			\
++#define MACB_BFINS(name,value,old)			\
+ 	(((old) & ~(((1 << MACB_##name##_SIZE) - 1)	\
+ 		    << MACB_##name##_OFFSET))		\
+-	 | MACB_BF(name, value))
++	 | MACB_BF(name,value))
+ 
+ #define GEM_BIT(name)					\
+ 	(1 << GEM_##name##_OFFSET)
+@@ -316,6 +675,95 @@
+ 	readl((port)->regs + GEM_##reg)
+ #define gem_writel(port, reg, value)			\
+ 	writel((value), (port)->regs + GEM_##reg)
++
++/* DMA descriptor bitfields */
++#define MACB_RX_USED_OFFSET			0
++#define MACB_RX_USED_SIZE			1
++#define MACB_RX_WRAP_OFFSET			1
++#define MACB_RX_WRAP_SIZE			1
++#define MACB_RX_WADDR_OFFSET			2
++#define MACB_RX_WADDR_SIZE			30
++
++#define MACB_RX_FRMLEN_OFFSET			0
++#define MACB_RX_FRMLEN_SIZE			12
++#define MACB_RX_OFFSET_OFFSET			12
++#define MACB_RX_OFFSET_SIZE			2
++#define MACB_RX_SOF_OFFSET			14
++#define MACB_RX_SOF_SIZE			1
++#define MACB_RX_EOF_OFFSET			15
++#define MACB_RX_EOF_SIZE			1
++#define MACB_RX_CFI_OFFSET			16
++#define MACB_RX_CFI_SIZE			1
++#define MACB_RX_VLAN_PRI_OFFSET			17
++#define MACB_RX_VLAN_PRI_SIZE			3
++#define MACB_RX_PRI_TAG_OFFSET			20
++#define MACB_RX_PRI_TAG_SIZE			1
++#define MACB_RX_VLAN_TAG_OFFSET			21
++#define MACB_RX_VLAN_TAG_SIZE			1
++#define MACB_RX_TYPEID_MATCH_OFFSET		22
++#define MACB_RX_TYPEID_MATCH_SIZE		1
++#define MACB_RX_SA4_MATCH_OFFSET		23
++#define MACB_RX_SA4_MATCH_SIZE			1
++#define MACB_RX_SA3_MATCH_OFFSET		24
++#define MACB_RX_SA3_MATCH_SIZE			1
++#define MACB_RX_SA2_MATCH_OFFSET		25
++#define MACB_RX_SA2_MATCH_SIZE			1
++#define MACB_RX_SA1_MATCH_OFFSET		26
++#define MACB_RX_SA1_MATCH_SIZE			1
++#define MACB_RX_EXT_MATCH_OFFSET		28
++#define MACB_RX_EXT_MATCH_SIZE			1
++#define MACB_RX_UHASH_MATCH_OFFSET		29
++#define MACB_RX_UHASH_MATCH_SIZE		1
++#define MACB_RX_MHASH_MATCH_OFFSET		30
++#define MACB_RX_MHASH_MATCH_SIZE		1
++#define MACB_RX_BROADCAST_OFFSET		31
++#define MACB_RX_BROADCAST_SIZE			1
++
++#define MACB_RX_FRMLEN_MASK			0xFFF
++#define MACB_RX_JFRMLEN_MASK			0x3FFF
++
++/* RX checksum offload disabled: bit 24 clear in NCFGR */
++#define GEM_RX_TYPEID_MATCH_OFFSET		22
++#define GEM_RX_TYPEID_MATCH_SIZE		2
++
++/* RX checksum offload enabled: bit 24 set in NCFGR */
++#define GEM_RX_CSUM_OFFSET			22
++#define GEM_RX_CSUM_SIZE			2
++
++#define MACB_TX_FRMLEN_OFFSET			0
++#define MACB_TX_FRMLEN_SIZE			11
++#define MACB_TX_LAST_OFFSET			15
++#define MACB_TX_LAST_SIZE			1
++#define MACB_TX_NOCRC_OFFSET			16
++#define MACB_TX_NOCRC_SIZE			1
++#define MACB_MSS_MFS_OFFSET			16
++#define MACB_MSS_MFS_SIZE			14
++#define MACB_TX_LSO_OFFSET			17
++#define MACB_TX_LSO_SIZE			2
++#define MACB_TX_TCP_SEQ_SRC_OFFSET		19
++#define MACB_TX_TCP_SEQ_SRC_SIZE		1
++#define MACB_TX_BUF_EXHAUSTED_OFFSET		27
++#define MACB_TX_BUF_EXHAUSTED_SIZE		1
++#define MACB_TX_UNDERRUN_OFFSET			28
++#define MACB_TX_UNDERRUN_SIZE			1
++#define MACB_TX_ERROR_OFFSET			29
++#define MACB_TX_ERROR_SIZE			1
++#define MACB_TX_WRAP_OFFSET			30
++#define MACB_TX_WRAP_SIZE			1
++#define MACB_TX_USED_OFFSET			31
++#define MACB_TX_USED_SIZE			1
++
++#define GEM_TX_FRMLEN_OFFSET			0
++#define GEM_TX_FRMLEN_SIZE			14
++
++/* Buffer descriptor constants */
++#define GEM_RX_CSUM_NONE			0
++#define GEM_RX_CSUM_IP_ONLY			1
++#define GEM_RX_CSUM_IP_TCP			2
++#define GEM_RX_CSUM_IP_UDP			3
++
++/* limit RX checksum offload to TCP and UDP packets */
++#define GEM_RX_CSUM_CHECKED_MASK		2
+ #define gem_writel_queue_TBQP(port, value, queue_num)	\
+ 	writel((value), (port)->regs + GEM_TBQP(queue_num))
+ 
+-- 
+2.22.0
+

+ 0 - 122
recipes-bsp/u-boot/files/0002-riscv-import-the-supervisor-binary-interface-header-.patch

@@ -1,122 +0,0 @@
-From 34a0626fc344f51cd768efecdd52628b677fb9a8 Mon Sep 17 00:00:00 2001
-From: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Date: Sun, 17 Mar 2019 19:28:33 +0100
-Subject: [PATCH 02/18] riscv: import the supervisor binary interface header
- file
-
-Import the supervisor binary interface (SBI) header file from Linux
-(arch/riscv/include/asm/sbi.h). The last change to it was in commit
-6d60b6ee0c97 ("RISC-V: Device, timer, IRQs, and the SBI").
-
-Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Reviewed-by: Anup Patel <anup.patel@wdc.com>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-Reviewed-by: Atish Patra <atish.patra@wdc.com>
----
- arch/riscv/include/asm/sbi.h | 94 ++++++++++++++++++++++++++++++++++++
- 1 file changed, 94 insertions(+)
- create mode 100644 arch/riscv/include/asm/sbi.h
-
-diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
-new file mode 100644
-index 0000000000..ced57defdd
---- /dev/null
-+++ b/arch/riscv/include/asm/sbi.h
-@@ -0,0 +1,94 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * Copyright (C) 2015 Regents of the University of California
-+ *
-+ * Taken from Linux arch/riscv/include/asm/sbi.h
-+ */
-+
-+#ifndef _ASM_RISCV_SBI_H
-+#define _ASM_RISCV_SBI_H
-+
-+#include <linux/types.h>
-+
-+#define SBI_SET_TIMER 0
-+#define SBI_CONSOLE_PUTCHAR 1
-+#define SBI_CONSOLE_GETCHAR 2
-+#define SBI_CLEAR_IPI 3
-+#define SBI_SEND_IPI 4
-+#define SBI_REMOTE_FENCE_I 5
-+#define SBI_REMOTE_SFENCE_VMA 6
-+#define SBI_REMOTE_SFENCE_VMA_ASID 7
-+#define SBI_SHUTDOWN 8
-+
-+#define SBI_CALL(which, arg0, arg1, arg2) ({			\
-+	register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0);	\
-+	register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1);	\
-+	register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2);	\
-+	register uintptr_t a7 asm ("a7") = (uintptr_t)(which);	\
-+	asm volatile ("ecall"					\
-+		      : "+r" (a0)				\
-+		      : "r" (a1), "r" (a2), "r" (a7)		\
-+		      : "memory");				\
-+	a0;							\
-+})
-+
-+/* Lazy implementations until SBI is finalized */
-+#define SBI_CALL_0(which) SBI_CALL(which, 0, 0, 0)
-+#define SBI_CALL_1(which, arg0) SBI_CALL(which, arg0, 0, 0)
-+#define SBI_CALL_2(which, arg0, arg1) SBI_CALL(which, arg0, arg1, 0)
-+
-+static inline void sbi_console_putchar(int ch)
-+{
-+	SBI_CALL_1(SBI_CONSOLE_PUTCHAR, ch);
-+}
-+
-+static inline int sbi_console_getchar(void)
-+{
-+	return SBI_CALL_0(SBI_CONSOLE_GETCHAR);
-+}
-+
-+static inline void sbi_set_timer(uint64_t stime_value)
-+{
-+#if __riscv_xlen == 32
-+	SBI_CALL_2(SBI_SET_TIMER, stime_value, stime_value >> 32);
-+#else
-+	SBI_CALL_1(SBI_SET_TIMER, stime_value);
-+#endif
-+}
-+
-+static inline void sbi_shutdown(void)
-+{
-+	SBI_CALL_0(SBI_SHUTDOWN);
-+}
-+
-+static inline void sbi_clear_ipi(void)
-+{
-+	SBI_CALL_0(SBI_CLEAR_IPI);
-+}
-+
-+static inline void sbi_send_ipi(const unsigned long *hart_mask)
-+{
-+	SBI_CALL_1(SBI_SEND_IPI, hart_mask);
-+}
-+
-+static inline void sbi_remote_fence_i(const unsigned long *hart_mask)
-+{
-+	SBI_CALL_1(SBI_REMOTE_FENCE_I, hart_mask);
-+}
-+
-+static inline void sbi_remote_sfence_vma(const unsigned long *hart_mask,
-+					 unsigned long start,
-+					 unsigned long size)
-+{
-+	SBI_CALL_1(SBI_REMOTE_SFENCE_VMA, hart_mask);
-+}
-+
-+static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
-+					      unsigned long start,
-+					      unsigned long size,
-+					      unsigned long asid)
-+{
-+	SBI_CALL_1(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask);
-+}
-+
-+#endif
--- 
-2.21.0
-

+ 48 - 0
recipes-bsp/u-boot/files/0003-net-macb-add-support-for-faster-clk-rates.patch

@@ -0,0 +1,48 @@
+From cde0950c41e0a8d559acbcaae86775898d511118 Mon Sep 17 00:00:00 2001
+From: Ramon Fried <rfried.dev@gmail.com>
+Date: Tue, 11 Jun 2019 18:19:26 +0300
+Subject: [PATCH 03/21] net: macb: add support for faster clk rates
+
+add support for clock rates higher than 2.4Mhz
+
+Signed-off-by: Ramon Fried <rfried.dev@gmail.com>
+Upstream-Status: Submitted
+---
+ drivers/net/macb.c | 6 +++++-
+ drivers/net/macb.h | 2 ++
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/macb.c b/drivers/net/macb.c
+index 5858004858..6885da9c38 100644
+--- a/drivers/net/macb.c
++++ b/drivers/net/macb.c
+@@ -901,8 +901,12 @@ static u32 gem_mdc_clk_div(int id, struct macb_device *macb)
+ 		config = GEM_BF(CLK, GEM_CLK_DIV48);
+ 	else if (macb_hz < 160000000)
+ 		config = GEM_BF(CLK, GEM_CLK_DIV64);
+-	else
++	else if (macb_hz < 240000000)
+ 		config = GEM_BF(CLK, GEM_CLK_DIV96);
++	else if (macb_hz < 320000000)
++		config = GEM_BF(CLK, GEM_CLK_DIV128);
++	else
++		config = GEM_BF(CLK, GEM_CLK_DIV224);
+ 
+ 	return config;
+ }
+diff --git a/drivers/net/macb.h b/drivers/net/macb.h
+index 8966c793a7..9b16383eba 100644
+--- a/drivers/net/macb.h
++++ b/drivers/net/macb.h
+@@ -613,6 +613,8 @@
+ #define GEM_CLK_DIV48				3
+ #define GEM_CLK_DIV64				4
+ #define GEM_CLK_DIV96				5
++#define GEM_CLK_DIV128				6
++#define GEM_CLK_DIV224				7
+ 
+ /* Constants for MAN register */
+ #define MACB_MAN_SOF				1
+-- 
+2.22.0
+

+ 0 - 85
recipes-bsp/u-boot/files/0003-riscv-implement-IPI-platform-functions-using-SBI.patch

@@ -1,85 +0,0 @@
-From f152febb2a97696f7c7e6df46bf585cfc962a835 Mon Sep 17 00:00:00 2001
-From: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Date: Sun, 17 Mar 2019 19:28:34 +0100
-Subject: [PATCH 03/18] riscv: implement IPI platform functions using SBI
-
-The supervisor binary interface (SBI) provides the necessary functions
-to implement the platform IPI functions riscv_send_ipi() and
-riscv_clear_ipi(). Use it to implement them.
-
-This adds support for inter-processor interrupts (IPIs) on RISC-V CPUs
-running in supervisor mode. Support for machine mode is already
-available for CPUs that include the SiFive CLINT.
-
-Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Reviewed-by: Anup Patel <anup.patel@wdc.com>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-Reviewed-by: Atish Patra <atish.patra@wdc.com>
-Tested-by: Bin Meng <bmeng.cn@gmail.com>
----
- arch/riscv/Kconfig       |  5 +++++
- arch/riscv/lib/Makefile  |  1 +
- arch/riscv/lib/sbi_ipi.c | 25 +++++++++++++++++++++++++
- 3 files changed, 31 insertions(+)
- create mode 100644 arch/riscv/lib/sbi_ipi.c
-
-diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
-index 4d7a115569..9da609b33b 100644
---- a/arch/riscv/Kconfig
-+++ b/arch/riscv/Kconfig
-@@ -139,4 +139,9 @@ config NR_CPUS
- 	  Stack memory is pre-allocated. U-Boot must therefore know the
- 	  maximum number of CPUs that may be present.
- 
-+config SBI_IPI
-+	bool
-+	default y if RISCV_SMODE
-+	depends on SMP
-+
- endmenu
-diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
-index 19370f9749..35dbf643e4 100644
---- a/arch/riscv/lib/Makefile
-+++ b/arch/riscv/lib/Makefile
-@@ -13,6 +13,7 @@ obj-$(CONFIG_RISCV_RDTIME) += rdtime.o
- obj-$(CONFIG_SIFIVE_CLINT) += sifive_clint.o
- obj-y	+= interrupts.o
- obj-y	+= reset.o
-+obj-$(CONFIG_SBI_IPI) += sbi_ipi.o
- obj-y   += setjmp.o
- obj-$(CONFIG_SMP) += smp.o
- 
-diff --git a/arch/riscv/lib/sbi_ipi.c b/arch/riscv/lib/sbi_ipi.c
-new file mode 100644
-index 0000000000..170346da68
---- /dev/null
-+++ b/arch/riscv/lib/sbi_ipi.c
-@@ -0,0 +1,25 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright (C) 2019 Fraunhofer AISEC,
-+ * Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-+ */
-+
-+#include <common.h>
-+#include <asm/sbi.h>
-+
-+int riscv_send_ipi(int hart)
-+{
-+	ulong mask;
-+
-+	mask = 1UL << hart;
-+	sbi_send_ipi(&mask);
-+
-+	return 0;
-+}
-+
-+int riscv_clear_ipi(int hart)
-+{
-+	sbi_clear_ipi();
-+
-+	return 0;
-+}
--- 
-2.21.0
-

+ 152 - 0
recipes-bsp/u-boot/files/0004-net-macb-use-bit-access-macro-from-header-file.patch

@@ -0,0 +1,152 @@
+From 1fe204b13da46ad8528589280bbd9574167402af Mon Sep 17 00:00:00 2001
+From: Ramon Fried <rfried.dev@gmail.com>
+Date: Tue, 11 Jun 2019 18:19:27 +0300
+Subject: [PATCH 04/21] net: macb: use bit access macro from header file
+
+macb.h provides macros for reading/setting bitfields,
+in macb registers and descriptors. use that instead
+of redefining them in the source file.
+
+Signed-off-by: Ramon Fried <rfried.dev@gmail.com>
+Upstream-Status: Submitted
+---
+ drivers/net/macb.c | 48 +++++++++++++++-------------------------------
+ 1 file changed, 15 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/net/macb.c b/drivers/net/macb.c
+index 6885da9c38..d957afe21a 100644
+--- a/drivers/net/macb.c
++++ b/drivers/net/macb.c
+@@ -77,27 +77,8 @@ struct macb_dma_desc {
+ #define MACB_RX_DMA_DESC_SIZE	(DMA_DESC_BYTES(MACB_RX_RING_SIZE))
+ #define MACB_TX_DUMMY_DMA_DESC_SIZE	(DMA_DESC_BYTES(1))
+ 
+-#define RXADDR_USED		0x00000001
+-#define RXADDR_WRAP		0x00000002
+-
+ #define RXBUF_FRMLEN_MASK	0x00000fff
+-#define RXBUF_FRAME_START	0x00004000
+-#define RXBUF_FRAME_END		0x00008000
+-#define RXBUF_TYPEID_MATCH	0x00400000
+-#define RXBUF_ADDR4_MATCH	0x00800000
+-#define RXBUF_ADDR3_MATCH	0x01000000
+-#define RXBUF_ADDR2_MATCH	0x02000000
+-#define RXBUF_ADDR1_MATCH	0x04000000
+-#define RXBUF_BROADCAST		0x80000000
+-
+ #define TXBUF_FRMLEN_MASK	0x000007ff
+-#define TXBUF_FRAME_END		0x00008000
+-#define TXBUF_NOCRC		0x00010000
+-#define TXBUF_EXHAUSTED		0x08000000
+-#define TXBUF_UNDERRUN		0x10000000
+-#define TXBUF_MAXRETRY		0x20000000
+-#define TXBUF_WRAP		0x40000000
+-#define TXBUF_USED		0x80000000
+ 
+ struct macb_device {
+ 	void			*regs;
+@@ -316,9 +297,9 @@ static int _macb_send(struct macb_device *macb, const char *name, void *packet,
+ 	paddr = dma_map_single(packet, length, DMA_TO_DEVICE);
+ 
+ 	ctrl = length & TXBUF_FRMLEN_MASK;
+-	ctrl |= TXBUF_FRAME_END;
++	ctrl |= MACB_BIT(TX_LAST);
+ 	if (tx_head == (MACB_TX_RING_SIZE - 1)) {
+-		ctrl |= TXBUF_WRAP;
++		ctrl |= MACB_BIT(TX_WRAP);
+ 		macb->tx_head = 0;
+ 	} else {
+ 		macb->tx_head++;
+@@ -340,7 +321,7 @@ static int _macb_send(struct macb_device *macb, const char *name, void *packet,
+ 		barrier();
+ 		macb_invalidate_ring_desc(macb, TX);
+ 		ctrl = macb->tx_ring[tx_head].ctrl;
+-		if (ctrl & TXBUF_USED)
++		if (ctrl & MACB_BIT(TX_USED))
+ 			break;
+ 		udelay(1);
+ 	}
+@@ -348,9 +329,9 @@ static int _macb_send(struct macb_device *macb, const char *name, void *packet,
+ 	dma_unmap_single(packet, length, paddr);
+ 
+ 	if (i <= MACB_TX_TIMEOUT) {
+-		if (ctrl & TXBUF_UNDERRUN)
++		if (ctrl & MACB_BIT(TX_UNDERRUN))
+ 			printf("%s: TX underrun\n", name);
+-		if (ctrl & TXBUF_EXHAUSTED)
++		if (ctrl & MACB_BIT(TX_BUF_EXHAUSTED))
+ 			printf("%s: TX buffers exhausted in mid frame\n", name);
+ 	} else {
+ 		printf("%s: TX timeout\n", name);
+@@ -369,14 +350,14 @@ static void reclaim_rx_buffers(struct macb_device *macb,
+ 
+ 	macb_invalidate_ring_desc(macb, RX);
+ 	while (i > new_tail) {
+-		macb->rx_ring[i].addr &= ~RXADDR_USED;
++		macb->rx_ring[i].addr &= ~MACB_BIT(RX_USED);
+ 		i++;
+ 		if (i > MACB_RX_RING_SIZE)
+ 			i = 0;
+ 	}
+ 
+ 	while (i < new_tail) {
+-		macb->rx_ring[i].addr &= ~RXADDR_USED;
++		macb->rx_ring[i].addr &= ~MACB_BIT(RX_USED);
+ 		i++;
+ 	}
+ 
+@@ -396,17 +377,17 @@ static int _macb_recv(struct macb_device *macb, uchar **packetp)
+ 	for (;;) {
+ 		macb_invalidate_ring_desc(macb, RX);
+ 
+-		if (!(macb->rx_ring[next_rx_tail].addr & RXADDR_USED))
++		if (!(macb->rx_ring[next_rx_tail].addr & MACB_BIT(RX_USED)))
+ 			return -EAGAIN;
+ 
+ 		status = macb->rx_ring[next_rx_tail].ctrl;
+-		if (status & RXBUF_FRAME_START) {
++		if (status & MACB_BIT(RX_SOF)) {
+ 			if (next_rx_tail != macb->rx_tail)
+ 				reclaim_rx_buffers(macb, next_rx_tail);
+ 			macb->wrapped = false;
+ 		}
+ 
+-		if (status & RXBUF_FRAME_END) {
++		if (status & MACB_BIT(RX_EOF)) {
+ 			buffer = macb->rx_buffer + 128 * macb->rx_tail;
+ 			length = status & RXBUF_FRMLEN_MASK;
+ 
+@@ -697,7 +678,7 @@ static int gmac_init_multi_queues(struct macb_device *macb)
+ 		if (queue_mask & (1 << i))
+ 			num_queues++;
+ 
+-	macb->dummy_desc->ctrl = TXBUF_USED;
++	macb->dummy_desc->ctrl = MACB_BIT(TX_USED);
+ 	macb->dummy_desc->addr = 0;
+ 	flush_dcache_range(macb->dummy_desc_dma, macb->dummy_desc_dma +
+ 			ALIGN(MACB_TX_DUMMY_DMA_DESC_SIZE, PKTALIGN));
+@@ -730,7 +711,7 @@ static int _macb_init(struct macb_device *macb, const char *name)
+ 	paddr = macb->rx_buffer_dma;
+ 	for (i = 0; i < MACB_RX_RING_SIZE; i++) {
+ 		if (i == (MACB_RX_RING_SIZE - 1))
+-			paddr |= RXADDR_WRAP;
++			paddr |= MACB_BIT(RX_WRAP);
+ 		macb->rx_ring[i].addr = paddr;
+ 		macb->rx_ring[i].ctrl = 0;
+ 		paddr += 128;
+@@ -741,9 +722,10 @@ static int _macb_init(struct macb_device *macb, const char *name)
+ 	for (i = 0; i < MACB_TX_RING_SIZE; i++) {
+ 		macb->tx_ring[i].addr = 0;
+ 		if (i == (MACB_TX_RING_SIZE - 1))
+-			macb->tx_ring[i].ctrl = TXBUF_USED | TXBUF_WRAP;
++			macb->tx_ring[i].ctrl = MACB_BIT(TX_USED) |
++				MACB_BIT(TX_WRAP);
+ 		else
+-			macb->tx_ring[i].ctrl = TXBUF_USED;
++			macb->tx_ring[i].ctrl = MACB_BIT(TX_USED);
+ 	}
+ 	macb_flush_ring_desc(macb, TX);
+ 
+-- 
+2.22.0
+

+ 0 - 62
recipes-bsp/u-boot/files/0004-riscv-delay-initialization-of-caches-and-debug-UART.patch

@@ -1,62 +0,0 @@
-From 2503ccc55ff2031ae2ff476fb06f666e6d1c7a64 Mon Sep 17 00:00:00 2001
-From: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Date: Sun, 17 Mar 2019 19:28:35 +0100
-Subject: [PATCH 04/18] riscv: delay initialization of caches and debug UART
-
-Move the initialization of the caches and the debug UART until after
-board_init_f_init_reserve. This is in preparation for SMP support, where
-code prior to this point will be executed by all harts. This ensures
-that initialization will only be performed once on the main hart running
-U-Boot.
-
-Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Reviewed-by: Anup Patel <anup.patel@wdc.com>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
----
- arch/riscv/cpu/start.S | 16 ++++++++--------
- 1 file changed, 8 insertions(+), 8 deletions(-)
-
-diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
-index 81ea52b170..a30f6f7194 100644
---- a/arch/riscv/cpu/start.S
-+++ b/arch/riscv/cpu/start.S
-@@ -45,10 +45,6 @@ _start:
- 	/* mask all interrupts */
- 	csrw	MODE_PREFIX(ie), zero
- 
--	/* Enable cache */
--	jal	icache_enable
--	jal	dcache_enable
--
- /*
-  * Set stackpointer in internal/ex RAM to call board_init_f
-  */
-@@ -57,10 +53,6 @@ call_board_init_f:
- 	li	t1, CONFIG_SYS_INIT_SP_ADDR
- 	and	sp, t1, t0		/* force 16 byte alignment */
- 
--#ifdef CONFIG_DEBUG_UART
--	jal	debug_uart_init
--#endif
--
- call_board_init_f_0:
- 	mv	a0, sp
- 	jal	board_init_f_alloc_reserve
-@@ -74,6 +66,14 @@ call_board_init_f_0:
- 	/* save the boot hart id to global_data */
- 	SREG	s0, GD_BOOT_HART(gp)
- 
-+	/* Enable cache */
-+	jal	icache_enable
-+	jal	dcache_enable
-+
-+#ifdef CONFIG_DEBUG_UART
-+	jal	debug_uart_init
-+#endif
-+
- 	mv	a0, zero		/* a0 <-- boot_flags = 0 */
- 	la	t5, board_init_f
- 	jr	t5			/* jump to board_init_f() */
--- 
-2.21.0
-

+ 36 - 0
recipes-bsp/u-boot/files/0005-net-macb-add-support-for-SGMII-phy-interface.patch

@@ -0,0 +1,36 @@
+From 641cab449fb58f7d66e434f9fd5a9a33b67d77e3 Mon Sep 17 00:00:00 2001
+From: Ramon Fried <rfried.dev@gmail.com>
+Date: Tue, 11 Jun 2019 18:19:28 +0300
+Subject: [PATCH 05/21] net: macb: add support for SGMII phy interface
+
+This patch adds support for the sgmii phy interface,
+available only to DM users, dictated by current driver
+design.
+
+Signed-off-by: Ramon Fried <rfried.dev@gmail.com>
+Upstream-Status: Submitted
+---
+ drivers/net/macb.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/net/macb.c b/drivers/net/macb.c
+index d957afe21a..ae8937bbb1 100644
+--- a/drivers/net/macb.c
++++ b/drivers/net/macb.c
+@@ -757,6 +757,13 @@ static int _macb_init(struct macb_device *macb, const char *name)
+ 			gem_writel(macb, USRIO, GEM_BIT(RGMII));
+ 		else
+ 			gem_writel(macb, USRIO, 0);
++
++		if (macb->phy_interface == PHY_INTERFACE_MODE_SGMII) {
++			unsigned int ncfgr = macb_readl(macb, NCFGR);
++
++			ncfgr |= GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL);
++			macb_writel(macb, NCFGR, ncfgr);
++		}
+ #else
+ #if defined(CONFIG_RGMII) || defined(CONFIG_RMII)
+ 		gem_writel(macb, UR, GEM_BIT(RGMII));
+-- 
+2.22.0
+

+ 0 - 44
recipes-bsp/u-boot/files/0005-riscv-save-hart-ID-in-register-tp-instead-of-s0.patch

@@ -1,44 +0,0 @@
-From 1446b26f7652124f0e3e98c348cdbc4fc55eb0cb Mon Sep 17 00:00:00 2001
-From: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Date: Sun, 17 Mar 2019 19:28:36 +0100
-Subject: [PATCH 05/18] riscv: save hart ID in register tp instead of s0
-
-The hart ID passed by the previous boot stage is currently stored in
-register s0. If we divert the control flow inside a function, which is
-required as part of multi-hart support, the function epilog may not be
-called, clobbering register s0. Save the hart ID in the unallocatable
-register tp instead to protect the hart ID.
-
-Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-Reviewed-by: Rick Chen <rick@andestech.com>
-Reviewed-by: Anup Patel <anup.patel@wdc.com>
----
- arch/riscv/cpu/start.S | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
-index a30f6f7194..bcc0ff696d 100644
---- a/arch/riscv/cpu/start.S
-+++ b/arch/riscv/cpu/start.S
-@@ -36,7 +36,7 @@
- .globl _start
- _start:
- 	/* save hart id and dtb pointer */
--	mv	s0, a0
-+	mv	tp, a0
- 	mv	s1, a1
- 
- 	la	t0, trap_entry
-@@ -64,7 +64,7 @@ call_board_init_f_0:
- 	jal	board_init_f_init_reserve
- 
- 	/* save the boot hart id to global_data */
--	SREG	s0, GD_BOOT_HART(gp)
-+	SREG	tp, GD_BOOT_HART(gp)
- 
- 	/* Enable cache */
- 	jal	icache_enable
--- 
-2.21.0
-

+ 86 - 0
recipes-bsp/u-boot/files/0006-net-macb-add-dma_burst_length-config.patch

@@ -0,0 +1,86 @@
+From 8da0745b86fb9b9e36d964afda797b161407971f Mon Sep 17 00:00:00 2001
+From: Ramon Fried <rfried.dev@gmail.com>
+Date: Tue, 11 Jun 2019 18:19:29 +0300
+Subject: [PATCH 06/21] net: macb: add dma_burst_length config
+
+GEM support higher DMA burst writes/reads than the default (4).
+add configuration structure with dma burst length so it could be
+applied later to DMA configuration.
+
+Signed-off-by: Ramon Fried <rfried.dev@gmail.com>
+Upstream-Status: Submitted
+---
+ drivers/net/macb.c | 22 +++++++++++++++++++++-
+ 1 file changed, 21 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/macb.c b/drivers/net/macb.c
+index ae8937bbb1..fb42172520 100644
+--- a/drivers/net/macb.c
++++ b/drivers/net/macb.c
+@@ -82,6 +82,7 @@ struct macb_dma_desc {
+ 
+ struct macb_device {
+ 	void			*regs;
++	unsigned int		dma_burst_length;
+ 
+ 	unsigned int		rx_tail;
+ 	unsigned int		tx_head;
+@@ -118,6 +119,11 @@ struct macb_device {
+ 	phy_interface_t		phy_interface;
+ #endif
+ };
++
++struct macb_config {
++	unsigned int		dma_burst_length;
++};
++
+ #ifndef CONFIG_DM_ETH
+ #define to_macb(_nd) container_of(_nd, struct macb_device, netdev)
+ #endif
+@@ -1133,8 +1139,13 @@ static int macb_enable_clk(struct udevice *dev)
+ }
+ #endif
+ 
++static const struct macb_config default_gem_config = {
++	.dma_burst_length = 16,
++};
++
+ static int macb_eth_probe(struct udevice *dev)
+ {
++	const struct macb_config *macb_config;
+ 	struct eth_pdata *pdata = dev_get_platdata(dev);
+ 	struct macb_device *macb = dev_get_priv(dev);
+ 	const char *phy_mode;
+@@ -1151,6 +1162,11 @@ static int macb_eth_probe(struct udevice *dev)
+ 
+ 	macb->regs = (void *)pdata->iobase;
+ 
++	macb_config = (struct macb_config *)dev_get_driver_data(dev);
++	if (!macb_config)
++		macb_config = &default_gem_config;
++
++	macb->dma_burst_length = macb_config->dma_burst_length;
+ #ifdef CONFIG_CLK
+ 	ret = macb_enable_clk(dev);
+ 	if (ret)
+@@ -1211,12 +1227,16 @@ static int macb_eth_ofdata_to_platdata(struct udevice *dev)
+ 	return macb_late_eth_ofdata_to_platdata(dev);
+ }
+ 
++static const struct macb_config sama5d4_config = {
++	.dma_burst_length = 4,
++};
++
+ static const struct udevice_id macb_eth_ids[] = {
+ 	{ .compatible = "cdns,macb" },
+ 	{ .compatible = "cdns,at91sam9260-macb" },
+ 	{ .compatible = "atmel,sama5d2-gem" },
+ 	{ .compatible = "atmel,sama5d3-gem" },
+-	{ .compatible = "atmel,sama5d4-gem" },
++	{ .compatible = "atmel,sama5d4-gem", .data = (ulong)&sama5d4_config },
+ 	{ .compatible = "cdns,zynq-gem" },
+ 	{ }
+ };
+-- 
+2.22.0
+

+ 0 - 283
recipes-bsp/u-boot/files/0006-riscv-add-support-for-multi-hart-systems.patch

@@ -1,283 +0,0 @@
-From 3dea63c8445b25eb3de471410bbafcf54c9f0e9b Mon Sep 17 00:00:00 2001
-From: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Date: Sun, 17 Mar 2019 19:28:37 +0100
-Subject: [PATCH 06/18] riscv: add support for multi-hart systems
-
-On RISC-V, all harts boot independently. To be able to run on a
-multi-hart system, U-Boot must be extended with the functionality to
-manage all harts in the system. All harts entering U-Boot are registered
-in the available_harts mask stored in global data. A hart lottery system
-as used in the Linux kernel selects the hart U-Boot runs on. All other
-harts are halted. U-Boot can delegate functions to them using
-smp_call_function().
-
-Every hart has a valid pointer to the global data structure and a 8KiB
-stack by default. The stack size is set with CONFIG_STACK_SIZE_SHIFT.
-
-Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Reviewed-by: Anup Patel <anup.patel@wdc.com>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-Tested-by: Bin Meng <bmeng.cn@gmail.com>
----
- arch/riscv/Kconfig           |   4 ++
- arch/riscv/cpu/cpu.c         |   9 ++-
- arch/riscv/cpu/start.S       | 134 ++++++++++++++++++++++++++++++++++-
- arch/riscv/include/asm/csr.h |   1 +
- arch/riscv/lib/asm-offsets.c |   1 +
- 5 files changed, 147 insertions(+), 2 deletions(-)
-
-diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
-index 9da609b33b..3a4470daf3 100644
---- a/arch/riscv/Kconfig
-+++ b/arch/riscv/Kconfig
-@@ -144,4 +144,8 @@ config SBI_IPI
- 	default y if RISCV_SMODE
- 	depends on SMP
- 
-+config STACK_SIZE_SHIFT
-+	int
-+	default 13
-+
- endmenu
-diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
-index e662140427..c32de8a4c3 100644
---- a/arch/riscv/cpu/cpu.c
-+++ b/arch/riscv/cpu/cpu.c
-@@ -12,10 +12,17 @@
- #include <dm/uclass-internal.h>
- 
- /*
-- * prior_stage_fdt_address must be stored in the data section since it is used
-+ * The variables here must be stored in the data section since they are used
-  * before the bss section is available.
-  */
- phys_addr_t prior_stage_fdt_address __attribute__((section(".data")));
-+u32 hart_lottery __attribute__((section(".data"))) = 0;
-+
-+/*
-+ * The main hart running U-Boot has acquired available_harts_lock until it has
-+ * finished initialization of global data.
-+ */
-+u32 available_harts_lock = 1;
- 
- static inline bool supports_extension(char ext)
- {
-diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
-index bcc0ff696d..f55b8cbc37 100644
---- a/arch/riscv/cpu/start.S
-+++ b/arch/riscv/cpu/start.S
-@@ -13,6 +13,7 @@
- #include <config.h>
- #include <common.h>
- #include <elf.h>
-+#include <asm/csr.h>
- #include <asm/encoding.h>
- #include <generated/asm-offsets.h>
- 
-@@ -45,6 +46,23 @@ _start:
- 	/* mask all interrupts */
- 	csrw	MODE_PREFIX(ie), zero
- 
-+#ifdef CONFIG_SMP
-+	/* check if hart is within range */
-+	/* tp: hart id */
-+	li	t0, CONFIG_NR_CPUS
-+	bge	tp, t0, hart_out_of_bounds_loop
-+#endif
-+
-+#ifdef CONFIG_SMP
-+	/* set xSIE bit to receive IPIs */
-+#ifdef CONFIG_RISCV_MMODE
-+	li	t0, MIE_MSIE
-+#else
-+	li	t0, SIE_SSIE
-+#endif
-+	csrs	MODE_PREFIX(ie), t0
-+#endif
-+
- /*
-  * Set stackpointer in internal/ex RAM to call board_init_f
-  */
-@@ -56,7 +74,30 @@ call_board_init_f:
- call_board_init_f_0:
- 	mv	a0, sp
- 	jal	board_init_f_alloc_reserve
-+
-+	/*
-+	 * Set global data pointer here for all harts, uninitialized at this
-+	 * point.
-+	 */
-+	mv	gp, a0
-+
-+	/* setup stack */
-+#ifdef CONFIG_SMP
-+	/* tp: hart id */
-+	slli	t0, tp, CONFIG_STACK_SIZE_SHIFT
-+	sub	sp, a0, t0
-+#else
- 	mv	sp, a0
-+#endif
-+
-+	/*
-+	 * Pick hart to initialize global data and run U-Boot. The other harts
-+	 * wait for initialization to complete.
-+	 */
-+	la	t0, hart_lottery
-+	li	s2, 1
-+	amoswap.w s2, t1, 0(t0)
-+	bnez	s2, wait_for_gd_init
- 
- 	la	t0, prior_stage_fdt_address
- 	SREG	s1, 0(t0)
-@@ -66,6 +107,33 @@ call_board_init_f_0:
- 	/* save the boot hart id to global_data */
- 	SREG	tp, GD_BOOT_HART(gp)
- 
-+	la	t0, available_harts_lock
-+	fence	rw, w
-+	amoswap.w zero, zero, 0(t0)
-+
-+wait_for_gd_init:
-+	la	t0, available_harts_lock
-+	li	t1, 1
-+1:	amoswap.w t1, t1, 0(t0)
-+	fence	r, rw
-+	bnez	t1, 1b
-+
-+	/* register available harts in the available_harts mask */
-+	li	t1, 1
-+	sll	t1, t1, tp
-+	LREG	t2, GD_AVAILABLE_HARTS(gp)
-+	or	t2, t2, t1
-+	SREG	t2, GD_AVAILABLE_HARTS(gp)
-+
-+	fence	rw, w
-+	amoswap.w zero, zero, 0(t0)
-+
-+	/*
-+	 * Continue on hart lottery winner, others branch to
-+	 * secondary_hart_loop.
-+	 */
-+	bnez	s2, secondary_hart_loop
-+
- 	/* Enable cache */
- 	jal	icache_enable
- 	jal	dcache_enable
-@@ -95,7 +163,14 @@ relocate_code:
-  *Set up the stack
-  */
- stack_setup:
-+#ifdef CONFIG_SMP
-+	/* tp: hart id */
-+	slli	t0, tp, CONFIG_STACK_SIZE_SHIFT
-+	sub	sp, s2, t0
-+#else
- 	mv	sp, s2
-+#endif
-+
- 	la	t0, _start
- 	sub	t6, s4, t0		/* t6 <- relocation offset */
- 	beq	t0, s4, clear_bss	/* skip relocation */
-@@ -175,13 +250,30 @@ clear_bss:
- 	add	t0, t0, t6		/* t0 <- rel __bss_start in RAM */
- 	la	t1, __bss_end		/* t1 <- rel __bss_end in FLASH */
- 	add	t1, t1, t6		/* t1 <- rel __bss_end in RAM */
--	beq	t0, t1, call_board_init_r
-+	beq	t0, t1, relocate_secondary_harts
- 
- clbss_l:
- 	SREG	zero, 0(t0)		/* clear loop... */
- 	addi	t0, t0, REGBYTES
- 	bne	t0, t1, clbss_l
- 
-+relocate_secondary_harts:
-+#ifdef CONFIG_SMP
-+	/* send relocation IPI */
-+	la	t0, secondary_hart_relocate
-+	add	a0, t0, t6
-+
-+	/* store relocation offset */
-+	mv	s5, t6
-+
-+	mv	a1, s2
-+	mv	a2, s3
-+	jal	smp_call_function
-+
-+	/* restore relocation offset */
-+	mv	t6, s5
-+#endif
-+
- /*
-  * We are done. Do not return, instead branch to second part of board
-  * initialization, now running from RAM.
-@@ -202,3 +294,43 @@ call_board_init_r:
-  * jump to it ...
-  */
- 	jr	t4			/* jump to board_init_r() */
-+
-+#ifdef CONFIG_SMP
-+hart_out_of_bounds_loop:
-+	/* Harts in this loop are out of bounds, increase CONFIG_NR_CPUS. */
-+	wfi
-+	j	hart_out_of_bounds_loop
-+#endif
-+
-+#ifdef CONFIG_SMP
-+/* SMP relocation entry */
-+secondary_hart_relocate:
-+	/* a1: new sp */
-+	/* a2: new gd */
-+	/* tp: hart id */
-+
-+	/* setup stack */
-+	slli	t0, tp, CONFIG_STACK_SIZE_SHIFT
-+	sub	sp, a1, t0
-+
-+	/* update global data pointer */
-+	mv	gp, a2
-+#endif
-+
-+secondary_hart_loop:
-+	wfi
-+
-+#ifdef CONFIG_SMP
-+	csrr	t0, MODE_PREFIX(ip)
-+#ifdef CONFIG_RISCV_MMODE
-+	andi	t0, t0, MIE_MSIE
-+#else
-+	andi	t0, t0, SIE_SSIE
-+#endif
-+	beqz	t0, secondary_hart_loop
-+
-+	mv	a0, tp
-+	jal	handle_ipi
-+#endif
-+
-+	j	secondary_hart_loop
-diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
-index 86136f542c..644e6baa15 100644
---- a/arch/riscv/include/asm/csr.h
-+++ b/arch/riscv/include/asm/csr.h
-@@ -46,6 +46,7 @@
- #endif
- 
- /* Interrupt Enable and Interrupt Pending flags */
-+#define MIE_MSIE	_AC(0x00000008, UL) /* Software Interrupt Enable */
- #define SIE_SSIE	_AC(0x00000002, UL) /* Software Interrupt Enable */
- #define SIE_STIE	_AC(0x00000020, UL) /* Timer Interrupt Enable */
- 
-diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c
-index e0b71f5691..f998402bd1 100644
---- a/arch/riscv/lib/asm-offsets.c
-+++ b/arch/riscv/lib/asm-offsets.c
-@@ -14,6 +14,7 @@
- int main(void)
- {
- 	DEFINE(GD_BOOT_HART, offsetof(gd_t, arch.boot_hart));
-+	DEFINE(GD_AVAILABLE_HARTS, offsetof(gd_t, arch.available_harts));
- 
- 	return 0;
- }
--- 
-2.21.0
-

+ 71 - 0
recipes-bsp/u-boot/files/0007-net-macb-apply-sane-DMA-configuration.patch

@@ -0,0 +1,71 @@
+From a9a63c1e906eecd9864ce016cdfcf0b867ae451d Mon Sep 17 00:00:00 2001
+From: Ramon Fried <rfried.dev@gmail.com>
+Date: Tue, 11 Jun 2019 18:19:30 +0300
+Subject: [PATCH 07/21] net: macb: apply sane DMA configuration
+
+DMA configuration was heavily dependent on the HW
+defaults, add function to properly set the required
+fields, including the new dma_burst_length.
+
+Signed-off-by: Ramon Fried <rfried.dev@gmail.com>
+Upstream-Status: Submitted
+---
+ drivers/net/macb.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/drivers/net/macb.c b/drivers/net/macb.c
+index fb42172520..c072f99d8f 100644
+--- a/drivers/net/macb.c
++++ b/drivers/net/macb.c
+@@ -47,6 +47,7 @@ DECLARE_GLOBAL_DATA_PTR;
+ 
+ #define MACB_RX_BUFFER_SIZE		4096
+ #define MACB_RX_RING_SIZE		(MACB_RX_BUFFER_SIZE / 128)
++#define RX_BUFFER_MULTIPLE		64
+ #define MACB_TX_RING_SIZE		16
+ #define MACB_TX_TIMEOUT		1000
+ #define MACB_AUTONEG_TIMEOUT	5000000
+@@ -695,6 +696,31 @@ static int gmac_init_multi_queues(struct macb_device *macb)
+ 	return 0;
+ }
+ 
++static void gmac_configure_dma(struct macb_device *macb)
++{
++	u32 buffer_size;
++	u32 dmacfg;
++
++	buffer_size = 128 / RX_BUFFER_MULTIPLE;
++	dmacfg = gem_readl(macb, DMACFG) & ~GEM_BF(RXBS, -1L);
++	dmacfg |= GEM_BF(RXBS, buffer_size);
++
++	if (macb->dma_burst_length)
++		dmacfg = GEM_BFINS(FBLDO, macb->dma_burst_length, dmacfg);
++
++	dmacfg |= GEM_BIT(TXPBMS) | GEM_BF(RXBMS, -1L);
++	dmacfg &= ~GEM_BIT(ENDIA_PKT);
++
++#ifdef CONFIG_SYS_LITTLE_ENDIAN
++		dmacfg &= ~GEM_BIT(ENDIA_DESC);
++#else
++		dmacfg |= GEM_BIT(ENDIA_DESC); /* CPU in big endian */
++#endif
++
++	dmacfg &= ~GEM_BIT(ADDR64);
++	gem_writel(macb, DMACFG, dmacfg);
++}
++
+ #ifdef CONFIG_DM_ETH
+ static int _macb_init(struct udevice *dev, const char *name)
+ #else
+@@ -748,6 +774,8 @@ static int _macb_init(struct macb_device *macb, const char *name)
+ 	macb_writel(macb, TBQP, macb->tx_ring_dma);
+ 
+ 	if (macb_is_gem(macb)) {
++		/* Initialize DMA properties */
++		gmac_configure_dma(macb);
+ 		/* Check the multi queue and initialize the queue for tx */
+ 		gmac_init_multi_queues(macb);
+ 
+-- 
+2.22.0
+

+ 0 - 55
recipes-bsp/u-boot/files/0007-riscv-boot-images-passed-to-bootm-on-all-harts.patch

@@ -1,55 +0,0 @@
-From f28ad250e6ef95ca58490b4e8651749d4f7e5c06 Mon Sep 17 00:00:00 2001
-From: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Date: Sun, 17 Mar 2019 19:28:38 +0100
-Subject: [PATCH 07/18] riscv: boot images passed to bootm on all harts
-
-Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Reviewed-by: Anup Patel <anup.patel@wdc.com>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-Tested-by: Bin Meng <bmeng.cn@gmail.com>
----
- arch/riscv/lib/bootm.c | 13 ++++++++++++-
- 1 file changed, 12 insertions(+), 1 deletion(-)
-
-diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c
-index f36b8702ef..efbd3e23e7 100644
---- a/arch/riscv/lib/bootm.c
-+++ b/arch/riscv/lib/bootm.c
-@@ -13,6 +13,7 @@
- #include <image.h>
- #include <asm/byteorder.h>
- #include <asm/csr.h>
-+#include <asm/smp.h>
- #include <dm/device.h>
- #include <dm/root.h>
- #include <u-boot/zlib.h>
-@@ -81,6 +82,9 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
- {
- 	void (*kernel)(ulong hart, void *dtb);
- 	int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
-+#ifdef CONFIG_SMP
-+	int ret;
-+#endif
- 
- 	kernel = (void (*)(ulong, void *))images->ep;
- 
-@@ -92,8 +96,15 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
- 	announce_and_cleanup(fake);
- 
- 	if (!fake) {
--		if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
-+		if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
-+#ifdef CONFIG_SMP
-+			ret = smp_call_function(images->ep,
-+						(ulong)images->ft_addr, 0);
-+			if (ret)
-+				hang();
-+#endif
- 			kernel(gd->arch.boot_hart, images->ft_addr);
-+		}
- 	}
- }
- 
--- 
-2.21.0
-

+ 135 - 0
recipes-bsp/u-boot/files/0008-clk-sifive-Factor-out-PLL-library-as-separate-module.patch

@@ -0,0 +1,135 @@
+From f1ec984fea3ce53fc0c6e9a98eb8ba3fa9d3b3ac Mon Sep 17 00:00:00 2001
+From: Anup Patel <anup.patel@wdc.com>
+Date: Tue, 18 Jun 2019 11:42:49 +0530
+Subject: [PATCH 08/21] clk: sifive: Factor-out PLL library as separate module
+
+To match SiFive clock driver with latest Linux, we factor-out PLL
+library as separate module under drivers/clk/analogbits.
+
+Signed-off-by: Anup Patel <anup.patel@wdc.com>
+Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
+Upstream-Status: Submitted
+---
+ drivers/clk/Kconfig                                           | 1 +
+ drivers/clk/Makefile                                          | 1 +
+ drivers/clk/analogbits/Kconfig                                | 4 ++++
+ drivers/clk/analogbits/Makefile                               | 3 +++
+ drivers/clk/{sifive => analogbits}/wrpll-cln28hpc.c           | 3 +--
+ drivers/clk/sifive/Kconfig                                    | 3 ---
+ drivers/clk/sifive/Makefile                                   | 2 --
+ drivers/clk/sifive/fu540-prci.c                               | 3 +--
+ .../sifive => include/linux/clk}/analogbits-wrpll-cln28hpc.h  | 0
+ 9 files changed, 11 insertions(+), 9 deletions(-)
+ create mode 100644 drivers/clk/analogbits/Kconfig
+ create mode 100644 drivers/clk/analogbits/Makefile
+ rename drivers/clk/{sifive => analogbits}/wrpll-cln28hpc.c (99%)
+ rename {drivers/clk/sifive => include/linux/clk}/analogbits-wrpll-cln28hpc.h (100%)
+
+diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
+index 96969b9e30..7b81eacf50 100644
+--- a/drivers/clk/Kconfig
++++ b/drivers/clk/Kconfig
+@@ -98,6 +98,7 @@ config CLK_STM32MP1
+ 	  Enable the STM32 clock (RCC) driver. Enable support for
+ 	  manipulating STM32MP1's on-SoC clocks.
+ 
++source "drivers/clk/analogbits/Kconfig"
+ source "drivers/clk/at91/Kconfig"
+ source "drivers/clk/exynos/Kconfig"
+ source "drivers/clk/imx/Kconfig"
+diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
+index 719b9b8e02..f0ced49e5a 100644
+--- a/drivers/clk/Makefile
++++ b/drivers/clk/Makefile
+@@ -8,6 +8,7 @@ obj-$(CONFIG_$(SPL_TPL_)CLK) += clk-uclass.o
+ obj-$(CONFIG_$(SPL_TPL_)CLK) += clk_fixed_rate.o
+ obj-$(CONFIG_$(SPL_TPL_)CLK) += clk_fixed_factor.o
+ 
++obj-y += analogbits/
+ obj-y += imx/
+ obj-y += tegra/
+ obj-$(CONFIG_ARCH_ASPEED) += aspeed/
+diff --git a/drivers/clk/analogbits/Kconfig b/drivers/clk/analogbits/Kconfig
+new file mode 100644
+index 0000000000..1d25e6f124
+--- /dev/null
++++ b/drivers/clk/analogbits/Kconfig
+@@ -0,0 +1,4 @@
++# SPDX-License-Identifier: GPL-2.0
++
++config CLK_ANALOGBITS_WRPLL_CLN28HPC
++	bool
+diff --git a/drivers/clk/analogbits/Makefile b/drivers/clk/analogbits/Makefile
+new file mode 100644
+index 0000000000..ec1bb4092b
+--- /dev/null
++++ b/drivers/clk/analogbits/Makefile
+@@ -0,0 +1,3 @@
++# SPDX-License-Identifier: GPL-2.0+
++
++obj-$(CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC)	+= wrpll-cln28hpc.o
+diff --git a/drivers/clk/sifive/wrpll-cln28hpc.c b/drivers/clk/analogbits/wrpll-cln28hpc.c
+similarity index 99%
+rename from drivers/clk/sifive/wrpll-cln28hpc.c
+rename to drivers/clk/analogbits/wrpll-cln28hpc.c
+index d377849693..68eb1148b9 100644
+--- a/drivers/clk/sifive/wrpll-cln28hpc.c
++++ b/drivers/clk/analogbits/wrpll-cln28hpc.c
+@@ -35,8 +35,7 @@
+ #include <linux/err.h>
+ #include <linux/log2.h>
+ #include <linux/math64.h>
+-
+-#include "analogbits-wrpll-cln28hpc.h"
++#include <linux/clk/analogbits-wrpll-cln28hpc.h>
+ 
+ /* MIN_INPUT_FREQ: minimum input clock frequency, in Hz (Fref_min) */
+ #define MIN_INPUT_FREQ			7000000
+diff --git a/drivers/clk/sifive/Kconfig b/drivers/clk/sifive/Kconfig
+index 644881b948..d90be1943f 100644
+--- a/drivers/clk/sifive/Kconfig
++++ b/drivers/clk/sifive/Kconfig
+@@ -1,8 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0
+ 
+-config CLK_ANALOGBITS_WRPLL_CLN28HPC
+-	bool
+-
+ config CLK_SIFIVE
+ 	bool "SiFive SoC driver support"
+ 	depends on CLK
+diff --git a/drivers/clk/sifive/Makefile b/drivers/clk/sifive/Makefile
+index f8263e79b7..0813360ca7 100644
+--- a/drivers/clk/sifive/Makefile
++++ b/drivers/clk/sifive/Makefile
+@@ -1,7 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0+
+ 
+-obj-$(CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC)	+= wrpll-cln28hpc.o
+-
+ obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI)		+= fu540-prci.o
+ 
+ obj-$(CONFIG_CLK_SIFIVE_GEMGXL_MGMT)		+= gemgxl-mgmt.o
+diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
+index 2d47ebc6b1..56084db2e6 100644
+--- a/drivers/clk/sifive/fu540-prci.c
++++ b/drivers/clk/sifive/fu540-prci.c
+@@ -37,10 +37,9 @@
+ #include <errno.h>
+ 
+ #include <linux/math64.h>
++#include <linux/clk/analogbits-wrpll-cln28hpc.h>
+ #include <dt-bindings/clk/sifive-fu540-prci.h>
+ 
+-#include "analogbits-wrpll-cln28hpc.h"
+-
+ /*
+  * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects:
+  *     hfclk and rtcclk
+diff --git a/drivers/clk/sifive/analogbits-wrpll-cln28hpc.h b/include/linux/clk/analogbits-wrpll-cln28hpc.h
+similarity index 100%
+rename from drivers/clk/sifive/analogbits-wrpll-cln28hpc.h
+rename to include/linux/clk/analogbits-wrpll-cln28hpc.h
+-- 
+2.22.0
+

+ 0 - 44
recipes-bsp/u-boot/files/0008-riscv-do-not-rely-on-hart-ID-passed-by-previous-boot.patch

@@ -1,44 +0,0 @@
-From e04324025275dee6e3e9a968c8d12e98c9b47567 Mon Sep 17 00:00:00 2001
-From: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Date: Sun, 17 Mar 2019 19:28:39 +0100
-Subject: [PATCH 08/18] riscv: do not rely on hart ID passed by previous boot
- stage
-
-RISC-V U-Boot expects the hart ID to be passed to it via register a0 by
-the previous boot stage. Machine mode firmware such as BBL and OpenSBI
-do this when starting their payload (U-Boot) in supervisor mode. If
-U-Boot is running in machine mode, this task must be handled by the boot
-ROM. Explicitly populate register a0 with the hart ID from the mhartid
-CSR to avoid possible problems on RISC-V processors with a boot ROM that
-does not handle this task.
-
-Suggested-by: Rick Chen <rick@andestech.com>
-Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Reviewed-by: Anup Patel <anup.patel@wdc.com>
-Reviewed-by: Atish Patra <atish.patra@wdc.com>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-Tested-by: Bin Meng <bmeng.cn@gmail.com>
-Reviewed-by: Rick Chen <rick@andestech.com>
-Tested-by: Rick Chen <rick@andestech.com>
----
- arch/riscv/cpu/start.S | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
-index f55b8cbc37..5ac899b141 100644
---- a/arch/riscv/cpu/start.S
-+++ b/arch/riscv/cpu/start.S
-@@ -36,6 +36,10 @@
- .section .text
- .globl _start
- _start:
-+#ifdef CONFIG_RISCV_MMODE
-+	csrr	a0, mhartid
-+#endif
-+
- 	/* save hart id and dtb pointer */
- 	mv	tp, a0
- 	mv	s1, a1
--- 
-2.21.0
-

+ 581 - 0
recipes-bsp/u-boot/files/0009-clk-sifive-Sync-up-WRPLL-library-with-upstream-Linux.patch

@@ -0,0 +1,581 @@
+From cbf99dc81055f9ebf52344ee071d282b29eb2daa Mon Sep 17 00:00:00 2001
+From: Anup Patel <anup.patel@wdc.com>
+Date: Tue, 18 Jun 2019 12:07:36 +0530
+Subject: [PATCH 09/21] clk: sifive: Sync-up WRPLL library with upstream Linux
+
+Now that SiFive clock driver is merged in upstream Linux, we
+sync-up WRPLL library used by SiFive clock driver with upstream
+Linux sources.
+
+Signed-off-by: Anup Patel <anup.patel@wdc.com>
+Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
+Upstream-Status: Submitted
+---
+ drivers/clk/analogbits/wrpll-cln28hpc.c       | 165 ++++++++----------
+ drivers/clk/sifive/fu540-prci.c               |  26 +--
+ include/linux/clk/analogbits-wrpll-cln28hpc.h |  70 +++-----
+ 3 files changed, 107 insertions(+), 154 deletions(-)
+
+diff --git a/drivers/clk/analogbits/wrpll-cln28hpc.c b/drivers/clk/analogbits/wrpll-cln28hpc.c
+index 68eb1148b9..776ead319a 100644
+--- a/drivers/clk/analogbits/wrpll-cln28hpc.c
++++ b/drivers/clk/analogbits/wrpll-cln28hpc.c
+@@ -1,20 +1,9 @@
+ // SPDX-License-Identifier: GPL-2.0
+ /*
+- * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+- *
+- * Copyright (C) 2018 SiFive, Inc.
++ * Copyright (C) 2018-2019 SiFive, Inc.
+  * Wesley Terpstra
+  * Paul Walmsley
+  *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License version 2 as
+- * published by the Free Software Foundation.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- *
+  * This library supports configuration parsing and reprogramming of
+  * the CLN28HPC variant of the Analog Bits Wide Range PLL.  The
+  * intention is for this library to be reusable for any device that
+@@ -29,6 +18,7 @@
+  * References:
+  * - Analog Bits "Wide Range PLL Datasheet", version 2015.10.01
+  * - SiFive FU540-C000 Manual v1p0, Chapter 7 "Clocking and Reset"
++ *   https://static.dev.sifive.com/FU540-C000-v1.0.pdf
+  */
+ 
+ #include <linux/bug.h>
+@@ -84,40 +74,38 @@
+  * range selection.
+  *
+  * Return: The RANGE value to be presented to the PLL configuration inputs,
+- *         or -1 upon error.
++ *         or a negative return code upon error.
+  */
+ static int __wrpll_calc_filter_range(unsigned long post_divr_freq)
+ {
+-	u8 range;
+-
+ 	if (post_divr_freq < MIN_POST_DIVR_FREQ ||
+ 	    post_divr_freq > MAX_POST_DIVR_FREQ) {
+ 		WARN(1, "%s: post-divider reference freq out of range: %lu",
+ 		     __func__, post_divr_freq);
+-		return -1;
++		return -ERANGE;
+ 	}
+ 
+-	if (post_divr_freq < 11000000)
+-		range = 1;
+-	else if (post_divr_freq < 18000000)
+-		range = 2;
+-	else if (post_divr_freq < 30000000)
+-		range = 3;
+-	else if (post_divr_freq < 50000000)
+-		range = 4;
+-	else if (post_divr_freq < 80000000)
+-		range = 5;
+-	else if (post_divr_freq < 130000000)
+-		range = 6;
+-	else
+-		range = 7;
+-
+-	return range;
++	switch (post_divr_freq) {
++	case 0 ... 10999999:
++		return 1;
++	case 11000000 ... 17999999:
++		return 2;
++	case 18000000 ... 29999999:
++		return 3;
++	case 30000000 ... 49999999:
++		return 4;
++	case 50000000 ... 79999999:
++		return 5;
++	case 80000000 ... 129999999:
++		return 6;
++	}
++
++	return 7;
+ }
+ 
+ /**
+  * __wrpll_calc_fbdiv() - return feedback fixed divide value
+- * @c: ptr to a struct analogbits_wrpll_cfg record to read from
++ * @c: ptr to a struct wrpll_cfg record to read from
+  *
+  * The internal feedback path includes a fixed by-two divider; the
+  * external feedback path does not.  Return the appropriate divider
+@@ -132,7 +120,7 @@ static int __wrpll_calc_filter_range(unsigned long post_divr_freq)
+  * Return: 2 if internal feedback is enabled or 1 if external feedback
+  *         is enabled.
+  */
+-static u8 __wrpll_calc_fbdiv(struct analogbits_wrpll_cfg *c)
++static u8 __wrpll_calc_fbdiv(const struct wrpll_cfg *c)
+ {
+ 	return (c->flags & WRPLL_FLAGS_INT_FEEDBACK_MASK) ? 2 : 1;
+ }
+@@ -172,7 +160,7 @@ static u8 __wrpll_calc_divq(u32 target_rate, u64 *vco_rate)
+ 		*vco_rate = MIN_VCO_FREQ;
+ 	} else {
+ 		divq = ilog2(s);
+-		*vco_rate = target_rate << divq;
++		*vco_rate = (u64)target_rate << divq;
+ 	}
+ 
+ wcd_out:
+@@ -181,7 +169,7 @@ wcd_out:
+ 
+ /**
+  * __wrpll_update_parent_rate() - update PLL data when parent rate changes
+- * @c: ptr to a struct analogbits_wrpll_cfg record to write PLL data to
++ * @c: ptr to a struct wrpll_cfg record to write PLL data to
+  * @parent_rate: PLL input refclk rate (pre-R-divider)
+  *
+  * Pre-compute some data used by the PLL configuration algorithm when
+@@ -189,46 +177,40 @@ wcd_out:
+  * computation when the parent rate remains constant - expected to be
+  * the common case.
+  *
+- * Returns: 0 upon success or -1 if the reference clock rate is out of range.
++ * Returns: 0 upon success or -ERANGE if the reference clock rate is
++ * out of range.
+  */
+-static int __wrpll_update_parent_rate(struct analogbits_wrpll_cfg *c,
++static int __wrpll_update_parent_rate(struct wrpll_cfg *c,
+ 				      unsigned long parent_rate)
+ {
+ 	u8 max_r_for_parent;
+ 
+ 	if (parent_rate > MAX_INPUT_FREQ || parent_rate < MIN_POST_DIVR_FREQ)
+-		return -1;
++		return -ERANGE;
+ 
+-	c->_parent_rate = parent_rate;
++	c->parent_rate = parent_rate;
+ 	max_r_for_parent = div_u64(parent_rate, MIN_POST_DIVR_FREQ);
+-	c->_max_r = min_t(u8, MAX_DIVR_DIVISOR, max_r_for_parent);
++	c->max_r = min_t(u8, MAX_DIVR_DIVISOR, max_r_for_parent);
+ 
+-	/* Round up */
+-	c->_init_r = div_u64(parent_rate + MAX_POST_DIVR_FREQ - 1,
+-			     MAX_POST_DIVR_FREQ);
++	c->init_r = DIV_ROUND_UP_ULL(parent_rate, MAX_POST_DIVR_FREQ);
+ 
+ 	return 0;
+ }
+ 
+-/*
+- * Public functions
+- */
+-
+ /**
+- * analogbits_wrpll_configure() - compute PLL configuration for a target rate
+- * @c: ptr to a struct analogbits_wrpll_cfg record to write into
++ * wrpll_configure() - compute PLL configuration for a target rate
++ * @c: ptr to a struct wrpll_cfg record to write into
+  * @target_rate: target PLL output clock rate (post-Q-divider)
+  * @parent_rate: PLL input refclk rate (pre-R-divider)
+  *
+- * Given a pointer to a PLL context @c, a desired PLL target output
+- * rate @target_rate, and a reference clock input rate @parent_rate,
+- * compute the appropriate PLL signal configuration values.  PLL
+- * reprogramming is not glitchless, so the caller should switch any
+- * downstream logic to a different clock source or clock-gate it
+- * before presenting these values to the PLL configuration signals.
++ * Compute the appropriate PLL signal configuration values and store
++ * in PLL context @c.  PLL reprogramming is not glitchless, so the
++ * caller should switch any downstream logic to a different clock
++ * source or clock-gate it before presenting these values to the PLL
++ * configuration signals.
+  *
+  * The caller must pass this function a pre-initialized struct
+- * analogbits_wrpll_cfg record: either initialized to zero (with the
++ * wrpll_cfg record: either initialized to zero (with the
+  * exception of the .name and .flags fields) or read from the PLL.
+  *
+  * Context: Any context.  Caller must protect the memory pointed to by @c
+@@ -236,41 +218,26 @@ static int __wrpll_update_parent_rate(struct analogbits_wrpll_cfg *c,
+  *
+  * Return: 0 upon success; anything else upon failure.
+  */
+-int analogbits_wrpll_configure_for_rate(struct analogbits_wrpll_cfg *c,
+-					u32 target_rate,
+-					unsigned long parent_rate)
++int wrpll_configure_for_rate(struct wrpll_cfg *c, u32 target_rate,
++			     unsigned long parent_rate)
+ {
+ 	unsigned long ratio;
+ 	u64 target_vco_rate, delta, best_delta, f_pre_div, vco, vco_pre;
+-	u32 best_f, f, post_divr_freq, fbcfg;
++	u32 best_f, f, post_divr_freq;
+ 	u8 fbdiv, divq, best_r, r;
+-
+-	if (!c)
+-		return -1;
++	int range;
+ 
+ 	if (c->flags == 0) {
+ 		WARN(1, "%s called with uninitialized PLL config", __func__);
+-		return -1;
+-	}
+-
+-	fbcfg = WRPLL_FLAGS_INT_FEEDBACK_MASK | WRPLL_FLAGS_EXT_FEEDBACK_MASK;
+-	if ((c->flags & fbcfg) == fbcfg) {
+-		WARN(1, "%s called with invalid PLL config", __func__);
+-		return -1;
+-	}
+-
+-	if (c->flags == WRPLL_FLAGS_EXT_FEEDBACK_MASK) {
+-		WARN(1, "%s: external feedback mode not currently supported",
+-		     __func__);
+-		return -1;
++		return -EINVAL;
+ 	}
+ 
+ 	/* Initialize rounding data if it hasn't been initialized already */
+-	if (parent_rate != c->_parent_rate) {
++	if (parent_rate != c->parent_rate) {
+ 		if (__wrpll_update_parent_rate(c, parent_rate)) {
+ 			pr_err("%s: PLL input rate is out of range\n",
+ 			       __func__);
+-			return -1;
++			return -ERANGE;
+ 		}
+ 	}
+ 
+@@ -281,11 +248,12 @@ int analogbits_wrpll_configure_for_rate(struct analogbits_wrpll_cfg *c,
+ 		c->flags |= WRPLL_FLAGS_BYPASS_MASK;
+ 		return 0;
+ 	}
++
+ 	c->flags &= ~WRPLL_FLAGS_BYPASS_MASK;
+ 
+ 	/* Calculate the Q shift and target VCO rate */
+ 	divq = __wrpll_calc_divq(target_rate, &target_vco_rate);
+-	if (divq == 0)
++	if (!divq)
+ 		return -1;
+ 	c->divq = divq;
+ 
+@@ -301,8 +269,7 @@ int analogbits_wrpll_configure_for_rate(struct analogbits_wrpll_cfg *c,
+ 	 * Consider all values for R which land within
+ 	 * [MIN_POST_DIVR_FREQ, MAX_POST_DIVR_FREQ]; prefer smaller R
+ 	 */
+-	for (r = c->_init_r; r <= c->_max_r; ++r) {
+-		/* What is the best F we can pick in this case? */
++	for (r = c->init_r; r <= c->max_r; ++r) {
+ 		f_pre_div = ratio * r;
+ 		f = (f_pre_div + (1 << ROUND_SHIFT)) >> ROUND_SHIFT;
+ 		f >>= (fbdiv - 1);
+@@ -334,46 +301,54 @@ int analogbits_wrpll_configure_for_rate(struct analogbits_wrpll_cfg *c,
+ 	post_divr_freq = div_u64(parent_rate, best_r);
+ 
+ 	/* Pick the best PLL jitter filter */
+-	c->range = __wrpll_calc_filter_range(post_divr_freq);
++	range = __wrpll_calc_filter_range(post_divr_freq);
++	if (range < 0)
++		return range;
++	c->range = range;
+ 
+ 	return 0;
+ }
+ 
+ /**
+- * analogbits_wrpll_calc_output_rate() - calculate the PLL's target output rate
+- * @c: ptr to a struct analogbits_wrpll_cfg record to read from
++ * wrpll_calc_output_rate() - calculate the PLL's target output rate
++ * @c: ptr to a struct wrpll_cfg record to read from
+  * @parent_rate: PLL refclk rate
+  *
+  * Given a pointer to the PLL's current input configuration @c and the
+  * PLL's input reference clock rate @parent_rate (before the R
+  * pre-divider), calculate the PLL's output clock rate (after the Q
+- * post-divider)
++ * post-divider).
+  *
+  * Context: Any context.  Caller must protect the memory pointed to by @c
+  *          from simultaneous modification.
+  *
+- * Return: the PLL's output clock rate, in Hz.
++ * Return: the PLL's output clock rate, in Hz.  The return value from
++ *         this function is intended to be convenient to pass directly
++ *         to the Linux clock framework; thus there is no explicit
++ *         error return value.
+  */
+-unsigned long analogbits_wrpll_calc_output_rate(struct analogbits_wrpll_cfg *c,
+-						unsigned long parent_rate)
++unsigned long wrpll_calc_output_rate(const struct wrpll_cfg *c,
++				     unsigned long parent_rate)
+ {
+ 	u8 fbdiv;
+ 	u64 n;
+ 
+-	WARN(c->flags & WRPLL_FLAGS_EXT_FEEDBACK_MASK,
+-	     "external feedback mode not yet supported");
++	if (c->flags & WRPLL_FLAGS_EXT_FEEDBACK_MASK) {
++		WARN(1, "external feedback mode not yet supported");
++		return ULONG_MAX;
++	}
+ 
+ 	fbdiv = __wrpll_calc_fbdiv(c);
+ 	n = parent_rate * fbdiv * (c->divf + 1);
+-	n = div_u64(n, (c->divr + 1));
++	n = div_u64(n, c->divr + 1);
+ 	n >>= c->divq;
+ 
+ 	return n;
+ }
+ 
+ /**
+- * analogbits_wrpll_calc_max_lock_us() - return the time for the PLL to lock
+- * @c: ptr to a struct analogbits_wrpll_cfg record to read from
++ * wrpll_calc_max_lock_us() - return the time for the PLL to lock
++ * @c: ptr to a struct wrpll_cfg record to read from
+  *
+  * Return the minimum amount of time (in microseconds) that the caller
+  * must wait after reprogramming the PLL to ensure that it is locked
+@@ -383,7 +358,7 @@ unsigned long analogbits_wrpll_calc_output_rate(struct analogbits_wrpll_cfg *c,
+  * Return: the minimum amount of time the caller must wait for the PLL
+  *         to lock (in microseconds)
+  */
+-unsigned int analogbits_wrpll_calc_max_lock_us(struct analogbits_wrpll_cfg *c)
++unsigned int wrpll_calc_max_lock_us(const struct wrpll_cfg *c)
+ {
+ 	return MAX_LOCK_US;
+ }
+diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
+index 56084db2e6..cdbf35e871 100644
+--- a/drivers/clk/sifive/fu540-prci.c
++++ b/drivers/clk/sifive/fu540-prci.c
+@@ -174,7 +174,7 @@ struct __prci_data {
+  * bypass mux is not glitchless.
+  */
+ struct __prci_wrpll_data {
+-	struct analogbits_wrpll_cfg c;
++	struct wrpll_cfg c;
+ 	void (*bypass)(struct __prci_data *pd);
+ 	void (*no_bypass)(struct __prci_data *pd);
+ 	u8 cfg0_offs;
+@@ -244,7 +244,7 @@ static void __prci_writel(u32 v, u32 offs, struct __prci_data *pd)
+ 
+ /**
+  * __prci_wrpll_unpack() - unpack WRPLL configuration registers into parameters
+- * @c: ptr to a struct analogbits_wrpll_cfg record to write config into
++ * @c: ptr to a struct wrpll_cfg record to write config into
+  * @r: value read from the PRCI PLL configuration register
+  *
+  * Given a value @r read from an FU540 PRCI PLL configuration register,
+@@ -256,7 +256,7 @@ static void __prci_writel(u32 v, u32 offs, struct __prci_data *pd)
+  *
+  * Context: Any context.
+  */
+-static void __prci_wrpll_unpack(struct analogbits_wrpll_cfg *c, u32 r)
++static void __prci_wrpll_unpack(struct wrpll_cfg *c, u32 r)
+ {
+ 	u32 v;
+ 
+@@ -287,7 +287,7 @@ static void __prci_wrpll_unpack(struct analogbits_wrpll_cfg *c, u32 r)
+ 
+ /**
+  * __prci_wrpll_pack() - pack PLL configuration parameters into a register value
+- * @c: pointer to a struct analogbits_wrpll_cfg record containing the PLL's cfg
++ * @c: pointer to a struct wrpll_cfg record containing the PLL's cfg
+  *
+  * Using a set of WRPLL configuration values pointed to by @c,
+  * assemble a PRCI PLL configuration register value, and return it to
+@@ -300,7 +300,7 @@ static void __prci_wrpll_unpack(struct analogbits_wrpll_cfg *c, u32 r)
+  * Returns: a value suitable for writing into a PRCI PLL configuration
+  *          register
+  */
+-static u32 __prci_wrpll_pack(struct analogbits_wrpll_cfg *c)
++static u32 __prci_wrpll_pack(struct wrpll_cfg *c)
+ {
+ 	u32 r = 0;
+ 
+@@ -348,11 +348,11 @@ static void __prci_wrpll_read_cfg(struct __prci_data *pd,
+  */
+ static void __prci_wrpll_write_cfg(struct __prci_data *pd,
+ 				   struct __prci_wrpll_data *pwd,
+-				   struct analogbits_wrpll_cfg *c)
++				   struct wrpll_cfg *c)
+ {
+ 	__prci_writel(__prci_wrpll_pack(c), pwd->cfg0_offs, pd);
+ 
+-	memcpy(&pwd->c, c, sizeof(struct analogbits_wrpll_cfg));
++	memcpy(&pwd->c, c, sizeof(struct wrpll_cfg));
+ }
+ 
+ /* Core clock mux control */
+@@ -403,7 +403,7 @@ static unsigned long sifive_fu540_prci_wrpll_recalc_rate(
+ {
+ 	struct __prci_wrpll_data *pwd = pc->pwd;
+ 
+-	return analogbits_wrpll_calc_output_rate(&pwd->c, parent_rate);
++	return wrpll_calc_output_rate(&pwd->c, parent_rate);
+ }
+ 
+ static unsigned long sifive_fu540_prci_wrpll_round_rate(
+@@ -412,13 +412,13 @@ static unsigned long sifive_fu540_prci_wrpll_round_rate(
+ 						unsigned long *parent_rate)
+ {
+ 	struct __prci_wrpll_data *pwd = pc->pwd;
+-	struct analogbits_wrpll_cfg c;
++	struct wrpll_cfg c;
+ 
+ 	memcpy(&c, &pwd->c, sizeof(c));
+ 
+-	analogbits_wrpll_configure_for_rate(&c, rate, *parent_rate);
++	wrpll_configure_for_rate(&c, rate, *parent_rate);
+ 
+-	return analogbits_wrpll_calc_output_rate(&c, *parent_rate);
++	return wrpll_calc_output_rate(&c, *parent_rate);
+ }
+ 
+ static int sifive_fu540_prci_wrpll_set_rate(struct __prci_clock *pc,
+@@ -429,7 +429,7 @@ static int sifive_fu540_prci_wrpll_set_rate(struct __prci_clock *pc,
+ 	struct __prci_data *pd = pc->pd;
+ 	int r;
+ 
+-	r = analogbits_wrpll_configure_for_rate(&pwd->c, rate, parent_rate);
++	r = wrpll_configure_for_rate(&pwd->c, rate, parent_rate);
+ 	if (r)
+ 		return -ERANGE;
+ 
+@@ -438,7 +438,7 @@ static int sifive_fu540_prci_wrpll_set_rate(struct __prci_clock *pc,
+ 
+ 	__prci_wrpll_write_cfg(pd, pwd, &pwd->c);
+ 
+-	udelay(analogbits_wrpll_calc_max_lock_us(&pwd->c));
++	udelay(wrpll_calc_max_lock_us(&pwd->c));
+ 
+ 	if (pwd->no_bypass)
+ 		pwd->no_bypass(pd);
+diff --git a/include/linux/clk/analogbits-wrpll-cln28hpc.h b/include/linux/clk/analogbits-wrpll-cln28hpc.h
+index 4432e24749..03279097e1 100644
+--- a/include/linux/clk/analogbits-wrpll-cln28hpc.h
++++ b/include/linux/clk/analogbits-wrpll-cln28hpc.h
+@@ -1,19 +1,8 @@
+ /* SPDX-License-Identifier: GPL-2.0 */
+ /*
+- * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+- *
+- * Copyright (C) 2018 SiFive, Inc.
++ * Copyright (C) 2018-2019 SiFive, Inc.
+  * Wesley Terpstra
+  * Paul Walmsley
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License version 2 as
+- * published by the Free Software Foundation.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+  */
+ 
+ #ifndef __LINUX_CLK_ANALOGBITS_WRPLL_CLN28HPC_H
+@@ -25,7 +14,7 @@
+ #define DIVQ_VALUES				6
+ 
+ /*
+- * Bit definitions for struct analogbits_wrpll_cfg.flags
++ * Bit definitions for struct wrpll_cfg.flags
+  *
+  * WRPLL_FLAGS_BYPASS_FLAG: if set, the PLL is either in bypass, or should be
+  *	programmed to enter bypass
+@@ -34,10 +23,6 @@
+  *	feedback mode
+  * WRPLL_FLAGS_EXT_FEEDBACK_FLAG: if set, the PLL is configured for external
+  *	feedback mode (not yet supported by this driver)
+- *
+- * The flags WRPLL_FLAGS_INT_FEEDBACK_FLAG and WRPLL_FLAGS_EXT_FEEDBACK_FLAG are
+- * mutually exclusive.  If both bits are set, or both are zero, the struct
+- * analogbits_wrpll_cfg record is uninitialized or corrupt.
+  */
+ #define WRPLL_FLAGS_BYPASS_SHIFT		0
+ #define WRPLL_FLAGS_BYPASS_MASK		BIT(WRPLL_FLAGS_BYPASS_SHIFT)
+@@ -49,53 +34,46 @@
+ #define WRPLL_FLAGS_EXT_FEEDBACK_MASK	BIT(WRPLL_FLAGS_EXT_FEEDBACK_SHIFT)
+ 
+ /**
+- * struct analogbits_wrpll_cfg - WRPLL configuration values
+- * @divr: reference divider value (6 bits), as presented to the PLL signals.
+- * @divf: feedback divider value (9 bits), as presented to the PLL signals.
+- * @divq: output divider value (3 bits), as presented to the PLL signals.
+- * @flags: PLL configuration flags.  See above for more information.
+- * @range: PLL loop filter range.  See below for more information.
+- * @_output_rate_cache: cached output rates, swept across DIVQ.
+- * @_parent_rate: PLL refclk rate for which values are valid
+- * @_max_r: maximum possible R divider value, given @parent_rate
+- * @_init_r: initial R divider value to start the search from
++ * struct wrpll_cfg - WRPLL configuration values
++ * @divr: reference divider value (6 bits), as presented to the PLL signals
++ * @divf: feedback divider value (9 bits), as presented to the PLL signals
++ * @divq: output divider value (3 bits), as presented to the PLL signals
++ * @flags: PLL configuration flags.  See above for more information
++ * @range: PLL loop filter range.  See below for more information
++ * @output_rate_cache: cached output rates, swept across DIVQ
++ * @parent_rate: PLL refclk rate for which values are valid
++ * @max_r: maximum possible R divider value, given @parent_rate
++ * @init_r: initial R divider value to start the search from
+  *
+  * @divr, @divq, @divq, @range represent what the PLL expects to see
+  * on its input signals.  Thus @divr and @divf are the actual divisors
+  * minus one.  @divq is a power-of-two divider; for example, 1 =
+  * divide-by-2 and 6 = divide-by-64.  0 is an invalid @divq value.
+  *
+- * When initially passing a struct analogbits_wrpll_cfg record, the
++ * When initially passing a struct wrpll_cfg record, the
+  * record should be zero-initialized with the exception of the @flags
+  * field.  The only flag bits that need to be set are either
+  * WRPLL_FLAGS_INT_FEEDBACK or WRPLL_FLAGS_EXT_FEEDBACK.
+- *
+- * Field names beginning with an underscore should be considered
+- * private to the wrpll-cln28hpc.c code.
+  */
+-struct analogbits_wrpll_cfg {
++struct wrpll_cfg {
+ 	u8 divr;
+ 	u8 divq;
+ 	u8 range;
+ 	u8 flags;
+ 	u16 divf;
+-	u32 _output_rate_cache[DIVQ_VALUES];
+-	unsigned long _parent_rate;
+-	u8 _max_r;
+-	u8 _init_r;
++/* private: */
++	u32 output_rate_cache[DIVQ_VALUES];
++	unsigned long parent_rate;
++	u8 max_r;
++	u8 init_r;
+ };
+ 
+-/*
+- * Function prototypes
+- */
+-
+-int analogbits_wrpll_configure_for_rate(struct analogbits_wrpll_cfg *c,
+-					u32 target_rate,
+-					unsigned long parent_rate);
++int wrpll_configure_for_rate(struct wrpll_cfg *c, u32 target_rate,
++			     unsigned long parent_rate);
+ 
+-unsigned int analogbits_wrpll_calc_max_lock_us(struct analogbits_wrpll_cfg *c);
++unsigned int wrpll_calc_max_lock_us(const struct wrpll_cfg *c);
+ 
+-unsigned long analogbits_wrpll_calc_output_rate(struct analogbits_wrpll_cfg *c,
+-						unsigned long parent_rate);
++unsigned long wrpll_calc_output_rate(const struct wrpll_cfg *c,
++				     unsigned long parent_rate);
+ 
+ #endif /* __LINUX_CLK_ANALOGBITS_WRPLL_CLN28HPC_H */
+-- 
+2.22.0
+

+ 0 - 51
recipes-bsp/u-boot/files/0009-riscv-hang-if-relocation-of-secondary-harts-fails.patch

@@ -1,51 +0,0 @@
-From 8ac39e2974d9f1395969a500e692f45717c4ccf2 Mon Sep 17 00:00:00 2001
-From: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Date: Sun, 17 Mar 2019 19:28:40 +0100
-Subject: [PATCH 09/18] riscv: hang if relocation of secondary harts fails
-
-Print an error message and hang if smp_call_function() returns an error,
-indicating that relocation of the secondary harts has failed.
-
-Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-Tested-by: Bin Meng <bmeng.cn@gmail.com>
-Reviewed-by: Anup Patel <anup.patel@wdc.com>
----
- arch/riscv/cpu/start.S | 13 ++++++++++++-
- 1 file changed, 12 insertions(+), 1 deletion(-)
-
-diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
-index 5ac899b141..a4433fbd6b 100644
---- a/arch/riscv/cpu/start.S
-+++ b/arch/riscv/cpu/start.S
-@@ -33,6 +33,10 @@
- #define SYM_SIZE		0x18
- #endif
- 
-+.section .data
-+secondary_harts_relocation_error:
-+	.ascii "Relocation of secondary harts has failed, error %d\n"
-+
- .section .text
- .globl _start
- _start:
-@@ -274,8 +278,15 @@ relocate_secondary_harts:
- 	mv	a2, s3
- 	jal	smp_call_function
- 
-+	/* hang if relocation of secondary harts has failed */
-+	beqz	a0, 1f
-+	mv	a1, a0
-+	la	a0, secondary_harts_relocation_error
-+	jal	printf
-+	jal	hang
-+
- 	/* restore relocation offset */
--	mv	t6, s5
-+1:	mv	t6, s5
- #endif
- 
- /*
--- 
-2.21.0
-

+ 95 - 0
recipes-bsp/u-boot/files/0010-clk-sifive-Sync-up-DT-bindings-header-with-upstream-.patch

@@ -0,0 +1,95 @@
+From 810b76326c3ea6a6747e5cd65c59d41124893305 Mon Sep 17 00:00:00 2001
+From: Anup Patel <anup.patel@wdc.com>
+Date: Tue, 18 Jun 2019 12:21:03 +0530
+Subject: [PATCH 10/21] clk: sifive: Sync-up DT bindings header with upstream
+ Linux
+
+The location and license header of DT bindings header for SiFive
+clock driver has changed in upstream Linux hence this patch.
+
+Signed-off-by: Anup Patel <anup.patel@wdc.com>
+Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
+Upstream-Status: Submitted
+---
+ drivers/clk/sifive/fu540-prci.c               |  2 +-
+ include/dt-bindings/clk/sifive-fu540-prci.h   | 29 -------------------
+ include/dt-bindings/clock/sifive-fu540-prci.h | 18 ++++++++++++
+ 3 files changed, 19 insertions(+), 30 deletions(-)
+ delete mode 100644 include/dt-bindings/clk/sifive-fu540-prci.h
+ create mode 100644 include/dt-bindings/clock/sifive-fu540-prci.h
+
+diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
+index cdbf35e871..ceb318e062 100644
+--- a/drivers/clk/sifive/fu540-prci.c
++++ b/drivers/clk/sifive/fu540-prci.c
+@@ -38,7 +38,7 @@
+ 
+ #include <linux/math64.h>
+ #include <linux/clk/analogbits-wrpll-cln28hpc.h>
+-#include <dt-bindings/clk/sifive-fu540-prci.h>
++#include <dt-bindings/clock/sifive-fu540-prci.h>
+ 
+ /*
+  * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects:
+diff --git a/include/dt-bindings/clk/sifive-fu540-prci.h b/include/dt-bindings/clk/sifive-fu540-prci.h
+deleted file mode 100644
+index 531523ea62..0000000000
+--- a/include/dt-bindings/clk/sifive-fu540-prci.h
++++ /dev/null
+@@ -1,29 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0 */
+-/*
+- * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+- *
+- * Copyright (C) 2018 SiFive, Inc.
+- * Wesley Terpstra
+- * Paul Walmsley
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License version 2 as
+- * published by the Free Software Foundation.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- */
+-
+-#ifndef __LINUX_CLK_SIFIVE_FU540_PRCI_H
+-#define __LINUX_CLK_SIFIVE_FU540_PRCI_H
+-
+-/* Clock indexes for use by Device Tree data */
+-
+-#define PRCI_CLK_COREPLL		0
+-#define PRCI_CLK_DDRPLL			1
+-#define PRCI_CLK_GEMGXLPLL		2
+-#define PRCI_CLK_TLCLK			3
+-
+-#endif
+diff --git a/include/dt-bindings/clock/sifive-fu540-prci.h b/include/dt-bindings/clock/sifive-fu540-prci.h
+new file mode 100644
+index 0000000000..6a0b70a37d
+--- /dev/null
++++ b/include/dt-bindings/clock/sifive-fu540-prci.h
+@@ -0,0 +1,18 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Copyright (C) 2018-2019 SiFive, Inc.
++ * Wesley Terpstra
++ * Paul Walmsley
++ */
++
++#ifndef __DT_BINDINGS_CLOCK_SIFIVE_FU540_PRCI_H
++#define __DT_BINDINGS_CLOCK_SIFIVE_FU540_PRCI_H
++
++/* Clock indexes for use by Device Tree data and the PRCI driver */
++
++#define PRCI_CLK_COREPLL	       0
++#define PRCI_CLK_DDRPLL		       1
++#define PRCI_CLK_GEMGXLPLL	       2
++#define PRCI_CLK_TLCLK		       3
++
++#endif
+-- 
+2.22.0
+

+ 0 - 26
recipes-bsp/u-boot/files/0010-riscv-fu540-enable-SMP.patch

@@ -1,26 +0,0 @@
-From 0ed93a8c59d7c100241390d912329e3e45382977 Mon Sep 17 00:00:00 2001
-From: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Date: Sun, 17 Mar 2019 19:28:41 +0100
-Subject: [PATCH 10/18] riscv: fu540: enable SMP
-
-Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Reviewed-by: Anup Patel <anup.patel@wdc.com>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
----
- board/sifive/fu540/Kconfig | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
-index 6be3d88144..f46437901d 100644
---- a/board/sifive/fu540/Kconfig
-+++ b/board/sifive/fu540/Kconfig
-@@ -38,5 +38,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
- 	imply PHY_LIB
- 	imply PHY_MSCC
- 	imply SIFIVE_SERIAL
-+	imply SMP
- 
- endif
--- 
-2.21.0
-

+ 246 - 0
recipes-bsp/u-boot/files/0011-clk-sifive-Sync-up-main-driver-with-upstream-Linux.patch

@@ -0,0 +1,246 @@
+From 43295ddfa3caa2494d682962cb358e9c1177facf Mon Sep 17 00:00:00 2001
+From: Anup Patel <anup.patel@wdc.com>
+Date: Tue, 18 Jun 2019 14:20:23 +0530
+Subject: [PATCH 11/21] clk: sifive: Sync-up main driver with upstream Linux
+
+The DT bindings of SiFive clock driver in upstream Linux has
+changes. As-per latest DT bindings, the clock driver takes two
+parent clocks and compatible string has also changed.
+
+This patch sync-up SiFive clock driver implementation as-per
+upstream Linux so that we now use latest DT bindings.
+
+Signed-off-by: Anup Patel <anup.patel@wdc.com>
+Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
+Upstream-Status: Submitted
+---
+ drivers/clk/sifive/fu540-prci.c | 96 ++++++++++++++++++++-------------
+ 1 file changed, 60 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
+index ceb318e062..ce0769f2d1 100644
+--- a/drivers/clk/sifive/fu540-prci.c
++++ b/drivers/clk/sifive/fu540-prci.c
+@@ -158,30 +158,32 @@
+  * PRCI per-device instance data
+  */
+ struct __prci_data {
+-	void *base;
+-	struct clk parent;
++	void *va;
++	struct clk parent_hfclk;
++	struct clk parent_rtcclk;
+ };
+ 
+ /**
+  * struct __prci_wrpll_data - WRPLL configuration and integration data
+  * @c: WRPLL current configuration record
+- * @bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL)
+- * @no_bypass: fn ptr to code to not bypass the WRPLL (if applicable; else NULL)
++ * @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL)
++ * @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL)
+  * @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address
+  *
+- * @bypass and @no_bypass are used for WRPLL instances that contain a separate
+- * external glitchless clock mux downstream from the PLL.  The WRPLL internal
+- * bypass mux is not glitchless.
++ * @enable_bypass and @disable_bypass are used for WRPLL instances
++ * that contain a separate external glitchless clock mux downstream
++ * from the PLL.  The WRPLL internal bypass mux is not glitchless.
+  */
+ struct __prci_wrpll_data {
+ 	struct wrpll_cfg c;
+-	void (*bypass)(struct __prci_data *pd);
+-	void (*no_bypass)(struct __prci_data *pd);
++	void (*enable_bypass)(struct __prci_data *pd);
++	void (*disable_bypass)(struct __prci_data *pd);
+ 	u8 cfg0_offs;
+ };
+ 
+ struct __prci_clock;
+ 
++/* struct __prci_clock_ops - clock operations */
+ struct __prci_clock_ops {
+ 	int (*set_rate)(struct __prci_clock *pc,
+ 			unsigned long rate,
+@@ -197,8 +199,7 @@ struct __prci_clock_ops {
+  * struct __prci_clock - describes a clock device managed by PRCI
+  * @name: user-readable clock name string - should match the manual
+  * @parent_name: parent name for this clock
+- * @ops: struct clk_ops for the Linux clock framework to use for control
+- * @hw: Linux-private clock data
++ * @ops: struct __prci_clock_ops for control
+  * @pwd: WRPLL-specific data, associated with this clock (if not NULL)
+  * @pd: PRCI-specific data associated with this clock (if not NULL)
+  *
+@@ -232,12 +233,12 @@ struct __prci_clock {
+  */
+ static u32 __prci_readl(struct __prci_data *pd, u32 offs)
+ {
+-	return readl(pd->base + offs);
++	return readl(pd->va + offs);
+ }
+ 
+ static void __prci_writel(u32 v, u32 offs, struct __prci_data *pd)
+ {
+-	return writel(v, pd->base + offs);
++	writel(v, pd->va + offs);
+ }
+ 
+ /* WRPLL-related private functions */
+@@ -279,10 +280,8 @@ static void __prci_wrpll_unpack(struct wrpll_cfg *c, u32 r)
+ 	c->flags &= (WRPLL_FLAGS_INT_FEEDBACK_MASK |
+ 		     WRPLL_FLAGS_EXT_FEEDBACK_MASK);
+ 
+-	if (r & PRCI_COREPLLCFG0_FSE_MASK)
+-		c->flags |= WRPLL_FLAGS_INT_FEEDBACK_MASK;
+-	else
+-		c->flags |= WRPLL_FLAGS_EXT_FEEDBACK_MASK;
++	/* external feedback mode not supported */
++	c->flags |= WRPLL_FLAGS_INT_FEEDBACK_MASK;
+ }
+ 
+ /**
+@@ -300,7 +299,7 @@ static void __prci_wrpll_unpack(struct wrpll_cfg *c, u32 r)
+  * Returns: a value suitable for writing into a PRCI PLL configuration
+  *          register
+  */
+-static u32 __prci_wrpll_pack(struct wrpll_cfg *c)
++static u32 __prci_wrpll_pack(const struct wrpll_cfg *c)
+ {
+ 	u32 r = 0;
+ 
+@@ -308,8 +307,9 @@ static u32 __prci_wrpll_pack(struct wrpll_cfg *c)
+ 	r |= c->divf << PRCI_COREPLLCFG0_DIVF_SHIFT;
+ 	r |= c->divq << PRCI_COREPLLCFG0_DIVQ_SHIFT;
+ 	r |= c->range << PRCI_COREPLLCFG0_RANGE_SHIFT;
+-	if (c->flags & WRPLL_FLAGS_INT_FEEDBACK_MASK)
+-		r |= PRCI_COREPLLCFG0_FSE_MASK;
++
++	/* external feedback mode not supported */
++	r |= PRCI_COREPLLCFG0_FSE_MASK;
+ 
+ 	return r;
+ }
+@@ -352,7 +352,7 @@ static void __prci_wrpll_write_cfg(struct __prci_data *pd,
+ {
+ 	__prci_writel(__prci_wrpll_pack(c), pwd->cfg0_offs, pd);
+ 
+-	memcpy(&pwd->c, c, sizeof(struct wrpll_cfg));
++	memcpy(&pwd->c, c, sizeof(*c));
+ }
+ 
+ /* Core clock mux control */
+@@ -431,17 +431,17 @@ static int sifive_fu540_prci_wrpll_set_rate(struct __prci_clock *pc,
+ 
+ 	r = wrpll_configure_for_rate(&pwd->c, rate, parent_rate);
+ 	if (r)
+-		return -ERANGE;
++		return r;
+ 
+-	if (pwd->bypass)
+-		pwd->bypass(pd);
++	if (pwd->enable_bypass)
++		pwd->enable_bypass(pd);
+ 
+ 	__prci_wrpll_write_cfg(pd, pwd, &pwd->c);
+ 
+ 	udelay(wrpll_calc_max_lock_us(&pwd->c));
+ 
+-	if (pwd->no_bypass)
+-		pwd->no_bypass(pd);
++	if (pwd->disable_bypass)
++		pwd->disable_bypass(pd);
+ 
+ 	return 0;
+ }
+@@ -483,8 +483,8 @@ static const struct __prci_clock_ops sifive_fu540_prci_tlclksel_clk_ops = {
+ 
+ static struct __prci_wrpll_data __prci_corepll_data = {
+ 	.cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
+-	.bypass = __prci_coreclksel_use_hfclk,
+-	.no_bypass = __prci_coreclksel_use_corepll,
++	.enable_bypass = __prci_coreclksel_use_hfclk,
++	.disable_bypass = __prci_coreclksel_use_corepll,
+ };
+ 
+ static struct __prci_wrpll_data __prci_ddrpll_data = {
+@@ -525,6 +525,27 @@ static struct __prci_clock __prci_init_clocks[] = {
+ 	},
+ };
+ 
++static ulong sifive_fu540_prci_parent_rate(struct __prci_clock *pc)
++{
++	ulong parent_rate;
++	struct __prci_clock *p;
++
++	if (strcmp(pc->parent_name, "corepll") == 0) {
++		p = &__prci_init_clocks[PRCI_CLK_COREPLL];
++		if (!p->pd || !p->ops->recalc_rate)
++			return -ENXIO;
++
++		return p->ops->recalc_rate(p, sifive_fu540_prci_parent_rate(p));
++	}
++
++	if (strcmp(pc->parent_name, "rtcclk") == 0)
++		parent_rate = clk_get_rate(&pc->pd->parent_rtcclk);
++	else
++		parent_rate = clk_get_rate(&pc->pd->parent_hfclk);
++
++	return parent_rate;
++}
++
+ static ulong sifive_fu540_prci_get_rate(struct clk *clk)
+ {
+ 	struct __prci_clock *pc;
+@@ -536,7 +557,7 @@ static ulong sifive_fu540_prci_get_rate(struct clk *clk)
+ 	if (!pc->pd || !pc->ops->recalc_rate)
+ 		return -ENXIO;
+ 
+-	return pc->ops->recalc_rate(pc, clk_get_rate(&pc->pd->parent));
++	return pc->ops->recalc_rate(pc, sifive_fu540_prci_parent_rate(pc));
+ }
+ 
+ static ulong sifive_fu540_prci_set_rate(struct clk *clk, ulong rate)
+@@ -551,7 +572,7 @@ static ulong sifive_fu540_prci_set_rate(struct clk *clk, ulong rate)
+ 	if (!pc->pd || !pc->ops->set_rate)
+ 		return -ENXIO;
+ 
+-	err = pc->ops->set_rate(pc, rate, clk_get_rate(&pc->pd->parent));
++	err = pc->ops->set_rate(pc, rate, sifive_fu540_prci_parent_rate(pc));
+ 	if (err)
+ 		return err;
+ 
+@@ -564,11 +585,15 @@ static int sifive_fu540_prci_probe(struct udevice *dev)
+ 	struct __prci_clock *pc;
+ 	struct __prci_data *pd = dev_get_priv(dev);
+ 
+-	pd->base = (void *)dev_read_addr(dev);
+-	if (IS_ERR(pd->base))
+-		return PTR_ERR(pd->base);
++	pd->va = (void *)dev_read_addr(dev);
++	if (IS_ERR(pd->va))
++		return PTR_ERR(pd->va);
++
++	err = clk_get_by_index(dev, 0, &pd->parent_hfclk);
++	if (err)
++		return err;
+ 
+-	err = clk_get_by_index(dev, 0, &pd->parent);
++	err = clk_get_by_index(dev, 1, &pd->parent_rtcclk);
+ 	if (err)
+ 		return err;
+ 
+@@ -588,8 +613,7 @@ static struct clk_ops sifive_fu540_prci_ops = {
+ };
+ 
+ static const struct udevice_id sifive_fu540_prci_ids[] = {
+-	{ .compatible = "sifive,fu540-c000-prci0" },
+-	{ .compatible = "sifive,aloeprci0" },
++	{ .compatible = "sifive,fu540-c000-prci" },
+ 	{ }
+ };
+ 
+-- 
+2.22.0
+

+ 0 - 27
recipes-bsp/u-boot/files/0011-riscv-qemu-enable-SMP.patch

@@ -1,27 +0,0 @@
-From d0a8fd3e4d2a5ab19b8f2d27d40dacb4942ba5a4 Mon Sep 17 00:00:00 2001
-From: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Date: Sun, 17 Mar 2019 19:28:42 +0100
-Subject: [PATCH 11/18] riscv: qemu: enable SMP
-
-Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
-Reviewed-by: Anup Patel <anup.patel@wdc.com>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-Tested-by: Bin Meng <bmeng.cn@gmail.com>
----
- board/emulation/qemu-riscv/Kconfig | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig
-index 88d07d568e..cf057e7de6 100644
---- a/board/emulation/qemu-riscv/Kconfig
-+++ b/board/emulation/qemu-riscv/Kconfig
-@@ -34,5 +34,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
- 	imply BOARD_LATE_INIT
- 	imply OF_BOARD_SETUP
- 	imply SIFIVE_SERIAL
-+	imply SMP
- 
- endif
--- 
-2.21.0
-

+ 127 - 0
recipes-bsp/u-boot/files/0012-clk-sifive-Drop-GEMGXL-clock-driver.patch

@@ -0,0 +1,127 @@
+From 5716c650d580a2de1e7dd9955eab049694a025b6 Mon Sep 17 00:00:00 2001
+From: Anup Patel <anup.patel@wdc.com>
+Date: Wed, 19 Jun 2019 09:11:51 +0530
+Subject: [PATCH 12/21] clk: sifive: Drop GEMGXL clock driver
+
+The GEMGXL clock driver is now directly part of Cadence MACB
+ethernet driver in upstream Linux kernel. There is no separate
+GEMGXL clock driver in upstream Linux kernel hence we drop
+GEMGXL clock driver from U-Boot as well.
+
+Signed-off-by: Anup Patel <anup.patel@wdc.com>
+Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
+Upstream-Status: Submitted
+---
+ board/sifive/fu540/Kconfig       |  1 -
+ drivers/clk/sifive/Kconfig       |  7 ----
+ drivers/clk/sifive/Makefile      |  2 --
+ drivers/clk/sifive/gemgxl-mgmt.c | 60 --------------------------------
+ 4 files changed, 70 deletions(-)
+ delete mode 100644 drivers/clk/sifive/gemgxl-mgmt.c
+
+diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
+index 8eb5e304ab..f46437901d 100644
+--- a/board/sifive/fu540/Kconfig
++++ b/board/sifive/fu540/Kconfig
+@@ -28,7 +28,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
+ 	imply CMD_PING
+ 	imply CLK_SIFIVE
+ 	imply CLK_SIFIVE_FU540_PRCI
+-	imply CLK_SIFIVE_GEMGXL_MGMT
+ 	imply DOS_PARTITION
+ 	imply EFI_PARTITION
+ 	imply IP_DYN
+diff --git a/drivers/clk/sifive/Kconfig b/drivers/clk/sifive/Kconfig
+index d90be1943f..c4d0a1f9b1 100644
+--- a/drivers/clk/sifive/Kconfig
++++ b/drivers/clk/sifive/Kconfig
+@@ -14,10 +14,3 @@ config CLK_SIFIVE_FU540_PRCI
+ 	  Supports the Power Reset Clock interface (PRCI) IP block found in
+ 	  FU540 SoCs.  If this kernel is meant to run on a SiFive FU540 SoC,
+ 	  enable this driver.
+-
+-config CLK_SIFIVE_GEMGXL_MGMT
+-	bool "GEMGXL management for SiFive FU540 SoCs"
+-	depends on CLK_SIFIVE
+-	help
+-	  Supports the GEMGXL management IP block found in FU540 SoCs to
+-	  control GEM TX clock operation mode for 10/100/1000 Mbps.
+diff --git a/drivers/clk/sifive/Makefile b/drivers/clk/sifive/Makefile
+index 0813360ca7..b224279afb 100644
+--- a/drivers/clk/sifive/Makefile
++++ b/drivers/clk/sifive/Makefile
+@@ -1,5 +1,3 @@
+ # SPDX-License-Identifier: GPL-2.0+
+ 
+ obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI)		+= fu540-prci.o
+-
+-obj-$(CONFIG_CLK_SIFIVE_GEMGXL_MGMT)		+= gemgxl-mgmt.o
+diff --git a/drivers/clk/sifive/gemgxl-mgmt.c b/drivers/clk/sifive/gemgxl-mgmt.c
+deleted file mode 100644
+index eb37416b5e..0000000000
+--- a/drivers/clk/sifive/gemgxl-mgmt.c
++++ /dev/null
+@@ -1,60 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0+
+-/*
+- * Copyright (C) 2019, Bin Meng <bmeng.cn@gmail.com>
+- */
+-
+-#include <common.h>
+-#include <clk-uclass.h>
+-#include <dm.h>
+-#include <asm/io.h>
+-
+-struct gemgxl_mgmt_regs {
+-	__u32 tx_clk_sel;
+-};
+-
+-struct gemgxl_mgmt_platdata {
+-	struct gemgxl_mgmt_regs *regs;
+-};
+-
+-static int gemgxl_mgmt_ofdata_to_platdata(struct udevice *dev)
+-{
+-	struct gemgxl_mgmt_platdata *plat = dev_get_platdata(dev);
+-
+-	plat->regs = (struct gemgxl_mgmt_regs *)dev_read_addr(dev);
+-
+-	return 0;
+-}
+-
+-static ulong gemgxl_mgmt_set_rate(struct clk *clk, ulong rate)
+-{
+-	struct gemgxl_mgmt_platdata *plat = dev_get_platdata(clk->dev);
+-
+-	/*
+-	 * GEMGXL TX clock operation mode:
+-	 *
+-	 * 0 = GMII mode. Use 125 MHz gemgxlclk from PRCI in TX logic
+-	 *     and output clock on GMII output signal GTX_CLK
+-	 * 1 = MII mode. Use MII input signal TX_CLK in TX logic
+-	 */
+-	writel(rate != 125000000, &plat->regs->tx_clk_sel);
+-
+-	return 0;
+-}
+-
+-const struct clk_ops gemgxl_mgmt_ops = {
+-	.set_rate = gemgxl_mgmt_set_rate,
+-};
+-
+-static const struct udevice_id gemgxl_mgmt_match[] = {
+-	{ .compatible = "sifive,cadencegemgxlmgmt0", },
+-	{ /* sentinel */ }
+-};
+-
+-U_BOOT_DRIVER(sifive_gemgxl_mgmt) = {
+-	.name = "sifive-gemgxl-mgmt",
+-	.id = UCLASS_CLK,
+-	.of_match = gemgxl_mgmt_match,
+-	.ofdata_to_platdata = gemgxl_mgmt_ofdata_to_platdata,
+-	.platdata_auto_alloc_size = sizeof(struct gemgxl_mgmt_platdata),
+-	.ops = &gemgxl_mgmt_ops,
+-};
+-- 
+2.22.0
+

+ 0 - 209
recipes-bsp/u-boot/files/0012-riscv-Add-a-SYSCON-driver-for-Andestech-s-PLIC.patch

@@ -1,209 +0,0 @@
-From 0d389468e2144f3ba3bdbc566c05c0c05dc14fc6 Mon Sep 17 00:00:00 2001
-From: Rick Chen <rick@andestech.com>
-Date: Tue, 2 Apr 2019 15:56:39 +0800
-Subject: [PATCH 12/18] riscv: Add a SYSCON driver for Andestech's PLIC
-
-The Platform-Level Interrupt Controller (PLIC)
-block holds memory-mapped claim and pending registers
-associated with software interrupt. It is required
-for handling IPI.
-
-Signed-off-by: Rick Chen <rick@andestech.com>
-Cc: Greentime Hu <greentime@andestech.com>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
----
- arch/riscv/Kconfig                   |   9 +++
- arch/riscv/include/asm/global_data.h |   3 +
- arch/riscv/include/asm/syscon.h      |   3 +-
- arch/riscv/lib/Makefile              |   1 +
- arch/riscv/lib/andes_plic.c          | 113 +++++++++++++++++++++++++++
- 5 files changed, 127 insertions(+), 2 deletions(-)
- create mode 100644 arch/riscv/lib/andes_plic.c
-
-diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
-index 3a4470daf3..511768befc 100644
---- a/arch/riscv/Kconfig
-+++ b/arch/riscv/Kconfig
-@@ -109,6 +109,15 @@ config SIFIVE_CLINT
- 	  The SiFive CLINT block holds memory-mapped control and status registers
- 	  associated with software and timer interrupts.
- 
-+config ANDES_PLIC
-+	bool
-+	depends on RISCV_MMODE
-+	select REGMAP
-+	select SYSCON
-+	help
-+	  The Andes PLIC block holds memory-mapped claim and pending registers
-+	  associated with software interrupt.
-+
- config RISCV_RDTIME
- 	bool
- 	default y if RISCV_SMODE
-diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
-index 80e3165e39..b86791094b 100644
---- a/arch/riscv/include/asm/global_data.h
-+++ b/arch/riscv/include/asm/global_data.h
-@@ -18,6 +18,9 @@ struct arch_global_data {
- #ifdef CONFIG_SIFIVE_CLINT
- 	void __iomem *clint;	/* clint base address */
- #endif
-+#ifdef CONFIG_ANDES_PLIC
-+	void __iomem *plic;	/* plic base address */
-+#endif
- #ifdef CONFIG_SMP
- 	struct ipi_data ipi[CONFIG_NR_CPUS];
- #endif
-diff --git a/arch/riscv/include/asm/syscon.h b/arch/riscv/include/asm/syscon.h
-index d311ee6b45..a086208261 100644
---- a/arch/riscv/include/asm/syscon.h
-+++ b/arch/riscv/include/asm/syscon.h
-@@ -8,12 +8,11 @@
- 
- /*
-  * System controllers in a RISC-V system
-- *
-- * So far only SiFive's Core Local Interruptor (CLINT) is defined.
-  */
- enum {
- 	RISCV_NONE,
- 	RISCV_SYSCON_CLINT,	/* Core Local Interruptor (CLINT) */
-+	RISCV_SYSCON_PLIC,	/* Platform Level Interrupt Controller (PLIC) */
- };
- 
- #endif /* _ASM_SYSCON_H */
-diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
-index 35dbf643e4..1bf554bad5 100644
---- a/arch/riscv/lib/Makefile
-+++ b/arch/riscv/lib/Makefile
-@@ -11,6 +11,7 @@ obj-$(CONFIG_CMD_GO) += boot.o
- obj-y	+= cache.o
- obj-$(CONFIG_RISCV_RDTIME) += rdtime.o
- obj-$(CONFIG_SIFIVE_CLINT) += sifive_clint.o
-+obj-$(CONFIG_ANDES_PLIC) += andes_plic.o
- obj-y	+= interrupts.o
- obj-y	+= reset.o
- obj-$(CONFIG_SBI_IPI) += sbi_ipi.o
-diff --git a/arch/riscv/lib/andes_plic.c b/arch/riscv/lib/andes_plic.c
-new file mode 100644
-index 0000000000..2ffe49ac90
---- /dev/null
-+++ b/arch/riscv/lib/andes_plic.c
-@@ -0,0 +1,113 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright (C) 2019, Rick Chen <rick@andestech.com>
-+ *
-+ * U-Boot syscon driver for Andes's Platform Level Interrupt Controller (PLIC).
-+ * The PLIC block holds memory-mapped claim and pending registers
-+ * associated with software interrupt.
-+ */
-+
-+#include <common.h>
-+#include <dm.h>
-+#include <dm/device-internal.h>
-+#include <dm/lists.h>
-+#include <dm/uclass-internal.h>
-+#include <regmap.h>
-+#include <syscon.h>
-+#include <asm/io.h>
-+#include <asm/syscon.h>
-+#include <cpu.h>
-+
-+/* pending register */
-+#define PENDING_REG(base, hart)	((ulong)(base) + 0x1000 + (hart) * 8)
-+/* enable register */
-+#define ENABLE_REG(base, hart)	((ulong)(base) + 0x2000 + (hart) * 0x80)
-+/* claim register */
-+#define CLAIM_REG(base, hart)	((ulong)(base) + 0x200004 + (hart) * 0x1000)
-+
-+#define ENABLE_HART_IPI         (0x80808080)
-+#define SEND_IPI_TO_HART(hart)  (0x80 >> (hart))
-+
-+DECLARE_GLOBAL_DATA_PTR;
-+static int init_plic(void);
-+
-+#define PLIC_BASE_GET(void)						\
-+	do {								\
-+		long *ret;						\
-+									\
-+		if (!gd->arch.plic) {					\
-+			ret = syscon_get_first_range(RISCV_SYSCON_PLIC); \
-+			if (IS_ERR(ret))				\
-+				return PTR_ERR(ret);			\
-+			gd->arch.plic = ret;				\
-+			init_plic();					\
-+		}							\
-+	} while (0)
-+
-+static int enable_ipi(int harts)
-+{
-+	int i;
-+	int en = ENABLE_HART_IPI;
-+
-+	for (i = 0; i < harts; i++) {
-+		en = en >> i;
-+		writel(en, (void __iomem *)ENABLE_REG(gd->arch.plic, i));
-+	}
-+
-+	return 0;
-+}
-+
-+static int init_plic(void)
-+{
-+	struct udevice *dev;
-+	int ret;
-+
-+	ret = uclass_find_first_device(UCLASS_CPU, &dev);
-+	if (ret)
-+		return ret;
-+
-+	if (ret == 0 && dev) {
-+		ret = cpu_get_count(dev);
-+		if (ret < 0)
-+			return ret;
-+
-+		enable_ipi(ret);
-+		return 0;
-+	}
-+
-+	return -ENODEV;
-+}
-+
-+int riscv_send_ipi(int hart)
-+{
-+	PLIC_BASE_GET();
-+
-+	writel(SEND_IPI_TO_HART(hart),
-+	       (void __iomem *)PENDING_REG(gd->arch.plic, gd->arch.boot_hart));
-+
-+	return 0;
-+}
-+
-+int riscv_clear_ipi(int hart)
-+{
-+	u32 source_id;
-+
-+	PLIC_BASE_GET();
-+
-+	source_id = readl((void __iomem *)CLAIM_REG(gd->arch.plic, hart));
-+	writel(source_id, (void __iomem *)CLAIM_REG(gd->arch.plic, hart));
-+
-+	return 0;
-+}
-+
-+static const struct udevice_id andes_plic_ids[] = {
-+	{ .compatible = "riscv,plic1", .data = RISCV_SYSCON_PLIC },
-+	{ }
-+};
-+
-+U_BOOT_DRIVER(andes_plic) = {
-+	.name		= "andes_plic",
-+	.id		= UCLASS_SYSCON,
-+	.of_match	= andes_plic_ids,
-+	.flags		= DM_FLAG_PRE_RELOC,
-+};
--- 
-2.21.0
-

+ 171 - 0
recipes-bsp/u-boot/files/0013-net-macb-Extend-MACB-driver-for-SiFive-Unleashed-boa.patch

@@ -0,0 +1,171 @@
+From 896f4c50ef098c5ed430ed06a346d244f9fa7c4e Mon Sep 17 00:00:00 2001
+From: Anup Patel <anup.patel@wdc.com>
+Date: Wed, 19 Jun 2019 19:11:50 +0530
+Subject: [PATCH 13/21] net: macb: Extend MACB driver for SiFive Unleashed
+ board
+
+The SiFive MACB ethernet has a custom TX_CLK_SEL register to select
+different TX clock for 1000mbps vs 10/100mbps.
+
+This patch adds SiFive MACB compatible string and extends the MACB
+ethernet driver to change TX clock using TX_CLK_SEL register for
+SiFive MACB.
+
+Signed-off-by: Anup Patel <anup.patel@wdc.com>
+Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
+Upstream-Status: Submitted
+---
+ drivers/net/macb.c | 70 +++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 53 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/net/macb.c b/drivers/net/macb.c
+index c072f99d8f..322302762a 100644
+--- a/drivers/net/macb.c
++++ b/drivers/net/macb.c
+@@ -83,7 +83,8 @@ struct macb_dma_desc {
+ 
+ struct macb_device {
+ 	void			*regs;
+-	unsigned int		dma_burst_length;
++
++	const struct macb_config*config;
+ 
+ 	unsigned int		rx_tail;
+ 	unsigned int		tx_head;
+@@ -123,6 +124,8 @@ struct macb_device {
+ 
+ struct macb_config {
+ 	unsigned int		dma_burst_length;
++
++	int			(*clk_init)(struct udevice *dev, ulong rate);
+ };
+ 
+ #ifndef CONFIG_DM_ETH
+@@ -483,21 +486,38 @@ static int macb_phy_find(struct macb_device *macb, const char *name)
+  * when operation failed.
+  */
+ #ifdef CONFIG_DM_ETH
++static int macb_sifive_clk_init(struct udevice *dev, ulong rate)
++{
++	fdt_addr_t addr;
++	void *gemgxl_regs;
++
++	addr = dev_read_addr_index(dev, 1);
++	if (addr == FDT_ADDR_T_NONE)
++		return -ENODEV;
++
++	gemgxl_regs = (void __iomem *)addr;
++	if (!gemgxl_regs)
++		return -ENODEV;
++
++	/*
++	 * SiFive GEMGXL TX clock operation mode:
++	 *
++	 * 0 = GMII mode. Use 125 MHz gemgxlclk from PRCI in TX logic
++	 *     and output clock on GMII output signal GTX_CLK
++	 * 1 = MII mode. Use MII input signal TX_CLK in TX logic
++	 */
++	writel(rate != 125000000, gemgxl_regs);
++	return 0;
++}
++
+ int __weak macb_linkspd_cb(struct udevice *dev, unsigned int speed)
+ {
+ #ifdef CONFIG_CLK
++	struct macb_device *macb = dev_get_priv(dev);
+ 	struct clk tx_clk;
+ 	ulong rate;
+ 	int ret;
+ 
+-	/*
+-	 * "tx_clk" is an optional clock source for MACB.
+-	 * Ignore if it does not exist in DT.
+-	 */
+-	ret = clk_get_by_name(dev, "tx_clk", &tx_clk);
+-	if (ret)
+-		return 0;
+-
+ 	switch (speed) {
+ 	case _10BASET:
+ 		rate = 2500000;		/* 2.5 MHz */
+@@ -513,6 +533,17 @@ int __weak macb_linkspd_cb(struct udevice *dev, unsigned int speed)
+ 		return 0;
+ 	}
+ 
++	if (macb->config->clk_init)
++		return macb->config->clk_init(dev, rate);
++
++	/*
++	 * "tx_clk" is an optional clock source for MACB.
++	 * Ignore if it does not exist in DT.
++	 */
++	ret = clk_get_by_name(dev, "tx_clk", &tx_clk);
++	if (ret)
++		return 0;
++
+ 	if (tx_clk.dev) {
+ 		ret = clk_set_rate(&tx_clk, rate);
+ 		if (ret)
+@@ -705,8 +736,9 @@ static void gmac_configure_dma(struct macb_device *macb)
+ 	dmacfg = gem_readl(macb, DMACFG) & ~GEM_BF(RXBS, -1L);
+ 	dmacfg |= GEM_BF(RXBS, buffer_size);
+ 
+-	if (macb->dma_burst_length)
+-		dmacfg = GEM_BFINS(FBLDO, macb->dma_burst_length, dmacfg);
++	if (macb->config->dma_burst_length)
++		dmacfg = GEM_BFINS(FBLDO,
++				   macb->config->dma_burst_length, dmacfg);
+ 
+ 	dmacfg |= GEM_BIT(TXPBMS) | GEM_BF(RXBMS, -1L);
+ 	dmacfg &= ~GEM_BIT(ENDIA_PKT);
+@@ -1173,11 +1205,10 @@ static const struct macb_config default_gem_config = {
+ 
+ static int macb_eth_probe(struct udevice *dev)
+ {
+-	const struct macb_config *macb_config;
+ 	struct eth_pdata *pdata = dev_get_platdata(dev);
+ 	struct macb_device *macb = dev_get_priv(dev);
+ 	const char *phy_mode;
+-	__maybe_unused int ret;
++	int ret;
+ 
+ 	phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
+ 			       NULL);
+@@ -1190,11 +1221,10 @@ static int macb_eth_probe(struct udevice *dev)
+ 
+ 	macb->regs = (void *)pdata->iobase;
+ 
+-	macb_config = (struct macb_config *)dev_get_driver_data(dev);
+-	if (!macb_config)
+-		macb_config = &default_gem_config;
++	macb->config = (struct macb_config *)dev_get_driver_data(dev);
++	if (!macb->config)
++		macb->config = &default_gem_config;
+ 
+-	macb->dma_burst_length = macb_config->dma_burst_length;
+ #ifdef CONFIG_CLK
+ 	ret = macb_enable_clk(dev);
+ 	if (ret)
+@@ -1259,6 +1289,11 @@ static const struct macb_config sama5d4_config = {
+ 	.dma_burst_length = 4,
+ };
+ 
++static const struct macb_config sifive_config = {
++	.dma_burst_length = 16,
++	.clk_init = macb_sifive_clk_init,
++};
++
+ static const struct udevice_id macb_eth_ids[] = {
+ 	{ .compatible = "cdns,macb" },
+ 	{ .compatible = "cdns,at91sam9260-macb" },
+@@ -1266,6 +1301,7 @@ static const struct udevice_id macb_eth_ids[] = {
+ 	{ .compatible = "atmel,sama5d3-gem" },
+ 	{ .compatible = "atmel,sama5d4-gem", .data = (ulong)&sama5d4_config },
+ 	{ .compatible = "cdns,zynq-gem" },
++	{ .compatible = "sifive,fu540-macb", .data = (ulong)&sifive_config },
+ 	{ }
+ };
+ 
+-- 
+2.22.0
+

+ 0 - 145
recipes-bsp/u-boot/files/0013-riscv-Add-a-SYSCON-driver-for-Andestech-s-PLMT.patch

@@ -1,145 +0,0 @@
-From a1f24875c346a1bf8940b793a27364631d9aabf7 Mon Sep 17 00:00:00 2001
-From: Rick Chen <rick@andestech.com>
-Date: Tue, 2 Apr 2019 15:56:40 +0800
-Subject: [PATCH 13/18] riscv: Add a SYSCON driver for Andestech's PLMT
-
-The platform-Level Machine Timer (PLMT) block
-holds memory-mapped mtime register associated
-with timer tick.
-
-This driver implements the riscv_get_time() which
-is required by the generic RISC-V timer driver.
-
-Signed-off-by: Rick Chen <rick@andestech.com>
-Cc: Greentime Hu <greentime@andestech.com>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
----
- arch/riscv/Kconfig                   |  9 +++++
- arch/riscv/include/asm/global_data.h |  3 ++
- arch/riscv/include/asm/syscon.h      |  1 +
- arch/riscv/lib/Makefile              |  1 +
- arch/riscv/lib/andes_plmt.c          | 53 ++++++++++++++++++++++++++++
- 5 files changed, 67 insertions(+)
- create mode 100644 arch/riscv/lib/andes_plmt.c
-
-diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
-index 511768befc..ae8ff7b765 100644
---- a/arch/riscv/Kconfig
-+++ b/arch/riscv/Kconfig
-@@ -118,6 +118,15 @@ config ANDES_PLIC
- 	  The Andes PLIC block holds memory-mapped claim and pending registers
- 	  associated with software interrupt.
- 
-+config ANDES_PLMT
-+	bool
-+	depends on RISCV_MMODE
-+	select REGMAP
-+	select SYSCON
-+	help
-+	  The Andes PLMT block holds memory-mapped mtime register
-+	  associated with timer tick.
-+
- config RISCV_RDTIME
- 	bool
- 	default y if RISCV_SMODE
-diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
-index b86791094b..dffcd45bf0 100644
---- a/arch/riscv/include/asm/global_data.h
-+++ b/arch/riscv/include/asm/global_data.h
-@@ -21,6 +21,9 @@ struct arch_global_data {
- #ifdef CONFIG_ANDES_PLIC
- 	void __iomem *plic;	/* plic base address */
- #endif
-+#ifdef CONFIG_ANDES_PLMT
-+	void __iomem *plmt;	/* plmt base address */
-+#endif
- #ifdef CONFIG_SMP
- 	struct ipi_data ipi[CONFIG_NR_CPUS];
- #endif
-diff --git a/arch/riscv/include/asm/syscon.h b/arch/riscv/include/asm/syscon.h
-index a086208261..26a008ca59 100644
---- a/arch/riscv/include/asm/syscon.h
-+++ b/arch/riscv/include/asm/syscon.h
-@@ -13,6 +13,7 @@ enum {
- 	RISCV_NONE,
- 	RISCV_SYSCON_CLINT,	/* Core Local Interruptor (CLINT) */
- 	RISCV_SYSCON_PLIC,	/* Platform Level Interrupt Controller (PLIC) */
-+	RISCV_SYSCON_PLMT,	/* Platform Level Machine Timer (PLMT) */
- };
- 
- #endif /* _ASM_SYSCON_H */
-diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
-index 1bf554bad5..1c332db436 100644
---- a/arch/riscv/lib/Makefile
-+++ b/arch/riscv/lib/Makefile
-@@ -12,6 +12,7 @@ obj-y	+= cache.o
- obj-$(CONFIG_RISCV_RDTIME) += rdtime.o
- obj-$(CONFIG_SIFIVE_CLINT) += sifive_clint.o
- obj-$(CONFIG_ANDES_PLIC) += andes_plic.o
-+obj-$(CONFIG_ANDES_PLMT) += andes_plmt.o
- obj-y	+= interrupts.o
- obj-y	+= reset.o
- obj-$(CONFIG_SBI_IPI) += sbi_ipi.o
-diff --git a/arch/riscv/lib/andes_plmt.c b/arch/riscv/lib/andes_plmt.c
-new file mode 100644
-index 0000000000..84f4607500
---- /dev/null
-+++ b/arch/riscv/lib/andes_plmt.c
-@@ -0,0 +1,53 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright (C) 2019, Rick Chen <rick@andestech.com>
-+ *
-+ * U-Boot syscon driver for Andes's Platform Level Machine Timer (PLMT).
-+ * The PLMT block holds memory-mapped mtime register
-+ * associated with timer tick.
-+ */
-+
-+#include <common.h>
-+#include <dm.h>
-+#include <regmap.h>
-+#include <syscon.h>
-+#include <asm/io.h>
-+#include <asm/syscon.h>
-+
-+/* mtime register */
-+#define MTIME_REG(base)			((ulong)(base))
-+
-+DECLARE_GLOBAL_DATA_PTR;
-+
-+#define PLMT_BASE_GET(void)						\
-+	do {								\
-+		long *ret;						\
-+									\
-+		if (!gd->arch.plmt) {					\
-+			ret = syscon_get_first_range(RISCV_SYSCON_PLMT); \
-+			if (IS_ERR(ret))				\
-+				return PTR_ERR(ret);			\
-+			gd->arch.plmt = ret;				\
-+		}							\
-+	} while (0)
-+
-+int riscv_get_time(u64 *time)
-+{
-+	PLMT_BASE_GET();
-+
-+	*time = readq((void __iomem *)MTIME_REG(gd->arch.plmt));
-+
-+	return 0;
-+}
-+
-+static const struct udevice_id andes_plmt_ids[] = {
-+	{ .compatible = "riscv,plmt0", .data = RISCV_SYSCON_PLMT },
-+	{ }
-+};
-+
-+U_BOOT_DRIVER(andes_plmt) = {
-+	.name		= "andes_plmt",
-+	.id		= UCLASS_SYSCON,
-+	.of_match	= andes_plmt_ids,
-+	.flags		= DM_FLAG_PRE_RELOC,
-+};
--- 
-2.21.0
-

+ 0 - 56
recipes-bsp/u-boot/files/0014-riscv-ax25-Add-platform-specific-Kconfig-options.patch

@@ -1,56 +0,0 @@
-From 8848474c5e9093ac27f6b7cc8be156629c7d0bad Mon Sep 17 00:00:00 2001
-From: Rick Chen <rick@andestech.com>
-Date: Tue, 2 Apr 2019 15:56:41 +0800
-Subject: [PATCH 14/18] riscv: ax25: Add platform-specific Kconfig options
-
-Add ax25 RISC-V platform-specific Kconfig options,
-to include CPU and timer drivers. Also disable
-ATCPIT100 SoC timer and replace by PLMT.
-
-Signed-off-by: Rick Chen <rick@andestech.com>
-Cc: Greentime Hu <greentime@andestech.com>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
----
- arch/riscv/cpu/ax25/Kconfig  | 6 ++++++
- configs/ae350_rv32_defconfig | 1 -
- configs/ae350_rv64_defconfig | 1 -
- 3 files changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/arch/riscv/cpu/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig
-index e9dbca2fae..68bd4e9419 100644
---- a/arch/riscv/cpu/ax25/Kconfig
-+++ b/arch/riscv/cpu/ax25/Kconfig
-@@ -1,5 +1,11 @@
- config RISCV_NDS
- 	bool
-+	select ARCH_EARLY_INIT_R
-+	imply CPU
-+	imply CPU_RISCV
-+	imply RISCV_TIMER
-+	imply ANDES_PLIC if RISCV_MMODE
-+	imply ANDES_PLMT if RISCV_MMODE
- 	help
- 	  Run U-Boot on AndeStar V5 platforms and use some specific features
- 	  which are provided by Andes Technology AndeStar V5 families.
-diff --git a/configs/ae350_rv32_defconfig b/configs/ae350_rv32_defconfig
-index 6e0be88d7c..f02945599f 100644
---- a/configs/ae350_rv32_defconfig
-+++ b/configs/ae350_rv32_defconfig
-@@ -34,4 +34,3 @@ CONFIG_BAUDRATE=38400
- CONFIG_SYS_NS16550=y
- CONFIG_SPI=y
- CONFIG_ATCSPI200_SPI=y
--CONFIG_ATCPIT100_TIMER=y
-diff --git a/configs/ae350_rv64_defconfig b/configs/ae350_rv64_defconfig
-index b472a76d17..98635a2ff9 100644
---- a/configs/ae350_rv64_defconfig
-+++ b/configs/ae350_rv64_defconfig
-@@ -35,4 +35,3 @@ CONFIG_BAUDRATE=38400
- CONFIG_SYS_NS16550=y
- CONFIG_SPI=y
- CONFIG_ATCSPI200_SPI=y
--CONFIG_ATCPIT100_TIMER=y
--- 
-2.21.0
-

+ 163 - 0
recipes-bsp/u-boot/files/0014-riscv-sifive-fu540-Setup-ethaddr-env-variable-using-.patch

@@ -0,0 +1,163 @@
+From fc7ee5955a7aafd972c93d6f9da9e862272a6822 Mon Sep 17 00:00:00 2001
+From: Anup Patel <anup.patel@wdc.com>
+Date: Wed, 19 Jun 2019 20:55:53 +0530
+Subject: [PATCH 14/21] riscv: sifive: fu540: Setup ethaddr env variable using
+ OTP
+
+This patch extends SiFive FU540 board support to setup ethaddr
+env variable based on board serialnum read from OTP.
+
+Signed-off-by: Anup Patel <anup.patel@wdc.com>
+Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
+Upstream-Status: Submitted
+---
+ board/sifive/fu540/fu540.c     | 122 +++++++++++++++++++++++++++++++++
+ configs/sifive_fu540_defconfig |   1 +
+ 2 files changed, 123 insertions(+)
+
+diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
+index 5adc4a3d4a..11daf1a75a 100644
+--- a/board/sifive/fu540/fu540.c
++++ b/board/sifive/fu540/fu540.c
+@@ -8,6 +8,128 @@
+ 
+ #include <common.h>
+ #include <dm.h>
++#include <linux/delay.h>
++#include <linux/io.h>
++
++#ifdef CONFIG_MISC_INIT_R
++
++#define FU540_OTP_BASE_ADDR			0x10070000
++
++struct fu540_otp_regs {
++	u32 pa;     /* Address input */
++	u32 paio;   /* Program address input */
++	u32 pas;    /* Program redundancy cell selection input */
++	u32 pce;    /* OTP Macro enable input */
++	u32 pclk;   /* Clock input */
++	u32 pdin;   /* Write data input */
++	u32 pdout;  /* Read data output */
++	u32 pdstb;  /* Deep standby mode enable input (active low) */
++	u32 pprog;  /* Program mode enable input */
++	u32 ptc;    /* Test column enable input */
++	u32 ptm;    /* Test mode enable input */
++	u32 ptm_rep;/* Repair function test mode enable input */
++	u32 ptr;    /* Test row enable input */
++	u32 ptrim;  /* Repair function enable input */
++	u32 pwe;    /* Write enable input (defines program cycle) */
++} __packed;
++
++#define BYTES_PER_FUSE				4
++#define NUM_FUSES				0x1000
++
++static int fu540_otp_read(int offset, void *buf, int size)
++{
++	struct fu540_otp_regs *regs = (void __iomem *)FU540_OTP_BASE_ADDR;
++	unsigned int i;
++	int fuseidx = offset / BYTES_PER_FUSE;
++	int fusecount = size / BYTES_PER_FUSE;
++	u32 fusebuf[fusecount];
++
++	/* check bounds */
++	if (offset < 0 || size < 0)
++		return -EINVAL;
++	if (fuseidx >= NUM_FUSES)
++		return -EINVAL;
++	if ((fuseidx + fusecount) > NUM_FUSES)
++		return -EINVAL;
++
++	/* init OTP */
++	writel(0x01, &regs->pdstb); /* wake up from stand-by */
++	writel(0x01, &regs->ptrim); /* enable repair function */
++	writel(0x01, &regs->pce);   /* enable input */
++
++	/* read all requested fuses */
++	for (i = 0; i < fusecount; i++, fuseidx++) {
++		writel(fuseidx, &regs->pa);
++
++		/* cycle clock to read */
++		writel(0x01, &regs->pclk);
++		mdelay(1);
++		writel(0x00, &regs->pclk);
++		mdelay(1);
++
++		/* read the value */
++		fusebuf[i] = readl(&regs->pdout);
++	}
++
++	/* shut down */
++	writel(0, &regs->pce);
++	writel(0, &regs->ptrim);
++	writel(0, &regs->pdstb);
++
++	/* copy out */
++	memcpy(buf, fusebuf, size);
++
++	return 0;
++}
++
++static u32 fu540_read_serialnum(void)
++{
++	int ret;
++	u32 serial[2] = {0};
++
++	for (int i = 0xfe * 4; i > 0; i -= 8) {
++		ret = fu540_otp_read(i, serial, sizeof(serial));
++		if (ret) {
++			printf("%s: error reading from OTP\n", __func__);
++			break;
++		}
++		if (serial[0] == ~serial[1])
++			return serial[0];
++	}
++
++	return 0;
++}
++
++static void fu540_setup_macaddr(u32 serialnum)
++{
++	/* Default MAC address */
++	unsigned char mac[6] = { 0x70, 0xb3, 0xd5, 0x92, 0xf0, 0x00 };
++
++	/*
++	 * We derive our board MAC address by ORing last three bytes
++	 * of board serial number to above default MAC address.
++	 *
++	 * This logic of deriving board MAC address is taken from
++	 * SiFive FSBL and is kept unchanged.
++	 */
++	mac[5] |= (serialnum >>  0) & 0xff;
++	mac[4] |= (serialnum >>  8) & 0xff;
++	mac[3] |= (serialnum >> 16) & 0xff;
++
++	/* Update environment variable */
++	eth_env_set_enetaddr("ethaddr", mac);
++}
++
++int misc_init_r(void)
++{
++	/* Set ethaddr environment variable if not set */
++	if (!env_get("ethaddr"))
++		fu540_setup_macaddr(fu540_read_serialnum());
++
++	return 0;
++}
++
++#endif
+ 
+ int board_init(void)
+ {
+diff --git a/configs/sifive_fu540_defconfig b/configs/sifive_fu540_defconfig
+index f78412398e..f19203745e 100644
+--- a/configs/sifive_fu540_defconfig
++++ b/configs/sifive_fu540_defconfig
+@@ -7,4 +7,5 @@ CONFIG_DISTRO_DEFAULTS=y
+ CONFIG_FIT=y
+ CONFIG_DISPLAY_CPUINFO=y
+ CONFIG_DISPLAY_BOARDINFO=y
++CONFIG_MISC_INIT_R=y
+ CONFIG_OF_PRIOR_STAGE=y
+-- 
+2.22.0
+

+ 460 - 0
recipes-bsp/u-boot/files/0015-doc-sifive-fu540-Update-README-for-steps-to-create-F.patch

@@ -0,0 +1,460 @@
+From 0cd385af7e915ad38cf9d99b02726799408ebe36 Mon Sep 17 00:00:00 2001
+From: Anup Patel <anup.patel@wdc.com>
+Date: Thu, 20 Jun 2019 11:53:32 +0530
+Subject: [PATCH 15/21] doc: sifive-fu540: Update README for steps to create
+ FW_PAYLOAD
+
+Due changes in DT bindings, we now embed DTB from Linux-5.3 (or
+higher) in OpenSBI FW_PAYLOAD along with payload u-boot.bin. This
+patch updates SiFive FU540 README to reflect the changes in build
+and boot steps.
+
+Signed-off-by: Anup Patel <anup.patel@wdc.com>
+Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
+Reviewed-by: Alistair Francis <Alistair.Francis@wdc.com>
+Upstream-Status: Submitted
+---
+ doc/README.sifive-fu540 | 356 ++++++++++++++++++----------------------
+ 1 file changed, 164 insertions(+), 192 deletions(-)
+
+diff --git a/doc/README.sifive-fu540 b/doc/README.sifive-fu540
+index fd9f2a8e46..33e03dc861 100644
+--- a/doc/README.sifive-fu540
++++ b/doc/README.sifive-fu540
+@@ -13,7 +13,8 @@ The support for following drivers are already enabled:
+ 3. Cadence MACB ethernet driver for networking support.
+ 
+ TODO:
+-1. SPI driver is still missing. So MMC card can't be used in U-Boot as of now.
++1. SPI host driver is still missing.
++2. SPI MMC driver does not compile and needs a re-write using U-Boot DM.
+ 2. U-Boot expects the serial console device entry to be present under /chosen
+    DT node. Example:
+    chosen {
+@@ -33,16 +34,21 @@ Building
+ 
+ Flashing
+ ========
+-The current U-Boot port is supported in S-mode only and loaded from DRAM.
++The current U-Boot port is supported in S-mode only and loaded directly
++into DRAM.
+ 
+-A prior stage (M-mode) firmware/bootloader (e.g OpenSBI or BBL) is required to
+-load the u-boot.bin into memory and provide runtime services. The u-boot.bin
+-can be given as a payload to the prior stage (M-mode) firmware/bootloader.
++A prior stage (M-mode) firmware/bootloader (e.g OpenSBI) is required to
++boot the u-boot.bin in S-mode and provide M-mode runtime services.
+ 
+-The description of steps required to build the firmware is beyond the scope of
+-this document. Please refer OpenSBI or BBL documenation.
++Currently, the u-boot.bin is used as a payload of the OpenSBI FW_PAYLOAD
++firmware. We need to compile OpenSBI with below command:
++make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=<path to u-boot.bin> FW_PAYLOAD_FDT_PATH=<path to hifive-unleashed-a00.dtb from Linux>
++(Note: Prefer hifive-unleashed-a00.dtb from Linux-5.3 or higher)
++(Note: Linux-5.2 is also fine but it does not have ethernet DT node)
++
++More detailed description of steps required to build FW_PAYLOAD firmware
++is beyond the scope of this document. Please refer OpenSBI documenation.
+ (Note: OpenSBI git repo is at https://github.com/riscv/opensbi.git)
+-(Note: BBL git repo is at https://github.com/riscv/riscv-pk.git)
+ 
+ Once the prior stage firmware/bootloader binary is generated, it should be
+ copied to the first partition of the sdcard.
+@@ -55,20 +61,18 @@ Once you plugin the sdcard and power up, you should see the U-Boot prompt.
+ 
+ Sample boot log from HiFive Unleashed board
+ ===========================================
+-U-Boot 2019.01-00019-gc7953536-dirty (Jan 22 2019 - 11:05:40 -0800)
++U-Boot 2019.07-rc4-00013-g1837f893b0 (Jun 20 2019 - 11:08:48 +0530)
+ 
+ CPU:   rv64imafdc
+-Model: sifive,hifive-unleashed-a00
++Model: SiFive HiFive Unleashed A00
+ DRAM:  8 GiB
+ In:    serial@10010000
+ Out:   serial@10010000
+ Err:   serial@10010000
+-Net:
+-Warning: ethernet@10090000 (eth0) using random MAC address - b6:75:4d:48:50:94
+-eth0: ethernet@10090000
++Net:   eth0: ethernet@10090000
+ Hit any key to stop autoboot:  0
+ => version
+-U-Boot 2019.01-00019-gc7953536-dirty (Jan 22 2019 - 11:05:40 -0800)
++U-Boot 2019.07-rc4-00013-g1837f893b0 (Jun 20 2019 - 11:08:48 +0530)
+ 
+ riscv64-linux-gcc.br_real (Buildroot 2018.11-rc2-00003-ga0787e9) 8.2.0
+ GNU ld (GNU Binutils) 2.31.1
+@@ -79,30 +83,19 @@ Now you can configure your networking, tftp server and use tftp boot method to
+ load uImage.
+ 
+ ==========================================================================
+-=> setenv ethaddr 70:B3:D5:92:F0:C2
+-=> setenv ipaddr 10.196.157.189
+-=> setenv serverip 10.11.143.218
+-=> setenv gatewayip 10.196.156.1
++=> setenv ipaddr 10.206.5.241
+ => setenv netmask 255.255.252.0
+-=> bdinfo
+-boot_params = 0x0000000000000000
+-DRAM bank   = 0x0000000000000000
+--> start    = 0x0000000080000000
+--> size     = 0x0000000200000000
+-relocaddr   = 0x00000000fff90000
+-reloc off   = 0x000000007fd90000
+-ethaddr     = 70:B3:D5:92:F0:C2
+-IP addr     = 10.196.157.189
+-baudrate    = 115200 bps
+-=> tftpboot uImage
++=> setenv serverip 10.206.4.143
++=> setenv gateway 10.206.4.1
++=> tftpboot ${kernel_addr_r} /sifive/fu540/uImage
+ ethernet@10090000: PHY present at 0
+ ethernet@10090000: Starting autonegotiation...
+ ethernet@10090000: Autonegotiation complete
+-ethernet@10090000: link up, 1000Mbps full-duplex (lpa: 0x3800)
++ethernet@10090000: link up, 1000Mbps full-duplex (lpa: 0x7c00)
+ Using ethernet@10090000 device
+-TFTP from server 10.11.143.218; our IP address is 10.196.157.189; sending through gateway 10.196.156.1
+-Filename 'uImage'.
+-Load address: 0x80200000
++TFTP from server 10.206.4.143; our IP address is 10.206.5.241
++Filename '/sifive/fu540/uImage'.
++Load address: 0x80600000
+ Loading: #################################################################
+          #################################################################
+          #################################################################
+@@ -112,192 +105,171 @@ Loading: #################################################################
+          #################################################################
+          #################################################################
+          #################################################################
++         ########################################
++         1.5 MiB/s
++done
++Bytes transferred = 9162364 (8bce7c hex)
++=> tftpboot ${ramdisk_addr_r} /sifive/fu540/uRamdisk
++ethernet@10090000: PHY present at 0
++ethernet@10090000: Starting autonegotiation...
++ethernet@10090000: Autonegotiation complete
++ethernet@10090000: link up, 1000Mbps full-duplex (lpa: 0x7c00)
++Using ethernet@10090000 device
++TFTP from server 10.206.4.143; our IP address is 10.206.5.241
++Filename '/sifive/fu540/uRamdisk'.
++Load address: 0x82500000
++Loading: #################################################################
+          #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         #################################################################
+-         ##########################################################
+-         2.5 MiB/s
++         ##################################
++         448.2 KiB/s
+ done
+-Bytes transferred = 14939132 (e3f3fc hex)
+-=> bootm 0x80200000 - 0x82200000
+-## Booting kernel from Legacy Image at 80200000 ...
++Bytes transferred = 2398272 (249840 hex)
++=> setenv bootargs "root=/dev/ram rw console=ttySIF0 earlycon=sbi"
++=> bootm ${kernel_addr_r} ${ramdisk_addr_r} ${fdtcontroladdr}
++## Booting kernel from Legacy Image at 80600000 ...
+    Image Name:   Linux
+    Image Type:   RISC-V Linux Kernel Image (uncompressed)
+-   Data Size:    14939068 Bytes = 14.2 MiB
++   Data Size:    9162300 Bytes = 8.7 MiB
+    Load Address: 80200000
+    Entry Point:  80200000
+    Verifying Checksum ... OK
+-## Flattened Device Tree blob at 82200000
+-   Booting using the fdt blob at 0x82200000
++## Loading init Ramdisk from Legacy Image at 82500000 ...
++   Image Name:   Linux RootFS
++   Image Type:   RISC-V Linux RAMDisk Image (uncompressed)
++   Data Size:    2398208 Bytes = 2.3 MiB
++   Load Address: 00000000
++   Entry Point:  00000000
++   Verifying Checksum ... OK
++## Flattened Device Tree blob at ff795730
++   Booting using the fdt blob at 0xff795730
+    Loading Kernel Image ... OK
+-   Using Device Tree in place at 0000000082200000, end 0000000082205c69
++   Using Device Tree in place at 00000000ff795730, end 00000000ff799dac
+ 
+ Starting kernel ...
+ 
+ [    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
+-[    0.000000] Linux version 5.0.0-rc1-00020-g4b51f736 (atish@jedi-01) (gcc version 7.2.0 (GCC)) #262 SMP Mon Jan 21 17:39:27 PST 2019
+-[    0.000000] initrd not found or empty - disabling initrd
++[    0.000000] Linux version 5.2.0-rc1-00003-gb9543e66e700 (anup@anup-lab-machine) (gcc version 8.2.0 (Buildroot 2018.11-rc2-00003-ga0787e9)) #1 SMP Thu Jun 20 11:41:26 IST 2019
++[    0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
++[    0.000000] printk: bootconsole [sbi0] enabled
++[    0.000000] Initial ramdisk at: 0x(____ptrval____) (2398208 bytes)
+ [    0.000000] Zone ranges:
+ [    0.000000]   DMA32    [mem 0x0000000080200000-0x00000000ffffffff]
+-[    0.000000]   Normal   [mem 0x0000000100000000-0x000027ffffffffff]
++[    0.000000]   Normal   [mem 0x0000000100000000-0x000000027fffffff]
+ [    0.000000] Movable zone start for each node
+ [    0.000000] Early memory node ranges
+ [    0.000000]   node   0: [mem 0x0000000080200000-0x000000027fffffff]
+ [    0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x000000027fffffff]
+-[    0.000000] software IO TLB: mapped [mem 0xfbfff000-0xfffff000] (64MB)
+-[    0.000000] CPU with hartid=0 has a non-okay status of "masked"
+-[    0.000000] CPU with hartid=0 has a non-okay status of "masked"
++[    0.000000] software IO TLB: mapped [mem 0xfb795000-0xff795000] (64MB)
++[    0.000000] CPU with hartid=0 is not available
++[    0.000000] CPU with hartid=0 is not available
+ [    0.000000] elf_hwcap is 0x112d
+-[    0.000000] percpu: Embedded 15 pages/cpu @(____ptrval____) s29720 r0 d31720 u61440
++[    0.000000] percpu: Embedded 17 pages/cpu s29592 r8192 d31848 u69632
+ [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 2067975
+-[    0.000000] Kernel command line: earlyprintk
++[    0.000000] Kernel command line: root=/dev/ram rw console=ttySIF0 earlycon=sbi
+ [    0.000000] Dentry cache hash table entries: 1048576 (order: 11, 8388608 bytes)
+ [    0.000000] Inode-cache hash table entries: 524288 (order: 10, 4194304 bytes)
+ [    0.000000] Sorting __ex_table...
+-[    0.000000] Memory: 8178760K/8386560K available (3309K kernel code, 248K rwdata, 872K rodata, 9381K init, 763K bss, 207800K reserved, 0K cma-reserved)
++[    0.000000] Memory: 8182056K/8386560K available (5753K kernel code, 357K rwdata, 1804K rodata, 204K init, 808K bss, 204504K reserved, 0K cma-reserved)
+ [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
+ [    0.000000] rcu: Hierarchical RCU implementation.
+-[    0.000000] rcu:     RCU event tracing is enabled.
+ [    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4.
+-[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
++[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
+ [    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
+ [    0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0
+-[    0.000000] plic: mapped 53 interrupts to 4 (out of 9) handlers.
+-[    0.000000] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [1]
++[    0.000000] plic: mapped 53 interrupts with 4 handlers for 9 contexts.
++[    0.000000] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [2]
+ [    0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x1d854df40, max_idle_ns: 3526361616960 ns
+-[    0.000008] sched_clock: 64 bits at 1000kHz, resolution 1000ns, wraps every 2199023255500ns
+-[    0.000221] Console: colour dummy device 80x25
+-[    0.000902] printk: console [tty0] enabled
+-[    0.000963] Calibrating delay loop (skipped), value calculated using timer frequency.. 2.00 BogoMIPS (lpj=10000)
+-[    0.001034] pid_max: default: 32768 minimum: 301
+-[    0.001541] Mount-cache hash table entries: 16384 (order: 5, 131072 bytes)
+-[    0.001912] Mountpoint-cache hash table entries: 16384 (order: 5, 131072 bytes)
+-[    0.003542] rcu: Hierarchical SRCU implementation.
+-[    0.004347] smp: Bringing up secondary CPUs ...
+-[    1.040259] CPU1: failed to come online
+-[    2.080483] CPU2: failed to come online
+-[    3.120699] CPU3: failed to come online
+-[    3.120765] smp: Brought up 1 node, 1 CPU
+-[    3.121923] devtmpfs: initialized
+-[    3.124649] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
+-[    3.124727] futex hash table entries: 1024 (order: 4, 65536 bytes)
+-[    3.125346] random: get_random_u32 called from bucket_table_alloc+0x72/0x172 with crng_init=0
+-[    3.125578] NET: Registered protocol family 16
+-[    3.126400] sifive-u54-prci 10000000.prci: Registered U54 core clocks
+-[    3.126649] sifive-gemgxl-mgmt 100a0000.cadence-gemgxl-mgmt: Registered clock switch 'cadence-gemgxl-mgmt'
+-[    3.135572] vgaarb: loaded
+-[    3.135858] SCSI subsystem initialized
+-[    3.136193] usbcore: registered new interface driver usbfs
+-[    3.136266] usbcore: registered new interface driver hub
+-[    3.136348] usbcore: registered new device driver usb
+-[    3.136446] pps_core: LinuxPPS API ver. 1 registered
+-[    3.136484] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
+-[    3.136575] PTP clock support registered
+-[    3.137256] clocksource: Switched to clocksource riscv_clocksource
+-[    3.142711] NET: Registered protocol family 2
+-[    3.143322] tcp_listen_portaddr_hash hash table entries: 4096 (order: 4, 65536 bytes)
+-[    3.143634] TCP established hash table entries: 65536 (order: 7, 524288 bytes)
+-[    3.145799] TCP bind hash table entries: 65536 (order: 8, 1048576 bytes)
+-[    3.149121] TCP: Hash tables configured (established 65536 bind 65536)
+-[    3.149591] UDP hash table entries: 4096 (order: 5, 131072 bytes)
+-[    3.150094] UDP-Lite hash table entries: 4096 (order: 5, 131072 bytes)
+-[    3.150781] NET: Registered protocol family 1
+-[    3.230693] workingset: timestamp_bits=62 max_order=21 bucket_order=0
+-[    3.241224] io scheduler mq-deadline registered
+-[    3.241269] io scheduler kyber registered
+-[    3.242143] sifive_gpio 10060000.gpio: SiFive GPIO chip registered 16 GPIOs
+-[    3.242357] pwm-sifivem 10020000.pwm: Unable to find controller clock
+-[    3.242439] pwm-sifivem 10021000.pwm: Unable to find controller clock
+-[    3.243228] xilinx-pcie 2000000000.pci: PCIe Link is DOWN
+-[    3.243289] xilinx-pcie 2000000000.pci: host bridge /soc/pci@2000000000 ranges:
+-[    3.243360] xilinx-pcie 2000000000.pci:   No bus range found for /soc/pci@2000000000, using [bus 00-ff]
+-[    3.243447] xilinx-pcie 2000000000.pci:   MEM 0x40000000..0x5fffffff -> 0x40000000
+-[    3.243591] xilinx-pcie 2000000000.pci: PCI host bridge to bus 0000:00
+-[    3.243636] pci_bus 0000:00: root bus resource [bus 00-ff]
+-[    3.243676] pci_bus 0000:00: root bus resource [mem 0x40000000-0x5fffffff]
+-[    3.276547] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
+-[    3.277689] 10010000.serial: ttySIF0 at MMIO 0x10010000 (irq = 39, base_baud = 0) is a SiFive UART v0
+-[    3.786963] printk: console [ttySIF0] enabled
+-[    3.791504] 10011000.serial: ttySIF1 at MMIO 0x10011000 (irq = 40, base_baud = 0) is a SiFive UART v0
+-[    3.801251] sifive_spi 10040000.spi: mapped; irq=41, cs=1
+-[    3.806362] m25p80 spi0.0: unrecognized JEDEC id bytes: 9d, 70, 19
+-[    3.812084] m25p80: probe of spi0.0 failed with error -2
+-[    3.817453] sifive_spi 10041000.spi: mapped; irq=42, cs=4
+-[    3.823027] sifive_spi 10050000.spi: mapped; irq=43, cs=1
+-[    3.828604] libphy: Fixed MDIO Bus: probed
+-[    3.832623] macb: GEM doesn't support hardware ptp.
+-[    3.837196] libphy: MACB_mii_bus: probed
+-[    4.041156] Microsemi VSC8541 SyncE 10090000.ethernet-ffffffff:00: attached PHY driver [Microsemi VSC8541 SyncE] (mii_bus:phy_addr=10090000.ethernet-ffffffff:00, irq=POLL)
+-[    4.055779] macb 10090000.ethernet eth0: Cadence GEM rev 0x10070109 at 0x10090000 irq 12 (70:b3:d5:92:f0:c2)
+-[    4.065780] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
+-[    4.072033] ehci-pci: EHCI PCI platform driver
+-[    4.076521] usbcore: registered new interface driver usb-storage
+-[    4.082843] softdog: initialized. soft_noboot=0 soft_margin=60 sec soft_panic=0 (nowayout=0)
+-[    4.127465] mmc_spi spi2.0: SD/MMC host mmc0, no DMA, no WP, no poweroff
+-[    4.133645] usbcore: registered new interface driver usbhid
+-[    4.138980] usbhid: USB HID core driver
+-[    4.143017] NET: Registered protocol family 17
+-[    4.147885] pwm-sifivem 10020000.pwm: SiFive PWM chip registered 4 PWMs
+-[    4.153945] pwm-sifivem 10021000.pwm: SiFive PWM chip registered 4 PWMs
+-[    4.186407] Freeing unused kernel memory: 9380K
+-[    4.190224] This architecture does not have kernel memory protection.
+-[    4.196609] Run /init as init process
+-Starting logging: OK
+-Starting mdev...
+-[    4.303785] mmc0: host does not support reading read-only switch, assuming write-enable
+-[    4.311109] mmc0: new SDHC card on SPI
+-[    4.317103] mmcblk0: mmc0:0000 SS08G 7.40 GiB
+-[    4.386471]  mmcblk0: p1 p2
+-sort: /sys/devices/platform/Fixed: No such file or directory
+-modprobe: can't change directory to '/lib/modules': No such file or directory
+-Initializing random[    4.759075] random: dd: uninitialized urandom read (512 bytes read)
+- number generator... done.
+-Starting network...
+-udhcpc (v1.24.2) started
+-Sending discover...
+-Sending discover...
+-[    7.927510] macb 10090000.ethernet eth0: link up (1000/Full)
+-Sending discover...
+-Sending select for 10.196.157.190...
+-Lease of 10.196.157.190 obtained, lease time 499743
+-deleting routers
+-adding dns 10.86.1.1
+-adding dns 10.86.2.1
+-/etc/init.d/S50dropbear
+-Starting dropbear sshd: [   12.772393] random: dropbear: uninitialized urandom read (32 bytes read)
+-OK
++[    0.000007] sched_clock: 64 bits at 1000kHz, resolution 1000ns, wraps every 2199023255500ns
++[    0.008553] Console: colour dummy device 80x25
++[    0.012990] Calibrating delay loop (skipped), value calculated using timer frequency.. 2.00 BogoMIPS (lpj=4000)
++[    0.023103] pid_max: default: 32768 minimum: 301
++[    0.028269] Mount-cache hash table entries: 16384 (order: 5, 131072 bytes)
++[    0.035068] Mountpoint-cache hash table entries: 16384 (order: 5, 131072 bytes)
++[    0.042770] *** VALIDATE proc ***
++[    0.045610] *** VALIDATE cgroup1 ***
++[    0.049157] *** VALIDATE cgroup2 ***
++[    0.053743] rcu: Hierarchical SRCU implementation.
++[    0.058297] smp: Bringing up secondary CPUs ...
++[    0.064134] smp: Brought up 1 node, 4 CPUs
++[    0.069114] devtmpfs: initialized
++[    0.073281] random: get_random_u32 called from bucket_table_alloc.isra.10+0x4e/0x160 with crng_init=0
++[    0.082157] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
++[    0.091634] futex hash table entries: 1024 (order: 4, 65536 bytes)
++[    0.098480] NET: Registered protocol family 16
++[    0.114101] vgaarb: loaded
++[    0.116397] SCSI subsystem initialized
++[    0.120358] usbcore: registered new interface driver usbfs
++[    0.125541] usbcore: registered new interface driver hub
++[    0.130936] usbcore: registered new device driver usb
++[    0.136618] clocksource: Switched to clocksource riscv_clocksource
++[    0.148108] NET: Registered protocol family 2
++[    0.152358] tcp_listen_portaddr_hash hash table entries: 4096 (order: 4, 65536 bytes)
++[    0.159928] TCP established hash table entries: 65536 (order: 7, 524288 bytes)
++[    0.169027] TCP bind hash table entries: 65536 (order: 8, 1048576 bytes)
++[    0.178360] TCP: Hash tables configured (established 65536 bind 65536)
++[    0.184653] UDP hash table entries: 4096 (order: 5, 131072 bytes)
++[    0.190819] UDP-Lite hash table entries: 4096 (order: 5, 131072 bytes)
++[    0.197618] NET: Registered protocol family 1
++[    0.201892] RPC: Registered named UNIX socket transport module.
++[    0.207395] RPC: Registered udp transport module.
++[    0.212159] RPC: Registered tcp transport module.
++[    0.216940] RPC: Registered tcp NFSv4.1 backchannel transport module.
++[    0.223445] PCI: CLS 0 bytes, default 64
++[    0.227726] Unpacking initramfs...
++[    0.260556] Freeing initrd memory: 2336K
++[    0.264652] workingset: timestamp_bits=62 max_order=21 bucket_order=0
++[    0.278452] NFS: Registering the id_resolver key type
++[    0.282841] Key type id_resolver registered
++[    0.287067] Key type id_legacy registered
++[    0.291155] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
++[    0.298299] NET: Registered protocol family 38
++[    0.302470] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
++[    0.309906] io scheduler mq-deadline registered
++[    0.314501] io scheduler kyber registered
++[    0.354134] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
++[    0.360725] 10010000.serial: ttySIF0 at MMIO 0x10010000 (irq = 4, base_baud = 0) is a SiFive UART v0
++[    0.369191] printk: console [ttySIF0] enabled
++[    0.369191] printk: console [ttySIF0] enabled
++[    0.377938] printk: bootconsole [sbi0] disabled
++[    0.377938] printk: bootconsole [sbi0] disabled
++[    0.387298] 10011000.serial: ttySIF1 at MMIO 0x10011000 (irq = 1, base_baud = 0) is a SiFive UART v0
++[    0.396411] [drm] radeon kernel modesetting enabled.
++[    0.409818] loop: module loaded
++[    0.412606] libphy: Fixed MDIO Bus: probed
++[    0.416870] macb 10090000.ethernet: Registered clk switch 'sifive-gemgxl-mgmt'
++[    0.423570] macb: GEM doesn't support hardware ptp.
++[    0.428469] libphy: MACB_mii_bus: probed
++[    1.053009] Microsemi VSC8541 SyncE 10090000.ethernet-ffffffff:00: attached PHY driver [Microsemi VSC8541 SyncE] (mii_bus:phy_addr=10090000.ethernet-ffffffff:00, irq=POLL)
++[    1.067548] macb 10090000.ethernet eth0: Cadence GEM rev 0x10070109 at 0x10090000 irq 7 (70:b3:d5:92:f2:f3)
++[    1.077330] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
++[    1.083069] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
++[    1.089061] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
++[    1.095485] ehci-pci: EHCI PCI platform driver
++[    1.099947] ehci-platform: EHCI generic platform driver
++[    1.105196] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
++[    1.111286] ohci-pci: OHCI PCI platform driver
++[    1.115742] ohci-platform: OHCI generic platform driver
++[    1.121142] usbcore: registered new interface driver uas
++[    1.126269] usbcore: registered new interface driver usb-storage
++[    1.132331] mousedev: PS/2 mouse device common for all mice
++[    1.137978] usbcore: registered new interface driver usbhid
++[    1.143325] usbhid: USB HID core driver
++[    1.148022] NET: Registered protocol family 10
++[    1.152609] Segment Routing with IPv6
++[    1.155571] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
++[    1.161927] NET: Registered protocol family 17
++[    1.165907] Key type dns_resolver registered
++[    1.171694] Freeing unused kernel memory: 204K
++[    1.175375] This architecture does not have kernel memory protection.
++[    1.181792] Run /init as init process
++           _  _
++          | ||_|
++          | | _ ____  _   _  _  _
++          | || |  _ \| | | |\ \/ /
++          | || | | | | |_| |/    \
++          |_||_|_| |_|\____|\_/\_/
++
++               Busybox Rootfs
+ 
+-Welcome to Buildroot
+-buildroot login:
++Please press Enter to activate this console.
++/ #
+-- 
+2.22.0
+

+ 0 - 32
recipes-bsp/u-boot/files/0015-riscv-ax25-Andes-specific-cache-shall-only-support-i.patch

@@ -1,32 +0,0 @@
-From dda00ae4ef357233a72c74e6c02d27b70c844422 Mon Sep 17 00:00:00 2001
-From: Rick Chen <rick@andestech.com>
-Date: Tue, 2 Apr 2019 15:56:42 +0800
-Subject: [PATCH 15/18] riscv: ax25: Andes specific cache shall only support in
- M-mode
-
-Limit the cache configuration only can be supported in M mode.
-It can not be manipulated in S mode.
-
-Signed-off-by: Rick Chen <rick@andestech.com>
-Cc: Greentime Hu <greentime@andestech.com>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
----
- arch/riscv/cpu/ax25/Kconfig | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/arch/riscv/cpu/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig
-index 68bd4e9419..6b4b92e692 100644
---- a/arch/riscv/cpu/ax25/Kconfig
-+++ b/arch/riscv/cpu/ax25/Kconfig
-@@ -14,6 +14,7 @@ if RISCV_NDS
- 
- config RISCV_NDS_CACHE
- 	bool "AndeStar V5 families specific cache support"
-+	depends on RISCV_MMODE
- 	help
- 	  Provide Andes Technology AndeStar V5 families specific cache support.
- 
--- 
-2.21.0
-

+ 60 - 0
recipes-bsp/u-boot/files/0016-net-macb-Fix-check-for-little-endian-system-in.patch

@@ -0,0 +1,60 @@
+From a30c65f4d5478eb53f267d71623ff2721c6f4c3d Mon Sep 17 00:00:00 2001
+From: Anup Patel <anup.patel@wdc.com>
+Date: Tue, 25 Jun 2019 11:50:05 +0530
+Subject: [PATCH 16/21] net: macb: Fix check for little-endian system in 
+ gmac_configure_dma()
+
+Instead of depending on CONFIG_SYS_LITTLE_ENDIAN, we check at runtime
+whether underlying system is little-endian or big-endian. This way
+we are not dependent on any U-Boot specific OR compiler specific macro
+to check system endianness.
+
+Signed-off-by: Anup Patel <anup.patel@wdc.com>
+Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
+Reviewed-By: Ramon Fried <rfried.dev@gmail.com>
+Upstream-Status: Submitted
+---
+ drivers/net/macb.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/macb.c b/drivers/net/macb.c
+index 322302762a..a4015e9bd5 100644
+--- a/drivers/net/macb.c
++++ b/drivers/net/macb.c
+@@ -84,6 +84,8 @@ struct macb_dma_desc {
+ struct macb_device {
+ 	void			*regs;
+ 
++	bool			is_big_endian;
++
+ 	const struct macb_config*config;
+ 
+ 	unsigned int		rx_tail;
+@@ -743,11 +745,10 @@ static void gmac_configure_dma(struct macb_device *macb)
+ 	dmacfg |= GEM_BIT(TXPBMS) | GEM_BF(RXBMS, -1L);
+ 	dmacfg &= ~GEM_BIT(ENDIA_PKT);
+ 
+-#ifdef CONFIG_SYS_LITTLE_ENDIAN
+-		dmacfg &= ~GEM_BIT(ENDIA_DESC);
+-#else
++	if (macb->is_big_endian)
+ 		dmacfg |= GEM_BIT(ENDIA_DESC); /* CPU in big endian */
+-#endif
++	else
++		dmacfg &= ~GEM_BIT(ENDIA_DESC);
+ 
+ 	dmacfg &= ~GEM_BIT(ADDR64);
+ 	gem_writel(macb, DMACFG, dmacfg);
+@@ -1221,6 +1222,9 @@ static int macb_eth_probe(struct udevice *dev)
+ 
+ 	macb->regs = (void *)pdata->iobase;
+ 
++	macb->is_big_endian = (cpu_to_be32(0x12345678) == 0x12345678) ?
++				true : false;
++
+ 	macb->config = (struct macb_config *)dev_get_driver_data(dev);
+ 	if (!macb->config)
+ 		macb->config = &default_gem_config;
+-- 
+2.22.0
+

+ 0 - 257
recipes-bsp/u-boot/files/0016-riscv-dts-ae350-support-SMP.patch

@@ -1,257 +0,0 @@
-From a1ce531ab24b1ef5e69dbf29ecbfc6898b454ec1 Mon Sep 17 00:00:00 2001
-From: Rick Chen <rick@andestech.com>
-Date: Tue, 2 Apr 2019 15:56:43 +0800
-Subject: [PATCH 16/18] riscv: dts: ae350 support SMP
-
-Signed-off-by: Rick Chen <rick@andestech.com>
-Cc: Greentime Hu <greentime@andestech.com>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
----
- arch/riscv/dts/ae350_32.dts | 81 +++++++++++++++++++++++++++----------
- arch/riscv/dts/ae350_64.dts | 81 +++++++++++++++++++++++++++----------
- 2 files changed, 118 insertions(+), 44 deletions(-)
-
-diff --git a/arch/riscv/dts/ae350_32.dts b/arch/riscv/dts/ae350_32.dts
-index 0679827313..2ec01a5ce7 100644
---- a/arch/riscv/dts/ae350_32.dts
-+++ b/arch/riscv/dts/ae350_32.dts
-@@ -26,16 +26,49 @@
- 			status = "okay";
- 			compatible = "riscv";
- 			riscv,isa = "rv32imafdc";
-+			riscv,priv-major = <1>;
-+			riscv,priv-minor = <10>;
- 			mmu-type = "riscv,sv32";
- 			clock-frequency = <60000000>;
-+			i-cache-size = <0x8000>;
-+			i-cache-line-size = <32>;
- 			d-cache-size = <0x8000>;
- 			d-cache-line-size = <32>;
-+			next-level-cache = <&L2>;
- 			CPU0_intc: interrupt-controller {
- 				#interrupt-cells = <1>;
- 				interrupt-controller;
- 				compatible = "riscv,cpu-intc";
- 			};
- 		};
-+		CPU1: cpu@1 {
-+			device_type = "cpu";
-+			reg = <1>;
-+			status = "okay";
-+			compatible = "riscv";
-+			riscv,isa = "rv32imafdc";
-+			riscv,priv-major = <1>;
-+			riscv,priv-minor = <10>;
-+			mmu-type = "riscv,sv32";
-+			clock-frequency = <60000000>;
-+			i-cache-size = <0x8000>;
-+			i-cache-line-size = <32>;
-+			d-cache-size = <0x8000>;
-+			d-cache-line-size = <32>;
-+			next-level-cache = <&L2>;
-+			CPU1_intc: interrupt-controller {
-+				#interrupt-cells = <1>;
-+				interrupt-controller;
-+				compatible = "riscv,cpu-intc";
-+			};
-+		};
-+
-+		L2: l2-cache@e0500000 {
-+			compatible = "cache";
-+			cache-level = <2>;
-+			cache-size = <0x40000>;
-+			reg = <0x0 0xe0500000 0x0 0x40000>;
-+		};
- 	};
- 
- 	memory@0 {
-@@ -46,32 +79,32 @@
- 	soc {
- 		#address-cells = <1>;
- 		#size-cells = <1>;
--		compatible = "andestech,riscv-ae350-soc";
-+		compatible = "simple-bus";
- 		ranges;
- 
--	plic0: interrupt-controller@e4000000 {
--		compatible = "riscv,plic0";
--		#address-cells = <1>;
--		#interrupt-cells = <1>;
--		interrupt-controller;
--		reg = <0xe4000000 0x2000000>;
--		riscv,ndev=<71>;
--		interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>;
--	};
-+		plic0: interrupt-controller@e4000000 {
-+			compatible = "riscv,plic0";
-+			#address-cells = <1>;
-+			#interrupt-cells = <1>;
-+			interrupt-controller;
-+			reg = <0xe4000000 0x2000000>;
-+			riscv,ndev=<71>;
-+			interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9 &CPU1_intc 11 &CPU1_intc 9>;
-+		};
- 
--	plic1: interrupt-controller@e6400000 {
--		compatible = "riscv,plic1";
--		#address-cells = <1>;
--		#interrupt-cells = <1>;
--		interrupt-controller;
--		reg = <0xe6400000 0x400000>;
--		riscv,ndev=<1>;
--		interrupts-extended = <&CPU0_intc 3>;
--	};
-+		plic1: interrupt-controller@e6400000 {
-+			compatible = "riscv,plic1";
-+			#address-cells = <1>;
-+			#interrupt-cells = <1>;
-+			interrupt-controller;
-+			reg = <0xe6400000 0x400000>;
-+			riscv,ndev=<2>;
-+			interrupts-extended = <&CPU0_intc 3 &CPU1_intc 3>;
-+		};
- 
--	plmt0@e6000000 {
--		compatible = "riscv,plmt0";
--			interrupts-extended = <&CPU0_intc 7>;
-+		plmt0@e6000000 {
-+			compatible = "riscv,plmt0";
-+			interrupts-extended = <&CPU0_intc 7 &CPU1_intc 7>;
- 			reg = <0xe6000000 0x100000>;
- 		};
- 	};
-@@ -146,6 +179,10 @@
- 		interrupt-parent = <&plic0>;
- 	};
- 
-+	pmu {
-+		compatible = "riscv,base-pmu";
-+	};
-+
- 	virtio_mmio@fe007000 {
- 		interrupts = <0x17 0x4>;
- 		interrupt-parent = <0x2>;
-diff --git a/arch/riscv/dts/ae350_64.dts b/arch/riscv/dts/ae350_64.dts
-index e48c298645..cde5cdeff8 100644
---- a/arch/riscv/dts/ae350_64.dts
-+++ b/arch/riscv/dts/ae350_64.dts
-@@ -26,16 +26,49 @@
- 			status = "okay";
- 			compatible = "riscv";
- 			riscv,isa = "rv64imafdc";
-+			riscv,priv-major = <1>;
-+			riscv,priv-minor = <10>;
- 			mmu-type = "riscv,sv39";
- 			clock-frequency = <60000000>;
-+			i-cache-size = <0x8000>;
-+			i-cache-line-size = <32>;
- 			d-cache-size = <0x8000>;
- 			d-cache-line-size = <32>;
-+			next-level-cache = <&L2>;
- 			CPU0_intc: interrupt-controller {
- 				#interrupt-cells = <1>;
- 				interrupt-controller;
- 				compatible = "riscv,cpu-intc";
- 			};
- 		};
-+		CPU1: cpu@1 {
-+			device_type = "cpu";
-+			reg = <1>;
-+			status = "okay";
-+			compatible = "riscv";
-+			riscv,isa = "rv64imafdc";
-+			riscv,priv-major = <1>;
-+			riscv,priv-minor = <10>;
-+			mmu-type = "riscv,sv39";
-+			clock-frequency = <60000000>;
-+			i-cache-size = <0x8000>;
-+			i-cache-line-size = <32>;
-+			d-cache-size = <0x8000>;
-+			d-cache-line-size = <32>;
-+			next-level-cache = <&L2>;
-+			CPU1_intc: interrupt-controller {
-+				#interrupt-cells = <1>;
-+				interrupt-controller;
-+				compatible = "riscv,cpu-intc";
-+			};
-+		};
-+
-+		L2: l2-cache@e0500000 {
-+			compatible = "cache";
-+			cache-level = <2>;
-+			cache-size = <0x40000>;
-+			reg = <0x0 0xe0500000 0x0 0x40000>;
-+		};
- 	};
- 
- 	memory@0 {
-@@ -46,32 +79,32 @@
- 	soc {
- 		#address-cells = <2>;
- 		#size-cells = <2>;
--		compatible = "andestech,riscv-ae350-soc";
-+		compatible = "simple-bus";
- 		ranges;
- 
--	plic0: interrupt-controller@e4000000 {
--		compatible = "riscv,plic0";
--		#address-cells = <2>;
--		#interrupt-cells = <2>;
--		interrupt-controller;
--		reg = <0x0 0xe4000000 0x0 0x2000000>;
--		riscv,ndev=<71>;
--		interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>;
--	};
-+		plic0: interrupt-controller@e4000000 {
-+			compatible = "riscv,plic0";
-+			#address-cells = <2>;
-+			#interrupt-cells = <2>;
-+			interrupt-controller;
-+			reg = <0x0 0xe4000000 0x0 0x2000000>;
-+			riscv,ndev=<71>;
-+			interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9 &CPU1_intc 11 &CPU1_intc 9>;
-+		};
- 
--	plic1: interrupt-controller@e6400000 {
--		compatible = "riscv,plic1";
--		#address-cells = <2>;
--		#interrupt-cells = <2>;
--		interrupt-controller;
--		reg = <0x0 0xe6400000 0x0 0x400000>;
--		riscv,ndev=<1>;
--		interrupts-extended = <&CPU0_intc 3>;
--	};
-+		plic1: interrupt-controller@e6400000 {
-+			compatible = "riscv,plic1";
-+			#address-cells = <2>;
-+			#interrupt-cells = <2>;
-+			interrupt-controller;
-+			reg = <0x0 0xe6400000 0x0 0x400000>;
-+			riscv,ndev=<2>;
-+			interrupts-extended = <&CPU0_intc 3 &CPU1_intc 3>;
-+		};
- 
--	plmt0@e6000000 {
--		compatible = "riscv,plmt0";
--			interrupts-extended = <&CPU0_intc 7>;
-+		plmt0@e6000000 {
-+			compatible = "riscv,plmt0";
-+			interrupts-extended = <&CPU0_intc 7 &CPU1_intc 7>;
- 			reg = <0x0 0xe6000000 0x0 0x100000>;
- 		};
- 	};
-@@ -146,6 +179,10 @@
- 		interrupt-parent = <&plic0>;
- 	};
- 
-+	pmu {
-+		compatible = "riscv,base-pmu";
-+	};
-+
- 	virtio_mmio@fe007000 {
- 		interrupts = <0x17 0x4>;
- 		interrupt-parent = <0x2>;
--- 
-2.21.0
-

+ 0 - 27
recipes-bsp/u-boot/files/0017-riscv-ae350-enable-SMP.patch

@@ -1,27 +0,0 @@
-From 076b845893f3bb59dfad80b012d28191c19e2f7b Mon Sep 17 00:00:00 2001
-From: Rick Chen <rick@andestech.com>
-Date: Tue, 2 Apr 2019 15:56:44 +0800
-Subject: [PATCH 17/18] riscv: ae350: enable SMP
-
-Signed-off-by: Rick Chen <rick@andestech.com>
-Cc: Greentime Hu <greentime@andestech.com>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
----
- board/AndesTech/ax25-ae350/Kconfig | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/board/AndesTech/ax25-ae350/Kconfig b/board/AndesTech/ax25-ae350/Kconfig
-index 44cb302f70..5e682b679d 100644
---- a/board/AndesTech/ax25-ae350/Kconfig
-+++ b/board/AndesTech/ax25-ae350/Kconfig
-@@ -24,5 +24,6 @@ config ENV_OFFSET
- config BOARD_SPECIFIC_OPTIONS # dummy
- 	def_bool y
- 	select RISCV_NDS
-+	imply SMP
- 
- endif
--- 
-2.21.0
-

+ 469 - 0
recipes-bsp/u-boot/files/0017-spi-Add-SiFive-SPI-driver.patch

@@ -0,0 +1,469 @@
+From 912588aa9f43bc085aa79428275935ac1327620e Mon Sep 17 00:00:00 2001
+From: Bhargav Shah <bhargavshah1988@gmail.com>
+Date: Sun, 27 Jan 2019 00:19:43 +0530
+Subject: [PATCH 17/21] spi: Add SiFive SPI driver
+
+This patch adds SiFive SPI driver. The driver is 100% DM driver
+and it determines input clock using clk framework.
+
+The SiFive SPI block is found on SiFive FU540 SOC and is used to
+access flash and MMC devices on SiFive Unleashed board.
+
+This driver implementation is inspired from the Linux SiFive SPI
+driver available in Linux-5.2 or higher and SiFive FSBL sources.
+
+Signed-off-by: Bhargav Shah <bhargavshah1988@gmail.com>
+Signed-off-by: Anup Patel <anup.patel@wdc.com>
+Upstream-Status: Submitted
+---
+ drivers/spi/Kconfig      |   8 +
+ drivers/spi/Makefile     |   1 +
+ drivers/spi/spi-sifive.c | 405 +++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 414 insertions(+)
+ create mode 100644 drivers/spi/spi-sifive.c
+
+diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
+index eb32f082fe..2712bad310 100644
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -224,6 +224,14 @@ config SANDBOX_SPI
+ 		};
+ 	  };
+ 
++config SIFIVE_SPI
++	bool "SiFive SPI driver"
++	help
++	  This driver supports the SiFive SPI IP. If unsure say N.
++	  Enable the SiFive SPI controller driver.
++
++	  The SiFive SPI controller driver is found on various SiFive SoCs.
++
+ config SPI_SUNXI
+ 	bool "Allwinner SoC SPI controllers"
+ 	help
+diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
+index 8be9a4baa2..09a9d3697e 100644
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -49,6 +49,7 @@ obj-$(CONFIG_PL022_SPI) += pl022_spi.o
+ obj-$(CONFIG_RENESAS_RPC_SPI) += renesas_rpc_spi.o
+ obj-$(CONFIG_ROCKCHIP_SPI) += rk_spi.o
+ obj-$(CONFIG_SANDBOX_SPI) += sandbox_spi.o
++obj-$(CONFIG_SIFIVE_SPI) += spi-sifive.o
+ obj-$(CONFIG_SPI_SUNXI) += spi-sunxi.o
+ obj-$(CONFIG_SH_SPI) += sh_spi.o
+ obj-$(CONFIG_SH_QSPI) += sh_qspi.o
+diff --git a/drivers/spi/spi-sifive.c b/drivers/spi/spi-sifive.c
+new file mode 100644
+index 0000000000..70eebc0463
+--- /dev/null
++++ b/drivers/spi/spi-sifive.c
+@@ -0,0 +1,405 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Copyright 2018 SiFive, Inc.
++ * Copyright 2019 Bhargav Shah <bhargavshah1988@gmail.com>
++ *
++ * SiFive SPI controller driver (master mode only)
++ */
++
++#include <common.h>
++#include <dm.h>
++#include <malloc.h>
++#include <spi.h>
++#include <asm/io.h>
++#include <linux/log2.h>
++#include <clk.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++#define SIFIVE_SPI_MAX_CS		32
++
++#define SIFIVE_SPI_DEFAULT_DEPTH	8
++#define SIFIVE_SPI_DEFAULT_BITS		8
++
++/* register offsets */
++#define SIFIVE_SPI_REG_SCKDIV            0x00 /* Serial clock divisor */
++#define SIFIVE_SPI_REG_SCKMODE           0x04 /* Serial clock mode */
++#define SIFIVE_SPI_REG_CSID              0x10 /* Chip select ID */
++#define SIFIVE_SPI_REG_CSDEF             0x14 /* Chip select default */
++#define SIFIVE_SPI_REG_CSMODE            0x18 /* Chip select mode */
++#define SIFIVE_SPI_REG_DELAY0            0x28 /* Delay control 0 */
++#define SIFIVE_SPI_REG_DELAY1            0x2c /* Delay control 1 */
++#define SIFIVE_SPI_REG_FMT               0x40 /* Frame format */
++#define SIFIVE_SPI_REG_TXDATA            0x48 /* Tx FIFO data */
++#define SIFIVE_SPI_REG_RXDATA            0x4c /* Rx FIFO data */
++#define SIFIVE_SPI_REG_TXMARK            0x50 /* Tx FIFO watermark */
++#define SIFIVE_SPI_REG_RXMARK            0x54 /* Rx FIFO watermark */
++#define SIFIVE_SPI_REG_FCTRL             0x60 /* SPI flash interface control */
++#define SIFIVE_SPI_REG_FFMT              0x64 /* SPI flash instruction format */
++#define SIFIVE_SPI_REG_IE                0x70 /* Interrupt Enable Register */
++#define SIFIVE_SPI_REG_IP                0x74 /* Interrupt Pendings Register */
++
++/* sckdiv bits */
++#define SIFIVE_SPI_SCKDIV_DIV_MASK       0xfffU
++
++/* sckmode bits */
++#define SIFIVE_SPI_SCKMODE_PHA           BIT(0)
++#define SIFIVE_SPI_SCKMODE_POL           BIT(1)
++#define SIFIVE_SPI_SCKMODE_MODE_MASK     (SIFIVE_SPI_SCKMODE_PHA | \
++					  SIFIVE_SPI_SCKMODE_POL)
++
++/* csmode bits */
++#define SIFIVE_SPI_CSMODE_MODE_AUTO      0U
++#define SIFIVE_SPI_CSMODE_MODE_HOLD      2U
++#define SIFIVE_SPI_CSMODE_MODE_OFF       3U
++
++/* delay0 bits */
++#define SIFIVE_SPI_DELAY0_CSSCK(x)       ((u32)(x))
++#define SIFIVE_SPI_DELAY0_CSSCK_MASK     0xffU
++#define SIFIVE_SPI_DELAY0_SCKCS(x)       ((u32)(x) << 16)
++#define SIFIVE_SPI_DELAY0_SCKCS_MASK     (0xffU << 16)
++
++/* delay1 bits */
++#define SIFIVE_SPI_DELAY1_INTERCS(x)     ((u32)(x))
++#define SIFIVE_SPI_DELAY1_INTERCS_MASK   0xffU
++#define SIFIVE_SPI_DELAY1_INTERXFR(x)    ((u32)(x) << 16)
++#define SIFIVE_SPI_DELAY1_INTERXFR_MASK  (0xffU << 16)
++
++/* fmt bits */
++#define SIFIVE_SPI_FMT_PROTO_SINGLE      0U
++#define SIFIVE_SPI_FMT_PROTO_DUAL        1U
++#define SIFIVE_SPI_FMT_PROTO_QUAD        2U
++#define SIFIVE_SPI_FMT_PROTO_MASK        3U
++#define SIFIVE_SPI_FMT_ENDIAN            BIT(2)
++#define SIFIVE_SPI_FMT_DIR               BIT(3)
++#define SIFIVE_SPI_FMT_LEN(x)            ((u32)(x) << 16)
++#define SIFIVE_SPI_FMT_LEN_MASK          (0xfU << 16)
++
++/* txdata bits */
++#define SIFIVE_SPI_TXDATA_DATA_MASK      0xffU
++#define SIFIVE_SPI_TXDATA_FULL           BIT(31)
++
++/* rxdata bits */
++#define SIFIVE_SPI_RXDATA_DATA_MASK      0xffU
++#define SIFIVE_SPI_RXDATA_EMPTY          BIT(31)
++
++/* ie and ip bits */
++#define SIFIVE_SPI_IP_TXWM               BIT(0)
++#define SIFIVE_SPI_IP_RXWM               BIT(1)
++
++struct sifive_spi {
++	void		*regs;		/* base address of the registers */
++	u32		fifo_depth;
++	u32		bits_per_word;
++	u32		cs_inactive;	/* Level of the CS pins when inactive*/
++	u32		freq;
++	u32		num_cs;
++};
++
++static void sifive_spi_write(struct sifive_spi *spi, int offset, u32 value)
++{
++	writel(value, spi->regs + offset);
++}
++
++static u32 sifive_spi_read(struct sifive_spi *spi, int offset)
++{
++	return readl(spi->regs + offset);
++}
++
++static void sifive_spi_prep_device(struct sifive_spi *spi,
++				   struct dm_spi_slave_platdata *slave)
++{
++	/* Update the chip select polarity */
++	if (slave->mode & SPI_CS_HIGH)
++		spi->cs_inactive &= ~BIT(slave->cs);
++	else
++		spi->cs_inactive |= BIT(slave->cs);
++	sifive_spi_write(spi, SIFIVE_SPI_REG_CSDEF, spi->cs_inactive);
++
++	/* Select the correct device */
++	sifive_spi_write(spi, SIFIVE_SPI_REG_CSID, slave->cs);
++}
++
++static int sifive_spi_set_cs(struct sifive_spi *spi,
++			     struct dm_spi_slave_platdata *slave)
++{
++	u32 cs_mode = SIFIVE_SPI_CSMODE_MODE_HOLD;
++
++	if (slave->cs > spi->num_cs)
++		return -EINVAL;
++
++	if (slave->mode & SPI_CS_HIGH)
++		cs_mode = SIFIVE_SPI_CSMODE_MODE_AUTO;
++
++	sifive_spi_write(spi, SIFIVE_SPI_REG_CSMODE, cs_mode);
++
++	return 0;
++}
++
++static void sifive_spi_clear_cs(struct sifive_spi *spi)
++{
++	sifive_spi_write(spi, SIFIVE_SPI_REG_CSMODE,
++			 SIFIVE_SPI_CSMODE_MODE_AUTO);
++}
++
++static void sifive_spi_prep_transfer(struct sifive_spi *spi,
++				     bool is_rx_xfer,
++				     struct dm_spi_slave_platdata *slave)
++{
++	u32 cr;
++
++	/* Modify the SPI protocol mode */
++	cr = sifive_spi_read(spi, SIFIVE_SPI_REG_FMT);
++
++	/* Bits per word ? */
++	cr &= ~SIFIVE_SPI_FMT_LEN_MASK;
++	cr |= SIFIVE_SPI_FMT_LEN(SIFIVE_SPI_DEFAULT_BITS);
++
++	/* LSB first? */
++	cr &= ~SIFIVE_SPI_FMT_ENDIAN;
++	if (slave->mode & SPI_LSB_FIRST)
++		cr |= SIFIVE_SPI_FMT_ENDIAN;
++
++	/* Number of wires ? */
++	cr &= ~SIFIVE_SPI_FMT_PROTO_MASK;
++	if ((slave->mode & SPI_TX_QUAD) || (slave->mode & SPI_RX_QUAD))
++		cr |= SIFIVE_SPI_FMT_PROTO_QUAD;
++	else if ((slave->mode & SPI_TX_DUAL) || (slave->mode & SPI_RX_DUAL))
++		cr |= SIFIVE_SPI_FMT_PROTO_DUAL;
++	else
++		cr |= SIFIVE_SPI_FMT_PROTO_SINGLE;
++
++	/* SPI direction in/out ? */
++	cr &= ~SIFIVE_SPI_FMT_DIR;
++	if (!is_rx_xfer)
++		cr |= SIFIVE_SPI_FMT_DIR;
++
++	sifive_spi_write(spi, SIFIVE_SPI_REG_FMT, cr);
++}
++
++static void sifive_spi_rx(struct sifive_spi *spi, u8 *rx_ptr)
++{
++	u32 data;
++
++	do {
++		data = sifive_spi_read(spi, SIFIVE_SPI_REG_RXDATA);
++	} while (data & SIFIVE_SPI_RXDATA_EMPTY);
++
++	if (rx_ptr)
++		*rx_ptr = data & SIFIVE_SPI_RXDATA_DATA_MASK;
++}
++
++static void sifive_spi_tx(struct sifive_spi *spi, const u8 *tx_ptr)
++{
++	u32 data;
++	u8 tx_data = (tx_ptr) ? *tx_ptr & SIFIVE_SPI_TXDATA_DATA_MASK :
++				SIFIVE_SPI_TXDATA_DATA_MASK;
++
++	do {
++		data = sifive_spi_read(spi, SIFIVE_SPI_REG_TXDATA);
++	} while (data & SIFIVE_SPI_TXDATA_FULL);
++
++	sifive_spi_write(spi, SIFIVE_SPI_REG_TXDATA, tx_data);
++}
++
++static u8 sifive_spi_txrx(struct sifive_spi *spi, const u8 *tx_ptr)
++{
++	u8 rx = 0;
++
++	sifive_spi_tx(spi, tx_ptr);
++	sifive_spi_rx(spi, &rx);
++
++	return rx;
++}
++
++static int sifive_spi_claim_bus(struct udevice *dev)
++{
++	int ret;
++	struct udevice *bus = dev->parent;
++	struct sifive_spi *spi = dev_get_priv(bus);
++	struct dm_spi_slave_platdata *slave = dev_get_parent_platdata(dev);
++
++	sifive_spi_prep_device(spi, slave);
++
++	ret = sifive_spi_set_cs(spi, slave);
++	if (ret)
++		return ret;
++
++	return 0;
++}
++
++static int sifive_spi_release_bus(struct udevice *dev)
++{
++	struct sifive_spi *spi = dev_get_priv(dev->parent);
++
++	sifive_spi_clear_cs(spi);
++
++	return 0;
++}
++
++static int sifive_spi_xfer(struct udevice *dev, unsigned int bitlen,
++			   const void *dout, void *din, unsigned long flags)
++{
++	struct udevice *bus = dev->parent;
++	struct sifive_spi *spi = dev_get_priv(bus);
++	struct dm_spi_slave_platdata *slave = dev_get_parent_platdata(dev);
++	const unsigned char *tx_ptr = dout;
++	unsigned char *rx_ptr = din;
++	u32 remaining_len;
++
++	sifive_spi_prep_transfer(spi, true, slave);
++
++	remaining_len = bitlen / 8;
++
++	while (remaining_len) {
++		int n_words, tx_words, rx_words;
++
++		n_words = min(remaining_len, spi->fifo_depth);
++
++		/* Enqueue n_words for transmission */
++		if (tx_ptr) {
++			for (tx_words = 0; tx_words < n_words; ++tx_words) {
++				sifive_spi_txrx(spi, tx_ptr);
++				tx_ptr++;
++			}
++		}
++
++		/* Read out all the data from the RX FIFO */
++		if (rx_ptr) {
++			for (rx_words = 0; rx_words < n_words; ++rx_words) {
++				*rx_ptr = sifive_spi_txrx(spi, NULL);
++				rx_ptr++;
++			}
++		}
++
++		remaining_len -= n_words;
++	}
++
++	return 0;
++}
++
++static int sifive_spi_set_speed(struct udevice *bus, uint speed)
++{
++	struct sifive_spi *spi = dev_get_priv(bus);
++	u32 scale;
++
++	if (speed > spi->freq)
++		speed = spi->freq;
++
++	/* Cofigure max speed */
++	scale = (DIV_ROUND_UP(spi->freq >> 1, speed) - 1)
++					& SIFIVE_SPI_SCKDIV_DIV_MASK;
++	sifive_spi_write(spi, SIFIVE_SPI_REG_SCKDIV, scale);
++	return 0;
++}
++
++static int sifive_spi_set_mode(struct udevice *bus, uint mode)
++{
++	struct sifive_spi *spi = dev_get_priv(bus);
++	u32 cr;
++
++	/* Switch clock mode bits */
++	cr = sifive_spi_read(spi, SIFIVE_SPI_REG_SCKMODE) &
++					~SIFIVE_SPI_SCKMODE_MODE_MASK;
++	if (mode & SPI_CPHA)
++		cr |= SIFIVE_SPI_SCKMODE_PHA;
++	if (mode & SPI_CPOL)
++		cr |= SIFIVE_SPI_SCKMODE_POL;
++
++	sifive_spi_write(spi, SIFIVE_SPI_REG_SCKMODE, cr);
++
++	return 0;
++}
++
++static int sifive_cs_info(struct udevice *bus, uint cs,
++			  struct spi_cs_info *info)
++{
++	return 0;
++}
++
++static void sifive_spi_init_hw(struct sifive_spi *spi)
++{
++	u32 cs_bits;
++
++	/* probe the number of CS lines */
++	spi->cs_inactive = sifive_spi_read(spi, SIFIVE_SPI_REG_CSDEF);
++	sifive_spi_write(spi, SIFIVE_SPI_REG_CSDEF, 0xffffffffU);
++	cs_bits = sifive_spi_read(spi, SIFIVE_SPI_REG_CSDEF);
++	sifive_spi_write(spi, SIFIVE_SPI_REG_CSDEF, spi->cs_inactive);
++	if (!cs_bits) {
++		printf("Could not auto probe CS lines\n");
++		return;
++	}
++
++	spi->num_cs = ilog2(cs_bits) + 1;
++	if (spi->num_cs > SIFIVE_SPI_MAX_CS) {
++		printf("Invalid number of spi slaves\n");
++		return;
++	}
++
++	/* Watermark interrupts are disabled by default */
++	sifive_spi_write(spi, SIFIVE_SPI_REG_IE, 0);
++
++	/* Set CS/SCK Delays and Inactive Time to defaults */
++	sifive_spi_write(spi, SIFIVE_SPI_REG_DELAY0,
++			 SIFIVE_SPI_DELAY0_CSSCK(1) |
++			 SIFIVE_SPI_DELAY0_SCKCS(1));
++	sifive_spi_write(spi, SIFIVE_SPI_REG_DELAY1,
++			 SIFIVE_SPI_DELAY1_INTERCS(1) |
++			 SIFIVE_SPI_DELAY1_INTERXFR(0));
++
++	/* Exit specialized memory-mapped SPI flash mode */
++	sifive_spi_write(spi, SIFIVE_SPI_REG_FCTRL, 0);
++}
++
++static int sifive_spi_probe(struct udevice *bus)
++{
++	struct sifive_spi *spi = dev_get_priv(bus);
++	struct clk clkdev;
++	int ret;
++
++	spi->regs = (void *)(ulong)dev_remap_addr(bus);
++	if (!spi->regs)
++		return -ENODEV;
++
++	spi->fifo_depth = dev_read_u32_default(bus,
++					       "sifive,fifo-depth",
++					       SIFIVE_SPI_DEFAULT_DEPTH);
++
++	spi->bits_per_word = dev_read_u32_default(bus,
++						  "sifive,max-bits-per-word",
++						  SIFIVE_SPI_DEFAULT_BITS);
++
++	ret = clk_get_by_index(bus, 0, &clkdev);
++	if (ret)
++		return ret;
++	spi->freq = clk_get_rate(&clkdev);
++
++	/* init the sifive spi hw */
++	sifive_spi_init_hw(spi);
++
++	return 0;
++}
++
++static const struct dm_spi_ops sifive_spi_ops = {
++	.claim_bus	= sifive_spi_claim_bus,
++	.release_bus	= sifive_spi_release_bus,
++	.xfer		= sifive_spi_xfer,
++	.set_speed	= sifive_spi_set_speed,
++	.set_mode	= sifive_spi_set_mode,
++	.cs_info        = sifive_cs_info,
++};
++
++static const struct udevice_id sifive_spi_ids[] = {
++	{ .compatible = "sifive,spi0" },
++	{ }
++};
++
++U_BOOT_DRIVER(sifive_spi) = {
++	.name	= "sifive_spi",
++	.id	= UCLASS_SPI,
++	.of_match = sifive_spi_ids,
++	.ops	= &sifive_spi_ops,
++	.priv_auto_alloc_size = sizeof(struct sifive_spi),
++	.probe	= sifive_spi_probe,
++};
+-- 
+2.22.0
+

+ 50 - 0
recipes-bsp/u-boot/files/0018-mmc-skip-select_mode_and_width-for-MMC-SPI-host.patch

@@ -0,0 +1,50 @@
+From 9d81a06f0812021d13f5ff1aed7b37f04ea36f1b Mon Sep 17 00:00:00 2001
+From: Anup Patel <anup.patel@wdc.com>
+Date: Thu, 27 Jun 2019 13:08:09 +0530
+Subject: [PATCH 18/21] mmc: skip select_mode_and_width for MMC SPI host
+
+The MMC mode and width are fixed for MMC SPI host hence we skip
+sd_select_mode_and_width() and mmc_select_mode_and_width() for
+MMC SPI host.
+
+Signed-off-by: Anup Patel <anup.patel@wdc.com>
+Upstream-Status: Submitted
+---
+ drivers/mmc/mmc.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
+index 456c1b4cc9..95008c72c3 100644
+--- a/drivers/mmc/mmc.c
++++ b/drivers/mmc/mmc.c
+@@ -1672,6 +1672,13 @@ static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
+ 	mmc_dump_capabilities("host", mmc->host_caps);
+ #endif
+ 
++	if (mmc_host_is_spi(mmc)) {
++		mmc_set_bus_width(mmc, 1);
++		mmc_select_mode(mmc, SD_LEGACY);
++		mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
++		return 0;
++	}
++
+ 	/* Restrict card's capabilities by what the host can do */
+ 	caps = card_caps & mmc->host_caps;
+ 
+@@ -1934,6 +1941,13 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
+ 	mmc_dump_capabilities("host", mmc->host_caps);
+ #endif
+ 
++	if (mmc_host_is_spi(mmc)) {
++		mmc_set_bus_width(mmc, 1);
++		mmc_select_mode(mmc, MMC_LEGACY);
++		mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
++		return 0;
++	}
++
+ 	/* Restrict card's capabilities by what the host can do */
+ 	card_caps &= mmc->host_caps;
+ 
+-- 
+2.22.0
+

+ 0 - 35
recipes-bsp/u-boot/files/0018-riscv-dts-fix-CONFIG_DEFAULT_DEVICE_TREE-failure.patch

@@ -1,35 +0,0 @@
-From 48b90d9db5d32e587901c4f33175488dd20fe0a5 Mon Sep 17 00:00:00 2001
-From: Rick Chen <rick@andestech.com>
-Date: Wed, 3 Apr 2019 10:43:37 +0800
-Subject: [PATCH 18/18] riscv: dts: fix CONFIG_DEFAULT_DEVICE_TREE failure
-
-It occurs since commit 27cb7300ffda
-("Ensure device tree DTS is compiled").
-
-More details can refer to
-89c2b5c02049aea746b1edee0b4e1d8519dec2f4
-ARM: fix arch/arm/dts/Makefile
-
-Signed-off-by: Rick Chen <rick@andestech.com>
-Cc: Greentime Hu <greentime@andestech.com>
-Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
----
- arch/riscv/dts/Makefile | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile
-index b400defb38..f9cd606a9a 100644
---- a/arch/riscv/dts/Makefile
-+++ b/arch/riscv/dts/Makefile
-@@ -1,5 +1,7 @@
- # SPDX-License-Identifier: GPL-2.0+
- 
-+dtb-$(CONFIG_TARGET_AX25_AE350) += ae350_32.dtb ae350_64.dtb
-+
- targets += $(dtb-y)
- 
- DTC_FLAGS += -R 4 -p 0x1000
--- 
-2.21.0
-

+ 641 - 0
recipes-bsp/u-boot/files/0019-mmc-mmc_spi-Re-write-driver-using-DM-framework.patch

@@ -0,0 +1,641 @@
+From 250c07102bfb556093f26fd4b4e1a16c8e5df9db Mon Sep 17 00:00:00 2001
+From: Bhargav Shah <bhargavshah1988@gmail.com>
+Date: Mon, 24 Jun 2019 09:30:28 +0530
+Subject: [PATCH 19/21] mmc: mmc_spi: Re-write driver using DM framework
+
+This patch rewrites MMC SPI driver using U-Boot DM
+framework and get it's working on SiFive Unleashed
+board.
+
+Signed-off-by: Bhargav Shah <bhargavshah1988@gmail.com>
+Signed-off-by: Anup Patel <anup.patel@wdc.com>
+Upstream-Status: Submitted
+---
+ drivers/mmc/Kconfig   |  18 ++
+ drivers/mmc/mmc_spi.c | 469 +++++++++++++++++++++++++++---------------
+ 2 files changed, 320 insertions(+), 167 deletions(-)
+
+diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
+index c23299ea96..f750dad00a 100644
+--- a/drivers/mmc/Kconfig
++++ b/drivers/mmc/Kconfig
+@@ -46,6 +46,24 @@ config SPL_DM_MMC
+ 
+ if MMC
+ 
++config MMC_SPI
++	bool "Support for SPI-based MMC controller"
++	depends on DM_MMC && DM_SPI
++	help
++	  This selects SPI-based MMC controllers.
++	  If you have an MMC controller on a SPI bus, say Y here.
++
++	  If unsure, say N.
++
++config MMC_SPI_CRC_ON
++	bool "Support CRC for SPI-based MMC controller"
++	depends on MMC_SPI
++	default y
++	help
++	  This enables CRC for SPI-based MMC controllers.
++
++	  If unsure, say N.
++
+ config ARM_PL180_MMCI
+ 	bool "ARM AMBA Multimedia Card Interface and compatible support"
+ 	depends on DM_MMC && OF_CONTROL
+diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c
+index 4f57990d9c..f3d687ae80 100644
+--- a/drivers/mmc/mmc_spi.c
++++ b/drivers/mmc/mmc_spi.c
+@@ -2,6 +2,8 @@
+  * generic mmc spi driver
+  *
+  * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
++ * Copyright 2019 Bhargav Shah <bhargavshah1988@gmail.com>
++ *
+  * Licensed under the GPL-2 or later.
+  */
+ #include <common.h>
+@@ -9,21 +11,23 @@
+ #include <malloc.h>
+ #include <part.h>
+ #include <mmc.h>
+-#include <spi.h>
++#include <stdlib.h>
+ #include <u-boot/crc.h>
+ #include <linux/crc7.h>
+ #include <asm/byteorder.h>
++#include <dm.h>
++#include <spi.h>
+ 
+ /* MMC/SD in SPI mode reports R1 status always */
+-#define R1_SPI_IDLE		(1 << 0)
+-#define R1_SPI_ERASE_RESET	(1 << 1)
+-#define R1_SPI_ILLEGAL_COMMAND	(1 << 2)
+-#define R1_SPI_COM_CRC		(1 << 3)
+-#define R1_SPI_ERASE_SEQ	(1 << 4)
+-#define R1_SPI_ADDRESS		(1 << 5)
+-#define R1_SPI_PARAMETER	(1 << 6)
++#define R1_SPI_IDLE			BIT(0)
++#define R1_SPI_ERASE_RESET		BIT(1)
++#define R1_SPI_ILLEGAL_COMMAND		BIT(2)
++#define R1_SPI_COM_CRC			BIT(3)
++#define R1_SPI_ERASE_SEQ		BIT(4)
++#define R1_SPI_ADDRESS			BIT(5)
++#define R1_SPI_PARAMETER		BIT(6)
+ /* R1 bit 7 is always zero, reuse this bit for error */
+-#define R1_SPI_ERROR		(1 << 7)
++#define R1_SPI_ERROR			BIT(7)
+ 
+ /* Response tokens used to ack each block written: */
+ #define SPI_MMC_RESPONSE_CODE(x)	((x) & 0x1f)
+@@ -34,28 +38,45 @@
+ /* Read and write blocks start with these tokens and end with crc;
+  * on error, read tokens act like a subset of R2_SPI_* values.
+  */
+-#define SPI_TOKEN_SINGLE	0xfe	/* single block r/w, multiblock read */
+-#define SPI_TOKEN_MULTI_WRITE	0xfc	/* multiblock write */
+-#define SPI_TOKEN_STOP_TRAN	0xfd	/* terminate multiblock write */
++/* single block write multiblock read */
++#define SPI_TOKEN_SINGLE		0xfe
++/* multiblock write */
++#define SPI_TOKEN_MULTI_WRITE		0xfc
++/* terminate multiblock write */
++#define SPI_TOKEN_STOP_TRAN		0xfd
+ 
+ /* MMC SPI commands start with a start bit "0" and a transmit bit "1" */
+-#define MMC_SPI_CMD(x) (0x40 | (x & 0x3f))
++#define MMC_SPI_CMD(x) (0x40 | (x))
+ 
+ /* bus capability */
+-#define MMC_SPI_VOLTAGE (MMC_VDD_32_33 | MMC_VDD_33_34)
+-#define MMC_SPI_MIN_CLOCK 400000 /* 400KHz to meet MMC spec */
++#define MMC_SPI_VOLTAGE			(MMC_VDD_32_33 | MMC_VDD_33_34)
++#define MMC_SPI_MIN_CLOCK		400000	/* 400KHz to meet MMC spec */
++#define MMC_SPI_MAX_CLOCK		25000000 /* SD/MMC legacy speed */
+ 
+ /* timeout value */
+-#define CTOUT 8
+-#define RTOUT 3000000 /* 1 sec */
+-#define WTOUT 3000000 /* 1 sec */
++#define CMD_TIMEOUT			8
++#define READ_TIMEOUT			3000000 /* 1 sec */
++#define WRITE_TIMEOUT			3000000 /* 1 sec */
+ 
+-static uint mmc_spi_sendcmd(struct mmc *mmc, ushort cmdidx, u32 cmdarg)
++struct mmc_spi_priv {
++	struct spi_slave *spi;
++	struct mmc_config cfg;
++	struct mmc mmc;
++};
++
++static int mmc_spi_sendcmd(struct udevice *dev,
++			   ushort cmdidx, u32 cmdarg, u32 resp_type,
++			   u8 *resp, u32 resp_size,
++			   bool resp_match, u8 resp_match_value)
+ {
+-	struct spi_slave *spi = mmc->priv;
+-	u8 cmdo[7];
+-	u8 r1;
+-	int i;
++	int i, rpos = 0, ret = 0;
++	u8 cmdo[7], r;
++
++	debug("%s: cmd%d cmdarg=0x%x resp_type=0x%x "
++	      "resp_size=%d resp_match=%d resp_match_value=0x%x\n",
++	      __func__, cmdidx, cmdarg, resp_type,
++	      resp_size, resp_match, resp_match_value);
++
+ 	cmdo[0] = 0xff;
+ 	cmdo[1] = MMC_SPI_CMD(cmdidx);
+ 	cmdo[2] = cmdarg >> 24;
+@@ -63,37 +84,79 @@ static uint mmc_spi_sendcmd(struct mmc *mmc, ushort cmdidx, u32 cmdarg)
+ 	cmdo[4] = cmdarg >> 8;
+ 	cmdo[5] = cmdarg;
+ 	cmdo[6] = (crc7(0, &cmdo[1], 5) << 1) | 0x01;
+-	spi_xfer(spi, sizeof(cmdo) * 8, cmdo, NULL, 0);
+-	for (i = 0; i < CTOUT; i++) {
+-		spi_xfer(spi, 1 * 8, NULL, &r1, 0);
+-		if (i && (r1 & 0x80) == 0) /* r1 response */
+-			break;
++	ret = dm_spi_xfer(dev, sizeof(cmdo) * 8, cmdo, NULL, 0);
++	if (ret)
++		return ret;
++
++	ret = dm_spi_xfer(dev, 1 * 8, NULL, &r, 0);
++	if (ret)
++		return ret;
++
++	if (!resp || !resp_size)
++		return 0;
++
++	debug("%s: cmd%d", __func__, cmdidx);
++
++	if (resp_match) {
++		r = ~resp_match_value;
++		i = CMD_TIMEOUT;
++		while (i--) {
++			ret = dm_spi_xfer(dev, 1 * 8, NULL, &r, 0);
++			if (ret)
++				return ret;
++			debug(" resp%d=0x%x", rpos, r);
++			rpos++;
++			if (r == resp_match_value)
++				break;
++		}
++		if (!i && (r != resp_match_value))
++			return -ETIMEDOUT;
++	}
++
++	for (i = 0; i < resp_size; i++) {
++		if (i == 0 && resp_match) {
++			resp[i] = resp_match_value;
++			continue;
++		}
++		ret = dm_spi_xfer(dev, 1 * 8, NULL, &r, 0);
++		if (ret)
++			return ret;
++		debug(" resp%d=0x%x", rpos, r);
++		rpos++;
++		resp[i] = r;
+ 	}
+-	debug("%s:cmd%d resp%d %x\n", __func__, cmdidx, i, r1);
+-	return r1;
++
++	debug("\n");
++
++	return 0;
+ }
+ 
+-static uint mmc_spi_readdata(struct mmc *mmc, void *xbuf,
+-				u32 bcnt, u32 bsize)
++static int mmc_spi_readdata(struct udevice *dev,
++			    void *xbuf, u32 bcnt, u32 bsize)
+ {
+-	struct spi_slave *spi = mmc->priv;
+-	u8 *buf = xbuf;
+-	u8 r1;
+ 	u16 crc;
+-	int i;
++	u8 *buf = xbuf, r1;
++	int i, ret = 0;
++
+ 	while (bcnt--) {
+-		for (i = 0; i < RTOUT; i++) {
+-			spi_xfer(spi, 1 * 8, NULL, &r1, 0);
+-			if (r1 != 0xff) /* data token */
++		for (i = 0; i < READ_TIMEOUT; i++) {
++			ret = dm_spi_xfer(dev, 1 * 8, NULL, &r1, 0);
++			if (ret)
++				return ret;
++			if (r1 == SPI_TOKEN_SINGLE)
+ 				break;
+ 		}
+-		debug("%s:tok%d %x\n", __func__, i, r1);
++		debug("%s: data tok%d 0x%x\n", __func__, i, r1);
+ 		if (r1 == SPI_TOKEN_SINGLE) {
+-			spi_xfer(spi, bsize * 8, NULL, buf, 0);
+-			spi_xfer(spi, 2 * 8, NULL, &crc, 0);
++			ret = dm_spi_xfer(dev, bsize * 8, NULL, buf, 0);
++			if (ret)
++				return ret;
++			ret = dm_spi_xfer(dev, 2 * 8, NULL, &crc, 0);
++			if (ret)
++				return ret;
+ #ifdef CONFIG_MMC_SPI_CRC_ON
+-			if (be_to_cpu16(crc16_ccitt(0, buf, bsize)) != crc) {
+-				debug("%s: CRC error\n", mmc->cfg->name);
++			if (be16_to_cpu(crc16_ccitt(0, buf, bsize)) != crc) {
++				debug("%s: data crc error\n", __func__);
+ 				r1 = R1_SPI_COM_CRC;
+ 				break;
+ 			}
+@@ -105,48 +168,56 @@ static uint mmc_spi_readdata(struct mmc *mmc, void *xbuf,
+ 		}
+ 		buf += bsize;
+ 	}
+-	return r1;
++
++	if (r1 & R1_SPI_COM_CRC)
++		ret = -ECOMM;
++	else if (r1) /* other errors */
++		ret = -ETIMEDOUT;
++
++	return ret;
+ }
+ 
+-static uint mmc_spi_writedata(struct mmc *mmc, const void *xbuf,
+-			      u32 bcnt, u32 bsize, int multi)
++static int mmc_spi_writedata(struct udevice *dev, const void *xbuf,
++			     u32 bcnt, u32 bsize, int multi)
+ {
+-	struct spi_slave *spi = mmc->priv;
+ 	const u8 *buf = xbuf;
+-	u8 r1;
++	u8 r1, tok[2];
+ 	u16 crc;
+-	u8 tok[2];
+-	int i;
++	int i, ret = 0;
++
+ 	tok[0] = 0xff;
+ 	tok[1] = multi ? SPI_TOKEN_MULTI_WRITE : SPI_TOKEN_SINGLE;
++
+ 	while (bcnt--) {
+ #ifdef CONFIG_MMC_SPI_CRC_ON
+ 		crc = cpu_to_be16(crc16_ccitt(0, (u8 *)buf, bsize));
+ #endif
+-		spi_xfer(spi, 2 * 8, tok, NULL, 0);
+-		spi_xfer(spi, bsize * 8, buf, NULL, 0);
+-		spi_xfer(spi, 2 * 8, &crc, NULL, 0);
+-		for (i = 0; i < CTOUT; i++) {
+-			spi_xfer(spi, 1 * 8, NULL, &r1, 0);
++		dm_spi_xfer(dev, 2 * 8, tok, NULL, 0);
++		dm_spi_xfer(dev, bsize * 8, buf, NULL, 0);
++		dm_spi_xfer(dev, 2 * 8, &crc, NULL, 0);
++		for (i = 0; i < CMD_TIMEOUT; i++) {
++			dm_spi_xfer(dev, 1 * 8, NULL, &r1, 0);
+ 			if ((r1 & 0x10) == 0) /* response token */
+ 				break;
+ 		}
+-		debug("%s:tok%d %x\n", __func__, i, r1);
++		debug("%s: data tok%d 0x%x\n", __func__, i, r1);
+ 		if (SPI_MMC_RESPONSE_CODE(r1) == SPI_RESPONSE_ACCEPTED) {
+-			for (i = 0; i < WTOUT; i++) { /* wait busy */
+-				spi_xfer(spi, 1 * 8, NULL, &r1, 0);
++			debug("%s: data accepted\n", __func__);
++			for (i = 0; i < WRITE_TIMEOUT; i++) { /* wait busy */
++				dm_spi_xfer(dev, 1 * 8, NULL, &r1, 0);
+ 				if (i && r1 == 0xff) {
+ 					r1 = 0;
+ 					break;
+ 				}
+ 			}
+-			if (i == WTOUT) {
+-				debug("%s:wtout %x\n", __func__, r1);
++			if (i == WRITE_TIMEOUT) {
++				debug("%s: data write timeout 0x%x\n",
++				      __func__, r1);
+ 				r1 = R1_SPI_ERROR;
+ 				break;
+ 			}
+ 		} else {
+-			debug("%s: err %x\n", __func__, r1);
++			debug("%s: data error 0x%x\n", __func__, r1);
+ 			r1 = R1_SPI_COM_CRC;
+ 			break;
+ 		}
+@@ -154,140 +225,204 @@ static uint mmc_spi_writedata(struct mmc *mmc, const void *xbuf,
+ 	}
+ 	if (multi && bcnt == -1) { /* stop multi write */
+ 		tok[1] = SPI_TOKEN_STOP_TRAN;
+-		spi_xfer(spi, 2 * 8, tok, NULL, 0);
+-		for (i = 0; i < WTOUT; i++) { /* wait busy */
+-			spi_xfer(spi, 1 * 8, NULL, &r1, 0);
++		dm_spi_xfer(dev, 2 * 8, tok, NULL, 0);
++		for (i = 0; i < WRITE_TIMEOUT; i++) { /* wait busy */
++			dm_spi_xfer(dev, 1 * 8, NULL, &r1, 0);
+ 			if (i && r1 == 0xff) {
+ 				r1 = 0;
+ 				break;
+ 			}
+ 		}
+-		if (i == WTOUT) {
+-			debug("%s:wstop %x\n", __func__, r1);
++		if (i == WRITE_TIMEOUT) {
++			debug("%s: data write timeout 0x%x\n", __func__, r1);
+ 			r1 = R1_SPI_ERROR;
+ 		}
+ 	}
+-	return r1;
+-}
+ 
+-static int mmc_spi_request(struct mmc *mmc, struct mmc_cmd *cmd,
+-		struct mmc_data *data)
+-{
+-	struct spi_slave *spi = mmc->priv;
+-	u8 r1;
+-	int i;
+-	int ret = 0;
+-	debug("%s:cmd%d %x %x\n", __func__,
+-	      cmd->cmdidx, cmd->resp_type, cmd->cmdarg);
+-	spi_claim_bus(spi);
+-	spi_cs_activate(spi);
+-	r1 = mmc_spi_sendcmd(mmc, cmd->cmdidx, cmd->cmdarg);
+-	if (r1 == 0xff) { /* no response */
+-		ret = -ENOMEDIUM;
+-		goto done;
+-	} else if (r1 & R1_SPI_COM_CRC) {
++	if (r1 & R1_SPI_COM_CRC)
+ 		ret = -ECOMM;
+-		goto done;
+-	} else if (r1 & ~R1_SPI_IDLE) { /* other errors */
++	else if (r1) /* other errors */
+ 		ret = -ETIMEDOUT;
++
++	return ret;
++}
++
++static int dm_mmc_spi_set_ios(struct udevice *dev)
++{
++	return 0;
++}
++
++static int dm_mmc_spi_request(struct udevice *dev, struct mmc_cmd *cmd,
++			      struct mmc_data *data)
++{
++	int i, multi, ret = 0;
++	u8 *resp = NULL;
++	u32 resp_size = 0;
++	bool resp_match = false;
++	u8 resp8 = 0, resp40[5] = { 0 }, resp_match_value = 0;
++
++	dm_spi_claim_bus(dev);
++
++	for (i = 0; i < 4; i++)
++		cmd->response[i] = 0;
++
++	switch (cmd->cmdidx) {
++	case SD_CMD_APP_SEND_OP_COND:
++	case MMC_CMD_SEND_OP_COND:
++		resp = &resp8;
++		resp_size = sizeof(resp8);
++		cmd->cmdarg = 0x40000000;
++		break;
++	case SD_CMD_SEND_IF_COND:
++		resp = (u8 *)&resp40[0];
++		resp_size = sizeof(resp40);
++		resp_match = true;
++		resp_match_value = R1_SPI_IDLE;
++		break;
++	case MMC_CMD_SPI_READ_OCR:
++		resp = (u8 *)&resp40[0];
++		resp_size = sizeof(resp40);
++		break;
++	case MMC_CMD_SEND_STATUS:
++	case MMC_CMD_SET_BLOCKLEN:
++	case MMC_CMD_SPI_CRC_ON_OFF:
++	case MMC_CMD_STOP_TRANSMISSION:
++		resp = &resp8;
++		resp_size = sizeof(resp8);
++		resp_match = true;
++		resp_match_value = 0x0;
++		break;
++	case MMC_CMD_SEND_CSD:
++	case MMC_CMD_SEND_CID:
++	case MMC_CMD_READ_SINGLE_BLOCK:
++	case MMC_CMD_READ_MULTIPLE_BLOCK:
++	case MMC_CMD_WRITE_SINGLE_BLOCK:
++	case MMC_CMD_WRITE_MULTIPLE_BLOCK:
++		break;
++	default:
++		resp = &resp8;
++		resp_size = sizeof(resp8);
++		resp_match = true;
++		resp_match_value = R1_SPI_IDLE;
++		break;
++	};
++
++	ret = mmc_spi_sendcmd(dev, cmd->cmdidx, cmd->cmdarg, cmd->resp_type,
++			      resp, resp_size, resp_match, resp_match_value);
++	if (ret)
+ 		goto done;
+-	} else if (cmd->resp_type == MMC_RSP_R2) {
+-		r1 = mmc_spi_readdata(mmc, cmd->response, 1, 16);
++
++	switch (cmd->cmdidx) {
++	case SD_CMD_APP_SEND_OP_COND:
++	case MMC_CMD_SEND_OP_COND:
++		cmd->response[0] = (resp8 & R1_SPI_IDLE) ? 0 : OCR_BUSY;
++		break;
++	case SD_CMD_SEND_IF_COND:
++	case MMC_CMD_SPI_READ_OCR:
++		cmd->response[0] = resp40[4];
++		cmd->response[0] |= (uint)resp40[3] << 8;
++		cmd->response[0] |= (uint)resp40[2] << 16;
++		cmd->response[0] |= (uint)resp40[1] << 24;
++		break;
++	case MMC_CMD_SEND_STATUS:
++		cmd->response[0] = (resp8 & 0xff) ?
++			MMC_STATUS_ERROR : MMC_STATUS_RDY_FOR_DATA;
++		break;
++	case MMC_CMD_SEND_CID:
++	case MMC_CMD_SEND_CSD:
++		ret = mmc_spi_readdata(dev, cmd->response, 1, 16);
++		if (ret)
++			return ret;
+ 		for (i = 0; i < 4; i++)
+-			cmd->response[i] = be32_to_cpu(cmd->response[i]);
+-		debug("r128 %x %x %x %x\n", cmd->response[0], cmd->response[1],
+-		      cmd->response[2], cmd->response[3]);
+-	} else if (!data) {
+-		switch (cmd->cmdidx) {
+-		case SD_CMD_APP_SEND_OP_COND:
+-		case MMC_CMD_SEND_OP_COND:
+-			cmd->response[0] = (r1 & R1_SPI_IDLE) ? 0 : OCR_BUSY;
+-			break;
+-		case SD_CMD_SEND_IF_COND:
+-		case MMC_CMD_SPI_READ_OCR:
+-			spi_xfer(spi, 4 * 8, NULL, cmd->response, 0);
+-			cmd->response[0] = be32_to_cpu(cmd->response[0]);
+-			debug("r32 %x\n", cmd->response[0]);
+-			break;
+-		case MMC_CMD_SEND_STATUS:
+-			spi_xfer(spi, 1 * 8, NULL, cmd->response, 0);
+-			cmd->response[0] = (cmd->response[0] & 0xff) ?
+-				MMC_STATUS_ERROR : MMC_STATUS_RDY_FOR_DATA;
+-			break;
+-		}
+-	} else {
+-		debug("%s:data %x %x %x\n", __func__,
+-		      data->flags, data->blocks, data->blocksize);
++			cmd->response[i] =
++				cpu_to_be32(cmd->response[i]);
++		break;
++	default:
++		cmd->response[0] = resp8;
++		break;
++	}
++
++	debug("%s: cmd%d resp0=0x%x resp1=0x%x resp2=0x%x resp3=0x%x\n",
++	      __func__, cmd->cmdidx, cmd->response[0], cmd->response[1],
++	      cmd->response[2], cmd->response[3]);
++
++	if (data) {
++		debug("%s: data flags=0x%x blocks=%d block_size=%d\n",
++		      __func__, data->flags, data->blocks, data->blocksize);
++		multi = (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK);
+ 		if (data->flags == MMC_DATA_READ)
+-			r1 = mmc_spi_readdata(mmc, data->dest,
+-				data->blocks, data->blocksize);
++			ret = mmc_spi_readdata(dev, data->dest,
++					       data->blocks, data->blocksize);
+ 		else if  (data->flags == MMC_DATA_WRITE)
+-			r1 = mmc_spi_writedata(mmc, data->src,
+-				data->blocks, data->blocksize,
+-				(cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK));
+-		if (r1 & R1_SPI_COM_CRC)
+-			ret = -ECOMM;
+-		else if (r1) /* other errors */
+-			ret = -ETIMEDOUT;
++			ret = mmc_spi_writedata(dev, data->src,
++						data->blocks, data->blocksize,
++						multi);
+ 	}
++
+ done:
+-	spi_cs_deactivate(spi);
+-	spi_release_bus(spi);
++	dm_spi_release_bus(dev);
++
+ 	return ret;
+ }
+ 
+-static int mmc_spi_set_ios(struct mmc *mmc)
++static int mmc_spi_probe(struct udevice *dev)
+ {
+-	struct spi_slave *spi = mmc->priv;
++	struct mmc_spi_priv *priv = dev_get_priv(dev);
++	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
++	char *name;
++
++	priv->spi = dev_get_parent_priv(dev);
++	if (!priv->spi->max_hz)
++		priv->spi->max_hz = MMC_SPI_MAX_CLOCK;
++	priv->spi->speed = 0;
++	priv->spi->mode = SPI_MODE_0;
++	priv->spi->wordlen = 8;
++
++	name = malloc(strlen(dev->parent->name) + strlen(dev->name) + 4);
++	if (!name)
++		return -ENOMEM;
++	sprintf(name, "%s:%s", dev->parent->name, dev->name);
++
++	priv->cfg.name = name;
++	priv->cfg.host_caps = MMC_MODE_SPI;
++	priv->cfg.voltages = MMC_SPI_VOLTAGE;
++	priv->cfg.f_min = MMC_SPI_MIN_CLOCK;
++	priv->cfg.f_max = priv->spi->max_hz;
++	priv->cfg.part_type = PART_TYPE_DOS;
++	priv->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
++
++	priv->mmc.cfg = &priv->cfg;
++	priv->mmc.priv = priv;
++	priv->mmc.dev = dev;
++
++	upriv->mmc = &priv->mmc;
+ 
+-	debug("%s: clock %u\n", __func__, mmc->clock);
+-	if (mmc->clock)
+-		spi_set_speed(spi, mmc->clock);
+ 	return 0;
+ }
+ 
+-static int mmc_spi_init_p(struct mmc *mmc)
++static int mmc_spi_bind(struct udevice *dev)
+ {
+-	struct spi_slave *spi = mmc->priv;
+-	spi_set_speed(spi, MMC_SPI_MIN_CLOCK);
+-	spi_claim_bus(spi);
+-	/* cs deactivated for 100+ clock */
+-	spi_xfer(spi, 18 * 8, NULL, NULL, 0);
+-	spi_release_bus(spi);
+-	return 0;
++	struct mmc_spi_priv *priv = dev_get_priv(dev);
++
++	return mmc_bind(dev, &priv->mmc, &priv->cfg);
+ }
+ 
+-static const struct mmc_ops mmc_spi_ops = {
+-	.send_cmd	= mmc_spi_request,
+-	.set_ios	= mmc_spi_set_ios,
+-	.init		= mmc_spi_init_p,
++static const struct dm_mmc_ops mmc_spi_ops = {
++	.send_cmd	= dm_mmc_spi_request,
++	.set_ios	= dm_mmc_spi_set_ios,
+ };
+ 
+-static struct mmc_config mmc_spi_cfg = {
+-	.name		= "MMC_SPI",
+-	.ops		= &mmc_spi_ops,
+-	.host_caps	= MMC_MODE_SPI,
+-	.voltages	= MMC_SPI_VOLTAGE,
+-	.f_min		= MMC_SPI_MIN_CLOCK,
+-	.part_type	= PART_TYPE_DOS,
+-	.b_max		= CONFIG_SYS_MMC_MAX_BLK_COUNT,
++static const struct udevice_id dm_mmc_spi_match[] = {
++	{ .compatible = "mmc-spi-slot" },
++	{ /* sentinel */ }
+ };
+ 
+-struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode)
+-{
+-	struct mmc *mmc;
+-	struct spi_slave *spi;
+-
+-	spi = spi_setup_slave(bus, cs, speed, mode);
+-	if (spi == NULL)
+-		return NULL;
+-
+-	mmc_spi_cfg.f_max = speed;
+-
+-	mmc = mmc_create(&mmc_spi_cfg, spi);
+-	if (mmc == NULL) {
+-		spi_free_slave(spi);
+-		return NULL;
+-	}
+-	return mmc;
+-}
++U_BOOT_DRIVER(mmc_spi) = {
++	.name = "mmc_spi",
++	.id = UCLASS_MMC,
++	.of_match = dm_mmc_spi_match,
++	.ops = &mmc_spi_ops,
++	.probe = mmc_spi_probe,
++	.bind = mmc_spi_bind,
++	.priv_auto_alloc_size = sizeof(struct mmc_spi_priv),
++};
+-- 
+2.22.0
+

+ 38 - 0
recipes-bsp/u-boot/files/0020-riscv-sifive-fu540-Enable-SiFive-SPI-and-MMC-SPI-dri.patch

@@ -0,0 +1,38 @@
+From b5d6a388b6b9d7b5b17e7cd2d468986d71b13f42 Mon Sep 17 00:00:00 2001
+From: Bhargav Shah <bhargavshah1988@gmail.com>
+Date: Sat, 22 Jun 2019 12:27:16 +0530
+Subject: [PATCH 20/21] riscv: sifive: fu540: Enable SiFive SPI and MMC SPI
+ drivers
+
+This patch enables SiFive SPI and MMC SPI drivers for the
+SiFive Unleashed board.
+
+Signed-off-by: Bhargav Shah <bhargavshah1988@gmail.com>
+Signed-off-by: Anup Patel <anup.patel@wdc.com>
+Upstream-Status: Submitted
+---
+ board/sifive/fu540/Kconfig | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
+index f46437901d..d6d5c7d170 100644
+--- a/board/sifive/fu540/Kconfig
++++ b/board/sifive/fu540/Kconfig
+@@ -38,6 +38,14 @@ config BOARD_SPECIFIC_OPTIONS # dummy
+ 	imply PHY_LIB
+ 	imply PHY_MSCC
+ 	imply SIFIVE_SERIAL
++	imply SPI
++	imply DM_SPI
++	imply SIFIVE_SPI
++	imply MMC
++	imply DM_MMC
++	imply MMC_SPI
++	imply MMC_BROKEN_CD
++	imply CMD_MMC
+ 	imply SMP
+ 
+ endif
+-- 
+2.22.0
+

+ 33 - 0
recipes-bsp/u-boot/files/0021-doc-sifive-fu540-Update-README-for-SiFive-SPI-and-MM.patch

@@ -0,0 +1,33 @@
+From 5a16f74516ea37c844134fecbcc04f5ac7befa8c Mon Sep 17 00:00:00 2001
+From: Anup Patel <anup.patel@wdc.com>
+Date: Sat, 29 Jun 2019 10:26:20 +0530
+Subject: [PATCH 21/21] doc: sifive-fu540: Update README for SiFive SPI and MMC
+ SPI drivers
+
+This patch removes SiFive SPI driver and MMC SPI drive from the TODO
+list in SiFive FU540 README.
+
+Signed-off-by: Anup Patel <anup.patel@wdc.com>
+Upstream-Status: Submitted
+---
+ doc/README.sifive-fu540 | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/doc/README.sifive-fu540 b/doc/README.sifive-fu540
+index 33e03dc861..944ba1c8a0 100644
+--- a/doc/README.sifive-fu540
++++ b/doc/README.sifive-fu540
+@@ -13,9 +13,7 @@ The support for following drivers are already enabled:
+ 3. Cadence MACB ethernet driver for networking support.
+ 
+ TODO:
+-1. SPI host driver is still missing.
+-2. SPI MMC driver does not compile and needs a re-write using U-Boot DM.
+-2. U-Boot expects the serial console device entry to be present under /chosen
++1. U-Boot expects the serial console device entry to be present under /chosen
+    DT node. Example:
+    chosen {
+         stdout-path = "/soc/serial@10010000:115200";
+-- 
+2.22.0
+

+ 0 - 48
recipes-bsp/u-boot/u-boot_2019.04.bbappend

@@ -1,48 +0,0 @@
-FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
-
-SRC_URI += "file://0001-riscv-add-infrastructure-for-calling-functions-on-ot.patch \
-            file://0002-riscv-import-the-supervisor-binary-interface-header-.patch \
-            file://0003-riscv-implement-IPI-platform-functions-using-SBI.patch \
-            file://0004-riscv-delay-initialization-of-caches-and-debug-UART.patch \
-            file://0005-riscv-save-hart-ID-in-register-tp-instead-of-s0.patch \
-            file://0006-riscv-add-support-for-multi-hart-systems.patch \
-            file://0007-riscv-boot-images-passed-to-bootm-on-all-harts.patch \
-            file://0008-riscv-do-not-rely-on-hart-ID-passed-by-previous-boot.patch \
-            file://0009-riscv-hang-if-relocation-of-secondary-harts-fails.patch \
-            file://0010-riscv-fu540-enable-SMP.patch \
-            file://0011-riscv-qemu-enable-SMP.patch \
-            file://0012-riscv-Add-a-SYSCON-driver-for-Andestech-s-PLIC.patch \
-            file://0013-riscv-Add-a-SYSCON-driver-for-Andestech-s-PLMT.patch \
-            file://0014-riscv-ax25-Add-platform-specific-Kconfig-options.patch \
-            file://0015-riscv-ax25-Andes-specific-cache-shall-only-support-i.patch \
-            file://0016-riscv-dts-ae350-support-SMP.patch \
-            file://0017-riscv-ae350-enable-SMP.patch \
-            file://0018-riscv-dts-fix-CONFIG_DEFAULT_DEVICE_TREE-failure.patch \
-            file://0001-sifive-fu540-Set-default-arguments-to-help-booting.patch \
-            file://tftp-boot.txt \
-           "
-
-DEPENDS += "u-boot-tools-native"
-
-# Overwrite this for your server
-TFTP_SERVER_IP ?= "127.0.0.1"
-
-do_configure_prepend() {
-    sed -i -e 's,@SERVERIP@,${TFTP_SERVER_IP},g' ${S}/include/configs/sifive-fu540.h
-
-    if [ -f "${WORKDIR}/${UBOOT_ENV}.txt" ]; then
-        mkimage -O linux -T script -C none -n "U-Boot boot script" \
-            -d ${WORKDIR}/${UBOOT_ENV}.txt ${WORKDIR}/boot.scr.uimg
-    fi
-}
-
-do_deploy_append () {
-    if [ -f "${WORKDIR}/boot.scr.uimg" ]; then
-        install -d ${DEPLOY_DIR_IMAGE}
-        install -m 755 ${WORKDIR}/boot.scr.uimg ${DEPLOY_DIR_IMAGE}
-    fi
-}
-
-addtask deploy after do_install
-
-FILES_${PN} += "/boot/boot.scr.uimg"

+ 50 - 0
recipes-bsp/u-boot/u-boot_2019.07.bbappend

@@ -0,0 +1,50 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI += "file://0001-sifive-fu540-Set-default-arguments-to-help-booting.patch \
+            file://0002-net-macb-sync-header-definitions-as-taken-from-Linux.patch \
+            file://0003-net-macb-add-support-for-faster-clk-rates.patch \
+            file://0004-net-macb-use-bit-access-macro-from-header-file.patch \
+            file://0005-net-macb-add-support-for-SGMII-phy-interface.patch \
+            file://0006-net-macb-add-dma_burst_length-config.patch \
+            file://0007-net-macb-apply-sane-DMA-configuration.patch \
+            file://0008-clk-sifive-Factor-out-PLL-library-as-separate-module.patch \
+            file://0009-clk-sifive-Sync-up-WRPLL-library-with-upstream-Linux.patch \
+            file://0010-clk-sifive-Sync-up-DT-bindings-header-with-upstream-.patch \
+            file://0011-clk-sifive-Sync-up-main-driver-with-upstream-Linux.patch \
+            file://0012-clk-sifive-Drop-GEMGXL-clock-driver.patch \
+            file://0013-net-macb-Extend-MACB-driver-for-SiFive-Unleashed-boa.patch \
+            file://0014-riscv-sifive-fu540-Setup-ethaddr-env-variable-using-.patch \
+            file://0015-doc-sifive-fu540-Update-README-for-steps-to-create-F.patch \
+            file://0016-net-macb-Fix-check-for-little-endian-system-in.patch \
+            file://0017-spi-Add-SiFive-SPI-driver.patch \
+            file://0018-mmc-skip-select_mode_and_width-for-MMC-SPI-host.patch \
+            file://0019-mmc-mmc_spi-Re-write-driver-using-DM-framework.patch \
+            file://0020-riscv-sifive-fu540-Enable-SiFive-SPI-and-MMC-SPI-dri.patch \
+            file://0021-doc-sifive-fu540-Update-README-for-SiFive-SPI-and-MM.patch \
+            file://tftp-boot.txt \
+           "
+
+DEPENDS += "u-boot-tools-native"
+
+# Overwrite this for your server
+TFTP_SERVER_IP ?= "127.0.0.1"
+
+do_configure_prepend() {
+    sed -i -e 's,@SERVERIP@,${TFTP_SERVER_IP},g' ${S}/include/configs/sifive-fu540.h
+
+    if [ -f "${WORKDIR}/${UBOOT_ENV}.txt" ]; then
+        mkimage -O linux -T script -C none -n "U-Boot boot script" \
+            -d ${WORKDIR}/${UBOOT_ENV}.txt ${WORKDIR}/boot.scr.uimg
+    fi
+}
+
+do_deploy_append () {
+    if [ -f "${WORKDIR}/boot.scr.uimg" ]; then
+        install -d ${DEPLOY_DIR_IMAGE}
+        install -m 755 ${WORKDIR}/boot.scr.uimg ${DEPLOY_DIR_IMAGE}
+    fi
+}
+
+addtask deploy after do_install
+
+FILES_${PN} += "/boot/boot.scr.uimg"