All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 00/14] RISC-V SiFive FU540 support SPL
@ 2020-03-11  7:03 Pragnesh Patel
  2020-03-11  7:03 ` [PATCH v5 01/14] misc: add driver for the SiFive otp controller Pragnesh Patel
                   ` (13 more replies)
  0 siblings, 14 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-11  7:03 UTC (permalink / raw)
  To: u-boot

This series add support for SPL to FU540.U-Boot SPL can boot from
L2 LIM (0x0800_0000) and jump to OpenSBI(FW_DYNAMIC firmware) and
U-Boot proper from MMC devices.

How to test this patch:
1) Go to OpenSBI-dir : make PLATFORM=sifive/fu540 O=build_dir I=install_dir FW_DYNAMIC=y install
2) cp install_dir/platform/sifive/fu540/firmware/fw_dynamic.bin <u-boot-dir>/
3) Change to u-boot-dir
4) make sifive_fu540_defconfig
5) make all
6) ZSBL loads the U-boot SPL(u-boot-spl.bin) from a partition with
   GUID type 5B193300-FC78-40CD-8002-E86C45580B47

   sudo dd if=spl/u-boot-spl.bin of=/dev/sdc4 bs=1M

7) U-boot SPL expects a u-boot FIT image(u-boot.itb) from 1st partition(/dev/sdc1)
   of SD card irrespective of GUID

   sudo dd if=u-boot.itb of=/dev/sdc1 bs=1M

Thanks to Yash Shah <yash.shah@sifive.com> for testing the series.

Changes in v5:
- Return read/write bytes for sifive_otp_read and sifive_otp_write
- Correct Palmer's email address

Changes in v4:
- Split misc DM driver patch into multiple patches
- Added new SPL_CRC7_SUPPORT Kconfig option
- Added DM driver for DDR
- Added clk_enable and clk_disable ops in SiFive PRCI driver
- Added early clock initialization for SPL in SiFive PRCI driver
- Added SPL config options in sifive_fu540_defconfig instead of
  creatiing a new config file for SPL
- Update fu540.rst on how to build and flash U-boot SPL

Changes in v3:
- Remove arch-fu540 and arch-sifive from arch/riscv/include/asm/
- Split SPL patches into DDR and SPL and spl defconfig
- Update fu540/MAINTAINERS file
- Update fu540.rst on how to build and flash U-boot SPL

Changes in v2:
- Add DM driver Sifive OTP
- Split SPL patches into multiple patches
- Add a seprate patch for _image_binary_end and crc7.c
- Add a seprate patch to add board -u-boot.dtsi files
- Update FU540 RISC-V documentation


Pragnesh Patel (14):
  misc: add driver for the SiFive otp controller
  riscv: sifive: fu540: Use OTP DM driver for serial environment
    variable
  riscv: Add _image_binary_end for SPL
  lib: Makefile: build crc7.c when CONFIG_MMC_SPI
  riscv: sifive: dts: fu540: Add board -u-boot.dtsi files
  sifive: fu540: add ddr driver
  sifive: dts: fu540: Add DDR controller and phy register settings
  clk: sifive: fu540-prci: Add clock enable and disable ops
  clk: sifive: fu540-prci: Add clock initialization for SPL
  riscv: sifive: fu540: add SPL configuration
  configs: fu540: Add config options for U-boot SPL
  riscv: sifive: fu540: enable all cache ways from u-boot proper
  sifive: fix palmer's email address
  doc: update FU540 RISC-V documentation

 arch/riscv/cpu/u-boot-spl.lds                 |    1 +
 arch/riscv/dts/fu540-c000-u-boot.dtsi         |   63 +
 arch/riscv/dts/fu540-sdram-ddr4.dtsi          | 1489 +++++++++++++++++
 .../dts/hifive-unleashed-a00-u-boot.dtsi      |   23 +
 board/sifive/fu540/Kconfig                    |   10 +
 board/sifive/fu540/MAINTAINERS                |    2 +-
 board/sifive/fu540/Makefile                   |    5 +
 board/sifive/fu540/cache.c                    |   20 +
 board/sifive/fu540/cache.h                    |   13 +
 board/sifive/fu540/fu540-memory-map.h         |   23 +
 board/sifive/fu540/fu540.c                    |  141 +-
 board/sifive/fu540/spl.c                      |   78 +
 common/spl/Kconfig                            |    7 +
 configs/sifive_fu540_defconfig                |   11 +
 doc/board/sifive/fu540.rst                    |  409 ++++-
 drivers/clk/sifive/fu540-prci.c               |  169 +-
 drivers/misc/Kconfig                          |    7 +
 drivers/misc/Makefile                         |    1 +
 drivers/misc/sifive-otp.c                     |  241 +++
 drivers/ram/Kconfig                           |    7 +
 drivers/ram/Makefile                          |    2 +
 drivers/ram/sifive/Kconfig                    |    8 +
 drivers/ram/sifive/Makefile                   |    6 +
 drivers/ram/sifive/sdram_fu540.c              |  295 ++++
 drivers/ram/sifive/sdram_fu540.h              |   94 ++
 include/configs/sifive-fu540.h                |   18 +
 lib/Makefile                                  |    1 +
 27 files changed, 3042 insertions(+), 102 deletions(-)
 create mode 100644 arch/riscv/dts/fu540-c000-u-boot.dtsi
 create mode 100644 arch/riscv/dts/fu540-sdram-ddr4.dtsi
 create mode 100644 arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
 create mode 100644 board/sifive/fu540/cache.c
 create mode 100644 board/sifive/fu540/cache.h
 create mode 100644 board/sifive/fu540/fu540-memory-map.h
 create mode 100644 board/sifive/fu540/spl.c
 create mode 100644 drivers/misc/sifive-otp.c
 create mode 100644 drivers/ram/sifive/Kconfig
 create mode 100644 drivers/ram/sifive/Makefile
 create mode 100644 drivers/ram/sifive/sdram_fu540.c
 create mode 100644 drivers/ram/sifive/sdram_fu540.h

-- 
2.17.1

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 01/14] misc: add driver for the SiFive otp controller
  2020-03-11  7:03 [PATCH v5 00/14] RISC-V SiFive FU540 support SPL Pragnesh Patel
@ 2020-03-11  7:03 ` Pragnesh Patel
  2020-03-11 10:25   ` Bin Meng
  2020-03-11  7:03 ` [PATCH v5 02/14] riscv: sifive: fu540: Use OTP DM driver for serial environment variable Pragnesh Patel
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-11  7:03 UTC (permalink / raw)
  To: u-boot

Added a misc driver to handle OTP memory in SiFive SoCs.

Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
---
 drivers/misc/Kconfig      |   7 ++
 drivers/misc/Makefile     |   1 +
 drivers/misc/sifive-otp.c | 241 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 249 insertions(+)
 create mode 100644 drivers/misc/sifive-otp.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index f18aa8f7ba..fcb45c63d4 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -68,6 +68,13 @@ config ROCKCHIP_OTP
 	  addressing and a length or through child-nodes that are generated
 	  based on the e-fuse map retrieved from the DTS.
 
+config SIFIVE_OTP
+	bool "SiFive Ememory OTP driver"
+	depends on RISCV && MISC
+	help
+	  Enable support for reading and writing the ememory OTP on the
+	  SiFive SoCs.
+
 config VEXPRESS_CONFIG
 	bool "Enable support for Arm Versatile Express config bus"
 	depends on MISC
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 2b843de93c..ee888631b6 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -58,6 +58,7 @@ obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
 obj-$(CONFIG_QFW) += qfw.o
 obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
 obj-$(CONFIG_ROCKCHIP_OTP) += rockchip-otp.o
+obj-$(CONFIG_SIFIVE_OTP) += sifive-otp.o
 obj-$(CONFIG_SANDBOX) += syscon_sandbox.o misc_sandbox.o
 obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o
 obj-$(CONFIG_SMSC_SIO1007) += smsc_sio1007.o
diff --git a/drivers/misc/sifive-otp.c b/drivers/misc/sifive-otp.c
new file mode 100644
index 0000000000..1e6c1a11b2
--- /dev/null
+++ b/drivers/misc/sifive-otp.c
@@ -0,0 +1,241 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * This is a driver for the eMemory EG004K32TQ028XW01 NeoFuse
+ * One-Time-Programmable (OTP) memory used within the SiFive FU540.
+ * It is documented in the FU540 manual here:
+ * https://www.sifive.com/documentation/chips/freedom-u540-c000-manual/
+ *
+ * Copyright (C) 2018 Philipp Hug <philipp@hug.cx>
+ * Copyright (C) 2018 Joey Hewitt <joey@joeyhewitt.com>
+ *
+ * Copyright (C) 2020 SiFive, Inc
+ */
+
+/*
+ * The FU540 stores 4096x32 bit (16KiB) values.
+ * Index 0x00-0xff are reserved for SiFive internal use. (first 1KiB)
+ * Right now first 1KB is used to store only serial number.
+ */
+
+#include <common.h>
+#include <dm/device.h>
+#include <dm/read.h>
+#include <linux/io.h>
+#include <misc.h>
+
+#define BYTES_PER_FUSE		4
+
+#define PA_RESET_VAL		0x00
+#define PAS_RESET_VAL		0x00
+#define PAIO_RESET_VAL		0x00
+#define PDIN_RESET_VAL		0x00
+#define PTM_RESET_VAL		0x00
+
+#define PCLK_ENABLE_VAL			BIT(0)
+#define PCLK_DISABLE_VAL		0x00
+
+#define PWE_WRITE_ENABLE		BIT(0)
+#define PWE_WRITE_DISABLE		0x00
+
+#define PTM_FUSE_PROGRAM_VAL		BIT(1)
+
+#define PCE_ENABLE_INPUT		BIT(0)
+#define PCE_DISABLE_INPUT		0x00
+
+#define PPROG_ENABLE_INPUT		BIT(0)
+#define PPROG_DISABLE_INPUT		0x00
+
+#define PTRIM_ENABLE_INPUT		BIT(0)
+#define PTRIM_DISABLE_INPUT		0x00
+
+#define PDSTB_DEEP_STANDBY_ENABLE	BIT(0)
+#define PDSTB_DEEP_STANDBY_DISABLE	0x00
+
+struct sifive_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;
+
+struct sifive_otp_platdata {
+	struct sifive_otp_regs __iomem *regs;
+	u32 total_fuses;
+};
+
+/*
+ * offset and size are assumed aligned to the size of the fuses (32bit).
+ */
+static int sifive_otp_read(struct udevice *dev, int offset,
+			   void *buf, int size)
+{
+	struct sifive_otp_platdata *plat = dev_get_platdata(dev);
+	struct sifive_otp_regs *regs = (struct sifive_otp_regs *)plat->regs;
+
+	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 >= plat->total_fuses)
+		return -EINVAL;
+	if ((fuseidx + fusecount) > plat->total_fuses)
+		return -EINVAL;
+
+	/* init OTP */
+	iowrite32(PDSTB_DEEP_STANDBY_ENABLE, &regs->pdstb);
+	iowrite32(PTRIM_ENABLE_INPUT, &regs->ptrim);
+	iowrite32(PCE_ENABLE_INPUT, &regs->pce);
+
+	/* read all requested fuses */
+	for (unsigned int i = 0; i < fusecount; i++, fuseidx++) {
+		iowrite32(fuseidx, &regs->pa);
+
+		/* cycle clock to read */
+		iowrite32(PCLK_ENABLE_VAL, &regs->pclk);
+		mdelay(1);
+		iowrite32(PCLK_DISABLE_VAL, &regs->pclk);
+		mdelay(1);
+
+		/* read the value */
+		fusebuf[i] = ioread32(&regs->pdout);
+	}
+
+	/* shut down */
+	iowrite32(PCE_DISABLE_INPUT, &regs->pce);
+	iowrite32(PTRIM_DISABLE_INPUT, &regs->ptrim);
+	iowrite32(PDSTB_DEEP_STANDBY_DISABLE, &regs->pdstb);
+
+	// copy out
+	memcpy(buf, fusebuf, size);
+
+	return size;
+}
+
+/*
+ * Caution:
+ * OTP can be written only once, so use carefully.
+ *
+ * offset and size are assumed aligned to the size of the fuses (32bit).
+ */
+static int sifive_otp_write(struct udevice *dev, int offset,
+			    const void *buf, int size)
+{
+	struct sifive_otp_platdata *plat = dev_get_platdata(dev);
+	struct sifive_otp_regs *regs = (struct sifive_otp_regs *)plat->regs;
+
+	int fuseidx = offset / BYTES_PER_FUSE;
+	int fusecount = size / BYTES_PER_FUSE;
+	u32 *write_buf = (u32 *)buf;
+	u32 write_data;
+	int i, pas, bit;
+
+	/* check bounds */
+	if (offset < 0 || size < 0)
+		return -EINVAL;
+	if (fuseidx >= plat->total_fuses)
+		return -EINVAL;
+	if ((fuseidx + fusecount) > plat->total_fuses)
+		return -EINVAL;
+
+	/* init OTP */
+	iowrite32(PDSTB_DEEP_STANDBY_ENABLE, &regs->pdstb);
+	iowrite32(PTRIM_ENABLE_INPUT, &regs->ptrim);
+
+	/* reset registers */
+	iowrite32(PCLK_DISABLE_VAL, &regs->pclk);
+	iowrite32(PA_RESET_VAL, &regs->pa);
+	iowrite32(PAS_RESET_VAL, &regs->pas);
+	iowrite32(PAIO_RESET_VAL, &regs->paio);
+	iowrite32(PDIN_RESET_VAL, &regs->pdin);
+	iowrite32(PWE_WRITE_DISABLE, &regs->pwe);
+	iowrite32(PTM_FUSE_PROGRAM_VAL, &regs->ptm);
+	mdelay(1);
+
+	iowrite32(PCE_ENABLE_INPUT, &regs->pce);
+	iowrite32(PPROG_ENABLE_INPUT, &regs->pprog);
+	iowrite32(PTRIM_ENABLE_INPUT, &regs->ptrim);
+
+	/* write all requested fuses */
+	for (i = 0; i < fusecount; i++, fuseidx++) {
+		iowrite32(fuseidx, &regs->pa);
+		write_data = *(write_buf++);
+
+		for (pas = 0; pas < 2; pas++) {
+			iowrite32(pas, &regs->pas);
+
+			for (bit = 0; bit < 32; bit++) {
+				iowrite32(bit, &regs->paio);
+				iowrite32(((write_data >> bit) & 1),
+					  &regs->pdin);
+				mdelay(1);
+
+				iowrite32(PWE_WRITE_ENABLE, &regs->pwe);
+				mdelay(1);
+				iowrite32(PWE_WRITE_DISABLE, &regs->pwe);
+				mdelay(1);
+			}
+		}
+
+		iowrite32(PAS_RESET_VAL, &regs->pas);
+	}
+
+	/* shut down */
+	iowrite32(PWE_WRITE_DISABLE, &regs->pwe);
+	iowrite32(PPROG_DISABLE_INPUT, &regs->pprog);
+	iowrite32(PCE_DISABLE_INPUT, &regs->pce);
+	iowrite32(PTM_RESET_VAL, &regs->ptm);
+
+	iowrite32(PTRIM_DISABLE_INPUT, &regs->ptrim);
+	iowrite32(PDSTB_DEEP_STANDBY_DISABLE, &regs->pdstb);
+
+	return size;
+}
+
+static int sifive_otp_ofdata_to_platdata(struct udevice *dev)
+{
+	struct sifive_otp_platdata *plat = dev_get_platdata(dev);
+	int ret;
+
+	plat->regs = dev_read_addr_ptr(dev);
+
+	ret = dev_read_u32(dev, "fuse-count", &plat->total_fuses);
+	if (ret < 0) {
+		pr_err("\"fuse-count\" not found\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct misc_ops sifive_otp_ops = {
+	.read = sifive_otp_read,
+	.write = sifive_otp_write,
+};
+
+static const struct udevice_id sifive_otp_ids[] = {
+	{ .compatible = "sifive,fu540-otp" },
+	{}
+};
+
+U_BOOT_DRIVER(sifive_otp) = {
+	.name = "sifive_otp",
+	.id = UCLASS_MISC,
+	.of_match = sifive_otp_ids,
+	.ofdata_to_platdata = sifive_otp_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct sifive_otp_platdata),
+	.ops = &sifive_otp_ops,
+};
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCH v5 02/14] riscv: sifive: fu540: Use OTP DM driver for serial environment variable
  2020-03-11  7:03 [PATCH v5 00/14] RISC-V SiFive FU540 support SPL Pragnesh Patel
  2020-03-11  7:03 ` [PATCH v5 01/14] misc: add driver for the SiFive otp controller Pragnesh Patel
@ 2020-03-11  7:03 ` Pragnesh Patel
  2020-03-11 13:32   ` Bin Meng
  2020-03-11 15:00   ` Bin Meng
  2020-03-11  7:03 ` [PATCH v5 03/14] riscv: Add _image_binary_end for SPL Pragnesh Patel
                   ` (11 subsequent siblings)
  13 siblings, 2 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-11  7:03 UTC (permalink / raw)
  To: u-boot

Use the OTP DM driver to set the serial environment variable.

Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
---
 arch/riscv/dts/fu540-c000-u-boot.dtsi         |  14 +++
 .../dts/hifive-unleashed-a00-u-boot.dtsi      |   6 +
 board/sifive/fu540/Kconfig                    |   2 +
 board/sifive/fu540/fu540.c                    | 113 +++++++-----------
 4 files changed, 62 insertions(+), 73 deletions(-)
 create mode 100644 arch/riscv/dts/fu540-c000-u-boot.dtsi
 create mode 100644 arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi

diff --git a/arch/riscv/dts/fu540-c000-u-boot.dtsi b/arch/riscv/dts/fu540-c000-u-boot.dtsi
new file mode 100644
index 0000000000..31fd113c7d
--- /dev/null
+++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 SiFive, Inc
+ */
+
+/ {
+	soc {
+		otp: otp at 10070000 {
+			compatible = "sifive,fu540-otp";
+			reg = <0x0 0x10070000 0x0 0x0FFF>;
+			fuse-count = <0x1000>;
+		};
+	};
+};
diff --git a/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
new file mode 100644
index 0000000000..bec0d19134
--- /dev/null
+++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 SiFive, Inc
+ */
+
+#include "fu540-c000-u-boot.dtsi"
diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
index 5ca21474de..900197bbb2 100644
--- a/board/sifive/fu540/Kconfig
+++ b/board/sifive/fu540/Kconfig
@@ -48,5 +48,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
 	imply SIFIVE_GPIO
 	imply CMD_GPIO
 	imply SMP
+	imply MISC
+	imply SIFIVE_OTP
 
 endif
diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
index 47a2090251..6c642b3082 100644
--- a/board/sifive/fu540/fu540.c
+++ b/board/sifive/fu540/fu540.c
@@ -10,94 +10,61 @@
 #include <dm.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <misc.h>
+
+/*
+ * This define is a value used for error/unknown serial.
+ * If we really care about distinguishing errors and 0 is
+ * valid, we'll need a different one.
+ */
+#define ERROR_READING_SERIAL_NUMBER       0
 
 #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)
+#if CONFIG_IS_ENABLED(SIFIVE_OTP)
+static u32 otp_read_serialnum(struct udevice *dev)
 {
-	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);
-	}
+	int ret;
+	u32 serial[2] = {0};
 
-	/* shut down */
-	writel(0, &regs->pce);
-	writel(0, &regs->ptrim);
-	writel(0, &regs->pdstb);
+	for (int i = 0xfe * 4; i > 0; i -= 8) {
+		ret = misc_read(dev, i, serial, sizeof(serial));
 
-	/* copy out */
-	memcpy(buf, fusebuf, size);
+		if (ret != sizeof(serial)) {
+			printf("%s: error reading serial from OTP\n", __func__);
+			break;
+		}
 
-	return 0;
+		if (serial[0] == ~serial[1])
+			return serial[0];
+	}
+
+	return ERROR_READING_SERIAL_NUMBER;
 }
+#endif
 
 static u32 fu540_read_serialnum(void)
 {
+	u32 serial = ERROR_READING_SERIAL_NUMBER;
+
+#if CONFIG_IS_ENABLED(SIFIVE_OTP)
+	struct udevice *dev;
 	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];
+	// init OTP
+	ret = uclass_get_device_by_driver(UCLASS_MISC,
+					  DM_GET_DRIVER(sifive_otp), &dev);
+
+	if (ret) {
+		debug("%s: could not find otp device\n", __func__);
+		return serial;
 	}
 
-	return 0;
+	// read serial from OTP and set env var
+	serial = otp_read_serialnum(dev);
+#endif
+
+	return serial;
 }
 
 static void fu540_setup_macaddr(u32 serialnum)
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCH v5 03/14] riscv: Add _image_binary_end for SPL
  2020-03-11  7:03 [PATCH v5 00/14] RISC-V SiFive FU540 support SPL Pragnesh Patel
  2020-03-11  7:03 ` [PATCH v5 01/14] misc: add driver for the SiFive otp controller Pragnesh Patel
  2020-03-11  7:03 ` [PATCH v5 02/14] riscv: sifive: fu540: Use OTP DM driver for serial environment variable Pragnesh Patel
@ 2020-03-11  7:03 ` Pragnesh Patel
  2020-03-11  7:03 ` [PATCH v5 04/14] lib: Makefile: build crc7.c when CONFIG_MMC_SPI Pragnesh Patel
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-11  7:03 UTC (permalink / raw)
  To: u-boot

For SPL_SEPARATE_BSS, Device tree will be put at _image_binary_end

Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
---
 arch/riscv/cpu/u-boot-spl.lds | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/riscv/cpu/u-boot-spl.lds b/arch/riscv/cpu/u-boot-spl.lds
index 955dd3106d..d0495ce248 100644
--- a/arch/riscv/cpu/u-boot-spl.lds
+++ b/arch/riscv/cpu/u-boot-spl.lds
@@ -72,6 +72,7 @@ SECTIONS
 	. = ALIGN(4);
 
 	_end = .;
+	_image_binary_end = .;
 
 	.bss : {
 		__bss_start = .;
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCH v5 04/14] lib: Makefile: build crc7.c when CONFIG_MMC_SPI
  2020-03-11  7:03 [PATCH v5 00/14] RISC-V SiFive FU540 support SPL Pragnesh Patel
                   ` (2 preceding siblings ...)
  2020-03-11  7:03 ` [PATCH v5 03/14] riscv: Add _image_binary_end for SPL Pragnesh Patel
@ 2020-03-11  7:03 ` Pragnesh Patel
  2020-03-11 13:52   ` Bin Meng
  2020-03-11  7:03 ` [PATCH v5 05/14] riscv: sifive: dts: fu540: Add board -u-boot.dtsi files Pragnesh Patel
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-11  7:03 UTC (permalink / raw)
  To: u-boot

When build U-boot SPL, meet an issue of undefined reference to
'crc7' for drivers/mmc/mmc_spi.c, so let's compile crc7.c when
CONFIG_MMC_SPI selected.

Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
---
 common/spl/Kconfig | 7 +++++++
 lib/Makefile       | 1 +
 2 files changed, 8 insertions(+)

diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index b03a476b9f..f93f552f5e 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -401,6 +401,13 @@ config SPL_CRC32_SUPPORT
 	  for detected accidental image corruption. For secure applications you
 	  should consider SHA1 or SHA256.
 
+config SPL_CRC7_SUPPORT
+	bool "Support CRC7"
+	default y if MMC_SPI
+	help
+	  Enable CRC7 hashing for drivers which are using in SPL.
+	  This is a 32-bit checksum value that can be used to verify images.
+
 config SPL_MD5_SUPPORT
 	bool "Support MD5"
 	depends on SPL_FIT
diff --git a/lib/Makefile b/lib/Makefile
index 15259d0473..7a50aa56ef 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -78,6 +78,7 @@ endif
 
 ifdef CONFIG_SPL_BUILD
 obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o
+obj-$(CONFIG_SPL_CRC7_SUPPORT) += crc7.o
 obj-$(CONFIG_$(SPL_TPL_)HASH_SUPPORT) += crc16.o
 obj-y += net_utils.o
 endif
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCH v5 05/14] riscv: sifive: dts: fu540: Add board -u-boot.dtsi files
  2020-03-11  7:03 [PATCH v5 00/14] RISC-V SiFive FU540 support SPL Pragnesh Patel
                   ` (3 preceding siblings ...)
  2020-03-11  7:03 ` [PATCH v5 04/14] lib: Makefile: build crc7.c when CONFIG_MMC_SPI Pragnesh Patel
@ 2020-03-11  7:03 ` Pragnesh Patel
  2020-03-11 14:51   ` Bin Meng
  2020-03-11  7:03 ` [PATCH v5 06/14] sifive: fu540: add ddr driver Pragnesh Patel
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-11  7:03 UTC (permalink / raw)
  To: u-boot

Devicetree files in FU540 platform is synced from Linux, like other
platforms does. Apart from these u-boot in FU540 would also require
some u-boot specific node like clint.

So, create board specific -u-boot.dtsi files. This would help of
maintain u-boot specific changes separately without touching Linux
dts(i) files which indeed easy for syncing from Linux between
releases.

Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
---
 arch/riscv/dts/fu540-c000-u-boot.dtsi         | 42 +++++++++++++++++++
 .../dts/hifive-unleashed-a00-u-boot.dtsi      | 16 +++++++
 2 files changed, 58 insertions(+)

diff --git a/arch/riscv/dts/fu540-c000-u-boot.dtsi b/arch/riscv/dts/fu540-c000-u-boot.dtsi
index 31fd113c7d..2d3d62801f 100644
--- a/arch/riscv/dts/fu540-c000-u-boot.dtsi
+++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
@@ -4,11 +4,53 @@
  */
 
 / {
+	cpus {
+		u-boot,dm-spl;
+		cpu0: cpu at 0 {
+			u-boot,dm-spl;
+			status = "okay";
+			cpu0_intc: interrupt-controller {
+				u-boot,dm-spl;
+			};
+		};
+		cpu1: cpu at 1 {
+			u-boot,dm-spl;
+		};
+		cpu2: cpu at 2 {
+			u-boot,dm-spl;
+		};
+		cpu3: cpu at 3 {
+			u-boot,dm-spl;
+		};
+		cpu4: cpu at 4 {
+			u-boot,dm-spl;
+		};
+	};
+
 	soc {
+		u-boot,dm-spl;
 		otp: otp at 10070000 {
 			compatible = "sifive,fu540-otp";
 			reg = <0x0 0x10070000 0x0 0x0FFF>;
 			fuse-count = <0x1000>;
 		};
+		clint at 2000000 {
+			compatible = "riscv,clint0";
+			interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7 >;
+			reg = <0x0 0x2000000 0x0 0xc0000>;
+			u-boot,dm-spl;
+		};
 	};
 };
+
+&prci {
+	u-boot,dm-spl;
+};
+
+&uart0 {
+	u-boot,dm-spl;
+};
+
+&qspi2 {
+	u-boot,dm-spl;
+};
diff --git a/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
index bec0d19134..cce1bd943e 100644
--- a/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
+++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
@@ -4,3 +4,19 @@
  */
 
 #include "fu540-c000-u-boot.dtsi"
+
+/ {
+	hfclk {
+		u-boot,dm-spl;
+	};
+
+	rtcclk {
+		u-boot,dm-spl;
+	};
+};
+
+&qspi2 {
+	mmc at 0 {
+		u-boot,dm-spl;
+	};
+};
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCH v5 06/14] sifive: fu540: add ddr driver
  2020-03-11  7:03 [PATCH v5 00/14] RISC-V SiFive FU540 support SPL Pragnesh Patel
                   ` (4 preceding siblings ...)
  2020-03-11  7:03 ` [PATCH v5 05/14] riscv: sifive: dts: fu540: Add board -u-boot.dtsi files Pragnesh Patel
@ 2020-03-11  7:03 ` Pragnesh Patel
  2020-03-13  7:48   ` Bin Meng
  2020-03-13 11:56   ` Giulio Benetti
  2020-03-11  7:03 ` [PATCH v5 07/14] sifive: dts: fu540: Add DDR controller and phy register settings Pragnesh Patel
                   ` (7 subsequent siblings)
  13 siblings, 2 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-11  7:03 UTC (permalink / raw)
  To: u-boot

Add driver for fu540 to support ddr initialization in SPL.
This driver is based on FSBL
(https://github.com/sifive/freedom-u540-c000-bootloader.git)

Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
---
 drivers/ram/Kconfig              |   7 +
 drivers/ram/Makefile             |   2 +
 drivers/ram/sifive/Kconfig       |   8 +
 drivers/ram/sifive/Makefile      |   6 +
 drivers/ram/sifive/sdram_fu540.c | 295 +++++++++++++++++++++++++++++++
 drivers/ram/sifive/sdram_fu540.h |  94 ++++++++++
 6 files changed, 412 insertions(+)
 create mode 100644 drivers/ram/sifive/Kconfig
 create mode 100644 drivers/ram/sifive/Makefile
 create mode 100644 drivers/ram/sifive/sdram_fu540.c
 create mode 100644 drivers/ram/sifive/sdram_fu540.h

diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig
index 56fea7c94c..c60c63204c 100644
--- a/drivers/ram/Kconfig
+++ b/drivers/ram/Kconfig
@@ -73,5 +73,12 @@ config IMXRT_SDRAM
 	  to support external memories like sdram, psram & nand.
 	  This driver is for the sdram memory interface with the SEMC.
 
+config SIFIVE_DDR
+	bool "Enable SiFive DDR support"
+	depends on RAM
+	help
+	  Enable support for the internal DDR Memory Controller of SiFive SoCs.
+
 source "drivers/ram/rockchip/Kconfig"
 source "drivers/ram/stm32mp1/Kconfig"
+source "drivers/ram/sifive/Kconfig"
diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile
index 5c897410c6..12bf61510b 100644
--- a/drivers/ram/Makefile
+++ b/drivers/ram/Makefile
@@ -17,3 +17,5 @@ obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
 obj-$(CONFIG_K3_J721E_DDRSS) += k3-j721e/
 
 obj-$(CONFIG_IMXRT_SDRAM) += imxrt_sdram.o
+
+obj-$(CONFIG_SIFIVE_DDR) += sifive/
diff --git a/drivers/ram/sifive/Kconfig b/drivers/ram/sifive/Kconfig
new file mode 100644
index 0000000000..b754700db8
--- /dev/null
+++ b/drivers/ram/sifive/Kconfig
@@ -0,0 +1,8 @@
+config SIFIVE_FU540_DDR
+	bool "SiFive FU540 DDR driver"
+	depends on DM && OF_CONTROL
+	select RAM
+	select SPL_RAM if SPL
+	select SIFIVE_DDR
+	help
+	  This enables DDR support for the platforms based on SiFive FU540 SoC.
diff --git a/drivers/ram/sifive/Makefile b/drivers/ram/sifive/Makefile
new file mode 100644
index 0000000000..0187805199
--- /dev/null
+++ b/drivers/ram/sifive/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2020 SiFive, Inc
+#
+
+obj-$(CONFIG_SIFIVE_FU540_DDR) += sdram_fu540.o
diff --git a/drivers/ram/sifive/sdram_fu540.c b/drivers/ram/sifive/sdram_fu540.c
new file mode 100644
index 0000000000..18926dbe15
--- /dev/null
+++ b/drivers/ram/sifive/sdram_fu540.c
@@ -0,0 +1,295 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * (C) Copyright 2020 SiFive, Inc.
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <init.h>
+#include <ram.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include "sdram_fu540.h"
+
+/* n: Unit bytes */
+void sdram_copy_to_reg(volatile u32 *dest, volatile u32 *src, u32 n)
+{
+	int i;
+
+	for (i = 0; i < n / sizeof(u32); i++) {
+		writel(*src, dest);
+		src++;
+		dest++;
+	}
+}
+
+static void ddr_setuprangeprotection(volatile u32 *ctl, u64 end_addr)
+{
+	writel(0x0, DENALI_CTL_209 + ctl);
+	u32 end_addr_16kblocks = ((end_addr >> 14) & 0x7FFFFF) - 1;
+
+	writel(end_addr_16kblocks, DENALI_CTL_210 + ctl);
+	writel(0x0, DENALI_CTL_212 + ctl);
+	writel(0x0, DENALI_CTL_214 + ctl);
+	writel(0x0, DENALI_CTL_216 + ctl);
+	setbits_le32(DENALI_CTL_224 + ctl,
+		     0x3 << AXI0_RANGE_PROT_BITS_0_OFFSET);
+	writel(0xFFFFFFFF, DENALI_CTL_225 + ctl);
+	setbits_le32(DENALI_CTL_208 + ctl, 0x1 << AXI0_ADDRESS_RANGE_ENABLE);
+	setbits_le32(DENALI_CTL_208 + ctl,
+		     0x1 << PORT_ADDR_PROTECTION_EN_OFFSET);
+}
+
+static void ddr_start(volatile u32 *ctl, u32 *physical_filter_ctrl, u64 ddr_end)
+{
+	setbits_le32(DENALI_CTL_0 + ctl, 0x1);
+	while ((readl(DENALI_CTL_132 + ctl) & (1 << MC_INIT_COMPLETE_OFFSET))
+	       == 0) {
+	}
+
+	// Disable the BusBlocker in front of the controller AXI slave ports
+	volatile u64 *filterreg = (volatile u64 *)physical_filter_ctrl;
+
+	filterreg[0] = 0x0f00000000000000UL | (ddr_end >> 2);
+}
+
+static u64 ddr_phy_fixup(volatile u32 *ddrphyreg)
+{
+	// return bitmask of failed lanes
+
+	u64 fails     = 0;
+	u32 slicebase = 0;
+	u32 dq        = 0;
+
+	// check errata condition
+	for (u32 slice = 0; slice < 8; slice++) {
+		u32 regbase = slicebase + 34;
+
+		for (u32 reg = 0; reg < 4; reg++) {
+			u32 updownreg = readl(regbase + reg + ddrphyreg);
+
+			for (u32 bit = 0; bit < 2; bit++) {
+				u32 phy_rx_cal_dqn_0_offset;
+
+				if (bit == 0) {
+					phy_rx_cal_dqn_0_offset =
+						PHY_RX_CAL_DQ0_0_OFFSET;
+				} else {
+					phy_rx_cal_dqn_0_offset =
+						PHY_RX_CAL_DQ1_0_OFFSET;
+				}
+
+				u32 down = (updownreg >>
+					    phy_rx_cal_dqn_0_offset) & 0x3F;
+				u32 up   = (updownreg >>
+					    (phy_rx_cal_dqn_0_offset + 6)) &
+					    0x3F;
+
+				u8 failc0 = ((down == 0) && (up == 0x3F));
+				u8 failc1 = ((up == 0) && (down == 0x3F));
+
+				// print error message on failure
+				if (failc0 || failc1) {
+					if (fails == 0)
+						printf("DDR error in fixing up\n");
+
+					fails |= (1 << dq);
+
+					char slicelsc = '0';
+					char slicemsc = '0';
+
+					slicelsc += (dq % 10);
+					slicemsc += (dq / 10);
+					printf("S ");
+					printf("%c", slicemsc);
+					printf("%c", slicelsc);
+
+					if (failc0)
+						printf("U");
+					else
+						printf("D");
+
+					printf("\n");
+				}
+				dq++;
+			}
+		}
+		slicebase += 128;
+	}
+	return(0);
+}
+
+static u32 ddr_getdramclass(volatile u32 *ctl)
+{
+	u32 reg = readl(DENALI_CTL_0 + ctl);
+
+	return ((reg >> DRAM_CLASS_OFFSET) & 0xF);
+}
+
+static __maybe_unused int fu540_ddr_setup(struct udevice *dev)
+{
+	struct ddr_info *priv = dev_get_priv(dev);
+	struct sifive_dmc_plat *plat = dev_get_platdata(dev);
+
+	int ret, i;
+	u32 physet;
+
+	volatile u32 *denali_ctl =  &priv->ctl->denali_ctl[0];
+	volatile u32 *denali_phy =  &priv->phy->denali_phy[0];
+
+	ret = dev_read_u32_array(dev, "sifive,sdram-params",
+				 (u32 *)&plat->sdram_params,
+				 sizeof(plat->sdram_params) / sizeof(u32));
+	if (ret) {
+		printf("%s: Cannot read sifive,sdram-params %d\n",
+		       __func__, ret);
+		return ret;
+	}
+
+	struct fu540_sdram_params *params = &plat->sdram_params;
+
+	sdram_copy_to_reg(&priv->ctl->denali_ctl[0],
+			  &params->pctl_regs.denali_ctl[0],
+			  sizeof(struct fu540_ddrctl));
+
+	/* phy reset */
+	for (i = DENALI_PHY_1152; i <= DENALI_PHY_1214; i++) {
+		physet = params->phy_regs.denali_phy[i];
+		priv->phy->denali_phy[i] = physet;
+	}
+
+	for (i = 0; i < DENALI_PHY_1152; i++) {
+		physet = params->phy_regs.denali_phy[i];
+		priv->phy->denali_phy[i] = physet;
+	}
+
+	/* Disable read interleave DENALI_CTL_120 */
+	setbits_le32(DENALI_CTL_120 + denali_ctl,
+		     1 << DISABLE_RD_INTERLEAVE_OFFSET);
+
+	/* Disable optimal read/modify/write logic DENALI_CTL_21 */
+	clrbits_le32(DENALI_CTL_21 + denali_ctl, 1 << OPTIMAL_RMODW_EN_OFFSET);
+
+	/* Enable write Leveling DENALI_CTL_170 */
+	setbits_le32(DENALI_CTL_170 + denali_ctl, (1 << WRLVL_EN_OFFSET)
+		     | (1 << DFI_PHY_WRLELV_MODE_OFFSET));
+
+	/* Enable read leveling DENALI_CTL_181 and DENALI_CTL_260 */
+	setbits_le32(DENALI_CTL_181 + denali_ctl,
+		     1 << DFI_PHY_RDLVL_MODE_OFFSET);
+	setbits_le32(DENALI_CTL_260 + denali_ctl, 1 << RDLVL_EN_OFFSET);
+
+	/* Enable read leveling gate DENALI_CTL_260 and DENALI_CTL_182 */
+	setbits_le32(DENALI_CTL_260 + denali_ctl, 1 << RDLVL_GATE_EN_OFFSET);
+	setbits_le32(DENALI_CTL_182 + denali_ctl,
+		     1 << DFI_PHY_RDLVL_GATE_MODE_OFFSET);
+
+	if (ddr_getdramclass(denali_ctl) == DRAM_CLASS_DDR4) {
+		/* Enable vref training DENALI_CTL_184 */
+		setbits_le32(DENALI_CTL_184 + denali_ctl, 1 << VREF_EN_OFFSET);
+	}
+
+	/* Mask off leveling completion interrupt DENALI_CTL_136 */
+	setbits_le32(DENALI_CTL_136 + denali_ctl,
+		     1 << LEVELING_OPERATION_COMPLETED_OFFSET);
+
+	/* Mask off MC init complete interrupt DENALI_CTL_136 */
+	setbits_le32(DENALI_CTL_136 + denali_ctl, 1 << MC_INIT_COMPLETE_OFFSET);
+
+	/* Mask off out of range interrupts DENALI_CTL_136 */
+	setbits_le32(DENALI_CTL_136 + denali_ctl, (1 << OUT_OF_RANGE_OFFSET)
+		     | (1 << MULTIPLE_OUT_OF_RANGE_OFFSET));
+
+	/* set up range protection */
+	ddr_setuprangeprotection(denali_ctl, DDR_MEM_SIZE);
+
+	/* Mask off port command error interrupt DENALI_CTL_136 */
+	setbits_le32(DENALI_CTL_136 + denali_ctl,
+		     1 << PORT_COMMAND_CHANNEL_ERROR_OFFSET);
+
+	const u64 ddr_size = DDR_MEM_SIZE;
+	const u64 ddr_end = PAYLOAD_DEST + ddr_size;
+
+	ddr_start(denali_ctl, priv->physical_filter_ctrl, ddr_end);
+
+	ddr_phy_fixup(denali_phy);
+
+	/* check size */
+	priv->info.size = get_ram_size((long *)priv->info.base,
+				       DDR_MEM_SIZE);
+
+	printf("priv->info.size = %lx\n", priv->info.size);
+	debug("%s : %lx\n", __func__, priv->info.size);
+
+	/* check memory access for all memory */
+
+	if (priv->info.size != DDR_MEM_SIZE) {
+		printf("DDR invalid size : 0x%lx, expected 0x%lx\n",
+		       priv->info.size, DDR_MEM_SIZE);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int fu540_ddr_probe(struct udevice *dev)
+{
+	struct ddr_info *priv = dev_get_priv(dev);
+
+#if defined(CONFIG_SPL_BUILD)
+	struct regmap *map;
+	int ret;
+
+	debug("FU540 DDR probe\n");
+	priv->dev = dev;
+
+	ret = regmap_init_mem(dev_ofnode(dev), &map);
+	if (ret)
+		return ret;
+
+	priv->ctl = regmap_get_range(map, 0);
+	priv->phy = regmap_get_range(map, 1);
+	priv->physical_filter_ctrl = regmap_get_range(map, 2);
+
+	priv->info.base = CONFIG_SYS_SDRAM_BASE;
+
+	priv->info.size = 0;
+	return fu540_ddr_setup(dev);
+#else
+	priv->info.base = CONFIG_SYS_SDRAM_BASE;
+	priv->info.size = DDR_MEM_SIZE;
+#endif
+	return 0;
+}
+
+static int fu540_ddr_get_info(struct udevice *dev, struct ram_info *info)
+{
+	struct ddr_info *priv = dev_get_priv(dev);
+
+	*info = priv->info;
+
+	return 0;
+}
+
+static struct ram_ops fu540_ddr_ops = {
+	.get_info = fu540_ddr_get_info,
+};
+
+static const struct udevice_id fu540_ddr_ids[] = {
+	{ .compatible = "sifive,fu540-ddr" },
+	{ }
+};
+
+U_BOOT_DRIVER(fu540_ddr) = {
+	.name = "fu540_ddr",
+	.id = UCLASS_RAM,
+	.of_match = fu540_ddr_ids,
+	.ops = &fu540_ddr_ops,
+	.probe = fu540_ddr_probe,
+	.priv_auto_alloc_size = sizeof(struct ddr_info),
+	.platdata_auto_alloc_size = sizeof(struct sifive_dmc_plat),
+};
diff --git a/drivers/ram/sifive/sdram_fu540.h b/drivers/ram/sifive/sdram_fu540.h
new file mode 100644
index 0000000000..09693a038e
--- /dev/null
+++ b/drivers/ram/sifive/sdram_fu540.h
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/*
+ * Copyright (C) 2020, SiFive, Inc
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ */
+
+#define DENALI_CTL_0	0
+#define DENALI_CTL_21	21
+#define DENALI_CTL_120	120
+#define DENALI_CTL_132	132
+#define DENALI_CTL_136	136
+#define DENALI_CTL_170	170
+#define DENALI_CTL_181	181
+#define DENALI_CTL_182	182
+#define DENALI_CTL_184	184
+#define DENALI_CTL_208	208
+#define DENALI_CTL_209	209
+#define DENALI_CTL_210	210
+#define DENALI_CTL_212	212
+#define DENALI_CTL_214	214
+#define DENALI_CTL_216	216
+#define DENALI_CTL_224	224
+#define DENALI_CTL_225	225
+#define DENALI_CTL_260	260
+
+#define DENALI_PHY_1152	1152
+#define DENALI_PHY_1214	1214
+
+#define PAYLOAD_DEST	0x80000000
+#define DDR_MEM_SIZE	(8UL * 1024UL * 1024UL * 1024UL)
+
+#define DRAM_CLASS_OFFSET                   8
+#define DRAM_CLASS_DDR4                     0xA
+#define OPTIMAL_RMODW_EN_OFFSET             0
+#define DISABLE_RD_INTERLEAVE_OFFSET        16
+#define OUT_OF_RANGE_OFFSET                 1
+#define MULTIPLE_OUT_OF_RANGE_OFFSET        2
+#define PORT_COMMAND_CHANNEL_ERROR_OFFSET   7
+#define MC_INIT_COMPLETE_OFFSET             8
+#define LEVELING_OPERATION_COMPLETED_OFFSET 22
+#define DFI_PHY_WRLELV_MODE_OFFSET          24
+#define DFI_PHY_RDLVL_MODE_OFFSET           24
+#define DFI_PHY_RDLVL_GATE_MODE_OFFSET      0
+#define VREF_EN_OFFSET                      24
+#define PORT_ADDR_PROTECTION_EN_OFFSET      0
+#define AXI0_ADDRESS_RANGE_ENABLE           8
+#define AXI0_RANGE_PROT_BITS_0_OFFSET       24
+#define RDLVL_EN_OFFSET                     16
+#define RDLVL_GATE_EN_OFFSET                24
+#define WRLVL_EN_OFFSET                     0
+
+#define PHY_RX_CAL_DQ0_0_OFFSET             0
+#define PHY_RX_CAL_DQ1_0_OFFSET             16
+
+struct fu540_ddrctl {
+	volatile u32 denali_ctl[265];
+};
+
+struct fu540_ddrphy {
+	volatile u32 denali_phy[1215];
+};
+
+struct fu540_sdram_params {
+	struct fu540_ddrctl pctl_regs;
+	struct fu540_ddrphy phy_regs;
+};
+
+struct sifive_dmc_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct dtd_sifive_fu540_dmc dtplat;
+#else
+	struct fu540_sdram_params sdram_params;
+#endif
+};
+
+/**
+ * struct ddr_info
+ *
+ * @dev				: pointer for the device
+ * @info			: UCLASS RAM information
+ * @ctl				: DDR controleur base address
+ * @phy				: DDR PHY base address
+ * @ctrl			: DDR control base address
+ * @physical_filter_ctrl	: DDR physical filter control base address
+ */
+struct ddr_info {
+	struct udevice *dev;
+	struct ram_info info;
+	struct fu540_ddrctl *ctl;
+	struct fu540_ddrphy *phy;
+	u32 *physical_filter_ctrl;
+};
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCH v5 07/14] sifive: dts: fu540: Add DDR controller and phy register settings
  2020-03-11  7:03 [PATCH v5 00/14] RISC-V SiFive FU540 support SPL Pragnesh Patel
                   ` (5 preceding siblings ...)
  2020-03-11  7:03 ` [PATCH v5 06/14] sifive: fu540: add ddr driver Pragnesh Patel
@ 2020-03-11  7:03 ` Pragnesh Patel
  2020-03-13  7:51   ` Bin Meng
  2020-03-11  7:03 ` [PATCH v5 08/14] clk: sifive: fu540-prci: Add clock enable and disable ops Pragnesh Patel
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-11  7:03 UTC (permalink / raw)
  To: u-boot

Add DDR controller and phy register settings, taken from fsbl
(https://github.com/sifive/freedom-u540-c000-bootloader.git)

Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
---
 arch/riscv/dts/fu540-c000-u-boot.dtsi         |    7 +
 arch/riscv/dts/fu540-sdram-ddr4.dtsi          | 1489 +++++++++++++++++
 .../dts/hifive-unleashed-a00-u-boot.dtsi      |    1 +
 3 files changed, 1497 insertions(+)
 create mode 100644 arch/riscv/dts/fu540-sdram-ddr4.dtsi

diff --git a/arch/riscv/dts/fu540-c000-u-boot.dtsi b/arch/riscv/dts/fu540-c000-u-boot.dtsi
index 2d3d62801f..b8cef67885 100644
--- a/arch/riscv/dts/fu540-c000-u-boot.dtsi
+++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
@@ -40,6 +40,13 @@
 			reg = <0x0 0x2000000 0x0 0xc0000>;
 			u-boot,dm-spl;
 		};
+		dmc: dmc at 100b0000 {
+			compatible = "sifive,fu540-ddr";
+			reg = <0x0 0x100b0000 0x0 0x0800
+			       0x0 0x100b2000 0x0 0x2000
+			       0x0 0x100b8000 0x0 0x0fff>;
+			u-boot,dm-spl;
+		};
 	};
 };
 
diff --git a/arch/riscv/dts/fu540-sdram-ddr4.dtsi b/arch/riscv/dts/fu540-sdram-ddr4.dtsi
new file mode 100644
index 0000000000..370c53800d
--- /dev/null
+++ b/arch/riscv/dts/fu540-sdram-ddr4.dtsi
@@ -0,0 +1,1489 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2020 SiFive, Inc
+ */
+
+&dmc {
+	sifive,sdram-params = <
+		0x00000a00	/* DENALI_CTL_00_DATA */
+		0x00000000	/* DENALI_CTL_01_DATA */
+		0x00000000	/* DENALI_CTL_02_DATA */
+		0x00000000	/* DENALI_CTL_03_DATA */
+		0x00000000	/* DENALI_CTL_04_DATA */
+		0x00000000	/* DENALI_CTL_05_DATA */
+		0x0000000a	/* DENALI_CTL_06_DATA */
+		0x0002d362	/* DENALI_CTL_07_DATA */
+		0x00071073	/* DENALI_CTL_08_DATA */
+		0x0a1c0255	/* DENALI_CTL_09_DATA */
+		0x1c1c0400	/* DENALI_CTL_10_DATA */
+		0x0404990b	/* DENALI_CTL_11_DATA */
+		0x2b050405	/* DENALI_CTL_12_DATA */
+		0x0e0c081e	/* DENALI_CTL_13_DATA */
+		0x08090914	/* DENALI_CTL_14_DATA */
+		0x00fde718	/* DENALI_CTL_15_DATA */
+		0x00180a05	/* DENALI_CTL_16_DATA */
+		0x008b130e	/* DENALI_CTL_17_DATA */
+		0x01000118	/* DENALI_CTL_18_DATA */
+		0x0e032101	/* DENALI_CTL_19_DATA */
+		0x00000000	/* DENALI_CTL_20_DATA */
+		0x00000101	/* DENALI_CTL_21_DATA */
+		0x00000000	/* DENALI_CTL_22_DATA */
+		0x0a000000	/* DENALI_CTL_23_DATA */
+		0x00000000	/* DENALI_CTL_24_DATA */
+		0x01450100	/* DENALI_CTL_25_DATA */
+		0x00001c36	/* DENALI_CTL_26_DATA */
+		0x00000005	/* DENALI_CTL_27_DATA */
+		0x00170006	/* DENALI_CTL_28_DATA */
+		0x014e0300	/* DENALI_CTL_29_DATA */
+		0x03010000	/* DENALI_CTL_30_DATA */
+		0x000a0e00	/* DENALI_CTL_31_DATA */
+		0x04030200	/* DENALI_CTL_32_DATA */
+		0x0000031f	/* DENALI_CTL_33_DATA */
+		0x00070004	/* DENALI_CTL_34_DATA */
+		0x00000000	/* DENALI_CTL_35_DATA */
+		0x00000000	/* DENALI_CTL_36_DATA */
+		0x00000000	/* DENALI_CTL_37_DATA */
+		0x00000000	/* DENALI_CTL_38_DATA */
+		0x00000000	/* DENALI_CTL_39_DATA */
+		0x00000000	/* DENALI_CTL_40_DATA */
+		0x00000000	/* DENALI_CTL_41_DATA */
+		0x00000000	/* DENALI_CTL_42_DATA */
+		0x00000000	/* DENALI_CTL_43_DATA */
+		0x00000000	/* DENALI_CTL_44_DATA */
+		0x00000000	/* DENALI_CTL_45_DATA */
+		0x00000000	/* DENALI_CTL_46_DATA */
+		0x00000000	/* DENALI_CTL_47_DATA */
+		0x00000000	/* DENALI_CTL_48_DATA */
+		0x00000000	/* DENALI_CTL_49_DATA */
+		0x00000000	/* DENALI_CTL_50_DATA */
+		0x00000000	/* DENALI_CTL_51_DATA */
+		0x00000000	/* DENALI_CTL_52_DATA */
+		0x00000000	/* DENALI_CTL_53_DATA */
+		0x00000000	/* DENALI_CTL_54_DATA */
+		0x00000000	/* DENALI_CTL_55_DATA */
+		0x00000000	/* DENALI_CTL_56_DATA */
+		0x00000000	/* DENALI_CTL_57_DATA */
+		0x00000000	/* DENALI_CTL_58_DATA */
+		0x00000000	/* DENALI_CTL_59_DATA */
+		0x00000424	/* DENALI_CTL_60_DATA */
+		0x00000201	/* DENALI_CTL_61_DATA */
+		0x00001008	/* DENALI_CTL_62_DATA */
+		0x00000000	/* DENALI_CTL_63_DATA */
+		0x00000200	/* DENALI_CTL_64_DATA */
+		0x00000000	/* DENALI_CTL_65_DATA */
+		0x00000481	/* DENALI_CTL_66_DATA */
+		0x00000400	/* DENALI_CTL_67_DATA */
+		0x00000424	/* DENALI_CTL_68_DATA */
+		0x00000201	/* DENALI_CTL_69_DATA */
+		0x00001008	/* DENALI_CTL_70_DATA */
+		0x00000000	/* DENALI_CTL_71_DATA */
+		0x00000200	/* DENALI_CTL_72_DATA */
+		0x00000000	/* DENALI_CTL_73_DATA */
+		0x00000481	/* DENALI_CTL_74_DATA */
+		0x00000400	/* DENALI_CTL_75_DATA */
+		0x01010000	/* DENALI_CTL_76_DATA */
+		0x00000000	/* DENALI_CTL_77_DATA */
+		0x00000000	/* DENALI_CTL_78_DATA */
+		0x00000000	/* DENALI_CTL_79_DATA */
+		0x00000000	/* DENALI_CTL_80_DATA */
+		0x00000000	/* DENALI_CTL_81_DATA */
+		0x00000000	/* DENALI_CTL_82_DATA */
+		0x00000000	/* DENALI_CTL_83_DATA */
+		0x00000000	/* DENALI_CTL_84_DATA */
+		0x00000000	/* DENALI_CTL_85_DATA */
+		0x00000000	/* DENALI_CTL_86_DATA */
+		0x00000000	/* DENALI_CTL_87_DATA */
+		0x00000000	/* DENALI_CTL_88_DATA */
+		0x00000000	/* DENALI_CTL_89_DATA */
+		0x00000000	/* DENALI_CTL_90_DATA */
+		0x00000000	/* DENALI_CTL_91_DATA */
+		0x00000000	/* DENALI_CTL_92_DATA */
+		0x00000000	/* DENALI_CTL_93_DATA */
+		0x00000000	/* DENALI_CTL_94_DATA */
+		0x00000000	/* DENALI_CTL_95_DATA */
+		0x00000000	/* DENALI_CTL_96_DATA */
+		0x00000000	/* DENALI_CTL_97_DATA */
+		0x00000000	/* DENALI_CTL_98_DATA */
+		0x00000000	/* DENALI_CTL_99_DATA */
+		0x00000000	/* DENALI_CTL_100_DATA */
+		0x00000000	/* DENALI_CTL_101_DATA */
+		0x00000000	/* DENALI_CTL_102_DATA */
+		0x00000000	/* DENALI_CTL_103_DATA */
+		0x00000000	/* DENALI_CTL_104_DATA */
+		0x00000003	/* DENALI_CTL_105_DATA */
+		0x00000000	/* DENALI_CTL_106_DATA */
+		0x00000000	/* DENALI_CTL_107_DATA */
+		0x00000000	/* DENALI_CTL_108_DATA */
+		0x00000000	/* DENALI_CTL_109_DATA */
+		0x01000000	/* DENALI_CTL_110_DATA */
+		0x00040000	/* DENALI_CTL_111_DATA */
+		0x00800200	/* DENALI_CTL_112_DATA */
+		0x00000200	/* DENALI_CTL_113_DATA */
+		0x00000040	/* DENALI_CTL_114_DATA */
+		0x01000100	/* DENALI_CTL_115_DATA */
+		0x0a000002	/* DENALI_CTL_116_DATA */
+		0x0101ffff	/* DENALI_CTL_117_DATA */
+		0x01010101	/* DENALI_CTL_118_DATA */
+		0x01010101	/* DENALI_CTL_119_DATA */
+		0x0000010b	/* DENALI_CTL_120_DATA */
+		0x00000c01	/* DENALI_CTL_121_DATA */
+		0x00000000	/* DENALI_CTL_122_DATA */
+		0x00000000	/* DENALI_CTL_123_DATA */
+		0x00000000	/* DENALI_CTL_124_DATA */
+		0x00000000	/* DENALI_CTL_125_DATA */
+		0x00030300	/* DENALI_CTL_126_DATA */
+		0x00000000	/* DENALI_CTL_127_DATA */
+		0x00010001	/* DENALI_CTL_128_DATA */
+		0x00000000	/* DENALI_CTL_129_DATA */
+		0x00000000	/* DENALI_CTL_130_DATA */
+		0x00000000	/* DENALI_CTL_131_DATA */
+		0x00000000	/* DENALI_CTL_132_DATA */
+		0x00000000	/* DENALI_CTL_133_DATA */
+		0x00000000	/* DENALI_CTL_134_DATA */
+		0x00000000	/* DENALI_CTL_135_DATA */
+		0x00000000	/* DENALI_CTL_136_DATA */
+		0x00000000	/* DENALI_CTL_137_DATA */
+		0x00000000	/* DENALI_CTL_138_DATA */
+		0x00000000	/* DENALI_CTL_139_DATA */
+		0x00000000	/* DENALI_CTL_140_DATA */
+		0x00000000	/* DENALI_CTL_141_DATA */
+		0x00000000	/* DENALI_CTL_142_DATA */
+		0x00000000	/* DENALI_CTL_143_DATA */
+		0x00000000	/* DENALI_CTL_144_DATA */
+		0x00000000	/* DENALI_CTL_145_DATA */
+		0x00000000	/* DENALI_CTL_146_DATA */
+		0x00000000	/* DENALI_CTL_147_DATA */
+		0x00000000	/* DENALI_CTL_148_DATA */
+		0x00000000	/* DENALI_CTL_149_DATA */
+		0x00000000	/* DENALI_CTL_150_DATA */
+		0x00000000	/* DENALI_CTL_151_DATA */
+		0x00000000	/* DENALI_CTL_152_DATA */
+		0x00000000	/* DENALI_CTL_153_DATA */
+		0x00000000	/* DENALI_CTL_154_DATA */
+		0x00000000	/* DENALI_CTL_155_DATA */
+		0x00000000	/* DENALI_CTL_156_DATA */
+		0x00000000	/* DENALI_CTL_157_DATA */
+		0x00000000	/* DENALI_CTL_158_DATA */
+		0x00000000	/* DENALI_CTL_159_DATA */
+		0x00000000	/* DENALI_CTL_160_DATA */
+		0x02010102	/* DENALI_CTL_161_DATA */
+		0x0107070d	/* DENALI_CTL_162_DATA */
+		0x04040400	/* DENALI_CTL_163_DATA */
+		0x03000503	/* DENALI_CTL_164_DATA */
+		0x00000000	/* DENALI_CTL_165_DATA */
+		0x00000000	/* DENALI_CTL_166_DATA */
+		0x00000000	/* DENALI_CTL_167_DATA */
+		0x00000000	/* DENALI_CTL_168_DATA */
+		0x280d0000	/* DENALI_CTL_169_DATA */
+		0x01000000	/* DENALI_CTL_170_DATA */
+		0x00000000	/* DENALI_CTL_171_DATA */
+		0x00010001	/* DENALI_CTL_172_DATA */
+		0x00000000	/* DENALI_CTL_173_DATA */
+		0x00000000	/* DENALI_CTL_174_DATA */
+		0x00000000	/* DENALI_CTL_175_DATA */
+		0x00000000	/* DENALI_CTL_176_DATA */
+		0x00000000	/* DENALI_CTL_177_DATA */
+		0x00000000	/* DENALI_CTL_178_DATA */
+		0x00000000	/* DENALI_CTL_179_DATA */
+		0x00000000	/* DENALI_CTL_180_DATA */
+		0x01000000	/* DENALI_CTL_181_DATA */
+		0x00000001	/* DENALI_CTL_182_DATA */
+		0x00000100	/* DENALI_CTL_183_DATA */
+		0x00000101	/* DENALI_CTL_184_DATA */
+		0x67676701	/* DENALI_CTL_185_DATA */
+		0x67676767	/* DENALI_CTL_186_DATA */
+		0x67676767	/* DENALI_CTL_187_DATA */
+		0x67676767	/* DENALI_CTL_188_DATA */
+		0x67676767	/* DENALI_CTL_189_DATA */
+		0x67676767	/* DENALI_CTL_190_DATA */
+		0x67676767	/* DENALI_CTL_191_DATA */
+		0x67676767	/* DENALI_CTL_192_DATA */
+		0x67676767	/* DENALI_CTL_193_DATA */
+		0x01000067	/* DENALI_CTL_194_DATA */
+		0x00000001	/* DENALI_CTL_195_DATA */
+		0x00000101	/* DENALI_CTL_196_DATA */
+		0x00000000	/* DENALI_CTL_197_DATA */
+		0x00000000	/* DENALI_CTL_198_DATA */
+		0x00000000	/* DENALI_CTL_199_DATA */
+		0x00000000	/* DENALI_CTL_200_DATA */
+		0x00000000	/* DENALI_CTL_201_DATA */
+		0x00000000	/* DENALI_CTL_202_DATA */
+		0x00000000	/* DENALI_CTL_203_DATA */
+		0x00000000	/* DENALI_CTL_204_DATA */
+		0x00000000	/* DENALI_CTL_205_DATA */
+		0x00000000	/* DENALI_CTL_206_DATA */
+		0x00000000	/* DENALI_CTL_207_DATA */
+		0x00000001	/* DENALI_CTL_208_DATA */
+		0x00000000	/* DENALI_CTL_209_DATA */
+		0x007fffff	/* DENALI_CTL_210_DATA */
+		0x00000000	/* DENALI_CTL_211_DATA */
+		0x007fffff	/* DENALI_CTL_212_DATA */
+		0x00000000	/* DENALI_CTL_213_DATA */
+		0x007fffff	/* DENALI_CTL_214_DATA */
+		0x00000000	/* DENALI_CTL_215_DATA */
+		0x007fffff	/* DENALI_CTL_216_DATA */
+		0x00000000	/* DENALI_CTL_217_DATA */
+		0x007fffff	/* DENALI_CTL_218_DATA */
+		0x00000000	/* DENALI_CTL_219_DATA */
+		0x007fffff	/* DENALI_CTL_220_DATA */
+		0x00000000	/* DENALI_CTL_221_DATA */
+		0x007fffff	/* DENALI_CTL_222_DATA */
+		0x00000000	/* DENALI_CTL_223_DATA */
+		0x037fffff	/* DENALI_CTL_224_DATA */
+		0xffffffff	/* DENALI_CTL_225_DATA */
+		0x000f000f	/* DENALI_CTL_226_DATA */
+		0x00ffff03	/* DENALI_CTL_227_DATA */
+		0x000fffff	/* DENALI_CTL_228_DATA */
+		0x0003000f	/* DENALI_CTL_229_DATA */
+		0xffffffff	/* DENALI_CTL_230_DATA */
+		0x000f000f	/* DENALI_CTL_231_DATA */
+		0x00ffff03	/* DENALI_CTL_232_DATA */
+		0x000fffff	/* DENALI_CTL_233_DATA */
+		0x0003000f	/* DENALI_CTL_234_DATA */
+		0xffffffff	/* DENALI_CTL_235_DATA */
+		0x000f000f	/* DENALI_CTL_236_DATA */
+		0x00ffff03	/* DENALI_CTL_237_DATA */
+		0x000fffff	/* DENALI_CTL_238_DATA */
+		0x0003000f	/* DENALI_CTL_239_DATA */
+		0xffffffff	/* DENALI_CTL_240_DATA */
+		0x000f000f	/* DENALI_CTL_241_DATA */
+		0x00ffff03	/* DENALI_CTL_242_DATA */
+		0x000fffff	/* DENALI_CTL_243_DATA */
+		0x6407000f	/* DENALI_CTL_244_DATA */
+		0x01640001	/* DENALI_CTL_245_DATA */
+		0x00000000	/* DENALI_CTL_246_DATA */
+		0x00000000	/* DENALI_CTL_247_DATA */
+		0x00001700	/* DENALI_CTL_248_DATA */
+		0x00386c05	/* DENALI_CTL_249_DATA */
+		0x02000200	/* DENALI_CTL_250_DATA */
+		0x02000200	/* DENALI_CTL_251_DATA */
+		0x0000386c	/* DENALI_CTL_252_DATA */
+		0x00023438	/* DENALI_CTL_253_DATA */
+		0x02020d10	/* DENALI_CTL_254_DATA */
+		0x00140303	/* DENALI_CTL_255_DATA */
+		0x00000000	/* DENALI_CTL_256_DATA */
+		0x00000000	/* DENALI_CTL_257_DATA */
+		0x00001403	/* DENALI_CTL_258_DATA */
+		0x00000000	/* DENALI_CTL_259_DATA */
+		0x00000000	/* DENALI_CTL_260_DATA */
+		0x00000000	/* DENALI_CTL_261_DATA */
+		0x00000000	/* DENALI_CTL_262_DATA */
+		0x0d010000	/* DENALI_CTL_263_DATA */
+		0x00000008	/* DENALI_CTL_264_DATA */
+		0x31706542	/* DENALI_PHY_00_DATA */
+		0x0004c008	/* DENALI_PHY_01_DATA */
+		0x000000da	/* DENALI_PHY_02_DATA */
+		0x00000000	/* DENALI_PHY_03_DATA */
+		0x00000000	/* DENALI_PHY_04_DATA */
+		0x00010000	/* DENALI_PHY_05_DATA */
+		0x01DDDD90	/* DENALI_PHY_06_DATA */
+		0x01DDDD90	/* DENALI_PHY_07_DATA */
+		0x01030000	/* DENALI_PHY_08_DATA */
+		0x01000000	/* DENALI_PHY_09_DATA */
+		0x00c00000	/* DENALI_PHY_10_DATA */
+		0x00000007	/* DENALI_PHY_11_DATA */
+		0x00000000	/* DENALI_PHY_12_DATA */
+		0x00000000	/* DENALI_PHY_13_DATA */
+		0x04000408	/* DENALI_PHY_14_DATA */
+		0x00000408	/* DENALI_PHY_15_DATA */
+		0x00e4e400	/* DENALI_PHY_16_DATA */
+		0x00000000	/* DENALI_PHY_17_DATA */
+		0x00000000	/* DENALI_PHY_18_DATA */
+		0x00000000	/* DENALI_PHY_19_DATA */
+		0x00000000	/* DENALI_PHY_20_DATA */
+		0x00000000	/* DENALI_PHY_21_DATA */
+		0x00000000	/* DENALI_PHY_22_DATA */
+		0x00000000	/* DENALI_PHY_23_DATA */
+		0x00000000	/* DENALI_PHY_24_DATA */
+		0x00000000	/* DENALI_PHY_25_DATA */
+		0x00000000	/* DENALI_PHY_26_DATA */
+		0x00000000	/* DENALI_PHY_27_DATA */
+		0x00000000	/* DENALI_PHY_28_DATA */
+		0x00000000	/* DENALI_PHY_29_DATA */
+		0x00000000	/* DENALI_PHY_30_DATA */
+		0x00000000	/* DENALI_PHY_31_DATA */
+		0x00000000	/* DENALI_PHY_32_DATA */
+		0x00200000	/* DENALI_PHY_33_DATA */
+		0x00000000	/* DENALI_PHY_34_DATA */
+		0x00000000	/* DENALI_PHY_35_DATA */
+		0x00000000	/* DENALI_PHY_36_DATA */
+		0x00000000	/* DENALI_PHY_37_DATA */
+		0x00000000	/* DENALI_PHY_38_DATA */
+		0x00000000	/* DENALI_PHY_39_DATA */
+		0x02800280	/* DENALI_PHY_40_DATA */
+		0x02800280	/* DENALI_PHY_41_DATA */
+		0x02800280	/* DENALI_PHY_42_DATA */
+		0x02800280	/* DENALI_PHY_43_DATA */
+		0x00000280	/* DENALI_PHY_44_DATA */
+		0x00000000	/* DENALI_PHY_45_DATA */
+		0x00000000	/* DENALI_PHY_46_DATA */
+		0x00000000	/* DENALI_PHY_47_DATA */
+		0x00000000	/* DENALI_PHY_48_DATA */
+		0x00000000	/* DENALI_PHY_49_DATA */
+		0x00800080	/* DENALI_PHY_50_DATA */
+		0x00800080	/* DENALI_PHY_51_DATA */
+		0x00800080	/* DENALI_PHY_52_DATA */
+		0x00800080	/* DENALI_PHY_53_DATA */
+		0x00800080	/* DENALI_PHY_54_DATA */
+		0x00800080	/* DENALI_PHY_55_DATA */
+		0x00800080	/* DENALI_PHY_56_DATA */
+		0x00800080	/* DENALI_PHY_57_DATA */
+		0x00800080	/* DENALI_PHY_58_DATA */
+		0x000100da	/* DENALI_PHY_59_DATA */
+		0x01000200	/* DENALI_PHY_60_DATA */
+		0x00000000	/* DENALI_PHY_61_DATA */
+		0x00000000	/* DENALI_PHY_62_DATA */
+		0x00000002	/* DENALI_PHY_63_DATA */
+		0x51313152	/* DENALI_PHY_64_DATA */
+		0x80013130	/* DENALI_PHY_65_DATA */
+		0x02000080	/* DENALI_PHY_66_DATA */
+		0x00100001	/* DENALI_PHY_67_DATA */
+		0x0c064208	/* DENALI_PHY_68_DATA */
+		0x000f0c0f	/* DENALI_PHY_69_DATA */
+		0x01000140	/* DENALI_PHY_70_DATA */
+		0x0000000c	/* DENALI_PHY_71_DATA */
+		0x00000000	/* DENALI_PHY_72_DATA */
+		0x00000000	/* DENALI_PHY_73_DATA */
+		0x00000000	/* DENALI_PHY_74_DATA */
+		0x00000000	/* DENALI_PHY_75_DATA */
+		0x00000000	/* DENALI_PHY_76_DATA */
+		0x00000000	/* DENALI_PHY_77_DATA */
+		0x00000000	/* DENALI_PHY_78_DATA */
+		0x00000000	/* DENALI_PHY_79_DATA */
+		0x00000000	/* DENALI_PHY_80_DATA */
+		0x00000000	/* DENALI_PHY_81_DATA */
+		0x00000000	/* DENALI_PHY_82_DATA */
+		0x00000000	/* DENALI_PHY_83_DATA */
+		0x00000000	/* DENALI_PHY_84_DATA */
+		0x00000000	/* DENALI_PHY_85_DATA */
+		0x00000000	/* DENALI_PHY_86_DATA */
+		0x00000000	/* DENALI_PHY_87_DATA */
+		0x00000000	/* DENALI_PHY_88_DATA */
+		0x00000000	/* DENALI_PHY_89_DATA */
+		0x00000000	/* DENALI_PHY_90_DATA */
+		0x00000000	/* DENALI_PHY_91_DATA */
+		0x00000000	/* DENALI_PHY_92_DATA */
+		0x00000000	/* DENALI_PHY_93_DATA */
+		0x00000000	/* DENALI_PHY_94_DATA */
+		0x00000000	/* DENALI_PHY_95_DATA */
+		0x00000000	/* DENALI_PHY_96_DATA */
+		0x00000000	/* DENALI_PHY_97_DATA */
+		0x00000000	/* DENALI_PHY_98_DATA */
+		0x00000000	/* DENALI_PHY_99_DATA */
+		0x00000000	/* DENALI_PHY_100_DATA */
+		0x00000000	/* DENALI_PHY_101_DATA */
+		0x00000000	/* DENALI_PHY_102_DATA */
+		0x00000000	/* DENALI_PHY_103_DATA */
+		0x00000000	/* DENALI_PHY_104_DATA */
+		0x00000000	/* DENALI_PHY_105_DATA */
+		0x00000000	/* DENALI_PHY_106_DATA */
+		0x00000000	/* DENALI_PHY_107_DATA */
+		0x00000000	/* DENALI_PHY_108_DATA */
+		0x00000000	/* DENALI_PHY_109_DATA */
+		0x00000000	/* DENALI_PHY_110_DATA */
+		0x00000000	/* DENALI_PHY_111_DATA */
+		0x00000000	/* DENALI_PHY_112_DATA */
+		0x00000000	/* DENALI_PHY_113_DATA */
+		0x00000000	/* DENALI_PHY_114_DATA */
+		0x00000000	/* DENALI_PHY_115_DATA */
+		0x00000000	/* DENALI_PHY_116_DATA */
+		0x00000000	/* DENALI_PHY_117_DATA */
+		0x00000000	/* DENALI_PHY_118_DATA */
+		0x00000000	/* DENALI_PHY_119_DATA */
+		0x00000000	/* DENALI_PHY_120_DATA */
+		0x00000000	/* DENALI_PHY_121_DATA */
+		0x00000000	/* DENALI_PHY_122_DATA */
+		0x00000000	/* DENALI_PHY_123_DATA */
+		0x00000000	/* DENALI_PHY_124_DATA */
+		0x00000000	/* DENALI_PHY_125_DATA */
+		0x00000000	/* DENALI_PHY_126_DATA */
+		0x00000000	/* DENALI_PHY_127_DATA */
+		0x40263571	/* DENALI_PHY_128_DATA */
+		0x0004c008	/* DENALI_PHY_129_DATA */
+		0x000000da	/* DENALI_PHY_130_DATA */
+		0x00000000	/* DENALI_PHY_131_DATA */
+		0x00000000	/* DENALI_PHY_132_DATA */
+		0x00010000	/* DENALI_PHY_133_DATA */
+		0x01DDDD90	/* DENALI_PHY_134_DATA */
+		0x01DDDD90	/* DENALI_PHY_135_DATA */
+		0x01030000	/* DENALI_PHY_136_DATA */
+		0x01000000	/* DENALI_PHY_137_DATA */
+		0x00c00000	/* DENALI_PHY_138_DATA */
+		0x00000007	/* DENALI_PHY_139_DATA */
+		0x00000000	/* DENALI_PHY_140_DATA */
+		0x00000000	/* DENALI_PHY_141_DATA */
+		0x04000408	/* DENALI_PHY_142_DATA */
+		0x00000408	/* DENALI_PHY_143_DATA */
+		0x00e4e400	/* DENALI_PHY_144_DATA */
+		0x00000000	/* DENALI_PHY_145_DATA */
+		0x00000000	/* DENALI_PHY_146_DATA */
+		0x00000000	/* DENALI_PHY_147_DATA */
+		0x00000000	/* DENALI_PHY_148_DATA */
+		0x00000000	/* DENALI_PHY_149_DATA */
+		0x00000000	/* DENALI_PHY_150_DATA */
+		0x00000000	/* DENALI_PHY_151_DATA */
+		0x00000000	/* DENALI_PHY_152_DATA */
+		0x00000000	/* DENALI_PHY_153_DATA */
+		0x00000000	/* DENALI_PHY_154_DATA */
+		0x00000000	/* DENALI_PHY_155_DATA */
+		0x00000000	/* DENALI_PHY_156_DATA */
+		0x00000000	/* DENALI_PHY_157_DATA */
+		0x00000000	/* DENALI_PHY_158_DATA */
+		0x00000000	/* DENALI_PHY_159_DATA */
+		0x00000000	/* DENALI_PHY_160_DATA */
+		0x00200000	/* DENALI_PHY_161_DATA */
+		0x00000000	/* DENALI_PHY_162_DATA */
+		0x00000000	/* DENALI_PHY_163_DATA */
+		0x00000000	/* DENALI_PHY_164_DATA */
+		0x00000000	/* DENALI_PHY_165_DATA */
+		0x00000000	/* DENALI_PHY_166_DATA */
+		0x00000000	/* DENALI_PHY_167_DATA */
+		0x02800280	/* DENALI_PHY_168_DATA */
+		0x02800280	/* DENALI_PHY_169_DATA */
+		0x02800280	/* DENALI_PHY_170_DATA */
+		0x02800280	/* DENALI_PHY_171_DATA */
+		0x00000280	/* DENALI_PHY_172_DATA */
+		0x00000000	/* DENALI_PHY_173_DATA */
+		0x00000000	/* DENALI_PHY_174_DATA */
+		0x00000000	/* DENALI_PHY_175_DATA */
+		0x00000000	/* DENALI_PHY_176_DATA */
+		0x00000000	/* DENALI_PHY_177_DATA */
+		0x00800080	/* DENALI_PHY_178_DATA */
+		0x00800080	/* DENALI_PHY_179_DATA */
+		0x00800080	/* DENALI_PHY_180_DATA */
+		0x00800080	/* DENALI_PHY_181_DATA */
+		0x00800080	/* DENALI_PHY_182_DATA */
+		0x00800080	/* DENALI_PHY_183_DATA */
+		0x00800080	/* DENALI_PHY_184_DATA */
+		0x00800080	/* DENALI_PHY_185_DATA */
+		0x00800080	/* DENALI_PHY_186_DATA */
+		0x000100da	/* DENALI_PHY_187_DATA */
+		0x01000200	/* DENALI_PHY_188_DATA */
+		0x00000000	/* DENALI_PHY_189_DATA */
+		0x00000000	/* DENALI_PHY_190_DATA */
+		0x00000002	/* DENALI_PHY_191_DATA */
+		0x51313152	/* DENALI_PHY_192_DATA */
+		0x80013130	/* DENALI_PHY_193_DATA */
+		0x02000080	/* DENALI_PHY_194_DATA */
+		0x00100001	/* DENALI_PHY_195_DATA */
+		0x0c064208	/* DENALI_PHY_196_DATA */
+		0x000f0c0f	/* DENALI_PHY_197_DATA */
+		0x01000140	/* DENALI_PHY_198_DATA */
+		0x0000000c	/* DENALI_PHY_199_DATA */
+		0x00000000	/* DENALI_PHY_200_DATA */
+		0x00000000	/* DENALI_PHY_201_DATA */
+		0x00000000	/* DENALI_PHY_202_DATA */
+		0x00000000	/* DENALI_PHY_203_DATA */
+		0x00000000	/* DENALI_PHY_204_DATA */
+		0x00000000	/* DENALI_PHY_205_DATA */
+		0x00000000	/* DENALI_PHY_206_DATA */
+		0x00000000	/* DENALI_PHY_207_DATA */
+		0x00000000	/* DENALI_PHY_208_DATA */
+		0x00000000	/* DENALI_PHY_209_DATA */
+		0x00000000	/* DENALI_PHY_210_DATA */
+		0x00000000	/* DENALI_PHY_211_DATA */
+		0x00000000	/* DENALI_PHY_212_DATA */
+		0x00000000	/* DENALI_PHY_213_DATA */
+		0x00000000	/* DENALI_PHY_214_DATA */
+		0x00000000	/* DENALI_PHY_215_DATA */
+		0x00000000	/* DENALI_PHY_216_DATA */
+		0x00000000	/* DENALI_PHY_217_DATA */
+		0x00000000	/* DENALI_PHY_218_DATA */
+		0x00000000	/* DENALI_PHY_219_DATA */
+		0x00000000	/* DENALI_PHY_220_DATA */
+		0x00000000	/* DENALI_PHY_221_DATA */
+		0x00000000	/* DENALI_PHY_222_DATA */
+		0x00000000	/* DENALI_PHY_223_DATA */
+		0x00000000	/* DENALI_PHY_224_DATA */
+		0x00000000	/* DENALI_PHY_225_DATA */
+		0x00000000	/* DENALI_PHY_226_DATA */
+		0x00000000	/* DENALI_PHY_227_DATA */
+		0x00000000	/* DENALI_PHY_228_DATA */
+		0x00000000	/* DENALI_PHY_229_DATA */
+		0x00000000	/* DENALI_PHY_230_DATA */
+		0x00000000	/* DENALI_PHY_231_DATA */
+		0x00000000	/* DENALI_PHY_232_DATA */
+		0x00000000	/* DENALI_PHY_233_DATA */
+		0x00000000	/* DENALI_PHY_234_DATA */
+		0x00000000	/* DENALI_PHY_235_DATA */
+		0x00000000	/* DENALI_PHY_236_DATA */
+		0x00000000	/* DENALI_PHY_237_DATA */
+		0x00000000	/* DENALI_PHY_238_DATA */
+		0x00000000	/* DENALI_PHY_239_DATA */
+		0x00000000	/* DENALI_PHY_240_DATA */
+		0x00000000	/* DENALI_PHY_241_DATA */
+		0x00000000	/* DENALI_PHY_242_DATA */
+		0x00000000	/* DENALI_PHY_243_DATA */
+		0x00000000	/* DENALI_PHY_244_DATA */
+		0x00000000	/* DENALI_PHY_245_DATA */
+		0x00000000	/* DENALI_PHY_246_DATA */
+		0x00000000	/* DENALI_PHY_247_DATA */
+		0x00000000	/* DENALI_PHY_248_DATA */
+		0x00000000	/* DENALI_PHY_249_DATA */
+		0x00000000	/* DENALI_PHY_250_DATA */
+		0x00000000	/* DENALI_PHY_251_DATA */
+		0x00000000	/* DENALI_PHY_252_DATA */
+		0x00000000	/* DENALI_PHY_253_DATA */
+		0x00000000	/* DENALI_PHY_254_DATA */
+		0x00000000	/* DENALI_PHY_255_DATA */
+		0x46052371	/* DENALI_PHY_256_DATA */
+		0x0004c008	/* DENALI_PHY_257_DATA */
+		0x000000da	/* DENALI_PHY_258_DATA */
+		0x00000000	/* DENALI_PHY_259_DATA */
+		0x00000000	/* DENALI_PHY_260_DATA */
+		0x00010000	/* DENALI_PHY_261_DATA */
+		0x01DDDD90	/* DENALI_PHY_262_DATA */
+		0x01DDDD90	/* DENALI_PHY_263_DATA */
+		0x01030000	/* DENALI_PHY_264_DATA */
+		0x01000000	/* DENALI_PHY_265_DATA */
+		0x00c00000	/* DENALI_PHY_266_DATA */
+		0x00000007	/* DENALI_PHY_267_DATA */
+		0x00000000	/* DENALI_PHY_268_DATA */
+		0x00000000	/* DENALI_PHY_269_DATA */
+		0x04000408	/* DENALI_PHY_270_DATA */
+		0x00000408	/* DENALI_PHY_271_DATA */
+		0x00e4e400	/* DENALI_PHY_272_DATA */
+		0x00000000	/* DENALI_PHY_273_DATA */
+		0x00000000	/* DENALI_PHY_274_DATA */
+		0x00000000	/* DENALI_PHY_275_DATA */
+		0x00000000	/* DENALI_PHY_276_DATA */
+		0x00000000	/* DENALI_PHY_277_DATA */
+		0x00000000	/* DENALI_PHY_278_DATA */
+		0x00000000	/* DENALI_PHY_279_DATA */
+		0x00000000	/* DENALI_PHY_280_DATA */
+		0x00000000	/* DENALI_PHY_281_DATA */
+		0x00000000	/* DENALI_PHY_282_DATA */
+		0x00000000	/* DENALI_PHY_283_DATA */
+		0x00000000	/* DENALI_PHY_284_DATA */
+		0x00000000	/* DENALI_PHY_285_DATA */
+		0x00000000	/* DENALI_PHY_286_DATA */
+		0x00000000	/* DENALI_PHY_287_DATA */
+		0x00000000	/* DENALI_PHY_288_DATA */
+		0x00200000	/* DENALI_PHY_289_DATA */
+		0x00000000	/* DENALI_PHY_290_DATA */
+		0x00000000	/* DENALI_PHY_291_DATA */
+		0x00000000	/* DENALI_PHY_292_DATA */
+		0x00000000	/* DENALI_PHY_293_DATA */
+		0x00000000	/* DENALI_PHY_294_DATA */
+		0x00000000	/* DENALI_PHY_295_DATA */
+		0x02800280	/* DENALI_PHY_296_DATA */
+		0x02800280	/* DENALI_PHY_297_DATA */
+		0x02800280	/* DENALI_PHY_298_DATA */
+		0x02800280	/* DENALI_PHY_299_DATA */
+		0x00000280	/* DENALI_PHY_300_DATA */
+		0x00000000	/* DENALI_PHY_301_DATA */
+		0x00000000	/* DENALI_PHY_302_DATA */
+		0x00000000	/* DENALI_PHY_303_DATA */
+		0x00000000	/* DENALI_PHY_304_DATA */
+		0x00000000	/* DENALI_PHY_305_DATA */
+		0x00800080	/* DENALI_PHY_306_DATA */
+		0x00800080	/* DENALI_PHY_307_DATA */
+		0x00800080	/* DENALI_PHY_308_DATA */
+		0x00800080	/* DENALI_PHY_309_DATA */
+		0x00800080	/* DENALI_PHY_310_DATA */
+		0x00800080	/* DENALI_PHY_311_DATA */
+		0x00800080	/* DENALI_PHY_312_DATA */
+		0x00800080	/* DENALI_PHY_313_DATA */
+		0x00800080	/* DENALI_PHY_314_DATA */
+		0x000100da	/* DENALI_PHY_315_DATA */
+		0x00000200	/* DENALI_PHY_316_DATA */
+		0x00000000	/* DENALI_PHY_317_DATA */
+		0x00000000	/* DENALI_PHY_318_DATA */
+		0x00000002	/* DENALI_PHY_319_DATA */
+		0x51313152	/* DENALI_PHY_320_DATA */
+		0x80013130	/* DENALI_PHY_321_DATA */
+		0x02000080	/* DENALI_PHY_322_DATA */
+		0x00100001	/* DENALI_PHY_323_DATA */
+		0x0c064208	/* DENALI_PHY_324_DATA */
+		0x000f0c0f	/* DENALI_PHY_325_DATA */
+		0x01000140	/* DENALI_PHY_326_DATA */
+		0x0000000c	/* DENALI_PHY_327_DATA */
+		0x00000000	/* DENALI_PHY_328_DATA */
+		0x00000000	/* DENALI_PHY_329_DATA */
+		0x00000000	/* DENALI_PHY_330_DATA */
+		0x00000000	/* DENALI_PHY_331_DATA */
+		0x00000000	/* DENALI_PHY_332_DATA */
+		0x00000000	/* DENALI_PHY_333_DATA */
+		0x00000000	/* DENALI_PHY_334_DATA */
+		0x00000000	/* DENALI_PHY_335_DATA */
+		0x00000000	/* DENALI_PHY_336_DATA */
+		0x00000000	/* DENALI_PHY_337_DATA */
+		0x00000000	/* DENALI_PHY_338_DATA */
+		0x00000000	/* DENALI_PHY_339_DATA */
+		0x00000000	/* DENALI_PHY_340_DATA */
+		0x00000000	/* DENALI_PHY_341_DATA */
+		0x00000000	/* DENALI_PHY_342_DATA */
+		0x00000000	/* DENALI_PHY_343_DATA */
+		0x00000000	/* DENALI_PHY_344_DATA */
+		0x00000000	/* DENALI_PHY_345_DATA */
+		0x00000000	/* DENALI_PHY_346_DATA */
+		0x00000000	/* DENALI_PHY_347_DATA */
+		0x00000000	/* DENALI_PHY_348_DATA */
+		0x00000000	/* DENALI_PHY_349_DATA */
+		0x00000000	/* DENALI_PHY_350_DATA */
+		0x00000000	/* DENALI_PHY_351_DATA */
+		0x00000000	/* DENALI_PHY_352_DATA */
+		0x00000000	/* DENALI_PHY_353_DATA */
+		0x00000000	/* DENALI_PHY_354_DATA */
+		0x00000000	/* DENALI_PHY_355_DATA */
+		0x00000000	/* DENALI_PHY_356_DATA */
+		0x00000000	/* DENALI_PHY_357_DATA */
+		0x00000000	/* DENALI_PHY_358_DATA */
+		0x00000000	/* DENALI_PHY_359_DATA */
+		0x00000000	/* DENALI_PHY_360_DATA */
+		0x00000000	/* DENALI_PHY_361_DATA */
+		0x00000000	/* DENALI_PHY_362_DATA */
+		0x00000000	/* DENALI_PHY_363_DATA */
+		0x00000000	/* DENALI_PHY_364_DATA */
+		0x00000000	/* DENALI_PHY_365_DATA */
+		0x00000000	/* DENALI_PHY_366_DATA */
+		0x00000000	/* DENALI_PHY_367_DATA */
+		0x00000000	/* DENALI_PHY_368_DATA */
+		0x00000000	/* DENALI_PHY_369_DATA */
+		0x00000000	/* DENALI_PHY_370_DATA */
+		0x00000000	/* DENALI_PHY_371_DATA */
+		0x00000000	/* DENALI_PHY_372_DATA */
+		0x00000000	/* DENALI_PHY_373_DATA */
+		0x00000000	/* DENALI_PHY_374_DATA */
+		0x00000000	/* DENALI_PHY_375_DATA */
+		0x00000000	/* DENALI_PHY_376_DATA */
+		0x00000000	/* DENALI_PHY_377_DATA */
+		0x00000000	/* DENALI_PHY_378_DATA */
+		0x00000000	/* DENALI_PHY_379_DATA */
+		0x00000000	/* DENALI_PHY_380_DATA */
+		0x00000000	/* DENALI_PHY_381_DATA */
+		0x00000000	/* DENALI_PHY_382_DATA */
+		0x00000000	/* DENALI_PHY_383_DATA */
+		0x37654120	/* DENALI_PHY_384_DATA */
+		0x0004c008	/* DENALI_PHY_385_DATA */
+		0x000000da	/* DENALI_PHY_386_DATA */
+		0x00000000	/* DENALI_PHY_387_DATA */
+		0x00000000	/* DENALI_PHY_388_DATA */
+		0x00010000	/* DENALI_PHY_389_DATA */
+		0x01DDDD90	/* DENALI_PHY_390_DATA */
+		0x01DDDD90	/* DENALI_PHY_391_DATA */
+		0x01030000	/* DENALI_PHY_392_DATA */
+		0x01000000	/* DENALI_PHY_393_DATA */
+		0x00c00000	/* DENALI_PHY_394_DATA */
+		0x00000007	/* DENALI_PHY_395_DATA */
+		0x00000000	/* DENALI_PHY_396_DATA */
+		0x00000000	/* DENALI_PHY_397_DATA */
+		0x04000408	/* DENALI_PHY_398_DATA */
+		0x00000408	/* DENALI_PHY_399_DATA */
+		0x00e4e400	/* DENALI_PHY_400_DATA */
+		0x00000000	/* DENALI_PHY_401_DATA */
+		0x00000000	/* DENALI_PHY_402_DATA */
+		0x00000000	/* DENALI_PHY_403_DATA */
+		0x00000000	/* DENALI_PHY_404_DATA */
+		0x00000000	/* DENALI_PHY_405_DATA */
+		0x00000000	/* DENALI_PHY_406_DATA */
+		0x00000000	/* DENALI_PHY_407_DATA */
+		0x00000000	/* DENALI_PHY_408_DATA */
+		0x00000000	/* DENALI_PHY_409_DATA */
+		0x00000000	/* DENALI_PHY_410_DATA */
+		0x00000000	/* DENALI_PHY_411_DATA */
+		0x00000000	/* DENALI_PHY_412_DATA */
+		0x00000000	/* DENALI_PHY_413_DATA */
+		0x00000000	/* DENALI_PHY_414_DATA */
+		0x00000000	/* DENALI_PHY_415_DATA */
+		0x00000000	/* DENALI_PHY_416_DATA */
+		0x00200000	/* DENALI_PHY_417_DATA */
+		0x00000000	/* DENALI_PHY_418_DATA */
+		0x00000000	/* DENALI_PHY_419_DATA */
+		0x00000000	/* DENALI_PHY_420_DATA */
+		0x00000000	/* DENALI_PHY_421_DATA */
+		0x00000000	/* DENALI_PHY_422_DATA */
+		0x00000000	/* DENALI_PHY_423_DATA */
+		0x02800280	/* DENALI_PHY_424_DATA */
+		0x02800280	/* DENALI_PHY_425_DATA */
+		0x02800280	/* DENALI_PHY_426_DATA */
+		0x02800280	/* DENALI_PHY_427_DATA */
+		0x00000280	/* DENALI_PHY_428_DATA */
+		0x00000000	/* DENALI_PHY_429_DATA */
+		0x00000000	/* DENALI_PHY_430_DATA */
+		0x00000000	/* DENALI_PHY_431_DATA */
+		0x00000000	/* DENALI_PHY_432_DATA */
+		0x00000000	/* DENALI_PHY_433_DATA */
+		0x00800080	/* DENALI_PHY_434_DATA */
+		0x00800080	/* DENALI_PHY_435_DATA */
+		0x00800080	/* DENALI_PHY_436_DATA */
+		0x00800080	/* DENALI_PHY_437_DATA */
+		0x00800080	/* DENALI_PHY_438_DATA */
+		0x00800080	/* DENALI_PHY_439_DATA */
+		0x00800080	/* DENALI_PHY_440_DATA */
+		0x00800080	/* DENALI_PHY_441_DATA */
+		0x00800080	/* DENALI_PHY_442_DATA */
+		0x000100da	/* DENALI_PHY_443_DATA */
+		0x00000200	/* DENALI_PHY_444_DATA */
+		0x00000000	/* DENALI_PHY_445_DATA */
+		0x00000000	/* DENALI_PHY_446_DATA */
+		0x00000002	/* DENALI_PHY_447_DATA */
+		0x51313152	/* DENALI_PHY_448_DATA */
+		0x80013130	/* DENALI_PHY_449_DATA */
+		0x02000080	/* DENALI_PHY_450_DATA */
+		0x00100001	/* DENALI_PHY_451_DATA */
+		0x0c064208	/* DENALI_PHY_452_DATA */
+		0x000f0c0f	/* DENALI_PHY_453_DATA */
+		0x01000140	/* DENALI_PHY_454_DATA */
+		0x0000000c	/* DENALI_PHY_455_DATA */
+		0x00000000	/* DENALI_PHY_456_DATA */
+		0x00000000	/* DENALI_PHY_457_DATA */
+		0x00000000	/* DENALI_PHY_458_DATA */
+		0x00000000	/* DENALI_PHY_459_DATA */
+		0x00000000	/* DENALI_PHY_460_DATA */
+		0x00000000	/* DENALI_PHY_461_DATA */
+		0x00000000	/* DENALI_PHY_462_DATA */
+		0x00000000	/* DENALI_PHY_463_DATA */
+		0x00000000	/* DENALI_PHY_464_DATA */
+		0x00000000	/* DENALI_PHY_465_DATA */
+		0x00000000	/* DENALI_PHY_466_DATA */
+		0x00000000	/* DENALI_PHY_467_DATA */
+		0x00000000	/* DENALI_PHY_468_DATA */
+		0x00000000	/* DENALI_PHY_469_DATA */
+		0x00000000	/* DENALI_PHY_470_DATA */
+		0x00000000	/* DENALI_PHY_471_DATA */
+		0x00000000	/* DENALI_PHY_472_DATA */
+		0x00000000	/* DENALI_PHY_473_DATA */
+		0x00000000	/* DENALI_PHY_474_DATA */
+		0x00000000	/* DENALI_PHY_475_DATA */
+		0x00000000	/* DENALI_PHY_476_DATA */
+		0x00000000	/* DENALI_PHY_477_DATA */
+		0x00000000	/* DENALI_PHY_478_DATA */
+		0x00000000	/* DENALI_PHY_479_DATA */
+		0x00000000	/* DENALI_PHY_480_DATA */
+		0x00000000	/* DENALI_PHY_481_DATA */
+		0x00000000	/* DENALI_PHY_482_DATA */
+		0x00000000	/* DENALI_PHY_483_DATA */
+		0x00000000	/* DENALI_PHY_484_DATA */
+		0x00000000	/* DENALI_PHY_485_DATA */
+		0x00000000	/* DENALI_PHY_486_DATA */
+		0x00000000	/* DENALI_PHY_487_DATA */
+		0x00000000	/* DENALI_PHY_488_DATA */
+		0x00000000	/* DENALI_PHY_489_DATA */
+		0x00000000	/* DENALI_PHY_490_DATA */
+		0x00000000	/* DENALI_PHY_491_DATA */
+		0x00000000	/* DENALI_PHY_492_DATA */
+		0x00000000	/* DENALI_PHY_493_DATA */
+		0x00000000	/* DENALI_PHY_494_DATA */
+		0x00000000	/* DENALI_PHY_495_DATA */
+		0x00000000	/* DENALI_PHY_496_DATA */
+		0x00000000	/* DENALI_PHY_497_DATA */
+		0x00000000	/* DENALI_PHY_498_DATA */
+		0x00000000	/* DENALI_PHY_499_DATA */
+		0x00000000	/* DENALI_PHY_500_DATA */
+		0x00000000	/* DENALI_PHY_501_DATA */
+		0x00000000	/* DENALI_PHY_502_DATA */
+		0x00000000	/* DENALI_PHY_503_DATA */
+		0x00000000	/* DENALI_PHY_504_DATA */
+		0x00000000	/* DENALI_PHY_505_DATA */
+		0x00000000	/* DENALI_PHY_506_DATA */
+		0x00000000	/* DENALI_PHY_507_DATA */
+		0x00000000	/* DENALI_PHY_508_DATA */
+		0x00000000	/* DENALI_PHY_509_DATA */
+		0x00000000	/* DENALI_PHY_510_DATA */
+		0x00000000	/* DENALI_PHY_511_DATA */
+		0x24316750	/* DENALI_PHY_512_DATA */
+		0x0004c008	/* DENALI_PHY_513_DATA */
+		0x000000da	/* DENALI_PHY_514_DATA */
+		0x00000000	/* DENALI_PHY_515_DATA */
+		0x00000000	/* DENALI_PHY_516_DATA */
+		0x00010000	/* DENALI_PHY_517_DATA */
+		0x01DDDD90	/* DENALI_PHY_518_DATA */
+		0x01DDDD90	/* DENALI_PHY_519_DATA */
+		0x01030000	/* DENALI_PHY_520_DATA */
+		0x01000000	/* DENALI_PHY_521_DATA */
+		0x00c00000	/* DENALI_PHY_522_DATA */
+		0x00000007	/* DENALI_PHY_523_DATA */
+		0x00000000	/* DENALI_PHY_524_DATA */
+		0x00000000	/* DENALI_PHY_525_DATA */
+		0x04000408	/* DENALI_PHY_526_DATA */
+		0x00000408	/* DENALI_PHY_527_DATA */
+		0x00e4e400	/* DENALI_PHY_528_DATA */
+		0x00000000	/* DENALI_PHY_529_DATA */
+		0x00000000	/* DENALI_PHY_530_DATA */
+		0x00000000	/* DENALI_PHY_531_DATA */
+		0x00000000	/* DENALI_PHY_532_DATA */
+		0x00000000	/* DENALI_PHY_533_DATA */
+		0x00000000	/* DENALI_PHY_534_DATA */
+		0x00000000	/* DENALI_PHY_535_DATA */
+		0x00000000	/* DENALI_PHY_536_DATA */
+		0x00000000	/* DENALI_PHY_537_DATA */
+		0x00000000	/* DENALI_PHY_538_DATA */
+		0x00000000	/* DENALI_PHY_539_DATA */
+		0x00000000	/* DENALI_PHY_540_DATA */
+		0x00000000	/* DENALI_PHY_541_DATA */
+		0x00000000	/* DENALI_PHY_542_DATA */
+		0x00000000	/* DENALI_PHY_543_DATA */
+		0x00000000	/* DENALI_PHY_544_DATA */
+		0x00200000	/* DENALI_PHY_545_DATA */
+		0x00000000	/* DENALI_PHY_546_DATA */
+		0x00000000	/* DENALI_PHY_547_DATA */
+		0x00000000	/* DENALI_PHY_548_DATA */
+		0x00000000	/* DENALI_PHY_549_DATA */
+		0x00000000	/* DENALI_PHY_550_DATA */
+		0x00000000	/* DENALI_PHY_551_DATA */
+		0x02800280	/* DENALI_PHY_552_DATA */
+		0x02800280	/* DENALI_PHY_553_DATA */
+		0x02800280	/* DENALI_PHY_554_DATA */
+		0x02800280	/* DENALI_PHY_555_DATA */
+		0x00000280	/* DENALI_PHY_556_DATA */
+		0x00000000	/* DENALI_PHY_557_DATA */
+		0x00000000	/* DENALI_PHY_558_DATA */
+		0x00000000	/* DENALI_PHY_559_DATA */
+		0x00000000	/* DENALI_PHY_560_DATA */
+		0x00000000	/* DENALI_PHY_561_DATA */
+		0x00800080	/* DENALI_PHY_562_DATA */
+		0x00800080	/* DENALI_PHY_563_DATA */
+		0x00800080	/* DENALI_PHY_564_DATA */
+		0x00800080	/* DENALI_PHY_565_DATA */
+		0x00800080	/* DENALI_PHY_566_DATA */
+		0x00800080	/* DENALI_PHY_567_DATA */
+		0x00800080	/* DENALI_PHY_568_DATA */
+		0x00800080	/* DENALI_PHY_569_DATA */
+		0x00800080	/* DENALI_PHY_570_DATA */
+		0x000100da	/* DENALI_PHY_571_DATA */
+		0x00000200	/* DENALI_PHY_572_DATA */
+		0x00000000	/* DENALI_PHY_573_DATA */
+		0x00000000	/* DENALI_PHY_574_DATA */
+		0x00000002	/* DENALI_PHY_575_DATA */
+		0x51313152	/* DENALI_PHY_576_DATA */
+		0x80013130	/* DENALI_PHY_577_DATA */
+		0x02000080	/* DENALI_PHY_578_DATA */
+		0x00100001	/* DENALI_PHY_579_DATA */
+		0x0c064208	/* DENALI_PHY_580_DATA */
+		0x000f0c0f	/* DENALI_PHY_581_DATA */
+		0x01000140	/* DENALI_PHY_582_DATA */
+		0x0000000c	/* DENALI_PHY_583_DATA */
+		0x00000000	/* DENALI_PHY_584_DATA */
+		0x00000000	/* DENALI_PHY_585_DATA */
+		0x00000000	/* DENALI_PHY_586_DATA */
+		0x00000000	/* DENALI_PHY_587_DATA */
+		0x00000000	/* DENALI_PHY_588_DATA */
+		0x00000000	/* DENALI_PHY_589_DATA */
+		0x00000000	/* DENALI_PHY_590_DATA */
+		0x00000000	/* DENALI_PHY_591_DATA */
+		0x00000000	/* DENALI_PHY_592_DATA */
+		0x00000000	/* DENALI_PHY_593_DATA */
+		0x00000000	/* DENALI_PHY_594_DATA */
+		0x00000000	/* DENALI_PHY_595_DATA */
+		0x00000000	/* DENALI_PHY_596_DATA */
+		0x00000000	/* DENALI_PHY_597_DATA */
+		0x00000000	/* DENALI_PHY_598_DATA */
+		0x00000000	/* DENALI_PHY_599_DATA */
+		0x00000000	/* DENALI_PHY_600_DATA */
+		0x00000000	/* DENALI_PHY_601_DATA */
+		0x00000000	/* DENALI_PHY_602_DATA */
+		0x00000000	/* DENALI_PHY_603_DATA */
+		0x00000000	/* DENALI_PHY_604_DATA */
+		0x00000000	/* DENALI_PHY_605_DATA */
+		0x00000000	/* DENALI_PHY_606_DATA */
+		0x00000000	/* DENALI_PHY_607_DATA */
+		0x00000000	/* DENALI_PHY_608_DATA */
+		0x00000000	/* DENALI_PHY_609_DATA */
+		0x00000000	/* DENALI_PHY_610_DATA */
+		0x00000000	/* DENALI_PHY_611_DATA */
+		0x00000000	/* DENALI_PHY_612_DATA */
+		0x00000000	/* DENALI_PHY_613_DATA */
+		0x00000000	/* DENALI_PHY_614_DATA */
+		0x00000000	/* DENALI_PHY_615_DATA */
+		0x00000000	/* DENALI_PHY_616_DATA */
+		0x00000000	/* DENALI_PHY_617_DATA */
+		0x00000000	/* DENALI_PHY_618_DATA */
+		0x00000000	/* DENALI_PHY_619_DATA */
+		0x00000000	/* DENALI_PHY_620_DATA */
+		0x00000000	/* DENALI_PHY_621_DATA */
+		0x00000000	/* DENALI_PHY_622_DATA */
+		0x00000000	/* DENALI_PHY_623_DATA */
+		0x00000000	/* DENALI_PHY_624_DATA */
+		0x00000000	/* DENALI_PHY_625_DATA */
+		0x00000000	/* DENALI_PHY_626_DATA */
+		0x00000000	/* DENALI_PHY_627_DATA */
+		0x00000000	/* DENALI_PHY_628_DATA */
+		0x00000000	/* DENALI_PHY_629_DATA */
+		0x00000000	/* DENALI_PHY_630_DATA */
+		0x00000000	/* DENALI_PHY_631_DATA */
+		0x00000000	/* DENALI_PHY_632_DATA */
+		0x00000000	/* DENALI_PHY_633_DATA */
+		0x00000000	/* DENALI_PHY_634_DATA */
+		0x00000000	/* DENALI_PHY_635_DATA */
+		0x00000000	/* DENALI_PHY_636_DATA */
+		0x00000000	/* DENALI_PHY_637_DATA */
+		0x00000000	/* DENALI_PHY_638_DATA */
+		0x00000000	/* DENALI_PHY_639_DATA */
+		0x35174620	/* DENALI_PHY_640_DATA */
+		0x0004c008	/* DENALI_PHY_641_DATA */
+		0x000000da	/* DENALI_PHY_642_DATA */
+		0x00000000	/* DENALI_PHY_643_DATA */
+		0x00000000	/* DENALI_PHY_644_DATA */
+		0x00010000	/* DENALI_PHY_645_DATA */
+		0x01DDDD90	/* DENALI_PHY_646_DATA */
+		0x01DDDD90	/* DENALI_PHY_647_DATA */
+		0x01030000	/* DENALI_PHY_648_DATA */
+		0x01000000	/* DENALI_PHY_649_DATA */
+		0x00c00000	/* DENALI_PHY_650_DATA */
+		0x00000007	/* DENALI_PHY_651_DATA */
+		0x00000000	/* DENALI_PHY_652_DATA */
+		0x00000000	/* DENALI_PHY_653_DATA */
+		0x04000408	/* DENALI_PHY_654_DATA */
+		0x00000408	/* DENALI_PHY_655_DATA */
+		0x00e4e400	/* DENALI_PHY_656_DATA */
+		0x00000000	/* DENALI_PHY_657_DATA */
+		0x00000000	/* DENALI_PHY_658_DATA */
+		0x00000000	/* DENALI_PHY_659_DATA */
+		0x00000000	/* DENALI_PHY_660_DATA */
+		0x00000000	/* DENALI_PHY_661_DATA */
+		0x00000000	/* DENALI_PHY_662_DATA */
+		0x00000000	/* DENALI_PHY_663_DATA */
+		0x00000000	/* DENALI_PHY_664_DATA */
+		0x00000000	/* DENALI_PHY_665_DATA */
+		0x00000000	/* DENALI_PHY_666_DATA */
+		0x00000000	/* DENALI_PHY_667_DATA */
+		0x00000000	/* DENALI_PHY_668_DATA */
+		0x00000000	/* DENALI_PHY_669_DATA */
+		0x00000000	/* DENALI_PHY_670_DATA */
+		0x00000000	/* DENALI_PHY_671_DATA */
+		0x00000000	/* DENALI_PHY_672_DATA */
+		0x00200000	/* DENALI_PHY_673_DATA */
+		0x00000000	/* DENALI_PHY_674_DATA */
+		0x00000000	/* DENALI_PHY_675_DATA */
+		0x00000000	/* DENALI_PHY_676_DATA */
+		0x00000000	/* DENALI_PHY_677_DATA */
+		0x00000000	/* DENALI_PHY_678_DATA */
+		0x00000000	/* DENALI_PHY_679_DATA */
+		0x02800280	/* DENALI_PHY_680_DATA */
+		0x02800280	/* DENALI_PHY_681_DATA */
+		0x02800280	/* DENALI_PHY_682_DATA */
+		0x02800280	/* DENALI_PHY_683_DATA */
+		0x00000280	/* DENALI_PHY_684_DATA */
+		0x00000000	/* DENALI_PHY_685_DATA */
+		0x00000000	/* DENALI_PHY_686_DATA */
+		0x00000000	/* DENALI_PHY_687_DATA */
+		0x00000000	/* DENALI_PHY_688_DATA */
+		0x00000000	/* DENALI_PHY_689_DATA */
+		0x00800080	/* DENALI_PHY_690_DATA */
+		0x00800080	/* DENALI_PHY_691_DATA */
+		0x00800080	/* DENALI_PHY_692_DATA */
+		0x00800080	/* DENALI_PHY_693_DATA */
+		0x00800080	/* DENALI_PHY_694_DATA */
+		0x00800080	/* DENALI_PHY_695_DATA */
+		0x00800080	/* DENALI_PHY_696_DATA */
+		0x00800080	/* DENALI_PHY_697_DATA */
+		0x00800080	/* DENALI_PHY_698_DATA */
+		0x000100da	/* DENALI_PHY_699_DATA */
+		0x00000200	/* DENALI_PHY_700_DATA */
+		0x00000000	/* DENALI_PHY_701_DATA */
+		0x00000000	/* DENALI_PHY_702_DATA */
+		0x00000002	/* DENALI_PHY_703_DATA */
+		0x51313152	/* DENALI_PHY_704_DATA */
+		0x80013130	/* DENALI_PHY_705_DATA */
+		0x02000080	/* DENALI_PHY_706_DATA */
+		0x00100001	/* DENALI_PHY_707_DATA */
+		0x0c064208	/* DENALI_PHY_708_DATA */
+		0x000f0c0f	/* DENALI_PHY_709_DATA */
+		0x01000140	/* DENALI_PHY_710_DATA */
+		0x0000000c	/* DENALI_PHY_711_DATA */
+		0x00000000	/* DENALI_PHY_712_DATA */
+		0x00000000	/* DENALI_PHY_713_DATA */
+		0x00000000	/* DENALI_PHY_714_DATA */
+		0x00000000	/* DENALI_PHY_715_DATA */
+		0x00000000	/* DENALI_PHY_716_DATA */
+		0x00000000	/* DENALI_PHY_717_DATA */
+		0x00000000	/* DENALI_PHY_718_DATA */
+		0x00000000	/* DENALI_PHY_719_DATA */
+		0x00000000	/* DENALI_PHY_720_DATA */
+		0x00000000	/* DENALI_PHY_721_DATA */
+		0x00000000	/* DENALI_PHY_722_DATA */
+		0x00000000	/* DENALI_PHY_723_DATA */
+		0x00000000	/* DENALI_PHY_724_DATA */
+		0x00000000	/* DENALI_PHY_725_DATA */
+		0x00000000	/* DENALI_PHY_726_DATA */
+		0x00000000	/* DENALI_PHY_727_DATA */
+		0x00000000	/* DENALI_PHY_728_DATA */
+		0x00000000	/* DENALI_PHY_729_DATA */
+		0x00000000	/* DENALI_PHY_730_DATA */
+		0x00000000	/* DENALI_PHY_731_DATA */
+		0x00000000	/* DENALI_PHY_732_DATA */
+		0x00000000	/* DENALI_PHY_733_DATA */
+		0x00000000	/* DENALI_PHY_734_DATA */
+		0x00000000	/* DENALI_PHY_735_DATA */
+		0x00000000	/* DENALI_PHY_736_DATA */
+		0x00000000	/* DENALI_PHY_737_DATA */
+		0x00000000	/* DENALI_PHY_738_DATA */
+		0x00000000	/* DENALI_PHY_739_DATA */
+		0x00000000	/* DENALI_PHY_740_DATA */
+		0x00000000	/* DENALI_PHY_741_DATA */
+		0x00000000	/* DENALI_PHY_742_DATA */
+		0x00000000	/* DENALI_PHY_743_DATA */
+		0x00000000	/* DENALI_PHY_744_DATA */
+		0x00000000	/* DENALI_PHY_745_DATA */
+		0x00000000	/* DENALI_PHY_746_DATA */
+		0x00000000	/* DENALI_PHY_747_DATA */
+		0x00000000	/* DENALI_PHY_748_DATA */
+		0x00000000	/* DENALI_PHY_749_DATA */
+		0x00000000	/* DENALI_PHY_750_DATA */
+		0x00000000	/* DENALI_PHY_751_DATA */
+		0x00000000	/* DENALI_PHY_752_DATA */
+		0x00000000	/* DENALI_PHY_753_DATA */
+		0x00000000	/* DENALI_PHY_754_DATA */
+		0x00000000	/* DENALI_PHY_755_DATA */
+		0x00000000	/* DENALI_PHY_756_DATA */
+		0x00000000	/* DENALI_PHY_757_DATA */
+		0x00000000	/* DENALI_PHY_758_DATA */
+		0x00000000	/* DENALI_PHY_759_DATA */
+		0x00000000	/* DENALI_PHY_760_DATA */
+		0x00000000	/* DENALI_PHY_761_DATA */
+		0x00000000	/* DENALI_PHY_762_DATA */
+		0x00000000	/* DENALI_PHY_763_DATA */
+		0x00000000	/* DENALI_PHY_764_DATA */
+		0x00000000	/* DENALI_PHY_765_DATA */
+		0x00000000	/* DENALI_PHY_766_DATA */
+		0x00000000	/* DENALI_PHY_767_DATA */
+		0x15203476	/* DENALI_PHY_768_DATA */
+		0x0004c008	/* DENALI_PHY_769_DATA */
+		0x000000da	/* DENALI_PHY_770_DATA */
+		0x00000000	/* DENALI_PHY_771_DATA */
+		0x00000000	/* DENALI_PHY_772_DATA */
+		0x00010000	/* DENALI_PHY_773_DATA */
+		0x01DDDD90	/* DENALI_PHY_774_DATA */
+		0x01DDDD90	/* DENALI_PHY_775_DATA */
+		0x01030000	/* DENALI_PHY_776_DATA */
+		0x01000000	/* DENALI_PHY_777_DATA */
+		0x00c00000	/* DENALI_PHY_778_DATA */
+		0x00000007	/* DENALI_PHY_779_DATA */
+		0x00000000	/* DENALI_PHY_780_DATA */
+		0x00000000	/* DENALI_PHY_781_DATA */
+		0x04000408	/* DENALI_PHY_782_DATA */
+		0x00000408	/* DENALI_PHY_783_DATA */
+		0x00e4e400	/* DENALI_PHY_784_DATA */
+		0x00000000	/* DENALI_PHY_785_DATA */
+		0x00000000	/* DENALI_PHY_786_DATA */
+		0x00000000	/* DENALI_PHY_787_DATA */
+		0x00000000	/* DENALI_PHY_788_DATA */
+		0x00000000	/* DENALI_PHY_789_DATA */
+		0x00000000	/* DENALI_PHY_790_DATA */
+		0x00000000	/* DENALI_PHY_791_DATA */
+		0x00000000	/* DENALI_PHY_792_DATA */
+		0x00000000	/* DENALI_PHY_793_DATA */
+		0x00000000	/* DENALI_PHY_794_DATA */
+		0x00000000	/* DENALI_PHY_795_DATA */
+		0x00000000	/* DENALI_PHY_796_DATA */
+		0x00000000	/* DENALI_PHY_797_DATA */
+		0x00000000	/* DENALI_PHY_798_DATA */
+		0x00000000	/* DENALI_PHY_799_DATA */
+		0x00000000	/* DENALI_PHY_800_DATA */
+		0x00200000	/* DENALI_PHY_801_DATA */
+		0x00000000	/* DENALI_PHY_802_DATA */
+		0x00000000	/* DENALI_PHY_803_DATA */
+		0x00000000	/* DENALI_PHY_804_DATA */
+		0x00000000	/* DENALI_PHY_805_DATA */
+		0x00000000	/* DENALI_PHY_806_DATA */
+		0x00000000	/* DENALI_PHY_807_DATA */
+		0x02800280	/* DENALI_PHY_808_DATA */
+		0x02800280	/* DENALI_PHY_809_DATA */
+		0x02800280	/* DENALI_PHY_810_DATA */
+		0x02800280	/* DENALI_PHY_811_DATA */
+		0x00000280	/* DENALI_PHY_812_DATA */
+		0x00000000	/* DENALI_PHY_813_DATA */
+		0x00000000	/* DENALI_PHY_814_DATA */
+		0x00000000	/* DENALI_PHY_815_DATA */
+		0x00000000	/* DENALI_PHY_816_DATA */
+		0x00000000	/* DENALI_PHY_817_DATA */
+		0x00800080	/* DENALI_PHY_818_DATA */
+		0x00800080	/* DENALI_PHY_819_DATA */
+		0x00800080	/* DENALI_PHY_820_DATA */
+		0x00800080	/* DENALI_PHY_821_DATA */
+		0x00800080	/* DENALI_PHY_822_DATA */
+		0x00800080	/* DENALI_PHY_823_DATA */
+		0x00800080	/* DENALI_PHY_824_DATA */
+		0x00800080	/* DENALI_PHY_825_DATA */
+		0x00800080	/* DENALI_PHY_826_DATA */
+		0x000100da	/* DENALI_PHY_827_DATA */
+		0x00000200	/* DENALI_PHY_828_DATA */
+		0x00000000	/* DENALI_PHY_829_DATA */
+		0x00000000	/* DENALI_PHY_830_DATA */
+		0x00000002	/* DENALI_PHY_831_DATA */
+		0x51313152	/* DENALI_PHY_832_DATA */
+		0x80013130	/* DENALI_PHY_833_DATA */
+		0x02000080	/* DENALI_PHY_834_DATA */
+		0x00100001	/* DENALI_PHY_835_DATA */
+		0x0c064208	/* DENALI_PHY_836_DATA */
+		0x000f0c0f	/* DENALI_PHY_837_DATA */
+		0x01000140	/* DENALI_PHY_838_DATA */
+		0x0000000c	/* DENALI_PHY_839_DATA */
+		0x00000000	/* DENALI_PHY_840_DATA */
+		0x00000000	/* DENALI_PHY_841_DATA */
+		0x00000000	/* DENALI_PHY_842_DATA */
+		0x00000000	/* DENALI_PHY_843_DATA */
+		0x00000000	/* DENALI_PHY_844_DATA */
+		0x00000000	/* DENALI_PHY_845_DATA */
+		0x00000000	/* DENALI_PHY_846_DATA */
+		0x00000000	/* DENALI_PHY_847_DATA */
+		0x00000000	/* DENALI_PHY_848_DATA */
+		0x00000000	/* DENALI_PHY_849_DATA */
+		0x00000000	/* DENALI_PHY_850_DATA */
+		0x00000000	/* DENALI_PHY_851_DATA */
+		0x00000000	/* DENALI_PHY_852_DATA */
+		0x00000000	/* DENALI_PHY_853_DATA */
+		0x00000000	/* DENALI_PHY_854_DATA */
+		0x00000000	/* DENALI_PHY_855_DATA */
+		0x00000000	/* DENALI_PHY_856_DATA */
+		0x00000000	/* DENALI_PHY_857_DATA */
+		0x00000000	/* DENALI_PHY_858_DATA */
+		0x00000000	/* DENALI_PHY_859_DATA */
+		0x00000000	/* DENALI_PHY_860_DATA */
+		0x00000000	/* DENALI_PHY_861_DATA */
+		0x00000000	/* DENALI_PHY_862_DATA */
+		0x00000000	/* DENALI_PHY_863_DATA */
+		0x00000000	/* DENALI_PHY_864_DATA */
+		0x00000000	/* DENALI_PHY_865_DATA */
+		0x00000000	/* DENALI_PHY_866_DATA */
+		0x00000000	/* DENALI_PHY_867_DATA */
+		0x00000000	/* DENALI_PHY_868_DATA */
+		0x00000000	/* DENALI_PHY_869_DATA */
+		0x00000000	/* DENALI_PHY_870_DATA */
+		0x00000000	/* DENALI_PHY_871_DATA */
+		0x00000000	/* DENALI_PHY_872_DATA */
+		0x00000000	/* DENALI_PHY_873_DATA */
+		0x00000000	/* DENALI_PHY_874_DATA */
+		0x00000000	/* DENALI_PHY_875_DATA */
+		0x00000000	/* DENALI_PHY_876_DATA */
+		0x00000000	/* DENALI_PHY_877_DATA */
+		0x00000000	/* DENALI_PHY_878_DATA */
+		0x00000000	/* DENALI_PHY_879_DATA */
+		0x00000000	/* DENALI_PHY_880_DATA */
+		0x00000000	/* DENALI_PHY_881_DATA */
+		0x00000000	/* DENALI_PHY_882_DATA */
+		0x00000000	/* DENALI_PHY_883_DATA */
+		0x00000000	/* DENALI_PHY_884_DATA */
+		0x00000000	/* DENALI_PHY_885_DATA */
+		0x00000000	/* DENALI_PHY_886_DATA */
+		0x00000000	/* DENALI_PHY_887_DATA */
+		0x00000000	/* DENALI_PHY_888_DATA */
+		0x00000000	/* DENALI_PHY_889_DATA */
+		0x00000000	/* DENALI_PHY_890_DATA */
+		0x00000000	/* DENALI_PHY_891_DATA */
+		0x00000000	/* DENALI_PHY_892_DATA */
+		0x00000000	/* DENALI_PHY_893_DATA */
+		0x00000000	/* DENALI_PHY_894_DATA */
+		0x00000000	/* DENALI_PHY_895_DATA */
+		0x41753206	/* DENALI_PHY_896_DATA */
+		0x0004c008	/* DENALI_PHY_897_DATA */
+		0x000000da	/* DENALI_PHY_898_DATA */
+		0x00000000	/* DENALI_PHY_899_DATA */
+		0x00000000	/* DENALI_PHY_900_DATA */
+		0x00010000	/* DENALI_PHY_901_DATA */
+		0x01DDDD90	/* DENALI_PHY_902_DATA */
+		0x01DDDD90	/* DENALI_PHY_903_DATA */
+		0x01030000	/* DENALI_PHY_904_DATA */
+		0x01000000	/* DENALI_PHY_905_DATA */
+		0x00c00000	/* DENALI_PHY_906_DATA */
+		0x00000007	/* DENALI_PHY_907_DATA */
+		0x00000000	/* DENALI_PHY_908_DATA */
+		0x00000000	/* DENALI_PHY_909_DATA */
+		0x04000408	/* DENALI_PHY_910_DATA */
+		0x00000408	/* DENALI_PHY_911_DATA */
+		0x00e4e400	/* DENALI_PHY_912_DATA */
+		0x00000000	/* DENALI_PHY_913_DATA */
+		0x00000000	/* DENALI_PHY_914_DATA */
+		0x00000000	/* DENALI_PHY_915_DATA */
+		0x00000000	/* DENALI_PHY_916_DATA */
+		0x00000000	/* DENALI_PHY_917_DATA */
+		0x00000000	/* DENALI_PHY_918_DATA */
+		0x00000000	/* DENALI_PHY_919_DATA */
+		0x00000000	/* DENALI_PHY_920_DATA */
+		0x00000000	/* DENALI_PHY_921_DATA */
+		0x00000000	/* DENALI_PHY_922_DATA */
+		0x00000000	/* DENALI_PHY_923_DATA */
+		0x00000000	/* DENALI_PHY_924_DATA */
+		0x00000000	/* DENALI_PHY_925_DATA */
+		0x00000000	/* DENALI_PHY_926_DATA */
+		0x00000000	/* DENALI_PHY_927_DATA */
+		0x00000000	/* DENALI_PHY_928_DATA */
+		0x00200000	/* DENALI_PHY_929_DATA */
+		0x00000000	/* DENALI_PHY_930_DATA */
+		0x00000000	/* DENALI_PHY_931_DATA */
+		0x00000000	/* DENALI_PHY_932_DATA */
+		0x00000000	/* DENALI_PHY_933_DATA */
+		0x00000000	/* DENALI_PHY_934_DATA */
+		0x00000000	/* DENALI_PHY_935_DATA */
+		0x02800280	/* DENALI_PHY_936_DATA */
+		0x02800280	/* DENALI_PHY_937_DATA */
+		0x02800280	/* DENALI_PHY_938_DATA */
+		0x02800280	/* DENALI_PHY_939_DATA */
+		0x00000280	/* DENALI_PHY_940_DATA */
+		0x00000000	/* DENALI_PHY_941_DATA */
+		0x00000000	/* DENALI_PHY_942_DATA */
+		0x00000000	/* DENALI_PHY_943_DATA */
+		0x00000000	/* DENALI_PHY_944_DATA */
+		0x00000000	/* DENALI_PHY_945_DATA */
+		0x00800080	/* DENALI_PHY_946_DATA */
+		0x00800080	/* DENALI_PHY_947_DATA */
+		0x00800080	/* DENALI_PHY_948_DATA */
+		0x00800080	/* DENALI_PHY_949_DATA */
+		0x00800080	/* DENALI_PHY_950_DATA */
+		0x00800080	/* DENALI_PHY_951_DATA */
+		0x00800080	/* DENALI_PHY_952_DATA */
+		0x00800080	/* DENALI_PHY_953_DATA */
+		0x00800080	/* DENALI_PHY_954_DATA */
+		0x000100da	/* DENALI_PHY_955_DATA */
+		0x00000200	/* DENALI_PHY_956_DATA */
+		0x00000000	/* DENALI_PHY_957_DATA */
+		0x00000000	/* DENALI_PHY_958_DATA */
+		0x00000002	/* DENALI_PHY_959_DATA */
+		0x51313152	/* DENALI_PHY_960_DATA */
+		0x80013130	/* DENALI_PHY_961_DATA */
+		0x02000080	/* DENALI_PHY_962_DATA */
+		0x00100001	/* DENALI_PHY_963_DATA */
+		0x0c064208	/* DENALI_PHY_964_DATA */
+		0x000f0c0f	/* DENALI_PHY_965_DATA */
+		0x01000140	/* DENALI_PHY_966_DATA */
+		0x0000000c	/* DENALI_PHY_967_DATA */
+		0x00000000	/* DENALI_PHY_968_DATA */
+		0x00000000	/* DENALI_PHY_969_DATA */
+		0x00000000	/* DENALI_PHY_970_DATA */
+		0x00000000	/* DENALI_PHY_971_DATA */
+		0x00000000	/* DENALI_PHY_972_DATA */
+		0x00000000	/* DENALI_PHY_973_DATA */
+		0x00000000	/* DENALI_PHY_974_DATA */
+		0x00000000	/* DENALI_PHY_975_DATA */
+		0x00000000	/* DENALI_PHY_976_DATA */
+		0x00000000	/* DENALI_PHY_977_DATA */
+		0x00000000	/* DENALI_PHY_978_DATA */
+		0x00000000	/* DENALI_PHY_979_DATA */
+		0x00000000	/* DENALI_PHY_980_DATA */
+		0x00000000	/* DENALI_PHY_981_DATA */
+		0x00000000	/* DENALI_PHY_982_DATA */
+		0x00000000	/* DENALI_PHY_983_DATA */
+		0x00000000	/* DENALI_PHY_984_DATA */
+		0x00000000	/* DENALI_PHY_985_DATA */
+		0x00000000	/* DENALI_PHY_986_DATA */
+		0x00000000	/* DENALI_PHY_987_DATA */
+		0x00000000	/* DENALI_PHY_988_DATA */
+		0x00000000	/* DENALI_PHY_989_DATA */
+		0x00000000	/* DENALI_PHY_990_DATA */
+		0x00000000	/* DENALI_PHY_991_DATA */
+		0x00000000	/* DENALI_PHY_992_DATA */
+		0x00000000	/* DENALI_PHY_993_DATA */
+		0x00000000	/* DENALI_PHY_994_DATA */
+		0x00000000	/* DENALI_PHY_995_DATA */
+		0x00000000	/* DENALI_PHY_996_DATA */
+		0x00000000	/* DENALI_PHY_997_DATA */
+		0x00000000	/* DENALI_PHY_998_DATA */
+		0x00000000	/* DENALI_PHY_999_DATA */
+		0x00000000	/* DENALI_PHY_1000_DATA */
+		0x00000000	/* DENALI_PHY_1001_DATA */
+		0x00000000	/* DENALI_PHY_1002_DATA */
+		0x00000000	/* DENALI_PHY_1003_DATA */
+		0x00000000	/* DENALI_PHY_1004_DATA */
+		0x00000000	/* DENALI_PHY_1005_DATA */
+		0x00000000	/* DENALI_PHY_1006_DATA */
+		0x00000000	/* DENALI_PHY_1007_DATA */
+		0x00000000	/* DENALI_PHY_1008_DATA */
+		0x00000000	/* DENALI_PHY_1009_DATA */
+		0x00000000	/* DENALI_PHY_1010_DATA */
+		0x00000000	/* DENALI_PHY_1011_DATA */
+		0x00000000	/* DENALI_PHY_1012_DATA */
+		0x00000000	/* DENALI_PHY_1013_DATA */
+		0x00000000	/* DENALI_PHY_1014_DATA */
+		0x00000000	/* DENALI_PHY_1015_DATA */
+		0x00000000	/* DENALI_PHY_1016_DATA */
+		0x00000000	/* DENALI_PHY_1017_DATA */
+		0x00000000	/* DENALI_PHY_1018_DATA */
+		0x00000000	/* DENALI_PHY_1019_DATA */
+		0x00000000	/* DENALI_PHY_1020_DATA */
+		0x00000000	/* DENALI_PHY_1021_DATA */
+		0x00000000	/* DENALI_PHY_1022_DATA */
+		0x00000000	/* DENALI_PHY_1023_DATA */
+		0x36025174	/* DENALI_PHY_1024_DATA */
+		0x0004c008	/* DENALI_PHY_1025_DATA */
+		0x000000da	/* DENALI_PHY_1026_DATA */
+		0x00000000	/* DENALI_PHY_1027_DATA */
+		0x00000000	/* DENALI_PHY_1028_DATA */
+		0x00010000	/* DENALI_PHY_1029_DATA */
+		0x01DDDD90	/* DENALI_PHY_1030_DATA */
+		0x01DDDD90	/* DENALI_PHY_1031_DATA */
+		0x01030000	/* DENALI_PHY_1032_DATA */
+		0x01000000	/* DENALI_PHY_1033_DATA */
+		0x00c00000	/* DENALI_PHY_1034_DATA */
+		0x00000007	/* DENALI_PHY_1035_DATA */
+		0x00000000	/* DENALI_PHY_1036_DATA */
+		0x00000000	/* DENALI_PHY_1037_DATA */
+		0x04000408	/* DENALI_PHY_1038_DATA */
+		0x00000408	/* DENALI_PHY_1039_DATA */
+		0x00e4e400	/* DENALI_PHY_1040_DATA */
+		0x00000000	/* DENALI_PHY_1041_DATA */
+		0x00000000	/* DENALI_PHY_1042_DATA */
+		0x00000000	/* DENALI_PHY_1043_DATA */
+		0x00000000	/* DENALI_PHY_1044_DATA */
+		0x00000000	/* DENALI_PHY_1045_DATA */
+		0x00000000	/* DENALI_PHY_1046_DATA */
+		0x00000000	/* DENALI_PHY_1047_DATA */
+		0x00000000	/* DENALI_PHY_1048_DATA */
+		0x00000000	/* DENALI_PHY_1049_DATA */
+		0x00000000	/* DENALI_PHY_1050_DATA */
+		0x00000000	/* DENALI_PHY_1051_DATA */
+		0x00000000	/* DENALI_PHY_1052_DATA */
+		0x00000000	/* DENALI_PHY_1053_DATA */
+		0x00000000	/* DENALI_PHY_1054_DATA */
+		0x00000000	/* DENALI_PHY_1055_DATA */
+		0x00000000	/* DENALI_PHY_1056_DATA */
+		0x00200000	/* DENALI_PHY_1057_DATA */
+		0x00000000	/* DENALI_PHY_1058_DATA */
+		0x00000000	/* DENALI_PHY_1059_DATA */
+		0x00000000	/* DENALI_PHY_1060_DATA */
+		0x00000000	/* DENALI_PHY_1061_DATA */
+		0x00000000	/* DENALI_PHY_1062_DATA */
+		0x00000000	/* DENALI_PHY_1063_DATA */
+		0x02800280	/* DENALI_PHY_1064_DATA */
+		0x02800280	/* DENALI_PHY_1065_DATA */
+		0x02800280	/* DENALI_PHY_1066_DATA */
+		0x02800280	/* DENALI_PHY_1067_DATA */
+		0x00000280	/* DENALI_PHY_1068_DATA */
+		0x00000000	/* DENALI_PHY_1069_DATA */
+		0x00000000	/* DENALI_PHY_1070_DATA */
+		0x00000000	/* DENALI_PHY_1071_DATA */
+		0x00000000	/* DENALI_PHY_1072_DATA */
+		0x00000000	/* DENALI_PHY_1073_DATA */
+		0x00800080	/* DENALI_PHY_1074_DATA */
+		0x00800080	/* DENALI_PHY_1075_DATA */
+		0x00800080	/* DENALI_PHY_1076_DATA */
+		0x00800080	/* DENALI_PHY_1077_DATA */
+		0x00800080	/* DENALI_PHY_1078_DATA */
+		0x00800080	/* DENALI_PHY_1079_DATA */
+		0x00800080	/* DENALI_PHY_1080_DATA */
+		0x00800080	/* DENALI_PHY_1081_DATA */
+		0x00800080	/* DENALI_PHY_1082_DATA */
+		0x000100da	/* DENALI_PHY_1083_DATA */
+		0x00000200	/* DENALI_PHY_1084_DATA */
+		0x00000000	/* DENALI_PHY_1085_DATA */
+		0x00000000	/* DENALI_PHY_1086_DATA */
+		0x00000002	/* DENALI_PHY_1087_DATA */
+		0x51313152	/* DENALI_PHY_1088_DATA */
+		0x80013130	/* DENALI_PHY_1089_DATA */
+		0x02000080	/* DENALI_PHY_1090_DATA */
+		0x00100001	/* DENALI_PHY_1091_DATA */
+		0x0c064208	/* DENALI_PHY_1092_DATA */
+		0x000f0c0f	/* DENALI_PHY_1093_DATA */
+		0x01000140	/* DENALI_PHY_1094_DATA */
+		0x0000000c	/* DENALI_PHY_1095_DATA */
+		0x00000000	/* DENALI_PHY_1096_DATA */
+		0x00000000	/* DENALI_PHY_1097_DATA */
+		0x00000000	/* DENALI_PHY_1098_DATA */
+		0x00000000	/* DENALI_PHY_1099_DATA */
+		0x00000000	/* DENALI_PHY_1100_DATA */
+		0x00000000	/* DENALI_PHY_1101_DATA */
+		0x00000000	/* DENALI_PHY_1102_DATA */
+		0x00000000	/* DENALI_PHY_1103_DATA */
+		0x00000000	/* DENALI_PHY_1104_DATA */
+		0x00000000	/* DENALI_PHY_1105_DATA */
+		0x00000000	/* DENALI_PHY_1106_DATA */
+		0x00000000	/* DENALI_PHY_1107_DATA */
+		0x00000000	/* DENALI_PHY_1108_DATA */
+		0x00000000	/* DENALI_PHY_1109_DATA */
+		0x00000000	/* DENALI_PHY_1110_DATA */
+		0x00000000	/* DENALI_PHY_1111_DATA */
+		0x00000000	/* DENALI_PHY_1112_DATA */
+		0x00000000	/* DENALI_PHY_1113_DATA */
+		0x00000000	/* DENALI_PHY_1114_DATA */
+		0x00000000	/* DENALI_PHY_1115_DATA */
+		0x00000000	/* DENALI_PHY_1116_DATA */
+		0x00000000	/* DENALI_PHY_1117_DATA */
+		0x00000000	/* DENALI_PHY_1118_DATA */
+		0x00000000	/* DENALI_PHY_1119_DATA */
+		0x00000000	/* DENALI_PHY_1120_DATA */
+		0x00000000	/* DENALI_PHY_1121_DATA */
+		0x00000000	/* DENALI_PHY_1122_DATA */
+		0x00000000	/* DENALI_PHY_1123_DATA */
+		0x00000000	/* DENALI_PHY_1124_DATA */
+		0x00000000	/* DENALI_PHY_1125_DATA */
+		0x00000000	/* DENALI_PHY_1126_DATA */
+		0x00000000	/* DENALI_PHY_1127_DATA */
+		0x00000000	/* DENALI_PHY_1128_DATA */
+		0x00000000	/* DENALI_PHY_1129_DATA */
+		0x00000000	/* DENALI_PHY_1130_DATA */
+		0x00000000	/* DENALI_PHY_1131_DATA */
+		0x00000000	/* DENALI_PHY_1132_DATA */
+		0x00000000	/* DENALI_PHY_1133_DATA */
+		0x00000000	/* DENALI_PHY_1134_DATA */
+		0x00000000	/* DENALI_PHY_1135_DATA */
+		0x00000000	/* DENALI_PHY_1136_DATA */
+		0x00000000	/* DENALI_PHY_1137_DATA */
+		0x00000000	/* DENALI_PHY_1138_DATA */
+		0x00000000	/* DENALI_PHY_1139_DATA */
+		0x00000000	/* DENALI_PHY_1140_DATA */
+		0x00000000	/* DENALI_PHY_1141_DATA */
+		0x00000000	/* DENALI_PHY_1142_DATA */
+		0x00000000	/* DENALI_PHY_1143_DATA */
+		0x00000000	/* DENALI_PHY_1144_DATA */
+		0x00000000	/* DENALI_PHY_1145_DATA */
+		0x00000000	/* DENALI_PHY_1146_DATA */
+		0x00000000	/* DENALI_PHY_1147_DATA */
+		0x00000000	/* DENALI_PHY_1148_DATA */
+		0x00000000	/* DENALI_PHY_1149_DATA */
+		0x00000000	/* DENALI_PHY_1150_DATA */
+		0x00000000	/* DENALI_PHY_1151_DATA */
+		0x00000000	/* DENALI_PHY_1152_DATA */
+		0x00000000	/* DENALI_PHY_1153_DATA */
+		0x00050000	/* DENALI_PHY_1154_DATA */
+		0x00000000	/* DENALI_PHY_1155_DATA */
+		0x00000000	/* DENALI_PHY_1156_DATA */
+		0x00000000	/* DENALI_PHY_1157_DATA */
+		0x00000100	/* DENALI_PHY_1158_DATA */
+		0x00000000	/* DENALI_PHY_1159_DATA */
+		0x00000000	/* DENALI_PHY_1160_DATA */
+		0x00506401	/* DENALI_PHY_1161_DATA */
+		0x01221102	/* DENALI_PHY_1162_DATA */
+		0x00000122	/* DENALI_PHY_1163_DATA */
+		0x00000000	/* DENALI_PHY_1164_DATA */
+		0x000B1F00	/* DENALI_PHY_1165_DATA */
+		0x0B1F0B1F	/* DENALI_PHY_1166_DATA */
+		0x0B1F0B1B	/* DENALI_PHY_1167_DATA */
+		0x0B1F0B1F	/* DENALI_PHY_1168_DATA */
+		0x0B1F0B1F	/* DENALI_PHY_1169_DATA */
+		0x00000B00	/* DENALI_PHY_1170_DATA */
+		0x42080010	/* DENALI_PHY_1171_DATA */
+		0x01000100	/* DENALI_PHY_1172_DATA */
+		0x01000100	/* DENALI_PHY_1173_DATA */
+		0x01000100	/* DENALI_PHY_1174_DATA */
+		0x01000100	/* DENALI_PHY_1175_DATA */
+		0x00000000	/* DENALI_PHY_1176_DATA */
+		0x00000000	/* DENALI_PHY_1177_DATA */
+		0x00000000	/* DENALI_PHY_1178_DATA */
+		0x00000000	/* DENALI_PHY_1179_DATA */
+		0x00000000	/* DENALI_PHY_1180_DATA */
+		0x00000803	/* DENALI_PHY_1181_DATA */
+		0x223FFF00	/* DENALI_PHY_1182_DATA */
+		0x000008FF	/* DENALI_PHY_1183_DATA */
+		0x0000057F	/* DENALI_PHY_1184_DATA */
+		0x0000057F	/* DENALI_PHY_1185_DATA */
+		0x00037FFF	/* DENALI_PHY_1186_DATA */
+		0x00037FFF	/* DENALI_PHY_1187_DATA */
+		0x00004410	/* DENALI_PHY_1188_DATA */
+		0x00004410	/* DENALI_PHY_1189_DATA */
+		0x00004410	/* DENALI_PHY_1190_DATA */
+		0x00004410	/* DENALI_PHY_1191_DATA */
+		0x00004410	/* DENALI_PHY_1192_DATA */
+		0x00037FFF	/* DENALI_PHY_1193_DATA */
+		0x00037FFF	/* DENALI_PHY_1194_DATA */
+		0x00000000	/* DENALI_PHY_1195_DATA */
+		0x00000000	/* DENALI_PHY_1196_DATA */
+		0x00000000	/* DENALI_PHY_1197_DATA */
+		0x04000000	/* DENALI_PHY_1198_DATA */
+		0x00000000	/* DENALI_PHY_1199_DATA */
+		0x00000000	/* DENALI_PHY_1200_DATA */
+		0x00000108	/* DENALI_PHY_1201_DATA */
+		0x00000000	/* DENALI_PHY_1202_DATA */
+		0x00000000	/* DENALI_PHY_1203_DATA */
+		0x00000000	/* DENALI_PHY_1204_DATA */
+		0x00000001	/* DENALI_PHY_1205_DATA */
+		0x00000000	/* DENALI_PHY_1206_DATA */
+		0x00000000	/* DENALI_PHY_1207_DATA */
+		0x00000000	/* DENALI_PHY_1208_DATA */
+		0x00000000	/* DENALI_PHY_1209_DATA */
+		0x00000000	/* DENALI_PHY_1210_DATA */
+		0x00000000	/* DENALI_PHY_1211_DATA */
+		0x00020100	/* DENALI_PHY_1212_DATA */
+		0x00000000	/* DENALI_PHY_1213_DATA */
+		0x00000000	/* DENALI_PHY_1214_DATA */
+	>;
+};
diff --git a/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
index cce1bd943e..ffb0db1d73 100644
--- a/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
+++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
@@ -4,6 +4,7 @@
  */
 
 #include "fu540-c000-u-boot.dtsi"
+#include "fu540-sdram-ddr4.dtsi"
 
 / {
 	hfclk {
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCH v5 08/14] clk: sifive: fu540-prci: Add clock enable and disable ops
  2020-03-11  7:03 [PATCH v5 00/14] RISC-V SiFive FU540 support SPL Pragnesh Patel
                   ` (6 preceding siblings ...)
  2020-03-11  7:03 ` [PATCH v5 07/14] sifive: dts: fu540: Add DDR controller and phy register settings Pragnesh Patel
@ 2020-03-11  7:03 ` Pragnesh Patel
  2020-03-13  7:57   ` Bin Meng
  2020-03-11  7:03 ` [PATCH v5 09/14] clk: sifive: fu540-prci: Add clock initialization for SPL Pragnesh Patel
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-11  7:03 UTC (permalink / raw)
  To: u-boot

Added clock enable and disable functions in prci ops

Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
---
 drivers/clk/sifive/fu540-prci.c | 75 +++++++++++++++++++++++++++++++--
 1 file changed, 72 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
index 8847178001..c02c0466a8 100644
--- a/drivers/clk/sifive/fu540-prci.c
+++ b/drivers/clk/sifive/fu540-prci.c
@@ -68,6 +68,11 @@
 #define PRCI_COREPLLCFG0_LOCK_SHIFT	31
 #define PRCI_COREPLLCFG0_LOCK_MASK	(0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT)
 
+/* COREPLLCFG1 */
+#define PRCI_COREPLLCFG1_OFFSET		0x8
+#define PRCI_COREPLLCFG1_CKE_SHIFT	31
+#define PRCI_COREPLLCFG1_CKE_MASK	(0x1 << PRCI_COREPLLCFG1_CKE_SHIFT)
+
 /* DDRPLLCFG0 */
 #define PRCI_DDRPLLCFG0_OFFSET		0xc
 #define PRCI_DDRPLLCFG0_DIVR_SHIFT	0
@@ -87,7 +92,7 @@
 
 /* DDRPLLCFG1 */
 #define PRCI_DDRPLLCFG1_OFFSET		0x10
-#define PRCI_DDRPLLCFG1_CKE_SHIFT	24
+#define PRCI_DDRPLLCFG1_CKE_SHIFT	31
 #define PRCI_DDRPLLCFG1_CKE_MASK	(0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
 
 /* GEMGXLPLLCFG0 */
@@ -114,7 +119,7 @@
 
 /* GEMGXLPLLCFG1 */
 #define PRCI_GEMGXLPLLCFG1_OFFSET	0x20
-#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT	24
+#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT	31
 #define PRCI_GEMGXLPLLCFG1_CKE_MASK	(0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
 
 /* CORECLKSEL */
@@ -142,7 +147,7 @@
 			(0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT)
 
 /* CLKMUXSTATUSREG */
-#define PRCI_CLKMUXSTATUSREG_OFFSET		0x2c
+#define PRCI_CLKMUXSTATUSREG_OFFSET	0x2c
 #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1
 #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK \
 			(0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
@@ -170,6 +175,7 @@ struct __prci_data {
  * @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
+ * @cfg1_offs: WRPLL CFG1 register offset (in bytes) from the PRCI base address
  *
  * @enable_bypass and @disable_bypass are used for WRPLL instances
  * that contain a separate external glitchless clock mux downstream
@@ -180,6 +186,7 @@ struct __prci_wrpll_data {
 	void (*enable_bypass)(struct __prci_data *pd);
 	void (*disable_bypass)(struct __prci_data *pd);
 	u8 cfg0_offs;
+	u8 cfg1_offs;
 };
 
 struct __prci_clock;
@@ -194,6 +201,7 @@ struct __prci_clock_ops {
 				    unsigned long *parent_rate);
 	unsigned long (*recalc_rate)(struct __prci_clock *pc,
 				     unsigned long parent_rate);
+	int (*enable_clk)(struct __prci_clock *pc, bool enable);
 };
 
 /**
@@ -356,6 +364,13 @@ static void __prci_wrpll_write_cfg(struct __prci_data *pd,
 	memcpy(&pwd->c, c, sizeof(*c));
 }
 
+static void __prci_wrpll_write_cfg1(struct __prci_data *pd,
+				    struct __prci_wrpll_data *pwd,
+				    u32 enable)
+{
+	__prci_writel(enable, pwd->cfg1_offs, pd);
+}
+
 /* Core clock mux control */
 
 /**
@@ -447,14 +462,35 @@ static int sifive_fu540_prci_wrpll_set_rate(struct __prci_clock *pc,
 	return 0;
 }
 
+static int sifive_fu540_prci_clock_enable(struct __prci_clock *pc, bool enable)
+{
+	struct __prci_wrpll_data *pwd = pc->pwd;
+	struct __prci_data *pd = pc->pd;
+
+	if (enable) {
+		__prci_wrpll_write_cfg1(pd, pwd, PRCI_COREPLLCFG1_CKE_MASK);
+	} else {
+		u32 r;
+
+		r = __prci_readl(pd, pwd->cfg1_offs);
+		r &= ~PRCI_COREPLLCFG1_CKE_MASK;
+
+		__prci_wrpll_write_cfg1(pd, pwd, r);
+	}
+
+	return 0;
+}
+
 static const struct __prci_clock_ops sifive_fu540_prci_wrpll_clk_ops = {
 	.set_rate = sifive_fu540_prci_wrpll_set_rate,
 	.round_rate = sifive_fu540_prci_wrpll_round_rate,
 	.recalc_rate = sifive_fu540_prci_wrpll_recalc_rate,
+	.enable_clk = sifive_fu540_prci_clock_enable,
 };
 
 static const struct __prci_clock_ops sifive_fu540_prci_wrpll_ro_clk_ops = {
 	.recalc_rate = sifive_fu540_prci_wrpll_recalc_rate,
+	.enable_clk = sifive_fu540_prci_clock_enable,
 };
 
 /* TLCLKSEL clock integration */
@@ -484,16 +520,19 @@ 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,
+	.cfg1_offs = PRCI_COREPLLCFG1_OFFSET,
 	.enable_bypass = __prci_coreclksel_use_hfclk,
 	.disable_bypass = __prci_coreclksel_use_corepll,
 };
 
 static struct __prci_wrpll_data __prci_ddrpll_data = {
 	.cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
+	.cfg1_offs = PRCI_DDRPLLCFG1_OFFSET,
 };
 
 static struct __prci_wrpll_data __prci_gemgxlpll_data = {
 	.cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
+	.cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET,
 };
 
 /*
@@ -580,6 +619,34 @@ static ulong sifive_fu540_prci_set_rate(struct clk *clk, ulong rate)
 	return rate;
 }
 
+static int sifive_fu540_prci_enable(struct clk *clk)
+{
+	struct __prci_clock *pc;
+
+	if (ARRAY_SIZE(__prci_init_clocks) <= clk->id)
+		return -ENXIO;
+
+	pc = &__prci_init_clocks[clk->id];
+	if (!pc->pd || !pc->ops->enable_clk)
+		return -ENXIO;
+
+	return pc->ops->enable_clk(pc, 1);
+}
+
+static int sifive_fu540_prci_disable(struct clk *clk)
+{
+	struct __prci_clock *pc;
+
+	if (ARRAY_SIZE(__prci_init_clocks) <= clk->id)
+		return -ENXIO;
+
+	pc = &__prci_init_clocks[clk->id];
+	if (!pc->pd || !pc->ops->enable_clk)
+		return -ENXIO;
+
+	return pc->ops->enable_clk(pc, 0);
+}
+
 static int sifive_fu540_prci_probe(struct udevice *dev)
 {
 	int i, err;
@@ -611,6 +678,8 @@ static int sifive_fu540_prci_probe(struct udevice *dev)
 static struct clk_ops sifive_fu540_prci_ops = {
 	.set_rate = sifive_fu540_prci_set_rate,
 	.get_rate = sifive_fu540_prci_get_rate,
+	.enable = sifive_fu540_prci_enable,
+	.disable = sifive_fu540_prci_disable,
 };
 
 static const struct udevice_id sifive_fu540_prci_ids[] = {
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCH v5 09/14] clk: sifive: fu540-prci: Add clock initialization for SPL
  2020-03-11  7:03 [PATCH v5 00/14] RISC-V SiFive FU540 support SPL Pragnesh Patel
                   ` (7 preceding siblings ...)
  2020-03-11  7:03 ` [PATCH v5 08/14] clk: sifive: fu540-prci: Add clock enable and disable ops Pragnesh Patel
@ 2020-03-11  7:03 ` Pragnesh Patel
  2020-03-13  8:11   ` Bin Meng
  2020-03-11  7:03 ` [PATCH v5 10/14] riscv: sifive: fu540: add SPL configuration Pragnesh Patel
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-11  7:03 UTC (permalink / raw)
  To: u-boot

Set corepll, ddrpll and ethernet PLL for u-boot-spl

Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
---
 drivers/clk/sifive/fu540-prci.c | 94 +++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
index c02c0466a8..f043b0eccb 100644
--- a/drivers/clk/sifive/fu540-prci.c
+++ b/drivers/clk/sifive/fu540-prci.c
@@ -41,6 +41,10 @@
 #include <linux/clk/analogbits-wrpll-cln28hpc.h>
 #include <dt-bindings/clock/sifive-fu540-prci.h>
 
+#define DDRCTLPLL_F	55
+#define DDRCTLPLL_Q	2
+#define MHz		1000000
+
 /*
  * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects:
  *     hfclk and rtcclk
@@ -152,6 +156,27 @@
 #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK \
 			(0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
 
+/* PROCMONCFG */
+#define PRCI_PROCMONCFG_OFFSET			0xF0
+#define PRCI_PROCMONCFG_CORE_CLOCK_SHIFT	24
+#define PRCI_PROCMONCFG_CORE_CLOCK_MASK \
+			(0x1 << PRCI_PROCMONCFG_CORE_CLOCK_SHIFT)
+
+#define PLL_R(x) \
+	((x) << PRCI_DDRPLLCFG0_DIVR_SHIFT) & PRCI_DDRPLLCFG0_DIVR_MASK
+#define PLL_F(x) \
+	((x) << PRCI_DDRPLLCFG0_DIVF_SHIFT) & PRCI_DDRPLLCFG0_DIVF_MASK
+#define PLL_Q(x) \
+	((x) << PRCI_DDRPLLCFG0_DIVQ_SHIFT) & PRCI_DDRPLLCFG0_DIVQ_MASK
+#define PLL_RANGE(x) \
+	((x) << PRCI_DDRPLLCFG0_RANGE_SHIFT) & PRCI_DDRPLLCFG0_RANGE_MASK
+#define PLL_BYPASS(x) \
+	((x) << PRCI_DDRPLLCFG0_BYPASS_SHIFT) & PRCI_DDRPLLCFG0_BYPASS_MASK
+#define PLL_FSE(x) \
+	((x) << PRCI_DDRPLLCFG0_FSE_SHIFT) & PRCI_DDRPLLCFG0_FSE_MASK
+#define PLL_LOCK(x) \
+	((x) << PRCI_DDRPLLCFG0_LOCK_SHIFT) & PRCI_DDRPLLCFG0_LOCK_MASK
+
 /*
  * Private structures
  */
@@ -672,6 +697,75 @@ static int sifive_fu540_prci_probe(struct udevice *dev)
 			__prci_wrpll_read_cfg(pd, pc->pwd);
 	}
 
+#ifdef CONFIG_SPL_BUILD
+	u32 v;
+	struct clk clock;
+
+	v = __prci_readl(pd, PRCI_CLKMUXSTATUSREG_OFFSET);
+	v &= PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK;
+
+	clock.id = PRCI_CLK_COREPLL;
+
+	if (v) {
+		/* corepll 500 Mhz */
+		sifive_fu540_prci_set_rate(&clock, 500UL * MHz);
+	} else {
+		/* corepll 1 Ghz */
+		sifive_fu540_prci_set_rate(&clock, 1000UL * MHz);
+	}
+
+	sifive_fu540_prci_clock_enable(&__prci_init_clocks[clock.id], 1);
+
+	//DDR init
+	u32 ddrctlmhz =
+		(PLL_R(0)) |
+		(PLL_F(DDRCTLPLL_F)) |
+		(PLL_Q(DDRCTLPLL_Q)) |
+		(PLL_RANGE(0x4)) |
+		(PLL_BYPASS(0)) |
+		(PLL_FSE(1));
+	__prci_writel(ddrctlmhz, PRCI_DDRPLLCFG0_OFFSET, pd);
+
+	clock.id = PRCI_CLK_DDRPLL;
+	sifive_fu540_prci_clock_enable(&__prci_init_clocks[clock.id], 1);
+
+	/* Release DDR reset */
+	v = __prci_readl(pd, PRCI_DEVICESRESETREG_OFFSET);
+	v |= PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK;
+	__prci_writel(v, PRCI_DEVICESRESETREG_OFFSET, pd);
+
+	// HACK to get the '1 full controller clock cycle'.
+	asm volatile ("fence");
+	v = __prci_readl(pd, PRCI_DEVICESRESETREG_OFFSET);
+	v |= (PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK |
+	      PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK |
+	      PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK);
+	__prci_writel(v, PRCI_DEVICESRESETREG_OFFSET, pd);
+	// HACK to get the '1 full controller clock cycle'.
+	asm volatile ("fence");
+
+	/* These take like 16 cycles to actually propagate. We can't go sending
+	 * stuff before they come out of reset. So wait. (TODO: Add a register
+	 * to read the current reset states, or DDR Control device?)
+	 */
+	for (int i = 0; i < 256; i++)
+		asm volatile ("nop");
+
+	/* GEMGXL init */
+	clock.id = PRCI_CLK_GEMGXLPLL;
+	sifive_fu540_prci_set_rate(&clock, 125UL * MHz);
+	sifive_fu540_prci_clock_enable(&__prci_init_clocks[clock.id], 1);
+
+	/* Release GEMGXL reset */
+	v = __prci_readl(pd, PRCI_DEVICESRESETREG_OFFSET);
+	v |= PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK;
+	__prci_writel(v, PRCI_DEVICESRESETREG_OFFSET, pd);
+
+	/* Procmon => core clock */
+	__prci_writel(PRCI_PROCMONCFG_CORE_CLOCK_MASK, PRCI_PROCMONCFG_OFFSET,
+		      pd);
+#endif
+
 	return 0;
 }
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCH v5 10/14] riscv: sifive: fu540: add SPL configuration
  2020-03-11  7:03 [PATCH v5 00/14] RISC-V SiFive FU540 support SPL Pragnesh Patel
                   ` (8 preceding siblings ...)
  2020-03-11  7:03 ` [PATCH v5 09/14] clk: sifive: fu540-prci: Add clock initialization for SPL Pragnesh Patel
@ 2020-03-11  7:03 ` Pragnesh Patel
  2020-03-13  8:28   ` Bin Meng
  2020-03-13 13:59   ` Bin Meng
  2020-03-11  7:03 ` [PATCH v5 11/14] configs: fu540: Add config options for U-boot SPL Pragnesh Patel
                   ` (3 subsequent siblings)
  13 siblings, 2 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-11  7:03 UTC (permalink / raw)
  To: u-boot

Add a support for SPL which will boot from L2 LIM (0x0800_0000) and
then boot U-boot FIT image including OpenSBI FW_DYNAMIC firmware
and U-Boot proper images from 1st partition of MMC boot devices.

SPL related code is leverage from FSBL
(https://github.com/sifive/freedom-u540-c000-bootloader.git)

Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
---
 board/sifive/fu540/Kconfig            |  8 +++
 board/sifive/fu540/Makefile           |  4 ++
 board/sifive/fu540/fu540-memory-map.h | 23 ++++++++
 board/sifive/fu540/fu540.c            | 24 +++++++++
 board/sifive/fu540/spl.c              | 78 +++++++++++++++++++++++++++
 include/configs/sifive-fu540.h        | 18 +++++++
 6 files changed, 155 insertions(+)
 create mode 100644 board/sifive/fu540/fu540-memory-map.h
 create mode 100644 board/sifive/fu540/spl.c

diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
index 900197bbb2..ebe3472f9a 100644
--- a/board/sifive/fu540/Kconfig
+++ b/board/sifive/fu540/Kconfig
@@ -13,12 +13,20 @@ config SYS_CONFIG_NAME
 	default "sifive-fu540"
 
 config SYS_TEXT_BASE
+	default 0x80200000 if SPL
 	default 0x80000000 if !RISCV_SMODE
 	default 0x80200000 if RISCV_SMODE
 
+config SPL_TEXT_BASE
+	default 0x08000000
+
+config SPL_OPENSBI_LOAD_ADDR
+	default 0x80000000
+
 config BOARD_SPECIFIC_OPTIONS # dummy
 	def_bool y
 	select GENERIC_RISCV
+	select SUPPORT_SPL
 	imply CMD_DHCP
 	imply CMD_EXT2
 	imply CMD_EXT4
diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
index 6e1862c475..b05e2f5807 100644
--- a/board/sifive/fu540/Makefile
+++ b/board/sifive/fu540/Makefile
@@ -3,3 +3,7 @@
 # Copyright (c) 2019 Western Digital Corporation or its affiliates.
 
 obj-y	+= fu540.o
+
+ifdef CONFIG_SPL_BUILD
+obj-y += spl.o
+endif
diff --git a/board/sifive/fu540/fu540-memory-map.h b/board/sifive/fu540/fu540-memory-map.h
new file mode 100644
index 0000000000..cba464652b
--- /dev/null
+++ b/board/sifive/fu540/fu540-memory-map.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ */
+
+#ifndef FU540_MEMORY_MAP
+#define FU540_MEMORY_MAP
+
+#include <asm/arch/gpio.h>
+
+/****************************************************************************
+ * Platform definitions
+ *****************************************************************************/
+
+/* Memory map */
+#define GPIO_CTRL_ADDR                 _AC(0x10060000, UL)
+
+/* Helper functions */
+#define _REG32(p, i)    (*(volatile uint32_t *)((p) + (i)))
+
+#define GPIO_REG(offset)      _REG32(GPIO_CTRL_ADDR, offset)
+
+#endif /* FU540_MEMORY_MAP */
diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
index 6c642b3082..89a65eb3fb 100644
--- a/board/sifive/fu540/fu540.c
+++ b/board/sifive/fu540/fu540.c
@@ -11,6 +11,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <misc.h>
+#include <spl.h>
 
 /*
  * This define is a value used for error/unknown serial.
@@ -114,3 +115,26 @@ int board_init(void)
 
 	return 0;
 }
+
+#ifdef CONFIG_SPL
+void board_boot_order(u32 *spl_boot_list)
+{
+	u8 i;
+	u32 boot_devices[] = {
+#ifdef CONFIG_SPL_MMC_SUPPORT
+		BOOT_DEVICE_MMC1,
+#endif
+	};
+
+	for (i = 0; i < ARRAY_SIZE(boot_devices); i++)
+		spl_boot_list[i] = boot_devices[i];
+}
+#endif
+
+#ifdef CONFIG_SPL_LOAD_FIT
+int board_fit_config_name_match(const char *name)
+{
+	/* boot using first FIT config */
+	return 0;
+}
+#endif
diff --git a/board/sifive/fu540/spl.c b/board/sifive/fu540/spl.c
new file mode 100644
index 0000000000..522bc24753
--- /dev/null
+++ b/board/sifive/fu540/spl.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <misc.h>
+#include <dm.h>
+
+#include "fu540-memory-map.h"
+
+#define DDRCTLPLL_F 55
+#define DDRCTLPLL_Q 2
+
+#define PHY_NRESET 0x1000
+
+long nsec_per_cyc = 300; /* 33.333MHz */
+void nsleep(long nsec)
+{
+	long step = nsec_per_cyc * 2;
+
+	while (nsec > 0)
+		nsec -= step;
+}
+
+void init_clk_and_ddr(void)
+{
+	int ret;
+	struct udevice *dev;
+
+	/* PRCI init */
+	ret = uclass_get_device(UCLASS_CLK, 0, &dev);
+	if (ret) {
+		debug("Clock init failed: %d\n", ret);
+		return;
+	}
+
+	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+	if (ret) {
+		printf("DRAM init failed: %d\n", ret);
+		return;
+	}
+
+	/*
+	 * GEMGXL init VSC8541 PHY reset sequence;
+	 * leave pull-down active for 2ms
+	 */
+	nsleep(2000000);
+	/* Set GPIO 12 (PHY NRESET) to OE=1 and OVAL=1 */
+	GPIO_REG(GPIO_OUTPUT_VAL) |= PHY_NRESET;
+	GPIO_REG(GPIO_OUTPUT_EN) |= PHY_NRESET;
+	nsleep(100);
+
+	/* Reset PHY again to enter unmanaged mode */
+	GPIO_REG(GPIO_OUTPUT_VAL) &= ~PHY_NRESET;
+	nsleep(100);
+	GPIO_REG(GPIO_OUTPUT_VAL) |= PHY_NRESET;
+	nsleep(15000000);
+}
+
+void board_init_f(ulong dummy)
+{
+	int ret;
+
+	ret = spl_early_init();
+	if (ret)
+		panic("spl_early_init() failed: %d\n", ret);
+
+	arch_cpu_init_dm();
+
+	init_clk_and_ddr();
+
+	preloader_console_init();
+}
diff --git a/include/configs/sifive-fu540.h b/include/configs/sifive-fu540.h
index 2756ed5a77..ef3ae9b650 100644
--- a/include/configs/sifive-fu540.h
+++ b/include/configs/sifive-fu540.h
@@ -11,6 +11,22 @@
 
 #include <linux/sizes.h>
 
+#ifdef CONFIG_SPL
+
+#define CONFIG_SPL_MAX_SIZE		0x00100000
+#define CONFIG_SPL_BSS_START_ADDR	0x85000000
+#define CONFIG_SPL_BSS_MAX_SIZE		0x00100000
+#define CONFIG_SYS_SPL_MALLOC_START	(CONFIG_SPL_BSS_START_ADDR + \
+					 CONFIG_SPL_BSS_MAX_SIZE)
+#define CONFIG_SYS_SPL_MALLOC_SIZE	0x00100000
+
+#define CONFIG_SPL_LOAD_FIT_ADDRESS	0x84000000
+
+#define CONFIG_SPL_STACK	(0x08000000 + 0x001D0000 - \
+				 GENERATED_GBL_DATA_SIZE)
+
+#endif
+
 #define CONFIG_SYS_SDRAM_BASE		0x80000000
 #define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_SDRAM_BASE + SZ_2M)
 
@@ -24,6 +40,7 @@
 
 /* Environment options */
 
+#ifndef CONFIG_SPL_BUILD
 #define BOOT_TARGET_DEVICES(func) \
 	func(MMC, mmc, 0) \
 	func(DHCP, dhcp, na)
@@ -43,5 +60,6 @@
 #define CONFIG_PREBOOT \
 	"setenv fdt_addr ${fdtcontroladdr};" \
 	"fdt addr ${fdtcontroladdr};"
+#endif
 
 #endif /* __CONFIG_H */
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCH v5 11/14] configs: fu540: Add config options for U-boot SPL
  2020-03-11  7:03 [PATCH v5 00/14] RISC-V SiFive FU540 support SPL Pragnesh Patel
                   ` (9 preceding siblings ...)
  2020-03-11  7:03 ` [PATCH v5 10/14] riscv: sifive: fu540: add SPL configuration Pragnesh Patel
@ 2020-03-11  7:03 ` Pragnesh Patel
  2020-03-13  8:48   ` Bin Meng
  2020-03-11  7:03 ` [PATCH v5 12/14] riscv: sifive: fu540: enable all cache ways from u-boot proper Pragnesh Patel
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-11  7:03 UTC (permalink / raw)
  To: u-boot

With sifive_fu540_defconfig:

User can use FSBL or u-boot-spl.bin anyone at a time.

For FSBL,
fsbl->fw_payload.bin(opensbi+u-boot)

For u-boot-spl.bin,
u-boot-spl.bin->FIT image(opensbi+u-boot+dtb)

U-Boot SPL will be loaded by ZSBL from SD card (replace fsbl.bin with
u-boot-spl.bin) and runs in L2 LIM in machine mode and then load FIT
image u-boot.itb from 1st partition of SD card (replace fw_payload.bin
with u-boot.itb) into RAM.

U-boot SPL expects u-boot.itb FIT image in the 1st partition of SD
card irrespective of GUID

Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
---
 configs/sifive_fu540_defconfig | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/configs/sifive_fu540_defconfig b/configs/sifive_fu540_defconfig
index 6d61e6c960..1b33c81be4 100644
--- a/configs/sifive_fu540_defconfig
+++ b/configs/sifive_fu540_defconfig
@@ -12,3 +12,14 @@ CONFIG_DISPLAY_BOARDINFO=y
 CONFIG_DEFAULT_DEVICE_TREE="hifive-unleashed-a00"
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_DM_MTD=y
+CONFIG_SPL_SEPARATE_BSS=y
+CONFIG_SPL=y
+CONFIG_SPL_MMC_SUPPORT=y
+CONFIG_SPL_SPI_SUPPORT=y
+CONFIG_SPL_YMODEM_SUPPORT=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=1
+CONFIG_SPL_CLK=y
+CONFIG_SPL_PAYLOAD="u-boot.itb"
+CONFIG_SYS_MALLOC_F_LEN=0x3000
+CONFIG_SIFIVE_FU540_DDR=y
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCH v5 12/14] riscv: sifive: fu540: enable all cache ways from u-boot proper
  2020-03-11  7:03 [PATCH v5 00/14] RISC-V SiFive FU540 support SPL Pragnesh Patel
                   ` (10 preceding siblings ...)
  2020-03-11  7:03 ` [PATCH v5 11/14] configs: fu540: Add config options for U-boot SPL Pragnesh Patel
@ 2020-03-11  7:03 ` Pragnesh Patel
  2020-03-13  9:01   ` Bin Meng
  2020-03-11  7:03 ` [PATCH v5 13/14] sifive: fix palmer's email address Pragnesh Patel
  2020-03-11  7:03 ` [PATCH v5 14/14] doc: update FU540 RISC-V documentation Pragnesh Patel
  13 siblings, 1 reply; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-11  7:03 UTC (permalink / raw)
  To: u-boot

Enable all cache ways from u-boot proper.

Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
---
 board/sifive/fu540/Makefile |  1 +
 board/sifive/fu540/cache.c  | 20 ++++++++++++++++++++
 board/sifive/fu540/cache.h  | 13 +++++++++++++
 board/sifive/fu540/fu540.c  |  6 ++++--
 4 files changed, 38 insertions(+), 2 deletions(-)
 create mode 100644 board/sifive/fu540/cache.c
 create mode 100644 board/sifive/fu540/cache.h

diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
index b05e2f5807..3b867bbd89 100644
--- a/board/sifive/fu540/Makefile
+++ b/board/sifive/fu540/Makefile
@@ -3,6 +3,7 @@
 # Copyright (c) 2019 Western Digital Corporation or its affiliates.
 
 obj-y	+= fu540.o
+obj-y	+= cache.o
 
 ifdef CONFIG_SPL_BUILD
 obj-y += spl.o
diff --git a/board/sifive/fu540/cache.c b/board/sifive/fu540/cache.c
new file mode 100644
index 0000000000..a0bcd2ba48
--- /dev/null
+++ b/board/sifive/fu540/cache.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ */
+#include <asm/io.h>
+
+/* Register offsets */
+#define CACHE_ENABLE           0x008
+
+/* Enable ways; allow cache to use these ways */
+void cache_enable_ways(u64 base_addr, u8 value)
+{
+	volatile u32 *enable = (volatile u32 *)(base_addr +
+					  CACHE_ENABLE);
+	/* memory barrier */
+	mb();
+	(*enable) = value;
+	/* memory barrier */
+	mb();
+}
diff --git a/board/sifive/fu540/cache.h b/board/sifive/fu540/cache.h
new file mode 100644
index 0000000000..425124a23b
--- /dev/null
+++ b/board/sifive/fu540/cache.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ */
+
+#ifndef FU540_CACHE_H
+#define FU540_CACHE_H
+
+#define CACHE_CTRL_ADDR               _AC(0x2010000, UL)
+
+void cache_enable_ways(u64 base_addr, u8 value);
+
+#endif /* FU540_CACHE_H */
diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
index 89a65eb3fb..1d6c0c9bba 100644
--- a/board/sifive/fu540/fu540.c
+++ b/board/sifive/fu540/fu540.c
@@ -13,6 +13,8 @@
 #include <misc.h>
 #include <spl.h>
 
+#include "cache.h"
+
 /*
  * This define is a value used for error/unknown serial.
  * If we really care about distinguishing errors and 0 is
@@ -111,8 +113,8 @@ int misc_init_r(void)
 
 int board_init(void)
 {
-	/* For now nothing to do here. */
-
+	/* enable all cache ways */
+	cache_enable_ways(CACHE_CTRL_ADDR, 15);
 	return 0;
 }
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCH v5 13/14] sifive: fix palmer's email address
  2020-03-11  7:03 [PATCH v5 00/14] RISC-V SiFive FU540 support SPL Pragnesh Patel
                   ` (11 preceding siblings ...)
  2020-03-11  7:03 ` [PATCH v5 12/14] riscv: sifive: fu540: enable all cache ways from u-boot proper Pragnesh Patel
@ 2020-03-11  7:03 ` Pragnesh Patel
  2020-03-13  9:01   ` Bin Meng
  2020-03-11  7:03 ` [PATCH v5 14/14] doc: update FU540 RISC-V documentation Pragnesh Patel
  13 siblings, 1 reply; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-11  7:03 UTC (permalink / raw)
  To: u-boot

Fix Palmer's email address

Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
---
 board/sifive/fu540/MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/board/sifive/fu540/MAINTAINERS b/board/sifive/fu540/MAINTAINERS
index 702d803ad8..5381fc0639 100644
--- a/board/sifive/fu540/MAINTAINERS
+++ b/board/sifive/fu540/MAINTAINERS
@@ -1,6 +1,6 @@
 SiFive FU540 BOARD
 M:	Paul Walmsley <paul.walmsley@sifive.com>
-M:	Palmer Dabbelt <palmer@sifive.com>
+M:	Palmer Dabbelt <palmer@dabbelt.com>
 M:	Anup Patel <anup.patel@wdc.com>
 M:	Atish Patra <atish.patra@wdc.com>
 S:	Maintained
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCH v5 14/14] doc: update FU540 RISC-V documentation
  2020-03-11  7:03 [PATCH v5 00/14] RISC-V SiFive FU540 support SPL Pragnesh Patel
                   ` (12 preceding siblings ...)
  2020-03-11  7:03 ` [PATCH v5 13/14] sifive: fix palmer's email address Pragnesh Patel
@ 2020-03-11  7:03 ` Pragnesh Patel
  2020-03-13  9:22   ` Bin Meng
  13 siblings, 1 reply; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-11  7:03 UTC (permalink / raw)
  To: u-boot

Add descriptions about U-Boot SPL feature and how to build and run.

Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
---
 doc/board/sifive/fu540.rst | 409 ++++++++++++++++++++++++++++++++++---
 1 file changed, 385 insertions(+), 24 deletions(-)

diff --git a/doc/board/sifive/fu540.rst b/doc/board/sifive/fu540.rst
index 3937222c6c..e5414f4eef 100644
--- a/doc/board/sifive/fu540.rst
+++ b/doc/board/sifive/fu540.rst
@@ -42,8 +42,60 @@ Building
    export ARCH=riscv
    export CROSS_COMPILE=<riscv64 toolchain prefix>
 
-3. make sifive_fu540_defconfig
-4. make
+User can use FSBL or u-boot-spl as a 1st stage bootloader.
+
+1) Use FSBL as a 1st stage bootloader
+
+.. code-block:: console
+
+	git clone https://github.com/sifive/freedom-u540-c000-bootloader.git
+	cd freedom-u540-c000-bootloader
+	make
+
+	cd <u-boot-dir>
+	make sifive_fu540_defconfig
+	make
+
+	git clone https://github.com/riscv/opensbi.git
+	cd opensbi
+	make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=<path to u-boot.bin>
+
+This will generate a fw_payload.bin(build/platform/sifive/fu540/firmware/fw_payload.bin)
+
+u-boot.bin is used as a payload of the OpenSBI FW_PAYLOAD firmware.
+
+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)
+
+2) Use u-boot-spl as a 1st stage bootloader
+
+Before building U-Boot SPL, OpenSBI must be build first. OpenSBI can be
+cloned and build for FU540 as below:
+
+.. code-block:: console
+
+	git clone https://github.com/riscv/opensbi.git
+	cd opensbi
+	make PLATFORM=sifive/fu540
+
+Copy OpenSBI FW_DYNAMIC image (build/platform/sifive/fu540/firmware/fw_dynamic.bin)
+into U-Boot root directory
+
+.. code-block:: console
+
+	cp build/platform/sifive/fu540/firmware/fw_dynamic.bin <u-boot-dir>
+
+Now build the u-boot-spl and u-boot proper
+
+.. code-block:: console
+
+	cd <u-boot-dir>
+	make sifive_fu540_defconfig
+	make
+
+This will generate spl/u-boot-spl.bin and FIT image(u-boot.itb)
+
 
 Flashing
 --------
@@ -53,28 +105,55 @@ The current U-Boot port is supported in S-mode only and loaded from DRAM.
 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.
 
-Currently, the u-boot.bin is used as a payload of the OpenSBI FW_PAYLOAD
-firmware. We need to compile OpenSBI with below command:
+1) Use FSBL as a 1st stage bootloader
+
+ZSBL loads the FSBL(fsbl.bin) from a partition with GUID type
+5B193300-FC78-40CD-8002-E86C45580B47
+
+FSBL loads the fw_payload.bin from a partition with GUID type
+2E54B353-1271-4842-806F-E436D6AF6985
+
+Once the prior stage firmware/bootloader binary is generated, it should be
+copied to the first partition of the sdcard.
 
 .. code-block:: none
 
-make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=<path to u-boot-dtb.bin>
+     sudo dd if=fsbl.bin of=/dev/disk2s4 bs=1024
+     sudo dd if=fw_payload.bin of=/dev/disk2s1 bs=1024
 
-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)
+Assuming that /dev/disk2s4 partition is of GUID type
+5B193300-FC78-40CD-8002-E86C45580B47 and /dev/disk2s1 partition
+is of GUID type 2E54B353-1271-4842-806F-E436D6AF6985
+
+2) Use u-boot-spl as a 1st stage bootloader
+
+ZSBL loads the U-boot SPL(u-boot-spl.bin) from a partition with GUID type
+5B193300-FC78-40CD-8002-E86C45580B47
+
+U-boot SPL expects a u-boot FIT image(u-boot.itb) from 1st partition(/dev/sdc1)
+of SD card irrespective of GUID
+
+FIT image(u-boot.itb) is a combination of fw_dynamic.bin, u-boot-nodtb.bin and
+device tree blob(hifive-unleashed-a00.dtb)
 
 Once the prior stage firmware/bootloader binary is generated, it should be
 copied to the first partition of the sdcard.
 
 .. code-block:: none
 
-    sudo dd if=<prior_stage_firmware_binary> of=/dev/disk2s1 bs=1024
+    sudo dd if=spl/u-boot-spl.bin of=/dev/disk2s4 bs=1024
+    sudo dd if=u-boot.itb of=/dev/disk2s1 bs=1024
+
+Assuming that /dev/disk2s4 partition is of GUID type
+5B193300-FC78-40CD-8002-E86C45580B47 and /dev/disk2s1 is of
+any GUID type raw partition.
 
 Booting
 -------
 Once you plugin the sdcard and power up, you should see the U-Boot prompt.
 
+1) Use FSBL as a 1st stage bootloader
+
 Sample boot log from HiFive Unleashed board
 -------------------------------------------
 
@@ -145,19 +224,6 @@ load uImage.
    Filename '/sifive/fu540/Image'.
    Load address: 0x84000000
    Loading: #################################################################
-            #################################################################
-            #################################################################
-            #################################################################
-            #################################################################
-            #################################################################
-            #################################################################
-            #################################################################
-            #################################################################
-            #################################################################
-            #################################################################
-            #################################################################
-            #################################################################
-            #################################################################
             #################################################################
             #################################################################
             #################################################################
@@ -184,8 +250,6 @@ load uImage.
    Filename '/sifive/fu540/uRamdisk'.
    Load address: 0x88300000
    Loading: #################################################################
-            #################################################################
-            #################################################################
             #################################################################
             #################################################################
             #################################################################
@@ -363,3 +427,300 @@ load uImage.
 
    Please press Enter to activate this console.
    / #
+
+
+2) Use u-boot-spl as a 1st stage bootloader
+
+The U-Boot SPL will boot in M mode and load the FIT image which include
+OpenSBI and U-Boot proper images. After loading progress, it will jump
+to OpenSBI first and then U-Boot proper which will run in S mode.
+
+Sample boot log from HiFive Unleashed board
+-------------------------------------------
+
+.. code-block:: none
+
+   U-Boot SPL 2020.04-rc1-00212-g375b0a2dad-dirty (Feb 13 2020 - 17:45:44 +0530)
+   Trying to boot from MMC1
+
+
+   U-Boot 2020.04-rc1-00212-g375b0a2dad-dirty (Feb 13 2020 - 17:45:44 +0530)
+
+   CPU:   rv64imafdc
+   Model: SiFive HiFive Unleashed A00
+   DRAM:  8 GiB
+   MMC:   spi at 10050000:mmc at 0: 0
+   In:    serial at 10010000
+   Out:   serial at 10010000
+   Err:   serial at 10010000
+   Board serial number should not be 0 !!
+   Net:
+   Warning: ethernet at 10090000 (eth0) using random MAC address - 92:79:17:2d:7b:b7
+   eth0: ethernet at 10090000
+   Hit any key to stop autoboot:  0
+   => version
+   U-Boot 2020.04-rc1-00212-g375b0a2dad-dirty (Feb 13 2020 - 17:45:44 +0530)
+
+   riscv64-unknown-linux-gnu-gcc (crosstool-NG 1.24.0.37-3f461da) 9.2.0
+   GNU ld (crosstool-NG 1.24.0.37-3f461da) 2.32
+   => mmc info
+   Device: spi at 10050000:mmc at 0
+   Manufacturer ID: 3
+   OEM: 5344
+   Name: SC16G
+   Bus Speed: 20000000
+   Mode: SD Legacy
+   Rd Block Len: 512
+   SD version 2.0
+   High Capacity: Yes
+   Capacity: 14.8 GiB
+   Bus Width: 1-bit
+   Erase Group Size: 512 Bytes
+   => mmc part
+
+   Partition Map for MMC device 0  --   Partition Type: EFI
+
+   Part    Start LBA       End LBA         Name
+   Attributes
+   Type GUID
+   Partition GUID
+   1     0x00000800      0x000107ff      "SiFive bare-metal (or stage 2 loader"
+   attrs:  0x0000000000000000
+   type:   2e54b353-1271-4842-806f-e436d6af6985
+   guid:   3c9eabe1-b16b-4a2e-9b4e-f065c740bb86
+   2     0x00040800      0x00ecdfde      "Linux filesystem"
+   attrs:  0x0000000000000000
+   type:   0fc63daf-8483-4772-8e79-3d69d8477de4
+   guid:   ad9309ff-d204-42f0-9f99-f3275a83f565
+
+Now you can configure your networking, tftp server and use tftp boot method to
+load uImage.
+
+.. code-block:: none
+
+   => setenv serverip 172.16.35.74
+   => setenv ipaddr 172.16.35.40
+   => tftpboot 0x83000000 fit.itb
+   ethernet at 10090000: PHY present at 0
+   ethernet at 10090000: Starting autonegotiation...
+   ethernet at 10090000: Autonegotiation complete
+   ethernet at 10090000: link up, 100Mbps full-duplex (lpa: 0x41e1)
+   Using ethernet at 10090000 device
+   TFTP from server 172.16.35.74; our IP address is 172.16.35.40
+   Filename 'fit.itb'.
+   Load address: 0x83000000
+   Loading: #################################################################
+   #################################################################
+   #################################################################
+   #################################################################
+   #################################################################
+   #################################################################
+   #################################################################
+   #################################################################
+   #################################################################
+   #################################################################
+   #################################################################
+   #################################################################
+   #################################################################
+   #################################################################
+   #################################################################
+   #################################################################
+   #################################################################
+   #################################################################
+   ################################################################
+   ###################################
+   878.9 KiB/s
+   done
+   Bytes transferred = 13823823 (d2ef4f hex)
+   => bootm 0x83000000
+   ## Loading kernel from FIT Image at 83000000 ...
+   Using 'config-1' configuration
+   Trying 'kernel at 1' kernel subimage
+   Description:  Linux kernel
+   Type:         Kernel Image
+   Compression:  uncompressed
+   Data Start:   0x830000d8
+   Data Size:    9247260 Bytes = 8.8 MiB
+   Architecture: RISC-V
+   OS:           Linux
+   Load Address: 0x80200000
+   Entry Point:  0x80200000
+   Verifying Hash Integrity ... OK
+   ## Loading ramdisk from FIT Image at 83000000 ...
+   Using 'config-1' configuration
+   Trying 'ramdisk at 1' ramdisk subimage
+   Description:  ramdisk
+   Type:         RAMDisk Image
+   Compression:  gzip compressed
+   Data Start:   0x838d3378
+   Data Size:    4568674 Bytes = 4.4 MiB
+   Architecture: RISC-V
+   OS:           Linux
+   Load Address: 0x82000000
+   Entry Point:  unavailable
+   Verifying Hash Integrity ... OK
+   Loading ramdisk from 0x838d3378 to 0x82000000
+   WARNING: 'compression' nodes for ramdisks are deprecated, please fix your .its file!
+   ## Loading fdt from FIT Image at 83000000 ...
+   Using 'config-1' configuration
+   Trying 'fdt at 1' fdt subimage
+   Description:  unavailable
+   Type:         Flat Device Tree
+   Compression:  uncompressed
+   Data Start:   0x838d1b80
+   Data Size:    6023 Bytes = 5.9 KiB
+   Architecture: RISC-V
+   Verifying Hash Integrity ... OK
+   Booting using the fdt blob at 0x838d1b80
+   Loading Kernel Image
+   Using Device Tree in place at 00000000838d1b80, end 00000000838d6306
+
+   Starting kernel ...
+
+   [    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
+   [    0.000000] Linux version 5.3.0-13236-g97f9a3c4eee5 (pragneshp at sachinj2-OptiPlex-7010) (gcc version 8.2.0 (Buildroot 2018.11-rc2-00003-ga0787e9
+   [    0.000000] earlycon: sifive0 at MMIO 0x0000000010010000 (options '')
+   [    0.000000] printk: bootconsole [sifive0] enabled
+   [    0.000000] Initial ramdisk at: 0x(____ptrval____) (4568674 bytes)
+   [    0.000000] Zone ranges:
+   [    0.000000]   DMA32    [mem 0x0000000080200000-0x00000000ffffffff]
+   [    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 is not available
+   [    0.000000] CPU with hartid=0 is not available
+   [    0.000000] elf_hwcap is 0x112d
+   [    0.000000] percpu: Embedded 17 pages/cpu s30680 r8192 d30760 u69632
+   [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 2067975
+   [    0.000000] Kernel command line: earlycon=sifive,0x10010000 console=ttySIF0,115200
+   [    0.000000] Dentry cache hash table entries: 1048576 (order: 11, 8388608 bytes, linear)
+   [    0.000000] Inode-cache hash table entries: 524288 (order: 10, 4194304 bytes, linear)
+   [    0.000000] Sorting __ex_table...
+   [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
+   [    0.000000] Memory: 8179828K/8386560K available (6081K kernel code, 388K rwdata, 2025K rodata, 209K init, 307K bss, 206732K reserved, 0K cma-r)
+   [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
+   [    0.000000] rcu: Hierarchical RCU implementation.
+   [    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 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 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.000006] sched_clock: 64 bits at 1000kHz, resolution 1000ns, wraps every 2199023255500ns
+   [    0.008467] Console: colour dummy device 80x25
+   [    0.012819] Calibrating delay loop (skipped), value calculated using timer frequency.. 2.00 BogoMIPS (lpj=4000)
+   [    0.022844] pid_max: default: 32768 minimum: 301
+   [    0.027915] Mount-cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
+   [    0.035332] Mountpoint-cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
+   [    0.044791] rcu: Hierarchical SRCU implementation.
+   [    0.049255] smp: Bringing up secondary CPUs ...
+   [    0.055034] smp: Brought up 1 node, 4 CPUs
+   [    0.059664] devtmpfs: initialized
+   [    0.063818] random: get_random_u32 called from bucket_table_alloc.isra.29+0x4e/0x160 with crng_init=0
+   [    0.072588] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
+   [    0.082000] futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
+   [    0.089513] NET: Registered protocol family 16
+   [    0.105911] vgaarb: loaded
+   [    0.108166] SCSI subsystem initialized
+   [    0.111946] usbcore: registered new interface driver usbfs
+   [    0.117105] usbcore: registered new interface driver hub
+   [    0.122486] usbcore: registered new device driver usb
+   [    0.128073] clocksource: Switched to clocksource riscv_clocksource
+   [    0.140277] NET: Registered protocol family 2
+   [    0.144449] tcp_listen_portaddr_hash hash table entries: 4096 (order: 4, 65536 bytes, linear)
+   [    0.152620] TCP established hash table entries: 65536 (order: 7, 524288 bytes, linear)
+   [    0.162238] TCP bind hash table entries: 65536 (order: 8, 1048576 bytes, linear)
+   [    0.172159] TCP: Hash tables configured (established 65536 bind 65536)
+   [    0.178343] UDP hash table entries: 4096 (order: 5, 131072 bytes, linear)
+   [    0.185140] UDP-Lite hash table entries: 4096 (order: 5, 131072 bytes, linear)
+   [    0.192553] NET: Registered protocol family 1
+   [    0.196752] RPC: Registered named UNIX socket transport module.
+   [    0.202145] RPC: Registered udp transport module.
+   [    0.206828] RPC: Registered tcp transport module.
+   [    0.211512] RPC: Registered tcp NFSv4.1 backchannel transport module.
+   [    0.217939] PCI: CLS 0 bytes, default 64
+   [    0.222139] Unpacking initramfs...
+   [    0.578803] Freeing initrd memory: 4460K
+   [    0.582972] workingset: timestamp_bits=62 max_order=21 bucket_order=0
+   [    0.596643] NFS: Registering the id_resolver key type
+   [    0.600950] Key type id_resolver registered
+   [    0.605134] Key type id_legacy registered
+   [    0.609090] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
+   [    0.615928] 9p: Installing v9fs 9p2000 file system support
+   [    0.621581] NET: Registered protocol family 38
+   [    0.625700] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
+   [    0.633051] io scheduler mq-deadline registered
+   [    0.637559] io scheduler kyber registered
+   [    0.685592] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
+   [    0.692184] 10010000.serial: ttySIF0 at MMIO 0x10010000 (irq = 4, base_baud = 0) is a SiFive UART v0
+   [    0.700566] printk: console [ttySIF0] enabled
+   [    0.700566] printk: console [ttySIF0] enabled
+   [    0.709228] printk: bootconsole [sifive0] disabled
+   [    0.709228] printk: bootconsole [sifive0] disabled
+   [    0.719030] 10011000.serial: ttySIF1 at MMIO 0x10011000 (irq = 1, base_baud = 0) is a SiFive UART v0
+   [    0.728364] [drm] radeon kernel modesetting enabled.
+   [    0.745292] loop: module loaded
+   [    0.748208] sifive_spi 10040000.spi: mapped; irq=3, cs=1
+   [    0.753490] sifive_spi 10050000.spi: mapped; irq=5, cs=1
+   [    0.758811] libphy: Fixed MDIO Bus: probed
+   [    0.762886] macb 10090000.ethernet: Registered clk switch 'sifive-gemgxl-mgmt'
+   [    0.769643] macb: GEM doesn't support hardware ptp.
+   [    0.774532] libphy: MACB_mii_bus: probed
+   [    0.940349] Microsemi VSC8541 SyncE 10090000.ethernet-ffffffff:00: attached PHY driver [Microsemi VSC8541 SyncE] (mii_bus:phy_addr=10090000.et)
+   [    0.954893] macb 10090000.ethernet eth0: Cadence GEM rev 0x10070109 at 0x10090000 irq 6 (92:79:17:2d:7b:b7)
+   [    0.964698] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
+   [    0.970417] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
+   [    0.976410] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
+   [    0.982832] ehci-pci: EHCI PCI platform driver
+   [    0.987288] ehci-platform: EHCI generic platform driver
+   [    0.992547] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
+   [    0.998646] ohci-pci: OHCI PCI platform driver
+   [    1.003092] ohci-platform: OHCI generic platform driver
+   [    1.008557] usbcore: registered new interface driver uas
+   [    1.013621] usbcore: registered new interface driver usb-storage
+   [    1.019695] mousedev: PS/2 mouse device common for all mice
+   [    1.050569] mmc_spi spi1.0: SD/MMC host mmc0, no DMA, no WP, no poweroff, cd polling
+   [    1.057714] usbcore: registered new interface driver usbhid
+   [    1.063098] usbhid: USB HID core driver
+   [    1.067805] NET: Registered protocol family 10
+   [    1.072421] Segment Routing with IPv6
+   [    1.075367] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
+   [    1.081745] NET: Registered protocol family 17
+   [    1.085867] 9pnet: Installing 9P2000 support
+   [    1.089951] Key type dns_resolver registered
+   [    1.096367] Freeing unused kernel memory: 208K
+   [    1.100023] This architecture does not have kernel memory protection.
+   [    1.106468] Run /init as init process
+   Starting syslogd: OK
+   Starting klogd: OK
+   Starting mdev...
+   /etc/init.d/S10mdev: line 9: can't create /proc/sys/kernel/hotplug: nonexistent directory
+   [    1.167972] mmc0: host does not support reading read-only switch, assuming write-enable
+   [    1.175224] mmc0: new SDHC card on SPI
+   [    1.180428] mmcblk0: mmc0:0000 SC16G 14.8 GiB
+   [    1.214935]  mmcblk0: p1 p2 p4
+   modprobe: can't change directory to '/lib/modules': No such file or directory
+   Initializing random number generator... [    1.664435] random: dd: uninitialized urandom read (512 bytes read)
+   done.
+   Starting network: udhcpc: started, v1.29.3
+   udhcpc: sending discover
+   [    3.756700] macb 10090000.ethernet eth0: link up (100/Full)
+   [    3.761515] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
+   udhcpc: sending discover
+   udhcpc: sending select for 172.16.35.4
+   udhcpc: lease of 172.16.35.4 obtained, lease time 3600
+   deleting routers
+   adding dns 172.16.34.75
+   adding dns 172.16.24.25
+   OK
+   Starting dropbear sshd: [    4.893179] random: dropbear: uninitialized urandom read (32 bytes read)
+   OK
+
+   Welcome to Buildroot
+   buildroot login: root
+   Password:
+   #
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PATCH v5 01/14] misc: add driver for the SiFive otp controller
  2020-03-11  7:03 ` [PATCH v5 01/14] misc: add driver for the SiFive otp controller Pragnesh Patel
@ 2020-03-11 10:25   ` Bin Meng
  2020-03-17 17:30     ` Pragnesh Patel
  0 siblings, 1 reply; 53+ messages in thread
From: Bin Meng @ 2020-03-11 10:25 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 11, 2020 at 3:03 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> Added a misc driver to handle OTP memory in SiFive SoCs.
>
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> ---
>  drivers/misc/Kconfig      |   7 ++
>  drivers/misc/Makefile     |   1 +
>  drivers/misc/sifive-otp.c | 241 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 249 insertions(+)
>  create mode 100644 drivers/misc/sifive-otp.c
>
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index f18aa8f7ba..fcb45c63d4 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -68,6 +68,13 @@ config ROCKCHIP_OTP
>           addressing and a length or through child-nodes that are generated
>           based on the e-fuse map retrieved from the DTS.
>
> +config SIFIVE_OTP
> +       bool "SiFive Ememory OTP driver"

nits: eMemory

> +       depends on RISCV && MISC
> +       help
> +         Enable support for reading and writing the ememory OTP on the

nits: eMemory

> +         SiFive SoCs.
> +
>  config VEXPRESS_CONFIG
>         bool "Enable support for Arm Versatile Express config bus"
>         depends on MISC
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index 2b843de93c..ee888631b6 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -58,6 +58,7 @@ obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
>  obj-$(CONFIG_QFW) += qfw.o
>  obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
>  obj-$(CONFIG_ROCKCHIP_OTP) += rockchip-otp.o
> +obj-$(CONFIG_SIFIVE_OTP) += sifive-otp.o
>  obj-$(CONFIG_SANDBOX) += syscon_sandbox.o misc_sandbox.o
>  obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o
>  obj-$(CONFIG_SMSC_SIO1007) += smsc_sio1007.o
> diff --git a/drivers/misc/sifive-otp.c b/drivers/misc/sifive-otp.c
> new file mode 100644
> index 0000000000..1e6c1a11b2
> --- /dev/null
> +++ b/drivers/misc/sifive-otp.c
> @@ -0,0 +1,241 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * This is a driver for the eMemory EG004K32TQ028XW01 NeoFuse
> + * One-Time-Programmable (OTP) memory used within the SiFive FU540.
> + * It is documented in the FU540 manual here:
> + * https://www.sifive.com/documentation/chips/freedom-u540-c000-manual/
> + *
> + * Copyright (C) 2018 Philipp Hug <philipp@hug.cx>
> + * Copyright (C) 2018 Joey Hewitt <joey@joeyhewitt.com>
> + *
> + * Copyright (C) 2020 SiFive, Inc
> + */
> +
> +/*
> + * The FU540 stores 4096x32 bit (16KiB) values.
> + * Index 0x00-0xff are reserved for SiFive internal use. (first 1KiB)
> + * Right now first 1KB is used to store only serial number.

nits: 1KiB

> + */
> +
> +#include <common.h>
> +#include <dm/device.h>
> +#include <dm/read.h>
> +#include <linux/io.h>
> +#include <misc.h>
> +
> +#define BYTES_PER_FUSE         4
> +
> +#define PA_RESET_VAL           0x00
> +#define PAS_RESET_VAL          0x00
> +#define PAIO_RESET_VAL         0x00
> +#define PDIN_RESET_VAL         0x00
> +#define PTM_RESET_VAL          0x00
> +
> +#define PCLK_ENABLE_VAL                        BIT(0)
> +#define PCLK_DISABLE_VAL               0x00
> +
> +#define PWE_WRITE_ENABLE               BIT(0)
> +#define PWE_WRITE_DISABLE              0x00
> +
> +#define PTM_FUSE_PROGRAM_VAL           BIT(1)
> +
> +#define PCE_ENABLE_INPUT               BIT(0)
> +#define PCE_DISABLE_INPUT              0x00
> +
> +#define PPROG_ENABLE_INPUT             BIT(0)
> +#define PPROG_DISABLE_INPUT            0x00
> +
> +#define PTRIM_ENABLE_INPUT             BIT(0)
> +#define PTRIM_DISABLE_INPUT            0x00
> +
> +#define PDSTB_DEEP_STANDBY_ENABLE      BIT(0)
> +#define PDSTB_DEEP_STANDBY_DISABLE     0x00
> +
> +struct sifive_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;

__packed is not needed

> +
> +struct sifive_otp_platdata {
> +       struct sifive_otp_regs __iomem *regs;
> +       u32 total_fuses;
> +};
> +
> +/*
> + * offset and size are assumed aligned to the size of the fuses (32bit).

nits: 32-bit

> + */
> +static int sifive_otp_read(struct udevice *dev, int offset,
> +                          void *buf, int size)
> +{
> +       struct sifive_otp_platdata *plat = dev_get_platdata(dev);
> +       struct sifive_otp_regs *regs = (struct sifive_otp_regs *)plat->regs;
> +
> +       int fuseidx = offset / BYTES_PER_FUSE;
> +       int fusecount = size / BYTES_PER_FUSE;

Should we check whether offset and size are multiple of BYTES_PER_FUSE?

> +       u32 fusebuf[fusecount];

This utilizes C99 VLA. What is the largest fusecount this function
could aspect? If it's a large one we might have a stack overflow
problem.

> +
> +       /* check bounds */
> +       if (offset < 0 || size < 0)
> +               return -EINVAL;
> +       if (fuseidx >= plat->total_fuses)
> +               return -EINVAL;
> +       if ((fuseidx + fusecount) > plat->total_fuses)
> +               return -EINVAL;
> +
> +       /* init OTP */
> +       iowrite32(PDSTB_DEEP_STANDBY_ENABLE, &regs->pdstb);

Use writel()?

> +       iowrite32(PTRIM_ENABLE_INPUT, &regs->ptrim);
> +       iowrite32(PCE_ENABLE_INPUT, &regs->pce);
> +
> +       /* read all requested fuses */
> +       for (unsigned int i = 0; i < fusecount; i++, fuseidx++) {
> +               iowrite32(fuseidx, &regs->pa);
> +
> +               /* cycle clock to read */
> +               iowrite32(PCLK_ENABLE_VAL, &regs->pclk);
> +               mdelay(1);
> +               iowrite32(PCLK_DISABLE_VAL, &regs->pclk);
> +               mdelay(1);
> +
> +               /* read the value */
> +               fusebuf[i] = ioread32(&regs->pdout);
> +       }
> +
> +       /* shut down */
> +       iowrite32(PCE_DISABLE_INPUT, &regs->pce);
> +       iowrite32(PTRIM_DISABLE_INPUT, &regs->ptrim);
> +       iowrite32(PDSTB_DEEP_STANDBY_DISABLE, &regs->pdstb);
> +
> +       // copy out

Should use /* */ comment format

> +       memcpy(buf, fusebuf, size);
> +
> +       return size;
> +}
> +
> +/*
> + * Caution:
> + * OTP can be written only once, so use carefully.
> + *
> + * offset and size are assumed aligned to the size of the fuses (32bit).

nits: 32-bit

> + */
> +static int sifive_otp_write(struct udevice *dev, int offset,
> +                           const void *buf, int size)
> +{
> +       struct sifive_otp_platdata *plat = dev_get_platdata(dev);
> +       struct sifive_otp_regs *regs = (struct sifive_otp_regs *)plat->regs;
> +
> +       int fuseidx = offset / BYTES_PER_FUSE;
> +       int fusecount = size / BYTES_PER_FUSE;
> +       u32 *write_buf = (u32 *)buf;
> +       u32 write_data;
> +       int i, pas, bit;
> +
> +       /* check bounds */
> +       if (offset < 0 || size < 0)
> +               return -EINVAL;
> +       if (fuseidx >= plat->total_fuses)
> +               return -EINVAL;
> +       if ((fuseidx + fusecount) > plat->total_fuses)
> +               return -EINVAL;
> +
> +       /* init OTP */
> +       iowrite32(PDSTB_DEEP_STANDBY_ENABLE, &regs->pdstb);
> +       iowrite32(PTRIM_ENABLE_INPUT, &regs->ptrim);
> +
> +       /* reset registers */
> +       iowrite32(PCLK_DISABLE_VAL, &regs->pclk);
> +       iowrite32(PA_RESET_VAL, &regs->pa);
> +       iowrite32(PAS_RESET_VAL, &regs->pas);
> +       iowrite32(PAIO_RESET_VAL, &regs->paio);
> +       iowrite32(PDIN_RESET_VAL, &regs->pdin);
> +       iowrite32(PWE_WRITE_DISABLE, &regs->pwe);
> +       iowrite32(PTM_FUSE_PROGRAM_VAL, &regs->ptm);
> +       mdelay(1);
> +
> +       iowrite32(PCE_ENABLE_INPUT, &regs->pce);
> +       iowrite32(PPROG_ENABLE_INPUT, &regs->pprog);
> +       iowrite32(PTRIM_ENABLE_INPUT, &regs->ptrim);

This is already enabled a few lines above, in the /* init OTP */ section.

> +
> +       /* write all requested fuses */
> +       for (i = 0; i < fusecount; i++, fuseidx++) {
> +               iowrite32(fuseidx, &regs->pa);
> +               write_data = *(write_buf++);
> +
> +               for (pas = 0; pas < 2; pas++) {
> +                       iowrite32(pas, &regs->pas);
> +
> +                       for (bit = 0; bit < 32; bit++) {
> +                               iowrite32(bit, &regs->paio);
> +                               iowrite32(((write_data >> bit) & 1),
> +                                         &regs->pdin);
> +                               mdelay(1);
> +
> +                               iowrite32(PWE_WRITE_ENABLE, &regs->pwe);
> +                               mdelay(1);
> +                               iowrite32(PWE_WRITE_DISABLE, &regs->pwe);
> +                               mdelay(1);
> +                       }
> +               }
> +
> +               iowrite32(PAS_RESET_VAL, &regs->pas);
> +       }
> +
> +       /* shut down */
> +       iowrite32(PWE_WRITE_DISABLE, &regs->pwe);
> +       iowrite32(PPROG_DISABLE_INPUT, &regs->pprog);
> +       iowrite32(PCE_DISABLE_INPUT, &regs->pce);
> +       iowrite32(PTM_RESET_VAL, &regs->ptm);
> +
> +       iowrite32(PTRIM_DISABLE_INPUT, &regs->ptrim);
> +       iowrite32(PDSTB_DEEP_STANDBY_DISABLE, &regs->pdstb);
> +
> +       return size;
> +}
> +
> +static int sifive_otp_ofdata_to_platdata(struct udevice *dev)
> +{
> +       struct sifive_otp_platdata *plat = dev_get_platdata(dev);
> +       int ret;
> +
> +       plat->regs = dev_read_addr_ptr(dev);
> +
> +       ret = dev_read_u32(dev, "fuse-count", &plat->total_fuses);
> +       if (ret < 0) {
> +               pr_err("\"fuse-count\" not found\n");
> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +
> +static const struct misc_ops sifive_otp_ops = {
> +       .read = sifive_otp_read,
> +       .write = sifive_otp_write,
> +};
> +
> +static const struct udevice_id sifive_otp_ids[] = {
> +       { .compatible = "sifive,fu540-otp" },

Based on other existing compatible strings, I think this should be
named as "sifive,fu540-c000-otp".

> +       {}
> +};
> +
> +U_BOOT_DRIVER(sifive_otp) = {
> +       .name = "sifive_otp",
> +       .id = UCLASS_MISC,
> +       .of_match = sifive_otp_ids,
> +       .ofdata_to_platdata = sifive_otp_ofdata_to_platdata,
> +       .platdata_auto_alloc_size = sizeof(struct sifive_otp_platdata),
> +       .ops = &sifive_otp_ops,
> +};
> --

Regards,
Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 02/14] riscv: sifive: fu540: Use OTP DM driver for serial environment variable
  2020-03-11  7:03 ` [PATCH v5 02/14] riscv: sifive: fu540: Use OTP DM driver for serial environment variable Pragnesh Patel
@ 2020-03-11 13:32   ` Bin Meng
  2020-03-11 14:52     ` Bin Meng
  2020-03-11 15:00   ` Bin Meng
  1 sibling, 1 reply; 53+ messages in thread
From: Bin Meng @ 2020-03-11 13:32 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 11, 2020 at 3:03 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> Use the OTP DM driver to set the serial environment variable.
>
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> ---
>  arch/riscv/dts/fu540-c000-u-boot.dtsi         |  14 +++
>  .../dts/hifive-unleashed-a00-u-boot.dtsi      |   6 +
>  board/sifive/fu540/Kconfig                    |   2 +
>  board/sifive/fu540/fu540.c                    | 113 +++++++-----------
>  4 files changed, 62 insertions(+), 73 deletions(-)
>  create mode 100644 arch/riscv/dts/fu540-c000-u-boot.dtsi
>  create mode 100644 arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>
> diff --git a/arch/riscv/dts/fu540-c000-u-boot.dtsi b/arch/riscv/dts/fu540-c000-u-boot.dtsi
> new file mode 100644
> index 0000000000..31fd113c7d
> --- /dev/null
> +++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
> @@ -0,0 +1,14 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2019 SiFive, Inc

nits: 2020?

> + */
> +
> +/ {
> +       soc {
> +               otp: otp at 10070000 {
> +                       compatible = "sifive,fu540-otp";
> +                       reg = <0x0 0x10070000 0x0 0x0FFF>;
> +                       fuse-count = <0x1000>;

Add status = "disabled" here?

> +               };
> +       };
> +};
> diff --git a/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
> new file mode 100644
> index 0000000000..bec0d19134
> --- /dev/null
> +++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
> @@ -0,0 +1,6 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2019 SiFive, Inc

nits: 2020?

> + */
> +
> +#include "fu540-c000-u-boot.dtsi"

Add

&otp {
status = "okay";
}

here?

> diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
> index 5ca21474de..900197bbb2 100644
> --- a/board/sifive/fu540/Kconfig
> +++ b/board/sifive/fu540/Kconfig
> @@ -48,5 +48,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
>         imply SIFIVE_GPIO
>         imply CMD_GPIO
>         imply SMP
> +       imply MISC
> +       imply SIFIVE_OTP
>
>  endif
> diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
> index 47a2090251..6c642b3082 100644
> --- a/board/sifive/fu540/fu540.c
> +++ b/board/sifive/fu540/fu540.c
> @@ -10,94 +10,61 @@
>  #include <dm.h>
>  #include <linux/delay.h>
>  #include <linux/io.h>
> +#include <misc.h>
> +
> +/*
> + * This define is a value used for error/unknown serial.
> + * If we really care about distinguishing errors and 0 is
> + * valid, we'll need a different one.
> + */
> +#define ERROR_READING_SERIAL_NUMBER       0
>
>  #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)
> +#if CONFIG_IS_ENABLED(SIFIVE_OTP)
> +static u32 otp_read_serialnum(struct udevice *dev)
>  {
> -       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);
> -       }
> +       int ret;
> +       u32 serial[2] = {0};
>
> -       /* shut down */
> -       writel(0, &regs->pce);
> -       writel(0, &regs->ptrim);
> -       writel(0, &regs->pdstb);
> +       for (int i = 0xfe * 4; i > 0; i -= 8) {
> +               ret = misc_read(dev, i, serial, sizeof(serial));
>
> -       /* copy out */
> -       memcpy(buf, fusebuf, size);
> +               if (ret != sizeof(serial)) {
> +                       printf("%s: error reading serial from OTP\n", __func__);
> +                       break;
> +               }
>
> -       return 0;
> +               if (serial[0] == ~serial[1])
> +                       return serial[0];
> +       }
> +
> +       return ERROR_READING_SERIAL_NUMBER;
>  }
> +#endif
>
>  static u32 fu540_read_serialnum(void)
>  {
> +       u32 serial = ERROR_READING_SERIAL_NUMBER;
> +
> +#if CONFIG_IS_ENABLED(SIFIVE_OTP)
> +       struct udevice *dev;
>         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];
> +       // init OTP

Use /* */ comment format

> +       ret = uclass_get_device_by_driver(UCLASS_MISC,
> +                                         DM_GET_DRIVER(sifive_otp), &dev);
> +
> +       if (ret) {
> +               debug("%s: could not find otp device\n", __func__);
> +               return serial;
>         }
>
> -       return 0;
> +       // read serial from OTP and set env var

Use /* */ comment format

> +       serial = otp_read_serialnum(dev);
> +#endif
> +
> +       return serial;
>  }
>
>  static void fu540_setup_macaddr(u32 serialnum)
> --

Regards,
Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 04/14] lib: Makefile: build crc7.c when CONFIG_MMC_SPI
  2020-03-11  7:03 ` [PATCH v5 04/14] lib: Makefile: build crc7.c when CONFIG_MMC_SPI Pragnesh Patel
@ 2020-03-11 13:52   ` Bin Meng
  2020-03-17 16:47     ` Pragnesh Patel
  0 siblings, 1 reply; 53+ messages in thread
From: Bin Meng @ 2020-03-11 13:52 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> When build U-boot SPL, meet an issue of undefined reference to

nits: U-Boot

> 'crc7' for drivers/mmc/mmc_spi.c, so let's compile crc7.c when
> CONFIG_MMC_SPI selected.
>
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> ---
>  common/spl/Kconfig | 7 +++++++
>  lib/Makefile       | 1 +
>  2 files changed, 8 insertions(+)
>
> diff --git a/common/spl/Kconfig b/common/spl/Kconfig
> index b03a476b9f..f93f552f5e 100644
> --- a/common/spl/Kconfig
> +++ b/common/spl/Kconfig
> @@ -401,6 +401,13 @@ config SPL_CRC32_SUPPORT
>           for detected accidental image corruption. For secure applications you
>           should consider SHA1 or SHA256.
>
> +config SPL_CRC7_SUPPORT
> +       bool "Support CRC7"
> +       default y if MMC_SPI

This dependency should be set in the MMPC_SPI driver with a "select".
The driver cannot work without it.

> +       help
> +         Enable CRC7 hashing for drivers which are using in SPL.
> +         This is a 32-bit checksum value that can be used to verify images.
> +
>  config SPL_MD5_SUPPORT
>         bool "Support MD5"
>         depends on SPL_FIT
> diff --git a/lib/Makefile b/lib/Makefile
> index 15259d0473..7a50aa56ef 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -78,6 +78,7 @@ endif
>
>  ifdef CONFIG_SPL_BUILD
>  obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o
> +obj-$(CONFIG_SPL_CRC7_SUPPORT) += crc7.o
>  obj-$(CONFIG_$(SPL_TPL_)HASH_SUPPORT) += crc16.o
>  obj-y += net_utils.o
>  endif
> --

Regards,
Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 05/14] riscv: sifive: dts: fu540: Add board -u-boot.dtsi files
  2020-03-11  7:03 ` [PATCH v5 05/14] riscv: sifive: dts: fu540: Add board -u-boot.dtsi files Pragnesh Patel
@ 2020-03-11 14:51   ` Bin Meng
  2020-03-17 16:44     ` Pragnesh Patel
  0 siblings, 1 reply; 53+ messages in thread
From: Bin Meng @ 2020-03-11 14:51 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> Devicetree files in FU540 platform is synced from Linux, like other
> platforms does. Apart from these u-boot in FU540 would also require

nits: U-Boot

> some u-boot specific node like clint.

ditto

>
> So, create board specific -u-boot.dtsi files. This would help of
> maintain u-boot specific changes separately without touching Linux

ditto

> dts(i) files which indeed easy for syncing from Linux between
> releases.
>
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> Reviewed-by: Anup Patel <anup.patel@wdc.com>
> ---
>  arch/riscv/dts/fu540-c000-u-boot.dtsi         | 42 +++++++++++++++++++
>  .../dts/hifive-unleashed-a00-u-boot.dtsi      | 16 +++++++
>  2 files changed, 58 insertions(+)
>
> diff --git a/arch/riscv/dts/fu540-c000-u-boot.dtsi b/arch/riscv/dts/fu540-c000-u-boot.dtsi
> index 31fd113c7d..2d3d62801f 100644
> --- a/arch/riscv/dts/fu540-c000-u-boot.dtsi
> +++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
> @@ -4,11 +4,53 @@
>   */
>
>  / {
> +       cpus {
> +               u-boot,dm-spl;
> +               cpu0: cpu at 0 {
> +                       u-boot,dm-spl;
> +                       status = "okay";
> +                       cpu0_intc: interrupt-controller {
> +                               u-boot,dm-spl;
> +                       };
> +               };
> +               cpu1: cpu at 1 {
> +                       u-boot,dm-spl;
> +               };
> +               cpu2: cpu at 2 {
> +                       u-boot,dm-spl;
> +               };
> +               cpu3: cpu at 3 {
> +                       u-boot,dm-spl;
> +               };
> +               cpu4: cpu at 4 {
> +                       u-boot,dm-spl;
> +               };
> +       };
> +
>         soc {
> +               u-boot,dm-spl;
>                 otp: otp at 10070000 {
>                         compatible = "sifive,fu540-otp";
>                         reg = <0x0 0x10070000 0x0 0x0FFF>;
>                         fuse-count = <0x1000>;
>                 };
> +               clint at 2000000 {
> +                       compatible = "riscv,clint0";
> +                       interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7 >;

Looks this property value is incomplete: missing cpu1/2/3/4_intc ?

> +                       reg = <0x0 0x2000000 0x0 0xc0000>;
> +                       u-boot,dm-spl;
> +               };
>         };
>  };
> +
> +&prci {
> +       u-boot,dm-spl;
> +};
> +
> +&uart0 {
> +       u-boot,dm-spl;
> +};
> +
> +&qspi2 {
> +       u-boot,dm-spl;
> +};
> diff --git a/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
> index bec0d19134..cce1bd943e 100644
> --- a/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
> +++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
> @@ -4,3 +4,19 @@
>   */
>
>  #include "fu540-c000-u-boot.dtsi"
> +
> +/ {
> +       hfclk {
> +               u-boot,dm-spl;
> +       };
> +
> +       rtcclk {
> +               u-boot,dm-spl;
> +       };
> +};
> +
> +&qspi2 {
> +       mmc at 0 {
> +               u-boot,dm-spl;
> +       };
> +};
> --

Looks good otherwise

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 02/14] riscv: sifive: fu540: Use OTP DM driver for serial environment variable
  2020-03-11 13:32   ` Bin Meng
@ 2020-03-11 14:52     ` Bin Meng
  2020-03-17 15:45       ` Pragnesh Patel
  0 siblings, 1 reply; 53+ messages in thread
From: Bin Meng @ 2020-03-11 14:52 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 11, 2020 at 9:32 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Wed, Mar 11, 2020 at 3:03 PM Pragnesh Patel
> <pragnesh.patel@sifive.com> wrote:
> >
> > Use the OTP DM driver to set the serial environment variable.
> >
> > Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> > ---
> >  arch/riscv/dts/fu540-c000-u-boot.dtsi         |  14 +++
> >  .../dts/hifive-unleashed-a00-u-boot.dtsi      |   6 +
> >  board/sifive/fu540/Kconfig                    |   2 +
> >  board/sifive/fu540/fu540.c                    | 113 +++++++-----------
> >  4 files changed, 62 insertions(+), 73 deletions(-)
> >  create mode 100644 arch/riscv/dts/fu540-c000-u-boot.dtsi
> >  create mode 100644 arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
> >
> > diff --git a/arch/riscv/dts/fu540-c000-u-boot.dtsi b/arch/riscv/dts/fu540-c000-u-boot.dtsi
> > new file mode 100644
> > index 0000000000..31fd113c7d
> > --- /dev/null
> > +++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
> > @@ -0,0 +1,14 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * (C) Copyright 2019 SiFive, Inc
>
> nits: 2020?
>
> > + */
> > +
> > +/ {
> > +       soc {
> > +               otp: otp at 10070000 {
> > +                       compatible = "sifive,fu540-otp";
> > +                       reg = <0x0 0x10070000 0x0 0x0FFF>;
> > +                       fuse-count = <0x1000>;
>
> Add status = "disabled" here?

After reviewing patch 5 in this series, I think we can leave without
adding "status" property here.

>
> > +               };
> > +       };
> > +};
> > diff --git a/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
> > new file mode 100644
> > index 0000000000..bec0d19134
> > --- /dev/null
> > +++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
> > @@ -0,0 +1,6 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (C) 2019 SiFive, Inc
>
> nits: 2020?
>
> > + */
> > +
> > +#include "fu540-c000-u-boot.dtsi"
>
> Add
>
> &otp {
> status = "okay";
> }
>
> here?

After reviewing patch 5 in this series, I think we can leave without
adding "status" property here.

Regards,
Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 02/14] riscv: sifive: fu540: Use OTP DM driver for serial environment variable
  2020-03-11  7:03 ` [PATCH v5 02/14] riscv: sifive: fu540: Use OTP DM driver for serial environment variable Pragnesh Patel
  2020-03-11 13:32   ` Bin Meng
@ 2020-03-11 15:00   ` Bin Meng
  2020-03-17 17:36     ` Pragnesh Patel
  1 sibling, 1 reply; 53+ messages in thread
From: Bin Meng @ 2020-03-11 15:00 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 11, 2020 at 3:03 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> Use the OTP DM driver to set the serial environment variable.
>
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> ---
>  arch/riscv/dts/fu540-c000-u-boot.dtsi         |  14 +++
>  .../dts/hifive-unleashed-a00-u-boot.dtsi      |   6 +
>  board/sifive/fu540/Kconfig                    |   2 +
>  board/sifive/fu540/fu540.c                    | 113 +++++++-----------
>  4 files changed, 62 insertions(+), 73 deletions(-)
>  create mode 100644 arch/riscv/dts/fu540-c000-u-boot.dtsi
>  create mode 100644 arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>
> diff --git a/arch/riscv/dts/fu540-c000-u-boot.dtsi b/arch/riscv/dts/fu540-c000-u-boot.dtsi
> new file mode 100644
> index 0000000000..31fd113c7d
> --- /dev/null
> +++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
> @@ -0,0 +1,14 @@
> +// SPDX-License-Identifier: GPL-2.0+

Missed one thing:

I believe this file should be dual-licensed, like fu540-c000.dtsi

> +/*
> + * (C) Copyright 2019 SiFive, Inc
> + */
> +
> +/ {
> +       soc {
> +               otp: otp at 10070000 {
> +                       compatible = "sifive,fu540-otp";
> +                       reg = <0x0 0x10070000 0x0 0x0FFF>;
> +                       fuse-count = <0x1000>;
> +               };
> +       };
> +};
> diff --git a/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
> new file mode 100644
> index 0000000000..bec0d19134
> --- /dev/null
> +++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
> @@ -0,0 +1,6 @@
> +// SPDX-License-Identifier: GPL-2.0+

And this one dual-licensed too

> +/*
> + * Copyright (C) 2019 SiFive, Inc
> + */
> +

Regards,
Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 06/14] sifive: fu540: add ddr driver
  2020-03-11  7:03 ` [PATCH v5 06/14] sifive: fu540: add ddr driver Pragnesh Patel
@ 2020-03-13  7:48   ` Bin Meng
  2020-03-17 13:00     ` Pragnesh Patel
  2020-03-13 11:56   ` Giulio Benetti
  1 sibling, 1 reply; 53+ messages in thread
From: Bin Meng @ 2020-03-13  7:48 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> Add driver for fu540 to support ddr initialization in SPL.
> This driver is based on FSBL
> (https://github.com/sifive/freedom-u540-c000-bootloader.git)
>
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> ---
>  drivers/ram/Kconfig              |   7 +
>  drivers/ram/Makefile             |   2 +
>  drivers/ram/sifive/Kconfig       |   8 +
>  drivers/ram/sifive/Makefile      |   6 +
>  drivers/ram/sifive/sdram_fu540.c | 295 +++++++++++++++++++++++++++++++
>  drivers/ram/sifive/sdram_fu540.h |  94 ++++++++++
>  6 files changed, 412 insertions(+)
>  create mode 100644 drivers/ram/sifive/Kconfig
>  create mode 100644 drivers/ram/sifive/Makefile
>  create mode 100644 drivers/ram/sifive/sdram_fu540.c
>  create mode 100644 drivers/ram/sifive/sdram_fu540.h
>
> diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig
> index 56fea7c94c..c60c63204c 100644
> --- a/drivers/ram/Kconfig
> +++ b/drivers/ram/Kconfig
> @@ -73,5 +73,12 @@ config IMXRT_SDRAM
>           to support external memories like sdram, psram & nand.
>           This driver is for the sdram memory interface with the SEMC.
>
> +config SIFIVE_DDR
> +       bool "Enable SiFive DDR support"
> +       depends on RAM
> +       help
> +         Enable support for the internal DDR Memory Controller of SiFive SoCs.
> +
>  source "drivers/ram/rockchip/Kconfig"
>  source "drivers/ram/stm32mp1/Kconfig"
> +source "drivers/ram/sifive/Kconfig"
> diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile
> index 5c897410c6..12bf61510b 100644
> --- a/drivers/ram/Makefile
> +++ b/drivers/ram/Makefile
> @@ -17,3 +17,5 @@ obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
>  obj-$(CONFIG_K3_J721E_DDRSS) += k3-j721e/
>
>  obj-$(CONFIG_IMXRT_SDRAM) += imxrt_sdram.o
> +
> +obj-$(CONFIG_SIFIVE_DDR) += sifive/
> diff --git a/drivers/ram/sifive/Kconfig b/drivers/ram/sifive/Kconfig
> new file mode 100644
> index 0000000000..b754700db8
> --- /dev/null
> +++ b/drivers/ram/sifive/Kconfig
> @@ -0,0 +1,8 @@
> +config SIFIVE_FU540_DDR
> +       bool "SiFive FU540 DDR driver"
> +       depends on DM && OF_CONTROL
> +       select RAM

Do we need this driver for U-Boot proper?

> +       select SPL_RAM if SPL
> +       select SIFIVE_DDR
> +       help
> +         This enables DDR support for the platforms based on SiFive FU540 SoC.
> diff --git a/drivers/ram/sifive/Makefile b/drivers/ram/sifive/Makefile
> new file mode 100644
> index 0000000000..0187805199
> --- /dev/null
> +++ b/drivers/ram/sifive/Makefile
> @@ -0,0 +1,6 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +#
> +# Copyright (c) 2020 SiFive, Inc
> +#
> +
> +obj-$(CONFIG_SIFIVE_FU540_DDR) += sdram_fu540.o
> diff --git a/drivers/ram/sifive/sdram_fu540.c b/drivers/ram/sifive/sdram_fu540.c
> new file mode 100644
> index 0000000000..18926dbe15
> --- /dev/null
> +++ b/drivers/ram/sifive/sdram_fu540.c
> @@ -0,0 +1,295 @@
> +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
> +/*
> + * (C) Copyright 2020 SiFive, Inc.
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <init.h>
> +#include <ram.h>
> +#include <regmap.h>
> +#include <syscon.h>
> +#include <asm/io.h>
> +#include "sdram_fu540.h"
> +
> +/* n: Unit bytes */
> +void sdram_copy_to_reg(volatile u32 *dest, volatile u32 *src, u32 n)

This should be static, also use "int n"?

> +{
> +       int i;
> +
> +       for (i = 0; i < n / sizeof(u32); i++) {
> +               writel(*src, dest);
> +               src++;
> +               dest++;
> +       }
> +}
> +
> +static void ddr_setuprangeprotection(volatile u32 *ctl, u64 end_addr)

__maybe_unused ? Otherwise use #ifdef #endif ?


> +{
> +       writel(0x0, DENALI_CTL_209 + ctl);
> +       u32 end_addr_16kblocks = ((end_addr >> 14) & 0x7FFFFF) - 1;

nits: move the variable declaration

> +
> +       writel(end_addr_16kblocks, DENALI_CTL_210 + ctl);
> +       writel(0x0, DENALI_CTL_212 + ctl);
> +       writel(0x0, DENALI_CTL_214 + ctl);
> +       writel(0x0, DENALI_CTL_216 + ctl);
> +       setbits_le32(DENALI_CTL_224 + ctl,
> +                    0x3 << AXI0_RANGE_PROT_BITS_0_OFFSET);
> +       writel(0xFFFFFFFF, DENALI_CTL_225 + ctl);
> +       setbits_le32(DENALI_CTL_208 + ctl, 0x1 << AXI0_ADDRESS_RANGE_ENABLE);
> +       setbits_le32(DENALI_CTL_208 + ctl,
> +                    0x1 << PORT_ADDR_PROTECTION_EN_OFFSET);
> +}
> +
> +static void ddr_start(volatile u32 *ctl, u32 *physical_filter_ctrl, u64 ddr_end)

__maybe_unused ?

> +{
> +       setbits_le32(DENALI_CTL_0 + ctl, 0x1);
> +       while ((readl(DENALI_CTL_132 + ctl) & (1 << MC_INIT_COMPLETE_OFFSET))
> +              == 0) {
> +       }
> +

Use

do {
    val = readl(DENALI_CTL_132 + ctl) & (1 << MC_INIT_COMPLETE_OFFSET);
} while (val == 0)

?


> +       // Disable the BusBlocker in front of the controller AXI slave ports

nits: use /* */

> +       volatile u64 *filterreg = (volatile u64 *)physical_filter_ctrl;

Please move the variable declaration to the beginning of this function

> +
> +       filterreg[0] = 0x0f00000000000000UL | (ddr_end >> 2);
> +}
> +
> +static u64 ddr_phy_fixup(volatile u32 *ddrphyreg)

__maybe_unused ?

> +{
> +       // return bitmask of failed lanes

nits: use /* */

> +
> +       u64 fails     = 0;
> +       u32 slicebase = 0;
> +       u32 dq        = 0;
> +
> +       // check errata condition

nits: use /* */

> +       for (u32 slice = 0; slice < 8; slice++) {
> +               u32 regbase = slicebase + 34;
> +
> +               for (u32 reg = 0; reg < 4; reg++) {
> +                       u32 updownreg = readl(regbase + reg + ddrphyreg);
> +
> +                       for (u32 bit = 0; bit < 2; bit++) {
> +                               u32 phy_rx_cal_dqn_0_offset;
> +
> +                               if (bit == 0) {
> +                                       phy_rx_cal_dqn_0_offset =
> +                                               PHY_RX_CAL_DQ0_0_OFFSET;
> +                               } else {
> +                                       phy_rx_cal_dqn_0_offset =
> +                                               PHY_RX_CAL_DQ1_0_OFFSET;
> +                               }
> +
> +                               u32 down = (updownreg >>
> +                                           phy_rx_cal_dqn_0_offset) & 0x3F;
> +                               u32 up   = (updownreg >>
> +                                           (phy_rx_cal_dqn_0_offset + 6)) &
> +                                           0x3F;
> +
> +                               u8 failc0 = ((down == 0) && (up == 0x3F));
> +                               u8 failc1 = ((up == 0) && (down == 0x3F));
> +
> +                               // print error message on failure

nits: use /* */

> +                               if (failc0 || failc1) {
> +                                       if (fails == 0)
> +                                               printf("DDR error in fixing up\n");
> +
> +                                       fails |= (1 << dq);
> +
> +                                       char slicelsc = '0';
> +                                       char slicemsc = '0';
> +
> +                                       slicelsc += (dq % 10);
> +                                       slicemsc += (dq / 10);
> +                                       printf("S ");
> +                                       printf("%c", slicemsc);
> +                                       printf("%c", slicelsc);
> +
> +                                       if (failc0)
> +                                               printf("U");
> +                                       else
> +                                               printf("D");
> +
> +                                       printf("\n");
> +                               }
> +                               dq++;
> +                       }
> +               }
> +               slicebase += 128;
> +       }
> +       return(0);
> +}
> +
> +static u32 ddr_getdramclass(volatile u32 *ctl)

__maybe_unused ?

> +{
> +       u32 reg = readl(DENALI_CTL_0 + ctl);
> +
> +       return ((reg >> DRAM_CLASS_OFFSET) & 0xF);
> +}
> +
> +static __maybe_unused int fu540_ddr_setup(struct udevice *dev)
> +{
> +       struct ddr_info *priv = dev_get_priv(dev);
> +       struct sifive_dmc_plat *plat = dev_get_platdata(dev);
> +
> +       int ret, i;
> +       u32 physet;
> +
> +       volatile u32 *denali_ctl =  &priv->ctl->denali_ctl[0];
> +       volatile u32 *denali_phy =  &priv->phy->denali_phy[0];
> +
> +       ret = dev_read_u32_array(dev, "sifive,sdram-params",
> +                                (u32 *)&plat->sdram_params,
> +                                sizeof(plat->sdram_params) / sizeof(u32));
> +       if (ret) {
> +               printf("%s: Cannot read sifive,sdram-params %d\n",
> +                      __func__, ret);
> +               return ret;
> +       }
> +
> +       struct fu540_sdram_params *params = &plat->sdram_params;

Please move the variable declaration to the beginning of this function.

> +
> +       sdram_copy_to_reg(&priv->ctl->denali_ctl[0],
> +                         &params->pctl_regs.denali_ctl[0],
> +                         sizeof(struct fu540_ddrctl));
> +
> +       /* phy reset */
> +       for (i = DENALI_PHY_1152; i <= DENALI_PHY_1214; i++) {
> +               physet = params->phy_regs.denali_phy[i];
> +               priv->phy->denali_phy[i] = physet;
> +       }
> +
> +       for (i = 0; i < DENALI_PHY_1152; i++) {
> +               physet = params->phy_regs.denali_phy[i];
> +               priv->phy->denali_phy[i] = physet;
> +       }
> +
> +       /* Disable read interleave DENALI_CTL_120 */
> +       setbits_le32(DENALI_CTL_120 + denali_ctl,
> +                    1 << DISABLE_RD_INTERLEAVE_OFFSET);
> +
> +       /* Disable optimal read/modify/write logic DENALI_CTL_21 */
> +       clrbits_le32(DENALI_CTL_21 + denali_ctl, 1 << OPTIMAL_RMODW_EN_OFFSET);
> +
> +       /* Enable write Leveling DENALI_CTL_170 */
> +       setbits_le32(DENALI_CTL_170 + denali_ctl, (1 << WRLVL_EN_OFFSET)
> +                    | (1 << DFI_PHY_WRLELV_MODE_OFFSET));
> +
> +       /* Enable read leveling DENALI_CTL_181 and DENALI_CTL_260 */
> +       setbits_le32(DENALI_CTL_181 + denali_ctl,
> +                    1 << DFI_PHY_RDLVL_MODE_OFFSET);
> +       setbits_le32(DENALI_CTL_260 + denali_ctl, 1 << RDLVL_EN_OFFSET);
> +
> +       /* Enable read leveling gate DENALI_CTL_260 and DENALI_CTL_182 */
> +       setbits_le32(DENALI_CTL_260 + denali_ctl, 1 << RDLVL_GATE_EN_OFFSET);
> +       setbits_le32(DENALI_CTL_182 + denali_ctl,
> +                    1 << DFI_PHY_RDLVL_GATE_MODE_OFFSET);
> +
> +       if (ddr_getdramclass(denali_ctl) == DRAM_CLASS_DDR4) {
> +               /* Enable vref training DENALI_CTL_184 */
> +               setbits_le32(DENALI_CTL_184 + denali_ctl, 1 << VREF_EN_OFFSET);
> +       }
> +
> +       /* Mask off leveling completion interrupt DENALI_CTL_136 */
> +       setbits_le32(DENALI_CTL_136 + denali_ctl,
> +                    1 << LEVELING_OPERATION_COMPLETED_OFFSET);
> +
> +       /* Mask off MC init complete interrupt DENALI_CTL_136 */
> +       setbits_le32(DENALI_CTL_136 + denali_ctl, 1 << MC_INIT_COMPLETE_OFFSET);
> +
> +       /* Mask off out of range interrupts DENALI_CTL_136 */
> +       setbits_le32(DENALI_CTL_136 + denali_ctl, (1 << OUT_OF_RANGE_OFFSET)
> +                    | (1 << MULTIPLE_OUT_OF_RANGE_OFFSET));
> +
> +       /* set up range protection */
> +       ddr_setuprangeprotection(denali_ctl, DDR_MEM_SIZE);
> +
> +       /* Mask off port command error interrupt DENALI_CTL_136 */
> +       setbits_le32(DENALI_CTL_136 + denali_ctl,
> +                    1 << PORT_COMMAND_CHANNEL_ERROR_OFFSET);
> +
> +       const u64 ddr_size = DDR_MEM_SIZE;
> +       const u64 ddr_end = PAYLOAD_DEST + ddr_size;
> +

Please move the variable declaration to the beginning of this function.

> +       ddr_start(denali_ctl, priv->physical_filter_ctrl, ddr_end);
> +
> +       ddr_phy_fixup(denali_phy);
> +
> +       /* check size */
> +       priv->info.size = get_ram_size((long *)priv->info.base,
> +                                      DDR_MEM_SIZE);
> +
> +       printf("priv->info.size = %lx\n", priv->info.size);
> +       debug("%s : %lx\n", __func__, priv->info.size);
> +
> +       /* check memory access for all memory */
> +
> +       if (priv->info.size != DDR_MEM_SIZE) {
> +               printf("DDR invalid size : 0x%lx, expected 0x%lx\n",
> +                      priv->info.size, DDR_MEM_SIZE);
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int fu540_ddr_probe(struct udevice *dev)
> +{
> +       struct ddr_info *priv = dev_get_priv(dev);
> +
> +#if defined(CONFIG_SPL_BUILD)
> +       struct regmap *map;
> +       int ret;
> +
> +       debug("FU540 DDR probe\n");
> +       priv->dev = dev;
> +
> +       ret = regmap_init_mem(dev_ofnode(dev), &map);
> +       if (ret)
> +               return ret;
> +
> +       priv->ctl = regmap_get_range(map, 0);
> +       priv->phy = regmap_get_range(map, 1);
> +       priv->physical_filter_ctrl = regmap_get_range(map, 2);
> +
> +       priv->info.base = CONFIG_SYS_SDRAM_BASE;
> +
> +       priv->info.size = 0;
> +       return fu540_ddr_setup(dev);
> +#else
> +       priv->info.base = CONFIG_SYS_SDRAM_BASE;
> +       priv->info.size = DDR_MEM_SIZE;
> +#endif
> +       return 0;
> +}
> +
> +static int fu540_ddr_get_info(struct udevice *dev, struct ram_info *info)
> +{
> +       struct ddr_info *priv = dev_get_priv(dev);
> +
> +       *info = priv->info;
> +
> +       return 0;
> +}
> +
> +static struct ram_ops fu540_ddr_ops = {
> +       .get_info = fu540_ddr_get_info,
> +};
> +
> +static const struct udevice_id fu540_ddr_ids[] = {
> +       { .compatible = "sifive,fu540-ddr" },

"sifive,fu540-c000-ddr" ?

> +       { }
> +};
> +
> +U_BOOT_DRIVER(fu540_ddr) = {
> +       .name = "fu540_ddr",
> +       .id = UCLASS_RAM,
> +       .of_match = fu540_ddr_ids,
> +       .ops = &fu540_ddr_ops,
> +       .probe = fu540_ddr_probe,
> +       .priv_auto_alloc_size = sizeof(struct ddr_info),
> +       .platdata_auto_alloc_size = sizeof(struct sifive_dmc_plat),
> +};
> diff --git a/drivers/ram/sifive/sdram_fu540.h b/drivers/ram/sifive/sdram_fu540.h
> new file mode 100644
> index 0000000000..09693a038e
> --- /dev/null
> +++ b/drivers/ram/sifive/sdram_fu540.h
> @@ -0,0 +1,94 @@
> +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
> +/*
> + * Copyright (C) 2020, SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + */
> +
> +#define DENALI_CTL_0   0
> +#define DENALI_CTL_21  21
> +#define DENALI_CTL_120 120
> +#define DENALI_CTL_132 132
> +#define DENALI_CTL_136 136
> +#define DENALI_CTL_170 170
> +#define DENALI_CTL_181 181
> +#define DENALI_CTL_182 182
> +#define DENALI_CTL_184 184
> +#define DENALI_CTL_208 208
> +#define DENALI_CTL_209 209
> +#define DENALI_CTL_210 210
> +#define DENALI_CTL_212 212
> +#define DENALI_CTL_214 214
> +#define DENALI_CTL_216 216
> +#define DENALI_CTL_224 224
> +#define DENALI_CTL_225 225
> +#define DENALI_CTL_260 260
> +
> +#define DENALI_PHY_1152        1152
> +#define DENALI_PHY_1214        1214
> +
> +#define PAYLOAD_DEST   0x80000000
> +#define DDR_MEM_SIZE   (8UL * 1024UL * 1024UL * 1024UL)
> +
> +#define DRAM_CLASS_OFFSET                   8
> +#define DRAM_CLASS_DDR4                     0xA
> +#define OPTIMAL_RMODW_EN_OFFSET             0
> +#define DISABLE_RD_INTERLEAVE_OFFSET        16
> +#define OUT_OF_RANGE_OFFSET                 1
> +#define MULTIPLE_OUT_OF_RANGE_OFFSET        2
> +#define PORT_COMMAND_CHANNEL_ERROR_OFFSET   7
> +#define MC_INIT_COMPLETE_OFFSET             8
> +#define LEVELING_OPERATION_COMPLETED_OFFSET 22
> +#define DFI_PHY_WRLELV_MODE_OFFSET          24
> +#define DFI_PHY_RDLVL_MODE_OFFSET           24
> +#define DFI_PHY_RDLVL_GATE_MODE_OFFSET      0
> +#define VREF_EN_OFFSET                      24
> +#define PORT_ADDR_PROTECTION_EN_OFFSET      0
> +#define AXI0_ADDRESS_RANGE_ENABLE           8
> +#define AXI0_RANGE_PROT_BITS_0_OFFSET       24
> +#define RDLVL_EN_OFFSET                     16
> +#define RDLVL_GATE_EN_OFFSET                24
> +#define WRLVL_EN_OFFSET                     0
> +
> +#define PHY_RX_CAL_DQ0_0_OFFSET             0
> +#define PHY_RX_CAL_DQ1_0_OFFSET             16
> +
> +struct fu540_ddrctl {
> +       volatile u32 denali_ctl[265];
> +};
> +
> +struct fu540_ddrphy {
> +       volatile u32 denali_phy[1215];
> +};
> +
> +struct fu540_sdram_params {
> +       struct fu540_ddrctl pctl_regs;
> +       struct fu540_ddrphy phy_regs;
> +};
> +
> +struct sifive_dmc_plat {
> +#if CONFIG_IS_ENABLED(OF_PLATDATA)
> +       struct dtd_sifive_fu540_dmc dtplat;

Do we use this for SPL?

> +#else
> +       struct fu540_sdram_params sdram_params;
> +#endif
> +};
> +
> +/**
> + * struct ddr_info
> + *
> + * @dev                                : pointer for the device
> + * @info                       : UCLASS RAM information
> + * @ctl                                : DDR controleur base address

typo: controller

> + * @phy                                : DDR PHY base address
> + * @ctrl                       : DDR control base address
> + * @physical_filter_ctrl       : DDR physical filter control base address
> + */
> +struct ddr_info {
> +       struct udevice *dev;
> +       struct ram_info info;
> +       struct fu540_ddrctl *ctl;
> +       struct fu540_ddrphy *phy;
> +       u32 *physical_filter_ctrl;
> +};
> --

Regards,
Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 07/14] sifive: dts: fu540: Add DDR controller and phy register settings
  2020-03-11  7:03 ` [PATCH v5 07/14] sifive: dts: fu540: Add DDR controller and phy register settings Pragnesh Patel
@ 2020-03-13  7:51   ` Bin Meng
  2020-03-17 15:35     ` Pragnesh Patel
  0 siblings, 1 reply; 53+ messages in thread
From: Bin Meng @ 2020-03-13  7:51 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> Add DDR controller and phy register settings, taken from fsbl
> (https://github.com/sifive/freedom-u540-c000-bootloader.git)
>
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> ---
>  arch/riscv/dts/fu540-c000-u-boot.dtsi         |    7 +
>  arch/riscv/dts/fu540-sdram-ddr4.dtsi          | 1489 +++++++++++++++++
>  .../dts/hifive-unleashed-a00-u-boot.dtsi      |    1 +
>  3 files changed, 1497 insertions(+)
>  create mode 100644 arch/riscv/dts/fu540-sdram-ddr4.dtsi
>
> diff --git a/arch/riscv/dts/fu540-c000-u-boot.dtsi b/arch/riscv/dts/fu540-c000-u-boot.dtsi
> index 2d3d62801f..b8cef67885 100644
> --- a/arch/riscv/dts/fu540-c000-u-boot.dtsi
> +++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
> @@ -40,6 +40,13 @@
>                         reg = <0x0 0x2000000 0x0 0xc0000>;
>                         u-boot,dm-spl;
>                 };
> +               dmc: dmc at 100b0000 {
> +                       compatible = "sifive,fu540-ddr";
> +                       reg = <0x0 0x100b0000 0x0 0x0800
> +                              0x0 0x100b2000 0x0 0x2000
> +                              0x0 0x100b8000 0x0 0x0fff>;
> +                       u-boot,dm-spl;
> +               };
>         };
>  };
>
> diff --git a/arch/riscv/dts/fu540-sdram-ddr4.dtsi b/arch/riscv/dts/fu540-sdram-ddr4.dtsi
> new file mode 100644
> index 0000000000..370c53800d
> --- /dev/null
> +++ b/arch/riscv/dts/fu540-sdram-ddr4.dtsi
> @@ -0,0 +1,1489 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2020 SiFive, Inc
> + */
> +
> +&dmc {
> +       sifive,sdram-params = <

Are these parameter values SoC specific, or board specific? If it's
board specific, it should be renamed to
hifive-unleashed-a00_sdram_ddr4.dtsi, or put it directly into
hifive-unleashed-a00-u-boot.dtsi

> +               0x00000a00      /* DENALI_CTL_00_DATA */
> +               0x00000000      /* DENALI_CTL_01_DATA */
> +               0x00000000      /* DENALI_CTL_02_DATA */
> +               0x00000000      /* DENALI_CTL_03_DATA */
> +               0x00000000      /* DENALI_CTL_04_DATA */
> +               0x00000000      /* DENALI_CTL_05_DATA */
> +               0x0000000a      /* DENALI_CTL_06_DATA */
> +               0x0002d362      /* DENALI_CTL_07_DATA */
> +               0x00071073      /* DENALI_CTL_08_DATA */
> +               0x0a1c0255      /* DENALI_CTL_09_DATA */
> +               0x1c1c0400      /* DENALI_CTL_10_DATA */

[snip]

Regards,
Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 08/14] clk: sifive: fu540-prci: Add clock enable and disable ops
  2020-03-11  7:03 ` [PATCH v5 08/14] clk: sifive: fu540-prci: Add clock enable and disable ops Pragnesh Patel
@ 2020-03-13  7:57   ` Bin Meng
  2020-03-13  8:15     ` Pragnesh Patel
  0 siblings, 1 reply; 53+ messages in thread
From: Bin Meng @ 2020-03-13  7:57 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> Added clock enable and disable functions in prci ops
>
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> ---
>  drivers/clk/sifive/fu540-prci.c | 75 +++++++++++++++++++++++++++++++--
>  1 file changed, 72 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
> index 8847178001..c02c0466a8 100644
> --- a/drivers/clk/sifive/fu540-prci.c
> +++ b/drivers/clk/sifive/fu540-prci.c
> @@ -68,6 +68,11 @@
>  #define PRCI_COREPLLCFG0_LOCK_SHIFT    31
>  #define PRCI_COREPLLCFG0_LOCK_MASK     (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT)
>
> +/* COREPLLCFG1 */
> +#define PRCI_COREPLLCFG1_OFFSET                0x8
> +#define PRCI_COREPLLCFG1_CKE_SHIFT     31
> +#define PRCI_COREPLLCFG1_CKE_MASK      (0x1 << PRCI_COREPLLCFG1_CKE_SHIFT)
> +
>  /* DDRPLLCFG0 */
>  #define PRCI_DDRPLLCFG0_OFFSET         0xc
>  #define PRCI_DDRPLLCFG0_DIVR_SHIFT     0
> @@ -87,7 +92,7 @@
>
>  /* DDRPLLCFG1 */
>  #define PRCI_DDRPLLCFG1_OFFSET         0x10
> -#define PRCI_DDRPLLCFG1_CKE_SHIFT      24
> +#define PRCI_DDRPLLCFG1_CKE_SHIFT      31
>  #define PRCI_DDRPLLCFG1_CKE_MASK       (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
>
>  /* GEMGXLPLLCFG0 */
> @@ -114,7 +119,7 @@
>
>  /* GEMGXLPLLCFG1 */
>  #define PRCI_GEMGXLPLLCFG1_OFFSET      0x20
> -#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT   24
> +#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT   31
>  #define PRCI_GEMGXLPLLCFG1_CKE_MASK    (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
>
>  /* CORECLKSEL */
> @@ -142,7 +147,7 @@
>                         (0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT)
>
>  /* CLKMUXSTATUSREG */
> -#define PRCI_CLKMUXSTATUSREG_OFFSET            0x2c
> +#define PRCI_CLKMUXSTATUSREG_OFFSET    0x2c
>  #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1
>  #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK \
>                         (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
> @@ -170,6 +175,7 @@ struct __prci_data {
>   * @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
> + * @cfg1_offs: WRPLL CFG1 register offset (in bytes) from the PRCI base address
>   *
>   * @enable_bypass and @disable_bypass are used for WRPLL instances
>   * that contain a separate external glitchless clock mux downstream
> @@ -180,6 +186,7 @@ struct __prci_wrpll_data {
>         void (*enable_bypass)(struct __prci_data *pd);
>         void (*disable_bypass)(struct __prci_data *pd);
>         u8 cfg0_offs;
> +       u8 cfg1_offs;
>  };
>
>  struct __prci_clock;
> @@ -194,6 +201,7 @@ struct __prci_clock_ops {
>                                     unsigned long *parent_rate);
>         unsigned long (*recalc_rate)(struct __prci_clock *pc,
>                                      unsigned long parent_rate);
> +       int (*enable_clk)(struct __prci_clock *pc, bool enable);
>  };
>
>  /**
> @@ -356,6 +364,13 @@ static void __prci_wrpll_write_cfg(struct __prci_data *pd,
>         memcpy(&pwd->c, c, sizeof(*c));
>  }
>
> +static void __prci_wrpll_write_cfg1(struct __prci_data *pd,

nits: we should also rename the existing function
__prci_wrpll_write_cfg() to __prci_wrpll_write_cfg0()

> +                                   struct __prci_wrpll_data *pwd,
> +                                   u32 enable)
> +{
> +       __prci_writel(enable, pwd->cfg1_offs, pd);
> +}
> +

[snip]

Regards,
Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 09/14] clk: sifive: fu540-prci: Add clock initialization for SPL
  2020-03-11  7:03 ` [PATCH v5 09/14] clk: sifive: fu540-prci: Add clock initialization for SPL Pragnesh Patel
@ 2020-03-13  8:11   ` Bin Meng
  2020-03-17 17:47     ` Pragnesh Patel
  0 siblings, 1 reply; 53+ messages in thread
From: Bin Meng @ 2020-03-13  8:11 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> Set corepll, ddrpll and ethernet PLL for u-boot-spl
>
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> ---
>  drivers/clk/sifive/fu540-prci.c | 94 +++++++++++++++++++++++++++++++++
>  1 file changed, 94 insertions(+)
>
> diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
> index c02c0466a8..f043b0eccb 100644
> --- a/drivers/clk/sifive/fu540-prci.c
> +++ b/drivers/clk/sifive/fu540-prci.c
> @@ -41,6 +41,10 @@
>  #include <linux/clk/analogbits-wrpll-cln28hpc.h>
>  #include <dt-bindings/clock/sifive-fu540-prci.h>
>
> +#define DDRCTLPLL_F    55
> +#define DDRCTLPLL_Q    2
> +#define MHz            1000000
> +
>  /*
>   * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects:
>   *     hfclk and rtcclk
> @@ -152,6 +156,27 @@
>  #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK \
>                         (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
>
> +/* PROCMONCFG */
> +#define PRCI_PROCMONCFG_OFFSET                 0xF0
> +#define PRCI_PROCMONCFG_CORE_CLOCK_SHIFT       24
> +#define PRCI_PROCMONCFG_CORE_CLOCK_MASK \
> +                       (0x1 << PRCI_PROCMONCFG_CORE_CLOCK_SHIFT)
> +
> +#define PLL_R(x) \
> +       ((x) << PRCI_DDRPLLCFG0_DIVR_SHIFT) & PRCI_DDRPLLCFG0_DIVR_MASK
> +#define PLL_F(x) \
> +       ((x) << PRCI_DDRPLLCFG0_DIVF_SHIFT) & PRCI_DDRPLLCFG0_DIVF_MASK
> +#define PLL_Q(x) \
> +       ((x) << PRCI_DDRPLLCFG0_DIVQ_SHIFT) & PRCI_DDRPLLCFG0_DIVQ_MASK
> +#define PLL_RANGE(x) \
> +       ((x) << PRCI_DDRPLLCFG0_RANGE_SHIFT) & PRCI_DDRPLLCFG0_RANGE_MASK
> +#define PLL_BYPASS(x) \
> +       ((x) << PRCI_DDRPLLCFG0_BYPASS_SHIFT) & PRCI_DDRPLLCFG0_BYPASS_MASK
> +#define PLL_FSE(x) \
> +       ((x) << PRCI_DDRPLLCFG0_FSE_SHIFT) & PRCI_DDRPLLCFG0_FSE_MASK
> +#define PLL_LOCK(x) \
> +       ((x) << PRCI_DDRPLLCFG0_LOCK_SHIFT) & PRCI_DDRPLLCFG0_LOCK_MASK
> +
>  /*
>   * Private structures
>   */
> @@ -672,6 +697,75 @@ static int sifive_fu540_prci_probe(struct udevice *dev)
>                         __prci_wrpll_read_cfg(pd, pc->pwd);
>         }
>
> +#ifdef CONFIG_SPL_BUILD

I think the correct way is to add clocks property to each device node
that use the clock, e.g.:

    clocks = <&prci PRCI_CLK_COREPLL>;

Then we don't need anything added here, instead we call clk_enable()
from the device driver to enable their clock.

> +       u32 v;
> +       struct clk clock;
> +
> +       v = __prci_readl(pd, PRCI_CLKMUXSTATUSREG_OFFSET);
> +       v &= PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK;
> +
> +       clock.id = PRCI_CLK_COREPLL;
> +
> +       if (v) {
> +               /* corepll 500 Mhz */
> +               sifive_fu540_prci_set_rate(&clock, 500UL * MHz);
> +       } else {
> +               /* corepll 1 Ghz */
> +               sifive_fu540_prci_set_rate(&clock, 1000UL * MHz);
> +       }
> +
> +       sifive_fu540_prci_clock_enable(&__prci_init_clocks[clock.id], 1);
> +
> +       //DDR init
> +       u32 ddrctlmhz =
> +               (PLL_R(0)) |
> +               (PLL_F(DDRCTLPLL_F)) |
> +               (PLL_Q(DDRCTLPLL_Q)) |
> +               (PLL_RANGE(0x4)) |
> +               (PLL_BYPASS(0)) |
> +               (PLL_FSE(1));
> +       __prci_writel(ddrctlmhz, PRCI_DDRPLLCFG0_OFFSET, pd);
> +
> +       clock.id = PRCI_CLK_DDRPLL;
> +       sifive_fu540_prci_clock_enable(&__prci_init_clocks[clock.id], 1);
> +
> +       /* Release DDR reset */
> +       v = __prci_readl(pd, PRCI_DEVICESRESETREG_OFFSET);
> +       v |= PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK;
> +       __prci_writel(v, PRCI_DEVICESRESETREG_OFFSET, pd);
> +
> +       // HACK to get the '1 full controller clock cycle'.
> +       asm volatile ("fence");
> +       v = __prci_readl(pd, PRCI_DEVICESRESETREG_OFFSET);
> +       v |= (PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK |
> +             PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK |
> +             PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK);
> +       __prci_writel(v, PRCI_DEVICESRESETREG_OFFSET, pd);
> +       // HACK to get the '1 full controller clock cycle'.
> +       asm volatile ("fence");
> +
> +       /* These take like 16 cycles to actually propagate. We can't go sending
> +        * stuff before they come out of reset. So wait. (TODO: Add a register
> +        * to read the current reset states, or DDR Control device?)
> +        */
> +       for (int i = 0; i < 256; i++)
> +               asm volatile ("nop");
> +
> +       /* GEMGXL init */
> +       clock.id = PRCI_CLK_GEMGXLPLL;
> +       sifive_fu540_prci_set_rate(&clock, 125UL * MHz);
> +       sifive_fu540_prci_clock_enable(&__prci_init_clocks[clock.id], 1);
> +
> +       /* Release GEMGXL reset */
> +       v = __prci_readl(pd, PRCI_DEVICESRESETREG_OFFSET);
> +       v |= PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK;
> +       __prci_writel(v, PRCI_DEVICESRESETREG_OFFSET, pd);
> +
> +       /* Procmon => core clock */
> +       __prci_writel(PRCI_PROCMONCFG_CORE_CLOCK_MASK, PRCI_PROCMONCFG_OFFSET,
> +                     pd);
> +#endif
> +
>         return 0;
>  }

Regards,
Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 08/14] clk: sifive: fu540-prci: Add clock enable and disable ops
  2020-03-13  7:57   ` Bin Meng
@ 2020-03-13  8:15     ` Pragnesh Patel
  0 siblings, 0 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-13  8:15 UTC (permalink / raw)
  To: u-boot

Hi Bin,

>-----Original Message-----
>From: Bin Meng <bmeng.cn@gmail.com>
>Sent: 13 March 2020 13:27
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Atish Patra
><atish.patra@wdc.com>; Palmer Dabbelt <palmerdabbelt@google.com>; Paul
>Walmsley <paul.walmsley@sifive.com>; Jagan Teki
><jagan@amarulasolutions.com>; Troy Benjegerdes
><troy.benjegerdes@sifive.com>; Anup Patel <anup.patel@wdc.com>; Sagar
>Kadam <sagar.kadam@sifive.com>; Rick Chen <rick@andestech.com>; Lukasz
>Majewski <lukma@denx.de>; Anatolij Gustschin <agust@denx.de>; Simon
>Glass <sjg@chromium.org>
>Subject: Re: [PATCH v5 08/14] clk: sifive: fu540-prci: Add clock enable and
>disable ops
>
>On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
><pragnesh.patel@sifive.com> wrote:
>>
>> Added clock enable and disable functions in prci ops
>>
>> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
>> ---
>>  drivers/clk/sifive/fu540-prci.c | 75
>> +++++++++++++++++++++++++++++++--
>>  1 file changed, 72 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/clk/sifive/fu540-prci.c
>> b/drivers/clk/sifive/fu540-prci.c index 8847178001..c02c0466a8 100644
>> --- a/drivers/clk/sifive/fu540-prci.c
>> +++ b/drivers/clk/sifive/fu540-prci.c
>> @@ -68,6 +68,11 @@
>>  #define PRCI_COREPLLCFG0_LOCK_SHIFT    31
>>  #define PRCI_COREPLLCFG0_LOCK_MASK     (0x1 <<
>PRCI_COREPLLCFG0_LOCK_SHIFT)
>>
>> +/* COREPLLCFG1 */
>> +#define PRCI_COREPLLCFG1_OFFSET                0x8
>> +#define PRCI_COREPLLCFG1_CKE_SHIFT     31
>> +#define PRCI_COREPLLCFG1_CKE_MASK      (0x1 <<
>PRCI_COREPLLCFG1_CKE_SHIFT)
>> +
>>  /* DDRPLLCFG0 */
>>  #define PRCI_DDRPLLCFG0_OFFSET         0xc
>>  #define PRCI_DDRPLLCFG0_DIVR_SHIFT     0
>> @@ -87,7 +92,7 @@
>>
>>  /* DDRPLLCFG1 */
>>  #define PRCI_DDRPLLCFG1_OFFSET         0x10
>> -#define PRCI_DDRPLLCFG1_CKE_SHIFT      24
>> +#define PRCI_DDRPLLCFG1_CKE_SHIFT      31
>>  #define PRCI_DDRPLLCFG1_CKE_MASK       (0x1 <<
>PRCI_DDRPLLCFG1_CKE_SHIFT)
>>
>>  /* GEMGXLPLLCFG0 */
>> @@ -114,7 +119,7 @@
>>
>>  /* GEMGXLPLLCFG1 */
>>  #define PRCI_GEMGXLPLLCFG1_OFFSET      0x20
>> -#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT   24
>> +#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT   31
>>  #define PRCI_GEMGXLPLLCFG1_CKE_MASK    (0x1 <<
>PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
>>
>>  /* CORECLKSEL */
>> @@ -142,7 +147,7 @@
>>                         (0x1 <<
>> PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT)
>>
>>  /* CLKMUXSTATUSREG */
>> -#define PRCI_CLKMUXSTATUSREG_OFFSET            0x2c
>> +#define PRCI_CLKMUXSTATUSREG_OFFSET    0x2c
>>  #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1  #define
>> PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK \
>>                         (0x1 <<
>> PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
>> @@ -170,6 +175,7 @@ struct __prci_data {
>>   * @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
>> + * @cfg1_offs: WRPLL CFG1 register offset (in bytes) from the PRCI
>> + base address
>>   *
>>   * @enable_bypass and @disable_bypass are used for WRPLL instances
>>   * that contain a separate external glitchless clock mux downstream
>> @@ -180,6 +186,7 @@ struct __prci_wrpll_data {
>>         void (*enable_bypass)(struct __prci_data *pd);
>>         void (*disable_bypass)(struct __prci_data *pd);
>>         u8 cfg0_offs;
>> +       u8 cfg1_offs;
>>  };
>>
>>  struct __prci_clock;
>> @@ -194,6 +201,7 @@ struct __prci_clock_ops {
>>                                     unsigned long *parent_rate);
>>         unsigned long (*recalc_rate)(struct __prci_clock *pc,
>>                                      unsigned long parent_rate);
>> +       int (*enable_clk)(struct __prci_clock *pc, bool enable);
>>  };
>>
>>  /**
>> @@ -356,6 +364,13 @@ static void __prci_wrpll_write_cfg(struct
>__prci_data *pd,
>>         memcpy(&pwd->c, c, sizeof(*c));  }
>>
>> +static void __prci_wrpll_write_cfg1(struct __prci_data *pd,
>
>nits: we should also rename the existing function
>__prci_wrpll_write_cfg() to __prci_wrpll_write_cfg0()
>

I think you are right. I will check and update in v6.

>> +                                   struct __prci_wrpll_data *pwd,
>> +                                   u32 enable) {
>> +       __prci_writel(enable, pwd->cfg1_offs, pd); }
>> +
>
>[snip]
>
>Regards,
>Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 10/14] riscv: sifive: fu540: add SPL configuration
  2020-03-11  7:03 ` [PATCH v5 10/14] riscv: sifive: fu540: add SPL configuration Pragnesh Patel
@ 2020-03-13  8:28   ` Bin Meng
  2020-03-17  7:41     ` Pragnesh Patel
  2020-03-13 13:59   ` Bin Meng
  1 sibling, 1 reply; 53+ messages in thread
From: Bin Meng @ 2020-03-13  8:28 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> Add a support for SPL which will boot from L2 LIM (0x0800_0000) and
> then boot U-boot FIT image including OpenSBI FW_DYNAMIC firmware

nits: U-Boot

> and U-Boot proper images from 1st partition of MMC boot devices.
>
> SPL related code is leverage from FSBL
> (https://github.com/sifive/freedom-u540-c000-bootloader.git)
>
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> ---
>  board/sifive/fu540/Kconfig            |  8 +++
>  board/sifive/fu540/Makefile           |  4 ++
>  board/sifive/fu540/fu540-memory-map.h | 23 ++++++++
>  board/sifive/fu540/fu540.c            | 24 +++++++++
>  board/sifive/fu540/spl.c              | 78 +++++++++++++++++++++++++++
>  include/configs/sifive-fu540.h        | 18 +++++++
>  6 files changed, 155 insertions(+)
>  create mode 100644 board/sifive/fu540/fu540-memory-map.h
>  create mode 100644 board/sifive/fu540/spl.c
>
> diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
> index 900197bbb2..ebe3472f9a 100644
> --- a/board/sifive/fu540/Kconfig
> +++ b/board/sifive/fu540/Kconfig
> @@ -13,12 +13,20 @@ config SYS_CONFIG_NAME
>         default "sifive-fu540"
>
>  config SYS_TEXT_BASE
> +       default 0x80200000 if SPL
>         default 0x80000000 if !RISCV_SMODE
>         default 0x80200000 if RISCV_SMODE
>
> +config SPL_TEXT_BASE
> +       default 0x08000000
> +
> +config SPL_OPENSBI_LOAD_ADDR
> +       default 0x80000000
> +
>  config BOARD_SPECIFIC_OPTIONS # dummy
>         def_bool y
>         select GENERIC_RISCV
> +       select SUPPORT_SPL
>         imply CMD_DHCP
>         imply CMD_EXT2
>         imply CMD_EXT4
> diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
> index 6e1862c475..b05e2f5807 100644
> --- a/board/sifive/fu540/Makefile
> +++ b/board/sifive/fu540/Makefile
> @@ -3,3 +3,7 @@
>  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
>
>  obj-y  += fu540.o
> +
> +ifdef CONFIG_SPL_BUILD
> +obj-y += spl.o
> +endif
> diff --git a/board/sifive/fu540/fu540-memory-map.h b/board/sifive/fu540/fu540-memory-map.h
> new file mode 100644
> index 0000000000..cba464652b
> --- /dev/null
> +++ b/board/sifive/fu540/fu540-memory-map.h

This file is not needed. See below.

> @@ -0,0 +1,23 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + */
> +
> +#ifndef FU540_MEMORY_MAP
> +#define FU540_MEMORY_MAP
> +
> +#include <asm/arch/gpio.h>
> +
> +/****************************************************************************
> + * Platform definitions
> + *****************************************************************************/
> +
> +/* Memory map */
> +#define GPIO_CTRL_ADDR                 _AC(0x10060000, UL)
> +
> +/* Helper functions */
> +#define _REG32(p, i)    (*(volatile uint32_t *)((p) + (i)))
> +
> +#define GPIO_REG(offset)      _REG32(GPIO_CTRL_ADDR, offset)
> +
> +#endif /* FU540_MEMORY_MAP */
> diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
> index 6c642b3082..89a65eb3fb 100644
> --- a/board/sifive/fu540/fu540.c
> +++ b/board/sifive/fu540/fu540.c
> @@ -11,6 +11,7 @@
>  #include <linux/delay.h>
>  #include <linux/io.h>
>  #include <misc.h>
> +#include <spl.h>
>
>  /*
>   * This define is a value used for error/unknown serial.
> @@ -114,3 +115,26 @@ int board_init(void)
>
>         return 0;
>  }
> +
> +#ifdef CONFIG_SPL
> +void board_boot_order(u32 *spl_boot_list)
> +{
> +       u8 i;
> +       u32 boot_devices[] = {
> +#ifdef CONFIG_SPL_MMC_SUPPORT
> +               BOOT_DEVICE_MMC1,
> +#endif
> +       };
> +
> +       for (i = 0; i < ARRAY_SIZE(boot_devices); i++)
> +               spl_boot_list[i] = boot_devices[i];
> +}
> +#endif
> +
> +#ifdef CONFIG_SPL_LOAD_FIT
> +int board_fit_config_name_match(const char *name)
> +{
> +       /* boot using first FIT config */
> +       return 0;
> +}
> +#endif
> diff --git a/board/sifive/fu540/spl.c b/board/sifive/fu540/spl.c
> new file mode 100644
> index 0000000000..522bc24753
> --- /dev/null
> +++ b/board/sifive/fu540/spl.c
> @@ -0,0 +1,78 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + */
> +
> +#include <common.h>
> +#include <spl.h>
> +#include <misc.h>
> +#include <dm.h>
> +
> +#include "fu540-memory-map.h"
> +
> +#define DDRCTLPLL_F 55
> +#define DDRCTLPLL_Q 2

These 2 macros are not needed.

> +
> +#define PHY_NRESET 0x1000
> +
> +long nsec_per_cyc = 300; /* 33.333MHz */
> +void nsleep(long nsec)
> +{
> +       long step = nsec_per_cyc * 2;
> +
> +       while (nsec > 0)
> +               nsec -= step;
> +}
> +
> +void init_clk_and_ddr(void)
> +{
> +       int ret;
> +       struct udevice *dev;
> +
> +       /* PRCI init */
> +       ret = uclass_get_device(UCLASS_CLK, 0, &dev);
> +       if (ret) {
> +               debug("Clock init failed: %d\n", ret);
> +               return;
> +       }
> +
> +       ret = uclass_get_device(UCLASS_RAM, 0, &dev);
> +       if (ret) {
> +               printf("DRAM init failed: %d\n", ret);
> +               return;
> +       }
> +
> +       /*
> +        * GEMGXL init VSC8541 PHY reset sequence;
> +        * leave pull-down active for 2ms
> +        */
> +       nsleep(2000000);
> +       /* Set GPIO 12 (PHY NRESET) to OE=1 and OVAL=1 */
> +       GPIO_REG(GPIO_OUTPUT_VAL) |= PHY_NRESET;
> +       GPIO_REG(GPIO_OUTPUT_EN) |= PHY_NRESET;

Please switch to use DM GPIO APIs to do the PHY reset.

> +       nsleep(100);
> +
> +       /* Reset PHY again to enter unmanaged mode */
> +       GPIO_REG(GPIO_OUTPUT_VAL) &= ~PHY_NRESET;
> +       nsleep(100);
> +       GPIO_REG(GPIO_OUTPUT_VAL) |= PHY_NRESET;
> +       nsleep(15000000);
> +}
> +
> +void board_init_f(ulong dummy)
> +{
> +       int ret;
> +
> +       ret = spl_early_init();
> +       if (ret)
> +               panic("spl_early_init() failed: %d\n", ret);
> +
> +       arch_cpu_init_dm();
> +
> +       init_clk_and_ddr();
> +
> +       preloader_console_init();
> +}
> diff --git a/include/configs/sifive-fu540.h b/include/configs/sifive-fu540.h
> index 2756ed5a77..ef3ae9b650 100644
> --- a/include/configs/sifive-fu540.h
> +++ b/include/configs/sifive-fu540.h
> @@ -11,6 +11,22 @@
>
>  #include <linux/sizes.h>
>
> +#ifdef CONFIG_SPL
> +
> +#define CONFIG_SPL_MAX_SIZE            0x00100000
> +#define CONFIG_SPL_BSS_START_ADDR      0x85000000
> +#define CONFIG_SPL_BSS_MAX_SIZE                0x00100000
> +#define CONFIG_SYS_SPL_MALLOC_START    (CONFIG_SPL_BSS_START_ADDR + \
> +                                        CONFIG_SPL_BSS_MAX_SIZE)
> +#define CONFIG_SYS_SPL_MALLOC_SIZE     0x00100000
> +
> +#define CONFIG_SPL_LOAD_FIT_ADDRESS    0x84000000
> +
> +#define CONFIG_SPL_STACK       (0x08000000 + 0x001D0000 - \
> +                                GENERATED_GBL_DATA_SIZE)
> +
> +#endif
> +
>  #define CONFIG_SYS_SDRAM_BASE          0x80000000
>  #define CONFIG_SYS_INIT_SP_ADDR                (CONFIG_SYS_SDRAM_BASE + SZ_2M)
>
> @@ -24,6 +40,7 @@
>
>  /* Environment options */
>
> +#ifndef CONFIG_SPL_BUILD
>  #define BOOT_TARGET_DEVICES(func) \
>         func(MMC, mmc, 0) \
>         func(DHCP, dhcp, na)
> @@ -43,5 +60,6 @@
>  #define CONFIG_PREBOOT \
>         "setenv fdt_addr ${fdtcontroladdr};" \
>         "fdt addr ${fdtcontroladdr};"
> +#endif
>
>  #endif /* __CONFIG_H */
> --

Regards,
Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 11/14] configs: fu540: Add config options for U-boot SPL
  2020-03-11  7:03 ` [PATCH v5 11/14] configs: fu540: Add config options for U-boot SPL Pragnesh Patel
@ 2020-03-13  8:48   ` Bin Meng
  2020-03-17 14:45     ` Pragnesh Patel
  0 siblings, 1 reply; 53+ messages in thread
From: Bin Meng @ 2020-03-13  8:48 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> With sifive_fu540_defconfig:

Please use "U-Boot" in the commit title

>
> User can use FSBL or u-boot-spl.bin anyone at a time.
>
> For FSBL,
> fsbl->fw_payload.bin(opensbi+u-boot)
>
> For u-boot-spl.bin,
> u-boot-spl.bin->FIT image(opensbi+u-boot+dtb)
>
> U-Boot SPL will be loaded by ZSBL from SD card (replace fsbl.bin with
> u-boot-spl.bin) and runs in L2 LIM in machine mode and then load FIT
> image u-boot.itb from 1st partition of SD card (replace fw_payload.bin
> with u-boot.itb) into RAM.
>
> U-boot SPL expects u-boot.itb FIT image in the 1st partition of SD

U-Boot

> card irrespective of GUID
>
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> ---
>  configs/sifive_fu540_defconfig | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/configs/sifive_fu540_defconfig b/configs/sifive_fu540_defconfig
> index 6d61e6c960..1b33c81be4 100644
> --- a/configs/sifive_fu540_defconfig
> +++ b/configs/sifive_fu540_defconfig
> @@ -12,3 +12,14 @@ CONFIG_DISPLAY_BOARDINFO=y
>  CONFIG_DEFAULT_DEVICE_TREE="hifive-unleashed-a00"
>  CONFIG_SYS_RELOC_GD_ENV_ADDR=y
>  CONFIG_DM_MTD=y
> +CONFIG_SPL_SEPARATE_BSS=y
> +CONFIG_SPL=y
> +CONFIG_SPL_MMC_SUPPORT=y
> +CONFIG_SPL_SPI_SUPPORT=y
> +CONFIG_SPL_YMODEM_SUPPORT=y
> +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y
> +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=1
> +CONFIG_SPL_CLK=y
> +CONFIG_SPL_PAYLOAD="u-boot.itb"
> +CONFIG_SYS_MALLOC_F_LEN=0x3000
> +CONFIG_SIFIVE_FU540_DDR=y
> --

Please make sure this is exactly the same as:

$ make sifive_fu540_defconfig
$ make savedefconfig

Compare the generated defconfig with sifive_fu540_defconfig

Regards,
Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 12/14] riscv: sifive: fu540: enable all cache ways from u-boot proper
  2020-03-11  7:03 ` [PATCH v5 12/14] riscv: sifive: fu540: enable all cache ways from u-boot proper Pragnesh Patel
@ 2020-03-13  9:01   ` Bin Meng
  2020-03-13 10:02     ` Anup Patel
  0 siblings, 1 reply; 53+ messages in thread
From: Bin Meng @ 2020-03-13  9:01 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> Enable all cache ways from u-boot proper.

U-Boot

>
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> ---
>  board/sifive/fu540/Makefile |  1 +
>  board/sifive/fu540/cache.c  | 20 ++++++++++++++++++++
>  board/sifive/fu540/cache.h  | 13 +++++++++++++
>  board/sifive/fu540/fu540.c  |  6 ++++--
>  4 files changed, 38 insertions(+), 2 deletions(-)
>  create mode 100644 board/sifive/fu540/cache.c
>  create mode 100644 board/sifive/fu540/cache.h
>
> diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
> index b05e2f5807..3b867bbd89 100644
> --- a/board/sifive/fu540/Makefile
> +++ b/board/sifive/fu540/Makefile
> @@ -3,6 +3,7 @@
>  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
>
>  obj-y  += fu540.o
> +obj-y  += cache.o
>
>  ifdef CONFIG_SPL_BUILD
>  obj-y += spl.o
> diff --git a/board/sifive/fu540/cache.c b/board/sifive/fu540/cache.c
> new file mode 100644
> index 0000000000..a0bcd2ba48
> --- /dev/null
> +++ b/board/sifive/fu540/cache.c

This should be put into arch/riscv/cpu/fu540/cache.c

> @@ -0,0 +1,20 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + */
> +#include <asm/io.h>
> +
> +/* Register offsets */
> +#define CACHE_ENABLE           0x008
> +
> +/* Enable ways; allow cache to use these ways */
> +void cache_enable_ways(u64 base_addr, u8 value)
> +{
> +       volatile u32 *enable = (volatile u32 *)(base_addr +
> +                                         CACHE_ENABLE);
> +       /* memory barrier */
> +       mb();
> +       (*enable) = value;
> +       /* memory barrier */
> +       mb();
> +}
> diff --git a/board/sifive/fu540/cache.h b/board/sifive/fu540/cache.h
> new file mode 100644
> index 0000000000..425124a23b
> --- /dev/null
> +++ b/board/sifive/fu540/cache.h

arch/riscv/include/asm/arch-fu540/cache.h

> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + */
> +
> +#ifndef FU540_CACHE_H
> +#define FU540_CACHE_H
> +
> +#define CACHE_CTRL_ADDR               _AC(0x2010000, UL)
> +
> +void cache_enable_ways(u64 base_addr, u8 value);
> +
> +#endif /* FU540_CACHE_H */
> diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
> index 89a65eb3fb..1d6c0c9bba 100644
> --- a/board/sifive/fu540/fu540.c
> +++ b/board/sifive/fu540/fu540.c
> @@ -13,6 +13,8 @@
>  #include <misc.h>
>  #include <spl.h>
>
> +#include "cache.h"
> +
>  /*
>   * This define is a value used for error/unknown serial.
>   * If we really care about distinguishing errors and 0 is
> @@ -111,8 +113,8 @@ int misc_init_r(void)
>
>  int board_init(void)
>  {
> -       /* For now nothing to do here. */
> -
> +       /* enable all cache ways */
> +       cache_enable_ways(CACHE_CTRL_ADDR, 15);
>         return 0;
>  }
>

Regards,
Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 13/14] sifive: fix palmer's email address
  2020-03-11  7:03 ` [PATCH v5 13/14] sifive: fix palmer's email address Pragnesh Patel
@ 2020-03-13  9:01   ` Bin Meng
  0 siblings, 0 replies; 53+ messages in thread
From: Bin Meng @ 2020-03-13  9:01 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> Fix Palmer's email address
>
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> ---
>  board/sifive/fu540/MAINTAINERS | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 14/14] doc: update FU540 RISC-V documentation
  2020-03-11  7:03 ` [PATCH v5 14/14] doc: update FU540 RISC-V documentation Pragnesh Patel
@ 2020-03-13  9:22   ` Bin Meng
  2020-03-17 14:31     ` Pragnesh Patel
  0 siblings, 1 reply; 53+ messages in thread
From: Bin Meng @ 2020-03-13  9:22 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> Add descriptions about U-Boot SPL feature and how to build and run.
>
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> ---
>  doc/board/sifive/fu540.rst | 409 ++++++++++++++++++++++++++++++++++---
>  1 file changed, 385 insertions(+), 24 deletions(-)
>
> diff --git a/doc/board/sifive/fu540.rst b/doc/board/sifive/fu540.rst
> index 3937222c6c..e5414f4eef 100644
> --- a/doc/board/sifive/fu540.rst
> +++ b/doc/board/sifive/fu540.rst
> @@ -42,8 +42,60 @@ Building
>     export ARCH=riscv
>     export CROSS_COMPILE=<riscv64 toolchain prefix>
>
> -3. make sifive_fu540_defconfig
> -4. make
> +User can use FSBL or u-boot-spl as a 1st stage bootloader.
> +
> +1) Use FSBL as a 1st stage bootloader

The 1st stage. Please fix this globally in this file.

> +
> +.. code-block:: console
> +
> +       git clone https://github.com/sifive/freedom-u540-c000-bootloader.git
> +       cd freedom-u540-c000-bootloader
> +       make
> +
> +       cd <u-boot-dir>
> +       make sifive_fu540_defconfig
> +       make
> +
> +       git clone https://github.com/riscv/opensbi.git
> +       cd opensbi
> +       make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=<path to u-boot.bin>

It should be u-boot-dtb.bin

> +
> +This will generate a fw_payload.bin(build/platform/sifive/fu540/firmware/fw_payload.bin)

nits: needs one space after fw_payload.bin

> +
> +u-boot.bin is used as a payload of the OpenSBI FW_PAYLOAD firmware.

u-boot-dtb.bin

> +
> +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)
> +
> +2) Use u-boot-spl as a 1st stage bootloader
> +
> +Before building U-Boot SPL, OpenSBI must be build first. OpenSBI can be

must be built

> +cloned and build for FU540 as below:

built

> +
> +.. code-block:: console
> +
> +       git clone https://github.com/riscv/opensbi.git
> +       cd opensbi
> +       make PLATFORM=sifive/fu540
> +
> +Copy OpenSBI FW_DYNAMIC image (build/platform/sifive/fu540/firmware/fw_dynamic.bin)
> +into U-Boot root directory
> +
> +.. code-block:: console
> +
> +       cp build/platform/sifive/fu540/firmware/fw_dynamic.bin <u-boot-dir>
> +
> +Now build the u-boot-spl and u-boot proper

nits: U-Boot proper

> +
> +.. code-block:: console
> +
> +       cd <u-boot-dir>
> +       make sifive_fu540_defconfig
> +       make
> +
> +This will generate spl/u-boot-spl.bin and FIT image(u-boot.itb)

need one space after image

> +
>
>  Flashing
>  --------
> @@ -53,28 +105,55 @@ The current U-Boot port is supported in S-mode only and loaded from DRAM.
>  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.
>
> -Currently, the u-boot.bin is used as a payload of the OpenSBI FW_PAYLOAD
> -firmware. We need to compile OpenSBI with below command:
> +1) Use FSBL as a 1st stage bootloader
> +
> +ZSBL loads the FSBL(fsbl.bin) from a partition with GUID type

need one space after FSBL

> +5B193300-FC78-40CD-8002-E86C45580B47
> +
> +FSBL loads the fw_payload.bin from a partition with GUID type
> +2E54B353-1271-4842-806F-E436D6AF6985
> +
> +Once the prior stage firmware/bootloader binary is generated, it should be
> +copied to the first partition of the sdcard.
>
>  .. code-block:: none
>
> -make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=<path to u-boot-dtb.bin>
> +     sudo dd if=fsbl.bin of=/dev/disk2s4 bs=1024
> +     sudo dd if=fw_payload.bin of=/dev/disk2s1 bs=1024
>
> -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)
> +Assuming that /dev/disk2s4 partition is of GUID type
> +5B193300-FC78-40CD-8002-E86C45580B47 and /dev/disk2s1 partition
> +is of GUID type 2E54B353-1271-4842-806F-E436D6AF6985
> +
> +2) Use u-boot-spl as a 1st stage bootloader
> +
> +ZSBL loads the U-boot SPL(u-boot-spl.bin) from a partition with GUID type

U-Boot, and need one space after SPL

> +5B193300-FC78-40CD-8002-E86C45580B47
> +
> +U-boot SPL expects a u-boot FIT image(u-boot.itb) from 1st partition(/dev/sdc1)

U-Boot, and need one space after image

> +of SD card irrespective of GUID
> +
> +FIT image(u-boot.itb) is a combination of fw_dynamic.bin, u-boot-nodtb.bin and

need one space after image

> +device tree blob(hifive-unleashed-a00.dtb)

need one space after blob

>
>  Once the prior stage firmware/bootloader binary is generated, it should be
>  copied to the first partition of the sdcard.
>
>  .. code-block:: none
>
> -    sudo dd if=<prior_stage_firmware_binary> of=/dev/disk2s1 bs=1024
> +    sudo dd if=spl/u-boot-spl.bin of=/dev/disk2s4 bs=1024
> +    sudo dd if=u-boot.itb of=/dev/disk2s1 bs=1024
> +
> +Assuming that /dev/disk2s4 partition is of GUID type
> +5B193300-FC78-40CD-8002-E86C45580B47 and /dev/disk2s1 is of
> +any GUID type raw partition.
>
>  Booting
>  -------
>  Once you plugin the sdcard and power up, you should see the U-Boot prompt.
>
> +1) Use FSBL as a 1st stage bootloader
> +
>  Sample boot log from HiFive Unleashed board
>  -------------------------------------------
>
> @@ -145,19 +224,6 @@ load uImage.
>     Filename '/sifive/fu540/Image'.
>     Load address: 0x84000000
>     Loading: #################################################################
> -            #################################################################
> -            #################################################################
> -            #################################################################
> -            #################################################################
> -            #################################################################
> -            #################################################################
> -            #################################################################
> -            #################################################################
> -            #################################################################
> -            #################################################################
> -            #################################################################
> -            #################################################################
> -            #################################################################
>              #################################################################
>              #################################################################
>              #################################################################
> @@ -184,8 +250,6 @@ load uImage.
>     Filename '/sifive/fu540/uRamdisk'.
>     Load address: 0x88300000
>     Loading: #################################################################
> -            #################################################################
> -            #################################################################
>              #################################################################
>              #################################################################
>              #################################################################
> @@ -363,3 +427,300 @@ load uImage.
>
>     Please press Enter to activate this console.
>     / #
> +
> +
> +2) Use u-boot-spl as a 1st stage bootloader
> +
> +The U-Boot SPL will boot in M mode and load the FIT image which include
> +OpenSBI and U-Boot proper images. After loading progress, it will jump
> +to OpenSBI first and then U-Boot proper which will run in S mode.
> +
> +Sample boot log from HiFive Unleashed board
> +-------------------------------------------
> +
> +.. code-block:: none
> +
> +   U-Boot SPL 2020.04-rc1-00212-g375b0a2dad-dirty (Feb 13 2020 - 17:45:44 +0530)
> +   Trying to boot from MMC1
> +
> +
> +   U-Boot 2020.04-rc1-00212-g375b0a2dad-dirty (Feb 13 2020 - 17:45:44 +0530)
> +
> +   CPU:   rv64imafdc
> +   Model: SiFive HiFive Unleashed A00
> +   DRAM:  8 GiB
> +   MMC:   spi at 10050000:mmc at 0: 0
> +   In:    serial at 10010000
> +   Out:   serial at 10010000
> +   Err:   serial at 10010000
> +   Board serial number should not be 0 !!

Something is wrong with the OTP driver?

> +   Net:
> +   Warning: ethernet at 10090000 (eth0) using random MAC address - 92:79:17:2d:7b:b7
> +   eth0: ethernet at 10090000
> +   Hit any key to stop autoboot:  0
> +   => version
> +   U-Boot 2020.04-rc1-00212-g375b0a2dad-dirty (Feb 13 2020 - 17:45:44 +0530)
> +
> +   riscv64-unknown-linux-gnu-gcc (crosstool-NG 1.24.0.37-3f461da) 9.2.0
> +   GNU ld (crosstool-NG 1.24.0.37-3f461da) 2.32
> +   => mmc info
> +   Device: spi at 10050000:mmc at 0
> +   Manufacturer ID: 3
> +   OEM: 5344
> +   Name: SC16G
> +   Bus Speed: 20000000
> +   Mode: SD Legacy
> +   Rd Block Len: 512
> +   SD version 2.0
> +   High Capacity: Yes
> +   Capacity: 14.8 GiB
> +   Bus Width: 1-bit
> +   Erase Group Size: 512 Bytes
> +   => mmc part
> +
> +   Partition Map for MMC device 0  --   Partition Type: EFI
> +
> +   Part    Start LBA       End LBA         Name
> +   Attributes
> +   Type GUID
> +   Partition GUID
> +   1     0x00000800      0x000107ff      "SiFive bare-metal (or stage 2 loader"
> +   attrs:  0x0000000000000000
> +   type:   2e54b353-1271-4842-806f-e436d6af6985
> +   guid:   3c9eabe1-b16b-4a2e-9b4e-f065c740bb86
> +   2     0x00040800      0x00ecdfde      "Linux filesystem"
> +   attrs:  0x0000000000000000
> +   type:   0fc63daf-8483-4772-8e79-3d69d8477de4
> +   guid:   ad9309ff-d204-42f0-9f99-f3275a83f565
> +
> +Now you can configure your networking, tftp server and use tftp boot method to
> +load uImage.
> +
> +.. code-block:: none
> +
> +   => setenv serverip 172.16.35.74
> +   => setenv ipaddr 172.16.35.40
> +   => tftpboot 0x83000000 fit.itb
> +   ethernet at 10090000: PHY present at 0
> +   ethernet at 10090000: Starting autonegotiation...
> +   ethernet at 10090000: Autonegotiation complete
> +   ethernet at 10090000: link up, 100Mbps full-duplex (lpa: 0x41e1)
> +   Using ethernet at 10090000 device
> +   TFTP from server 172.16.35.74; our IP address is 172.16.35.40
> +   Filename 'fit.itb'.
> +   Load address: 0x83000000
> +   Loading: #################################################################
> +   #################################################################
> +   #################################################################
> +   #################################################################
> +   #################################################################
> +   #################################################################
> +   #################################################################
> +   #################################################################
> +   #################################################################
> +   #################################################################
> +   #################################################################
> +   #################################################################
> +   #################################################################
> +   #################################################################
> +   #################################################################
> +   #################################################################
> +   #################################################################
> +   #################################################################
> +   ################################################################
> +   ###################################
> +   878.9 KiB/s
> +   done
> +   Bytes transferred = 13823823 (d2ef4f hex)
> +   => bootm 0x83000000
> +   ## Loading kernel from FIT Image at 83000000 ...
> +   Using 'config-1' configuration
> +   Trying 'kernel at 1' kernel subimage
> +   Description:  Linux kernel
> +   Type:         Kernel Image
> +   Compression:  uncompressed
> +   Data Start:   0x830000d8
> +   Data Size:    9247260 Bytes = 8.8 MiB
> +   Architecture: RISC-V
> +   OS:           Linux
> +   Load Address: 0x80200000
> +   Entry Point:  0x80200000
> +   Verifying Hash Integrity ... OK
> +   ## Loading ramdisk from FIT Image at 83000000 ...
> +   Using 'config-1' configuration
> +   Trying 'ramdisk at 1' ramdisk subimage
> +   Description:  ramdisk
> +   Type:         RAMDisk Image
> +   Compression:  gzip compressed
> +   Data Start:   0x838d3378
> +   Data Size:    4568674 Bytes = 4.4 MiB
> +   Architecture: RISC-V
> +   OS:           Linux
> +   Load Address: 0x82000000
> +   Entry Point:  unavailable
> +   Verifying Hash Integrity ... OK
> +   Loading ramdisk from 0x838d3378 to 0x82000000
> +   WARNING: 'compression' nodes for ramdisks are deprecated, please fix your .its file!
> +   ## Loading fdt from FIT Image at 83000000 ...
> +   Using 'config-1' configuration
> +   Trying 'fdt at 1' fdt subimage
> +   Description:  unavailable
> +   Type:         Flat Device Tree
> +   Compression:  uncompressed
> +   Data Start:   0x838d1b80
> +   Data Size:    6023 Bytes = 5.9 KiB
> +   Architecture: RISC-V
> +   Verifying Hash Integrity ... OK
> +   Booting using the fdt blob at 0x838d1b80
> +   Loading Kernel Image
> +   Using Device Tree in place at 00000000838d1b80, end 00000000838d6306
> +
> +   Starting kernel ...
> +
> +   [    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
> +   [    0.000000] Linux version 5.3.0-13236-g97f9a3c4eee5 (pragneshp at sachinj2-OptiPlex-7010) (gcc version 8.2.0 (Buildroot 2018.11-rc2-00003-ga0787e9
> +   [    0.000000] earlycon: sifive0 at MMIO 0x0000000010010000 (options '')
> +   [    0.000000] printk: bootconsole [sifive0] enabled
> +   [    0.000000] Initial ramdisk at: 0x(____ptrval____) (4568674 bytes)
> +   [    0.000000] Zone ranges:
> +   [    0.000000]   DMA32    [mem 0x0000000080200000-0x00000000ffffffff]
> +   [    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 is not available
> +   [    0.000000] CPU with hartid=0 is not available
> +   [    0.000000] elf_hwcap is 0x112d
> +   [    0.000000] percpu: Embedded 17 pages/cpu s30680 r8192 d30760 u69632
> +   [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 2067975
> +   [    0.000000] Kernel command line: earlycon=sifive,0x10010000 console=ttySIF0,115200
> +   [    0.000000] Dentry cache hash table entries: 1048576 (order: 11, 8388608 bytes, linear)
> +   [    0.000000] Inode-cache hash table entries: 524288 (order: 10, 4194304 bytes, linear)
> +   [    0.000000] Sorting __ex_table...
> +   [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
> +   [    0.000000] Memory: 8179828K/8386560K available (6081K kernel code, 388K rwdata, 2025K rodata, 209K init, 307K bss, 206732K reserved, 0K cma-r)
> +   [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
> +   [    0.000000] rcu: Hierarchical RCU implementation.
> +   [    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 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 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.000006] sched_clock: 64 bits at 1000kHz, resolution 1000ns, wraps every 2199023255500ns
> +   [    0.008467] Console: colour dummy device 80x25
> +   [    0.012819] Calibrating delay loop (skipped), value calculated using timer frequency.. 2.00 BogoMIPS (lpj=4000)
> +   [    0.022844] pid_max: default: 32768 minimum: 301
> +   [    0.027915] Mount-cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
> +   [    0.035332] Mountpoint-cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
> +   [    0.044791] rcu: Hierarchical SRCU implementation.
> +   [    0.049255] smp: Bringing up secondary CPUs ...
> +   [    0.055034] smp: Brought up 1 node, 4 CPUs
> +   [    0.059664] devtmpfs: initialized
> +   [    0.063818] random: get_random_u32 called from bucket_table_alloc.isra.29+0x4e/0x160 with crng_init=0
> +   [    0.072588] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
> +   [    0.082000] futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
> +   [    0.089513] NET: Registered protocol family 16
> +   [    0.105911] vgaarb: loaded
> +   [    0.108166] SCSI subsystem initialized
> +   [    0.111946] usbcore: registered new interface driver usbfs
> +   [    0.117105] usbcore: registered new interface driver hub
> +   [    0.122486] usbcore: registered new device driver usb
> +   [    0.128073] clocksource: Switched to clocksource riscv_clocksource
> +   [    0.140277] NET: Registered protocol family 2
> +   [    0.144449] tcp_listen_portaddr_hash hash table entries: 4096 (order: 4, 65536 bytes, linear)
> +   [    0.152620] TCP established hash table entries: 65536 (order: 7, 524288 bytes, linear)
> +   [    0.162238] TCP bind hash table entries: 65536 (order: 8, 1048576 bytes, linear)
> +   [    0.172159] TCP: Hash tables configured (established 65536 bind 65536)
> +   [    0.178343] UDP hash table entries: 4096 (order: 5, 131072 bytes, linear)
> +   [    0.185140] UDP-Lite hash table entries: 4096 (order: 5, 131072 bytes, linear)
> +   [    0.192553] NET: Registered protocol family 1
> +   [    0.196752] RPC: Registered named UNIX socket transport module.
> +   [    0.202145] RPC: Registered udp transport module.
> +   [    0.206828] RPC: Registered tcp transport module.
> +   [    0.211512] RPC: Registered tcp NFSv4.1 backchannel transport module.
> +   [    0.217939] PCI: CLS 0 bytes, default 64
> +   [    0.222139] Unpacking initramfs...
> +   [    0.578803] Freeing initrd memory: 4460K
> +   [    0.582972] workingset: timestamp_bits=62 max_order=21 bucket_order=0
> +   [    0.596643] NFS: Registering the id_resolver key type
> +   [    0.600950] Key type id_resolver registered
> +   [    0.605134] Key type id_legacy registered
> +   [    0.609090] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
> +   [    0.615928] 9p: Installing v9fs 9p2000 file system support
> +   [    0.621581] NET: Registered protocol family 38
> +   [    0.625700] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
> +   [    0.633051] io scheduler mq-deadline registered
> +   [    0.637559] io scheduler kyber registered
> +   [    0.685592] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
> +   [    0.692184] 10010000.serial: ttySIF0 at MMIO 0x10010000 (irq = 4, base_baud = 0) is a SiFive UART v0
> +   [    0.700566] printk: console [ttySIF0] enabled
> +   [    0.700566] printk: console [ttySIF0] enabled
> +   [    0.709228] printk: bootconsole [sifive0] disabled
> +   [    0.709228] printk: bootconsole [sifive0] disabled
> +   [    0.719030] 10011000.serial: ttySIF1 at MMIO 0x10011000 (irq = 1, base_baud = 0) is a SiFive UART v0
> +   [    0.728364] [drm] radeon kernel modesetting enabled.
> +   [    0.745292] loop: module loaded
> +   [    0.748208] sifive_spi 10040000.spi: mapped; irq=3, cs=1
> +   [    0.753490] sifive_spi 10050000.spi: mapped; irq=5, cs=1
> +   [    0.758811] libphy: Fixed MDIO Bus: probed
> +   [    0.762886] macb 10090000.ethernet: Registered clk switch 'sifive-gemgxl-mgmt'
> +   [    0.769643] macb: GEM doesn't support hardware ptp.
> +   [    0.774532] libphy: MACB_mii_bus: probed
> +   [    0.940349] Microsemi VSC8541 SyncE 10090000.ethernet-ffffffff:00: attached PHY driver [Microsemi VSC8541 SyncE] (mii_bus:phy_addr=10090000.et)
> +   [    0.954893] macb 10090000.ethernet eth0: Cadence GEM rev 0x10070109 at 0x10090000 irq 6 (92:79:17:2d:7b:b7)
> +   [    0.964698] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
> +   [    0.970417] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
> +   [    0.976410] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
> +   [    0.982832] ehci-pci: EHCI PCI platform driver
> +   [    0.987288] ehci-platform: EHCI generic platform driver
> +   [    0.992547] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
> +   [    0.998646] ohci-pci: OHCI PCI platform driver
> +   [    1.003092] ohci-platform: OHCI generic platform driver
> +   [    1.008557] usbcore: registered new interface driver uas
> +   [    1.013621] usbcore: registered new interface driver usb-storage
> +   [    1.019695] mousedev: PS/2 mouse device common for all mice
> +   [    1.050569] mmc_spi spi1.0: SD/MMC host mmc0, no DMA, no WP, no poweroff, cd polling
> +   [    1.057714] usbcore: registered new interface driver usbhid
> +   [    1.063098] usbhid: USB HID core driver
> +   [    1.067805] NET: Registered protocol family 10
> +   [    1.072421] Segment Routing with IPv6
> +   [    1.075367] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
> +   [    1.081745] NET: Registered protocol family 17
> +   [    1.085867] 9pnet: Installing 9P2000 support
> +   [    1.089951] Key type dns_resolver registered
> +   [    1.096367] Freeing unused kernel memory: 208K
> +   [    1.100023] This architecture does not have kernel memory protection.
> +   [    1.106468] Run /init as init process
> +   Starting syslogd: OK
> +   Starting klogd: OK
> +   Starting mdev...
> +   /etc/init.d/S10mdev: line 9: can't create /proc/sys/kernel/hotplug: nonexistent directory
> +   [    1.167972] mmc0: host does not support reading read-only switch, assuming write-enable
> +   [    1.175224] mmc0: new SDHC card on SPI
> +   [    1.180428] mmcblk0: mmc0:0000 SC16G 14.8 GiB
> +   [    1.214935]  mmcblk0: p1 p2 p4
> +   modprobe: can't change directory to '/lib/modules': No such file or directory
> +   Initializing random number generator... [    1.664435] random: dd: uninitialized urandom read (512 bytes read)
> +   done.
> +   Starting network: udhcpc: started, v1.29.3
> +   udhcpc: sending discover
> +   [    3.756700] macb 10090000.ethernet eth0: link up (100/Full)
> +   [    3.761515] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
> +   udhcpc: sending discover
> +   udhcpc: sending select for 172.16.35.4
> +   udhcpc: lease of 172.16.35.4 obtained, lease time 3600
> +   deleting routers
> +   adding dns 172.16.34.75
> +   adding dns 172.16.24.25
> +   OK
> +   Starting dropbear sshd: [    4.893179] random: dropbear: uninitialized urandom read (32 bytes read)
> +   OK
> +
> +   Welcome to Buildroot
> +   buildroot login: root
> +   Password:
> +   #

Regards,
Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 12/14] riscv: sifive: fu540: enable all cache ways from u-boot proper
  2020-03-13  9:01   ` Bin Meng
@ 2020-03-13 10:02     ` Anup Patel
  2020-03-13 10:22       ` Bin Meng
  0 siblings, 1 reply; 53+ messages in thread
From: Anup Patel @ 2020-03-13 10:02 UTC (permalink / raw)
  To: u-boot

On Fri, Mar 13, 2020 at 2:31 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
> <pragnesh.patel@sifive.com> wrote:
> >
> > Enable all cache ways from u-boot proper.
>
> U-Boot
>
> >
> > Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> > ---
> >  board/sifive/fu540/Makefile |  1 +
> >  board/sifive/fu540/cache.c  | 20 ++++++++++++++++++++
> >  board/sifive/fu540/cache.h  | 13 +++++++++++++
> >  board/sifive/fu540/fu540.c  |  6 ++++--
> >  4 files changed, 38 insertions(+), 2 deletions(-)
> >  create mode 100644 board/sifive/fu540/cache.c
> >  create mode 100644 board/sifive/fu540/cache.h
> >
> > diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
> > index b05e2f5807..3b867bbd89 100644
> > --- a/board/sifive/fu540/Makefile
> > +++ b/board/sifive/fu540/Makefile
> > @@ -3,6 +3,7 @@
> >  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
> >
> >  obj-y  += fu540.o
> > +obj-y  += cache.o
> >
> >  ifdef CONFIG_SPL_BUILD
> >  obj-y += spl.o
> > diff --git a/board/sifive/fu540/cache.c b/board/sifive/fu540/cache.c
> > new file mode 100644
> > index 0000000000..a0bcd2ba48
> > --- /dev/null
> > +++ b/board/sifive/fu540/cache.c
>
> This should be put into arch/riscv/cpu/fu540/cache.c
>
> > @@ -0,0 +1,20 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (c) 2019 SiFive, Inc
> > + */
> > +#include <asm/io.h>
> > +
> > +/* Register offsets */
> > +#define CACHE_ENABLE           0x008
> > +
> > +/* Enable ways; allow cache to use these ways */
> > +void cache_enable_ways(u64 base_addr, u8 value)
> > +{
> > +       volatile u32 *enable = (volatile u32 *)(base_addr +
> > +                                         CACHE_ENABLE);
> > +       /* memory barrier */
> > +       mb();
> > +       (*enable) = value;
> > +       /* memory barrier */
> > +       mb();
> > +}
> > diff --git a/board/sifive/fu540/cache.h b/board/sifive/fu540/cache.h
> > new file mode 100644
> > index 0000000000..425124a23b
> > --- /dev/null
> > +++ b/board/sifive/fu540/cache.h
>
> arch/riscv/include/asm/arch-fu540/cache.h

Let's not entire FU540 directory under arch/riscv/cpu directory
just to have cache functions. The arch/riscv/cpu/generic is perfectly
suitable for FU540.

If we re-use arch/riscv/cpu/generic as-much as possible then
arch/riscv will be easy to maintain in future.

We can add arch/riscv/cpu/generic/cache.c which will do
things FU540 specific based on "#ifdef" or "DT compatible string".

>
> > @@ -0,0 +1,13 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/*
> > + * Copyright (c) 2019 SiFive, Inc
> > + */
> > +
> > +#ifndef FU540_CACHE_H
> > +#define FU540_CACHE_H
> > +
> > +#define CACHE_CTRL_ADDR               _AC(0x2010000, UL)
> > +
> > +void cache_enable_ways(u64 base_addr, u8 value);
> > +
> > +#endif /* FU540_CACHE_H */
> > diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
> > index 89a65eb3fb..1d6c0c9bba 100644
> > --- a/board/sifive/fu540/fu540.c
> > +++ b/board/sifive/fu540/fu540.c
> > @@ -13,6 +13,8 @@
> >  #include <misc.h>
> >  #include <spl.h>
> >
> > +#include "cache.h"
> > +
> >  /*
> >   * This define is a value used for error/unknown serial.
> >   * If we really care about distinguishing errors and 0 is
> > @@ -111,8 +113,8 @@ int misc_init_r(void)
> >
> >  int board_init(void)
> >  {
> > -       /* For now nothing to do here. */
> > -
> > +       /* enable all cache ways */
> > +       cache_enable_ways(CACHE_CTRL_ADDR, 15);
> >         return 0;
> >  }
> >
>
> Regards,
> Bin

Regards,
Anup

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 12/14] riscv: sifive: fu540: enable all cache ways from u-boot proper
  2020-03-13 10:02     ` Anup Patel
@ 2020-03-13 10:22       ` Bin Meng
  2020-03-13 10:49         ` Anup Patel
  2020-03-13 10:54         ` Anup Patel
  0 siblings, 2 replies; 53+ messages in thread
From: Bin Meng @ 2020-03-13 10:22 UTC (permalink / raw)
  To: u-boot

Hi Anup,

On Fri, Mar 13, 2020 at 6:02 PM Anup Patel <anup@brainfault.org> wrote:
>
> On Fri, Mar 13, 2020 at 2:31 PM Bin Meng <bmeng.cn@gmail.com> wrote:
> >
> > On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
> > <pragnesh.patel@sifive.com> wrote:
> > >
> > > Enable all cache ways from u-boot proper.
> >
> > U-Boot
> >
> > >
> > > Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> > > ---
> > >  board/sifive/fu540/Makefile |  1 +
> > >  board/sifive/fu540/cache.c  | 20 ++++++++++++++++++++
> > >  board/sifive/fu540/cache.h  | 13 +++++++++++++
> > >  board/sifive/fu540/fu540.c  |  6 ++++--
> > >  4 files changed, 38 insertions(+), 2 deletions(-)
> > >  create mode 100644 board/sifive/fu540/cache.c
> > >  create mode 100644 board/sifive/fu540/cache.h
> > >
> > > diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
> > > index b05e2f5807..3b867bbd89 100644
> > > --- a/board/sifive/fu540/Makefile
> > > +++ b/board/sifive/fu540/Makefile
> > > @@ -3,6 +3,7 @@
> > >  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
> > >
> > >  obj-y  += fu540.o
> > > +obj-y  += cache.o
> > >
> > >  ifdef CONFIG_SPL_BUILD
> > >  obj-y += spl.o
> > > diff --git a/board/sifive/fu540/cache.c b/board/sifive/fu540/cache.c
> > > new file mode 100644
> > > index 0000000000..a0bcd2ba48
> > > --- /dev/null
> > > +++ b/board/sifive/fu540/cache.c
> >
> > This should be put into arch/riscv/cpu/fu540/cache.c
> >
> > > @@ -0,0 +1,20 @@
> > > +// SPDX-License-Identifier: GPL-2.0+
> > > +/*
> > > + * Copyright (c) 2019 SiFive, Inc
> > > + */
> > > +#include <asm/io.h>
> > > +
> > > +/* Register offsets */
> > > +#define CACHE_ENABLE           0x008
> > > +
> > > +/* Enable ways; allow cache to use these ways */
> > > +void cache_enable_ways(u64 base_addr, u8 value)
> > > +{
> > > +       volatile u32 *enable = (volatile u32 *)(base_addr +
> > > +                                         CACHE_ENABLE);
> > > +       /* memory barrier */
> > > +       mb();
> > > +       (*enable) = value;
> > > +       /* memory barrier */
> > > +       mb();
> > > +}
> > > diff --git a/board/sifive/fu540/cache.h b/board/sifive/fu540/cache.h
> > > new file mode 100644
> > > index 0000000000..425124a23b
> > > --- /dev/null
> > > +++ b/board/sifive/fu540/cache.h
> >
> > arch/riscv/include/asm/arch-fu540/cache.h
>
> Let's not entire FU540 directory under arch/riscv/cpu directory
> just to have cache functions. The arch/riscv/cpu/generic is perfectly
> suitable for FU540.

I doubt arch/riscv/cpu/generic can be generic if we consider U-Boot
SPL phase. It can be generic for S-mode U-Boot though.

>
> If we re-use arch/riscv/cpu/generic as-much as possible then
> arch/riscv will be easy to maintain in future.
>
> We can add arch/riscv/cpu/generic/cache.c which will do
> things FU540 specific based on "#ifdef" or "DT compatible string".
>

Regards,
Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 12/14] riscv: sifive: fu540: enable all cache ways from u-boot proper
  2020-03-13 10:22       ` Bin Meng
@ 2020-03-13 10:49         ` Anup Patel
  2020-03-13 13:49           ` Bin Meng
  2020-03-13 10:54         ` Anup Patel
  1 sibling, 1 reply; 53+ messages in thread
From: Anup Patel @ 2020-03-13 10:49 UTC (permalink / raw)
  To: u-boot

On Fri, Mar 13, 2020 at 3:52 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> Hi Anup,
>
> On Fri, Mar 13, 2020 at 6:02 PM Anup Patel <anup@brainfault.org> wrote:
> >
> > On Fri, Mar 13, 2020 at 2:31 PM Bin Meng <bmeng.cn@gmail.com> wrote:
> > >
> > > On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
> > > <pragnesh.patel@sifive.com> wrote:
> > > >
> > > > Enable all cache ways from u-boot proper.
> > >
> > > U-Boot
> > >
> > > >
> > > > Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> > > > ---
> > > >  board/sifive/fu540/Makefile |  1 +
> > > >  board/sifive/fu540/cache.c  | 20 ++++++++++++++++++++
> > > >  board/sifive/fu540/cache.h  | 13 +++++++++++++
> > > >  board/sifive/fu540/fu540.c  |  6 ++++--
> > > >  4 files changed, 38 insertions(+), 2 deletions(-)
> > > >  create mode 100644 board/sifive/fu540/cache.c
> > > >  create mode 100644 board/sifive/fu540/cache.h
> > > >
> > > > diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
> > > > index b05e2f5807..3b867bbd89 100644
> > > > --- a/board/sifive/fu540/Makefile
> > > > +++ b/board/sifive/fu540/Makefile
> > > > @@ -3,6 +3,7 @@
> > > >  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
> > > >
> > > >  obj-y  += fu540.o
> > > > +obj-y  += cache.o
> > > >
> > > >  ifdef CONFIG_SPL_BUILD
> > > >  obj-y += spl.o
> > > > diff --git a/board/sifive/fu540/cache.c b/board/sifive/fu540/cache.c
> > > > new file mode 100644
> > > > index 0000000000..a0bcd2ba48
> > > > --- /dev/null
> > > > +++ b/board/sifive/fu540/cache.c
> > >
> > > This should be put into arch/riscv/cpu/fu540/cache.c
> > >
> > > > @@ -0,0 +1,20 @@
> > > > +// SPDX-License-Identifier: GPL-2.0+
> > > > +/*
> > > > + * Copyright (c) 2019 SiFive, Inc
> > > > + */
> > > > +#include <asm/io.h>
> > > > +
> > > > +/* Register offsets */
> > > > +#define CACHE_ENABLE           0x008
> > > > +
> > > > +/* Enable ways; allow cache to use these ways */
> > > > +void cache_enable_ways(u64 base_addr, u8 value)
> > > > +{
> > > > +       volatile u32 *enable = (volatile u32 *)(base_addr +
> > > > +                                         CACHE_ENABLE);
> > > > +       /* memory barrier */
> > > > +       mb();
> > > > +       (*enable) = value;
> > > > +       /* memory barrier */
> > > > +       mb();
> > > > +}
> > > > diff --git a/board/sifive/fu540/cache.h b/board/sifive/fu540/cache.h
> > > > new file mode 100644
> > > > index 0000000000..425124a23b
> > > > --- /dev/null
> > > > +++ b/board/sifive/fu540/cache.h
> > >
> > > arch/riscv/include/asm/arch-fu540/cache.h
> >
> > Let's not entire FU540 directory under arch/riscv/cpu directory
> > just to have cache functions. The arch/riscv/cpu/generic is perfectly
> > suitable for FU540.
>
> I doubt arch/riscv/cpu/generic can be generic if we consider U-Boot
> SPL phase. It can be generic for S-mode U-Boot though.

Its really very easy to do. We are already doing this in Xvisor.

As an example, of DT based operations in a generic board support refer:
https://github.com/avpatel/xvisor-next/blob/master/arch/arm/board/generic/brd_main.c
https://github.com/avpatel/xvisor-next/blob/master/arch/arm/board/generic/foundation-v8.c

Using the above approach, we are able to boot same Xvisor ARM/ARM64
binary on multiple boards.

>
> >
> > If we re-use arch/riscv/cpu/generic as-much as possible then
> > arch/riscv will be easy to maintain in future.
> >
> > We can add arch/riscv/cpu/generic/cache.c which will do
> > things FU540 specific based on "#ifdef" or "DT compatible string".
> >
>
> Regards,
> Bin

Regards,
Anup

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 12/14] riscv: sifive: fu540: enable all cache ways from u-boot proper
  2020-03-13 10:22       ` Bin Meng
  2020-03-13 10:49         ` Anup Patel
@ 2020-03-13 10:54         ` Anup Patel
  1 sibling, 0 replies; 53+ messages in thread
From: Anup Patel @ 2020-03-13 10:54 UTC (permalink / raw)
  To: u-boot

On Fri, Mar 13, 2020 at 3:52 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> Hi Anup,
>
> On Fri, Mar 13, 2020 at 6:02 PM Anup Patel <anup@brainfault.org> wrote:
> >
> > On Fri, Mar 13, 2020 at 2:31 PM Bin Meng <bmeng.cn@gmail.com> wrote:
> > >
> > > On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
> > > <pragnesh.patel@sifive.com> wrote:
> > > >
> > > > Enable all cache ways from u-boot proper.
> > >
> > > U-Boot
> > >
> > > >
> > > > Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> > > > ---
> > > >  board/sifive/fu540/Makefile |  1 +
> > > >  board/sifive/fu540/cache.c  | 20 ++++++++++++++++++++
> > > >  board/sifive/fu540/cache.h  | 13 +++++++++++++
> > > >  board/sifive/fu540/fu540.c  |  6 ++++--
> > > >  4 files changed, 38 insertions(+), 2 deletions(-)
> > > >  create mode 100644 board/sifive/fu540/cache.c
> > > >  create mode 100644 board/sifive/fu540/cache.h
> > > >
> > > > diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
> > > > index b05e2f5807..3b867bbd89 100644
> > > > --- a/board/sifive/fu540/Makefile
> > > > +++ b/board/sifive/fu540/Makefile
> > > > @@ -3,6 +3,7 @@
> > > >  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
> > > >
> > > >  obj-y  += fu540.o
> > > > +obj-y  += cache.o
> > > >
> > > >  ifdef CONFIG_SPL_BUILD
> > > >  obj-y += spl.o
> > > > diff --git a/board/sifive/fu540/cache.c b/board/sifive/fu540/cache.c
> > > > new file mode 100644
> > > > index 0000000000..a0bcd2ba48
> > > > --- /dev/null
> > > > +++ b/board/sifive/fu540/cache.c
> > >
> > > This should be put into arch/riscv/cpu/fu540/cache.c
> > >
> > > > @@ -0,0 +1,20 @@
> > > > +// SPDX-License-Identifier: GPL-2.0+
> > > > +/*
> > > > + * Copyright (c) 2019 SiFive, Inc
> > > > + */
> > > > +#include <asm/io.h>
> > > > +
> > > > +/* Register offsets */
> > > > +#define CACHE_ENABLE           0x008
> > > > +
> > > > +/* Enable ways; allow cache to use these ways */
> > > > +void cache_enable_ways(u64 base_addr, u8 value)
> > > > +{
> > > > +       volatile u32 *enable = (volatile u32 *)(base_addr +
> > > > +                                         CACHE_ENABLE);
> > > > +       /* memory barrier */
> > > > +       mb();
> > > > +       (*enable) = value;
> > > > +       /* memory barrier */
> > > > +       mb();
> > > > +}
> > > > diff --git a/board/sifive/fu540/cache.h b/board/sifive/fu540/cache.h
> > > > new file mode 100644
> > > > index 0000000000..425124a23b
> > > > --- /dev/null
> > > > +++ b/board/sifive/fu540/cache.h
> > >
> > > arch/riscv/include/asm/arch-fu540/cache.h
> >
> > Let's not entire FU540 directory under arch/riscv/cpu directory
> > just to have cache functions. The arch/riscv/cpu/generic is perfectly
> > suitable for FU540.
>
> I doubt arch/riscv/cpu/generic can be generic if we consider U-Boot
> SPL phase. It can be generic for S-mode U-Boot though.

We can also have a light weight U-Boot driver framework for cache
operations. This framework will figure-out cache operation based on
SOC compatible string in root DT node or some other way.

This will be useful in long-term when we have complex cache
hierarchy on RISC-V SOCs.

>
> >
> > If we re-use arch/riscv/cpu/generic as-much as possible then
> > arch/riscv will be easy to maintain in future.
> >
> > We can add arch/riscv/cpu/generic/cache.c which will do
> > things FU540 specific based on "#ifdef" or "DT compatible string".
> >
>
> Regards,
> Bin

Regards,
Anup

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 06/14] sifive: fu540: add ddr driver
  2020-03-11  7:03 ` [PATCH v5 06/14] sifive: fu540: add ddr driver Pragnesh Patel
  2020-03-13  7:48   ` Bin Meng
@ 2020-03-13 11:56   ` Giulio Benetti
  2020-03-17 13:05     ` Pragnesh Patel
  1 sibling, 1 reply; 53+ messages in thread
From: Giulio Benetti @ 2020-03-13 11:56 UTC (permalink / raw)
  To: u-boot

Hi Pragnesh,

On 3/11/20 8:03 AM, Pragnesh Patel wrote:
> Add driver for fu540 to support ddr initialization in SPL.
> This driver is based on FSBL
> (https://github.com/sifive/freedom-u540-c000-bootloader.git)
> 
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> ---
>   drivers/ram/Kconfig              |   7 +
>   drivers/ram/Makefile             |   2 +
>   drivers/ram/sifive/Kconfig       |   8 +
>   drivers/ram/sifive/Makefile      |   6 +
>   drivers/ram/sifive/sdram_fu540.c | 295 +++++++++++++++++++++++++++++++
>   drivers/ram/sifive/sdram_fu540.h |  94 ++++++++++
>   6 files changed, 412 insertions(+)
>   create mode 100644 drivers/ram/sifive/Kconfig
>   create mode 100644 drivers/ram/sifive/Makefile
>   create mode 100644 drivers/ram/sifive/sdram_fu540.c
>   create mode 100644 drivers/ram/sifive/sdram_fu540.h
> 
> diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig
> index 56fea7c94c..c60c63204c 100644
> --- a/drivers/ram/Kconfig
> +++ b/drivers/ram/Kconfig
> @@ -73,5 +73,12 @@ config IMXRT_SDRAM
>   	  to support external memories like sdram, psram & nand.
>   	  This driver is for the sdram memory interface with the SEMC.
>   
> +config SIFIVE_DDR
> +	bool "Enable SiFive DDR support"
> +	depends on RAM
> +	help
> +	  Enable support for the internal DDR Memory Controller of SiFive SoCs.
> +
>   source "drivers/ram/rockchip/Kconfig"
>   source "drivers/ram/stm32mp1/Kconfig"
> +source "drivers/ram/sifive/Kconfig"
> diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile
> index 5c897410c6..12bf61510b 100644
> --- a/drivers/ram/Makefile
> +++ b/drivers/ram/Makefile
> @@ -17,3 +17,5 @@ obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
>   obj-$(CONFIG_K3_J721E_DDRSS) += k3-j721e/
>   
>   obj-$(CONFIG_IMXRT_SDRAM) += imxrt_sdram.o
> +
> +obj-$(CONFIG_SIFIVE_DDR) += sifive/
> diff --git a/drivers/ram/sifive/Kconfig b/drivers/ram/sifive/Kconfig
> new file mode 100644
> index 0000000000..b754700db8
> --- /dev/null
> +++ b/drivers/ram/sifive/Kconfig
> @@ -0,0 +1,8 @@
> +config SIFIVE_FU540_DDR
> +	bool "SiFive FU540 DDR driver"
> +	depends on DM && OF_CONTROL
> +	select RAM
> +	select SPL_RAM if SPL
> +	select SIFIVE_DDR
> +	help
> +	  This enables DDR support for the platforms based on SiFive FU540 SoC.
> diff --git a/drivers/ram/sifive/Makefile b/drivers/ram/sifive/Makefile
> new file mode 100644
> index 0000000000..0187805199
> --- /dev/null
> +++ b/drivers/ram/sifive/Makefile
> @@ -0,0 +1,6 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +#
> +# Copyright (c) 2020 SiFive, Inc
> +#
> +
> +obj-$(CONFIG_SIFIVE_FU540_DDR) += sdram_fu540.o
> diff --git a/drivers/ram/sifive/sdram_fu540.c b/drivers/ram/sifive/sdram_fu540.c
> new file mode 100644
> index 0000000000..18926dbe15
> --- /dev/null
> +++ b/drivers/ram/sifive/sdram_fu540.c
> @@ -0,0 +1,295 @@
> +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
> +/*
> + * (C) Copyright 2020 SiFive, Inc.
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <init.h>
> +#include <ram.h>
> +#include <regmap.h>
> +#include <syscon.h>
> +#include <asm/io.h>
> +#include "sdram_fu540.h"
> +
> +/* n: Unit bytes */
> +void sdram_copy_to_reg(volatile u32 *dest, volatile u32 *src, u32 n)
> +{
> +	int i;
> +
> +	for (i = 0; i < n / sizeof(u32); i++) {
> +		writel(*src, dest);
> +		src++;
> +		dest++;
> +	}
> +}
> +
> +static void ddr_setuprangeprotection(volatile u32 *ctl, u64 end_addr)
> +{
> +	writel(0x0, DENALI_CTL_209 + ctl);
> +	u32 end_addr_16kblocks = ((end_addr >> 14) & 0x7FFFFF) - 1;
> +
> +	writel(end_addr_16kblocks, DENALI_CTL_210 + ctl);
> +	writel(0x0, DENALI_CTL_212 + ctl);
> +	writel(0x0, DENALI_CTL_214 + ctl);
> +	writel(0x0, DENALI_CTL_216 + ctl);
> +	setbits_le32(DENALI_CTL_224 + ctl,
> +		     0x3 << AXI0_RANGE_PROT_BITS_0_OFFSET);
> +	writel(0xFFFFFFFF, DENALI_CTL_225 + ctl);
> +	setbits_le32(DENALI_CTL_208 + ctl, 0x1 << AXI0_ADDRESS_RANGE_ENABLE);
> +	setbits_le32(DENALI_CTL_208 + ctl,
> +		     0x1 << PORT_ADDR_PROTECTION_EN_OFFSET);
> +}
> +
> +static void ddr_start(volatile u32 *ctl, u32 *physical_filter_ctrl, u64 ddr_end)
> +{
> +	setbits_le32(DENALI_CTL_0 + ctl, 0x1);
> +	while ((readl(DENALI_CTL_132 + ctl) & (1 << MC_INIT_COMPLETE_OFFSET))
> +	       == 0) {
> +	}
> +
> +	// Disable the BusBlocker in front of the controller AXI slave ports
> +	volatile u64 *filterreg = (volatile u64 *)physical_filter_ctrl;
> +
> +	filterreg[0] = 0x0f00000000000000UL | (ddr_end >> 2);
> +}
> +
> +static u64 ddr_phy_fixup(volatile u32 *ddrphyreg)
> +{
> +	// return bitmask of failed lanes
> +
> +	u64 fails     = 0;
> +	u32 slicebase = 0;
> +	u32 dq        = 0;
> +
> +	// check errata condition
> +	for (u32 slice = 0; slice < 8; slice++) {
> +		u32 regbase = slicebase + 34;
> +
> +		for (u32 reg = 0; reg < 4; reg++) {
> +			u32 updownreg = readl(regbase + reg + ddrphyreg);
> +
> +			for (u32 bit = 0; bit < 2; bit++) {
> +				u32 phy_rx_cal_dqn_0_offset;
> +
> +				if (bit == 0) {
> +					phy_rx_cal_dqn_0_offset =
> +						PHY_RX_CAL_DQ0_0_OFFSET;
> +				} else {
> +					phy_rx_cal_dqn_0_offset =
> +						PHY_RX_CAL_DQ1_0_OFFSET;
> +				}
> +
> +				u32 down = (updownreg >>
> +					    phy_rx_cal_dqn_0_offset) & 0x3F;
> +				u32 up   = (updownreg >>
> +					    (phy_rx_cal_dqn_0_offset + 6)) &
> +					    0x3F;
> +
> +				u8 failc0 = ((down == 0) && (up == 0x3F));
> +				u8 failc1 = ((up == 0) && (down == 0x3F));
> +
> +				// print error message on failure
> +				if (failc0 || failc1) {
> +					if (fails == 0)
> +						printf("DDR error in fixing up\n");
> +
> +					fails |= (1 << dq);
> +
> +					char slicelsc = '0';
> +					char slicemsc = '0';
> +
> +					slicelsc += (dq % 10);
> +					slicemsc += (dq / 10);
> +					printf("S ");
> +					printf("%c", slicemsc);
> +					printf("%c", slicelsc);
> +
> +					if (failc0)
> +						printf("U");
> +					else
> +						printf("D");
> +
> +					printf("\n");
> +				}

Here you've nested 5 times. Can you try to break up all these 
iterations? At least moving some code to external static functions. It 
is difficult to read these 3 nested for cycles plus other 2 nested if 
conditions. And for sure keep declare variables at the top.

> +				dq++;
> +			}
> +		}
> +		slicebase += 128;
> +	}
> +	return(0);
> +}
> +
> +static u32 ddr_getdramclass(volatile u32 *ctl)
> +{
> +	u32 reg = readl(DENALI_CTL_0 + ctl);
> +
> +	return ((reg >> DRAM_CLASS_OFFSET) & 0xF);
> +}
> +
> +static __maybe_unused int fu540_ddr_setup(struct udevice *dev)
> +{
> +	struct ddr_info *priv = dev_get_priv(dev);
> +	struct sifive_dmc_plat *plat = dev_get_platdata(dev);
> +
> +	int ret, i;
> +	u32 physet;
> +
> +	volatile u32 *denali_ctl =  &priv->ctl->denali_ctl[0];
> +	volatile u32 *denali_phy =  &priv->phy->denali_phy[0];
> +
> +	ret = dev_read_u32_array(dev, "sifive,sdram-params",
> +				 (u32 *)&plat->sdram_params,
> +				 sizeof(plat->sdram_params) / sizeof(u32));
> +	if (ret) {
> +		printf("%s: Cannot read sifive,sdram-params %d\n",
> +		       __func__, ret);
> +		return ret;
> +	}
> +
> +	struct fu540_sdram_params *params = &plat->sdram_params;
> +
> +	sdram_copy_to_reg(&priv->ctl->denali_ctl[0],
> +			  &params->pctl_regs.denali_ctl[0],
> +			  sizeof(struct fu540_ddrctl));
> +
> +	/* phy reset */
> +	for (i = DENALI_PHY_1152; i <= DENALI_PHY_1214; i++) {
> +		physet = params->phy_regs.denali_phy[i];
> +		priv->phy->denali_phy[i] = physet;
> +	}
> +
> +	for (i = 0; i < DENALI_PHY_1152; i++) {
> +		physet = params->phy_regs.denali_phy[i];
> +		priv->phy->denali_phy[i] = physet;
> +	}
> +
> +	/* Disable read interleave DENALI_CTL_120 */
> +	setbits_le32(DENALI_CTL_120 + denali_ctl,
> +		     1 << DISABLE_RD_INTERLEAVE_OFFSET);
> +
> +	/* Disable optimal read/modify/write logic DENALI_CTL_21 */
> +	clrbits_le32(DENALI_CTL_21 + denali_ctl, 1 << OPTIMAL_RMODW_EN_OFFSET);
> +
> +	/* Enable write Leveling DENALI_CTL_170 */
> +	setbits_le32(DENALI_CTL_170 + denali_ctl, (1 << WRLVL_EN_OFFSET)
> +		     | (1 << DFI_PHY_WRLELV_MODE_OFFSET));
> +
> +	/* Enable read leveling DENALI_CTL_181 and DENALI_CTL_260 */
> +	setbits_le32(DENALI_CTL_181 + denali_ctl,
> +		     1 << DFI_PHY_RDLVL_MODE_OFFSET);
> +	setbits_le32(DENALI_CTL_260 + denali_ctl, 1 << RDLVL_EN_OFFSET);
> +
> +	/* Enable read leveling gate DENALI_CTL_260 and DENALI_CTL_182 */
> +	setbits_le32(DENALI_CTL_260 + denali_ctl, 1 << RDLVL_GATE_EN_OFFSET);
> +	setbits_le32(DENALI_CTL_182 + denali_ctl,
> +		     1 << DFI_PHY_RDLVL_GATE_MODE_OFFSET);
> +
> +	if (ddr_getdramclass(denali_ctl) == DRAM_CLASS_DDR4) {
> +		/* Enable vref training DENALI_CTL_184 */
> +		setbits_le32(DENALI_CTL_184 + denali_ctl, 1 << VREF_EN_OFFSET);
> +	}
> +
> +	/* Mask off leveling completion interrupt DENALI_CTL_136 */
> +	setbits_le32(DENALI_CTL_136 + denali_ctl,
> +		     1 << LEVELING_OPERATION_COMPLETED_OFFSET);
> +
> +	/* Mask off MC init complete interrupt DENALI_CTL_136 */
> +	setbits_le32(DENALI_CTL_136 + denali_ctl, 1 << MC_INIT_COMPLETE_OFFSET);
> +
> +	/* Mask off out of range interrupts DENALI_CTL_136 */
> +	setbits_le32(DENALI_CTL_136 + denali_ctl, (1 << OUT_OF_RANGE_OFFSET)
> +		     | (1 << MULTIPLE_OUT_OF_RANGE_OFFSET));
> +
> +	/* set up range protection */
> +	ddr_setuprangeprotection(denali_ctl, DDR_MEM_SIZE);
> +
> +	/* Mask off port command error interrupt DENALI_CTL_136 */
> +	setbits_le32(DENALI_CTL_136 + denali_ctl,
> +		     1 << PORT_COMMAND_CHANNEL_ERROR_OFFSET);
> +
> +	const u64 ddr_size = DDR_MEM_SIZE;
> +	const u64 ddr_end = PAYLOAD_DEST + ddr_size;
> +
> +	ddr_start(denali_ctl, priv->physical_filter_ctrl, ddr_end);
> +
> +	ddr_phy_fixup(denali_phy);
> +
> +	/* check size */
> +	priv->info.size = get_ram_size((long *)priv->info.base,
> +				       DDR_MEM_SIZE);
> +
> +	printf("priv->info.size = %lx\n", priv->info.size);
> +	debug("%s : %lx\n", __func__, priv->info.size);
> +
> +	/* check memory access for all memory */
> +
> +	if (priv->info.size != DDR_MEM_SIZE) {
> +		printf("DDR invalid size : 0x%lx, expected 0x%lx\n",
> +		       priv->info.size, DDR_MEM_SIZE);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int fu540_ddr_probe(struct udevice *dev)
> +{
> +	struct ddr_info *priv = dev_get_priv(dev);
> +
> +#if defined(CONFIG_SPL_BUILD)
> +	struct regmap *map;
> +	int ret;
> +
> +	debug("FU540 DDR probe\n");
> +	priv->dev = dev;
> +
> +	ret = regmap_init_mem(dev_ofnode(dev), &map);
> +	if (ret)
> +		return ret;
> +
> +	priv->ctl = regmap_get_range(map, 0);
> +	priv->phy = regmap_get_range(map, 1);
> +	priv->physical_filter_ctrl = regmap_get_range(map, 2);
> +
> +	priv->info.base = CONFIG_SYS_SDRAM_BASE;
> +
> +	priv->info.size = 0;
> +	return fu540_ddr_setup(dev);
> +#else
> +	priv->info.base = CONFIG_SYS_SDRAM_BASE;
> +	priv->info.size = DDR_MEM_SIZE;
> +#endif
> +	return 0;
> +}
> +
> +static int fu540_ddr_get_info(struct udevice *dev, struct ram_info *info)
> +{
> +	struct ddr_info *priv = dev_get_priv(dev);
> +
> +	*info = priv->info;
> +
> +	return 0;
> +}
> +
> +static struct ram_ops fu540_ddr_ops = {
> +	.get_info = fu540_ddr_get_info,
> +};
> +
> +static const struct udevice_id fu540_ddr_ids[] = {
> +	{ .compatible = "sifive,fu540-ddr" },
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(fu540_ddr) = {
> +	.name = "fu540_ddr",
> +	.id = UCLASS_RAM,
> +	.of_match = fu540_ddr_ids,
> +	.ops = &fu540_ddr_ops,
> +	.probe = fu540_ddr_probe,
> +	.priv_auto_alloc_size = sizeof(struct ddr_info),
> +	.platdata_auto_alloc_size = sizeof(struct sifive_dmc_plat),
> +};
> diff --git a/drivers/ram/sifive/sdram_fu540.h b/drivers/ram/sifive/sdram_fu540.h
> new file mode 100644
> index 0000000000..09693a038e
> --- /dev/null
> +++ b/drivers/ram/sifive/sdram_fu540.h
> @@ -0,0 +1,94 @@
> +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
> +/*
> + * Copyright (C) 2020, SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + */
> +
> +#define DENALI_CTL_0	0
> +#define DENALI_CTL_21	21
> +#define DENALI_CTL_120	120
> +#define DENALI_CTL_132	132
> +#define DENALI_CTL_136	136
> +#define DENALI_CTL_170	170
> +#define DENALI_CTL_181	181
> +#define DENALI_CTL_182	182
> +#define DENALI_CTL_184	184
> +#define DENALI_CTL_208	208
> +#define DENALI_CTL_209	209
> +#define DENALI_CTL_210	210
> +#define DENALI_CTL_212	212
> +#define DENALI_CTL_214	214
> +#define DENALI_CTL_216	216
> +#define DENALI_CTL_224	224
> +#define DENALI_CTL_225	225
> +#define DENALI_CTL_260	260
> +
> +#define DENALI_PHY_1152	1152
> +#define DENALI_PHY_1214	1214
> +
> +#define PAYLOAD_DEST	0x80000000
> +#define DDR_MEM_SIZE	(8UL * 1024UL * 1024UL * 1024UL)
> +
> +#define DRAM_CLASS_OFFSET                   8
> +#define DRAM_CLASS_DDR4                     0xA
> +#define OPTIMAL_RMODW_EN_OFFSET             0
> +#define DISABLE_RD_INTERLEAVE_OFFSET        16
> +#define OUT_OF_RANGE_OFFSET                 1
> +#define MULTIPLE_OUT_OF_RANGE_OFFSET        2
> +#define PORT_COMMAND_CHANNEL_ERROR_OFFSET   7
> +#define MC_INIT_COMPLETE_OFFSET             8
> +#define LEVELING_OPERATION_COMPLETED_OFFSET 22
> +#define DFI_PHY_WRLELV_MODE_OFFSET          24
> +#define DFI_PHY_RDLVL_MODE_OFFSET           24
> +#define DFI_PHY_RDLVL_GATE_MODE_OFFSET      0
> +#define VREF_EN_OFFSET                      24
> +#define PORT_ADDR_PROTECTION_EN_OFFSET      0
> +#define AXI0_ADDRESS_RANGE_ENABLE           8
> +#define AXI0_RANGE_PROT_BITS_0_OFFSET       24
> +#define RDLVL_EN_OFFSET                     16
> +#define RDLVL_GATE_EN_OFFSET                24
> +#define WRLVL_EN_OFFSET                     0
> +
> +#define PHY_RX_CAL_DQ0_0_OFFSET             0
> +#define PHY_RX_CAL_DQ1_0_OFFSET             16
> +
> +struct fu540_ddrctl {
> +	volatile u32 denali_ctl[265];
> +};
> +
> +struct fu540_ddrphy {
> +	volatile u32 denali_phy[1215];
> +};
> +
> +struct fu540_sdram_params {
> +	struct fu540_ddrctl pctl_regs;
> +	struct fu540_ddrphy phy_regs;
> +};
> +
> +struct sifive_dmc_plat {
> +#if CONFIG_IS_ENABLED(OF_PLATDATA)
> +	struct dtd_sifive_fu540_dmc dtplat;
> +#else
> +	struct fu540_sdram_params sdram_params;
> +#endif
> +};
> +
> +/**
> + * struct ddr_info
> + *
> + * @dev				: pointer for the device
> + * @info			: UCLASS RAM information
> + * @ctl				: DDR controleur base address
> + * @phy				: DDR PHY base address
> + * @ctrl			: DDR control base address
> + * @physical_filter_ctrl	: DDR physical filter control base address
> + */
> +struct ddr_info {
> +	struct udevice *dev;
> +	struct ram_info info;
> +	struct fu540_ddrctl *ctl;
> +	struct fu540_ddrphy *phy;
> +	u32 *physical_filter_ctrl;
> +};
> 

IMHO I would keep all these structs and define in driver's .c file, I 
mean you should keep them private if not used outside. And then add to 
dt-bindings the define needed by dts files.

Best regards
-- 
Giulio Benetti
Benetti Engineering sas

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 12/14] riscv: sifive: fu540: enable all cache ways from u-boot proper
  2020-03-13 10:49         ` Anup Patel
@ 2020-03-13 13:49           ` Bin Meng
  2020-03-17  9:52             ` Pragnesh Patel
  0 siblings, 1 reply; 53+ messages in thread
From: Bin Meng @ 2020-03-13 13:49 UTC (permalink / raw)
  To: u-boot

Hi Anup,

On Fri, Mar 13, 2020 at 6:49 PM Anup Patel <anup@brainfault.org> wrote:
>
> On Fri, Mar 13, 2020 at 3:52 PM Bin Meng <bmeng.cn@gmail.com> wrote:
> >
> > Hi Anup,
> >
> > On Fri, Mar 13, 2020 at 6:02 PM Anup Patel <anup@brainfault.org> wrote:
> > >
> > > On Fri, Mar 13, 2020 at 2:31 PM Bin Meng <bmeng.cn@gmail.com> wrote:
> > > >
> > > > On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
> > > > <pragnesh.patel@sifive.com> wrote:
> > > > >
> > > > > Enable all cache ways from u-boot proper.
> > > >
> > > > U-Boot
> > > >
> > > > >
> > > > > Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> > > > > ---
> > > > >  board/sifive/fu540/Makefile |  1 +
> > > > >  board/sifive/fu540/cache.c  | 20 ++++++++++++++++++++
> > > > >  board/sifive/fu540/cache.h  | 13 +++++++++++++
> > > > >  board/sifive/fu540/fu540.c  |  6 ++++--
> > > > >  4 files changed, 38 insertions(+), 2 deletions(-)
> > > > >  create mode 100644 board/sifive/fu540/cache.c
> > > > >  create mode 100644 board/sifive/fu540/cache.h
> > > > >
> > > > > diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
> > > > > index b05e2f5807..3b867bbd89 100644
> > > > > --- a/board/sifive/fu540/Makefile
> > > > > +++ b/board/sifive/fu540/Makefile
> > > > > @@ -3,6 +3,7 @@
> > > > >  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
> > > > >
> > > > >  obj-y  += fu540.o
> > > > > +obj-y  += cache.o
> > > > >
> > > > >  ifdef CONFIG_SPL_BUILD
> > > > >  obj-y += spl.o
> > > > > diff --git a/board/sifive/fu540/cache.c b/board/sifive/fu540/cache.c
> > > > > new file mode 100644
> > > > > index 0000000000..a0bcd2ba48
> > > > > --- /dev/null
> > > > > +++ b/board/sifive/fu540/cache.c
> > > >
> > > > This should be put into arch/riscv/cpu/fu540/cache.c
> > > >
> > > > > @@ -0,0 +1,20 @@
> > > > > +// SPDX-License-Identifier: GPL-2.0+
> > > > > +/*
> > > > > + * Copyright (c) 2019 SiFive, Inc
> > > > > + */
> > > > > +#include <asm/io.h>
> > > > > +
> > > > > +/* Register offsets */
> > > > > +#define CACHE_ENABLE           0x008
> > > > > +
> > > > > +/* Enable ways; allow cache to use these ways */
> > > > > +void cache_enable_ways(u64 base_addr, u8 value)
> > > > > +{
> > > > > +       volatile u32 *enable = (volatile u32 *)(base_addr +
> > > > > +                                         CACHE_ENABLE);
> > > > > +       /* memory barrier */
> > > > > +       mb();
> > > > > +       (*enable) = value;
> > > > > +       /* memory barrier */
> > > > > +       mb();
> > > > > +}
> > > > > diff --git a/board/sifive/fu540/cache.h b/board/sifive/fu540/cache.h
> > > > > new file mode 100644
> > > > > index 0000000000..425124a23b
> > > > > --- /dev/null
> > > > > +++ b/board/sifive/fu540/cache.h
> > > >
> > > > arch/riscv/include/asm/arch-fu540/cache.h
> > >
> > > Let's not entire FU540 directory under arch/riscv/cpu directory
> > > just to have cache functions. The arch/riscv/cpu/generic is perfectly
> > > suitable for FU540.
> >
> > I doubt arch/riscv/cpu/generic can be generic if we consider U-Boot
> > SPL phase. It can be generic for S-mode U-Boot though.
>
> Its really very easy to do. We are already doing this in Xvisor.
>
> As an example, of DT based operations in a generic board support refer:
> https://github.com/avpatel/xvisor-next/blob/master/arch/arm/board/generic/brd_main.c
> https://github.com/avpatel/xvisor-next/blob/master/arch/arm/board/generic/foundation-v8.c

Yes, this can be easy to do if we have everything written based on DT.
But we cannot always assume DT is available in SPL. Some SoCs will not
allow SPL with DT support to run due to constraint resources.

Even for DT, due to SPL initialization codes can be very low-level and
specific to an SoC, not everything can be properly modeled by DT. Take
a look at the u-boot/arch/arm directory. Things are not that easy.

>
> Using the above approach, we are able to boot same Xvisor ARM/ARM64
> binary on multiple boards.
>

Yes, I know. The same as what is done in the Linux kernel. Take x86
for example, the same kernel image can boot on almost every x86
desktop/laptop/server we have today. But we have to understand that
this is built on top of BIOS which does all low-level processor /
chipset initialization and hide that very well for OS.

> >
> > >
> > > If we re-use arch/riscv/cpu/generic as-much as possible then
> > > arch/riscv will be easy to maintain in future.
> > >
> > > We can add arch/riscv/cpu/generic/cache.c which will do
> > > things FU540 specific based on "#ifdef" or "DT compatible string".
> > >

Regards,
Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 10/14] riscv: sifive: fu540: add SPL configuration
  2020-03-11  7:03 ` [PATCH v5 10/14] riscv: sifive: fu540: add SPL configuration Pragnesh Patel
  2020-03-13  8:28   ` Bin Meng
@ 2020-03-13 13:59   ` Bin Meng
  2020-03-17  8:04     ` Pragnesh Patel
  1 sibling, 1 reply; 53+ messages in thread
From: Bin Meng @ 2020-03-13 13:59 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> Add a support for SPL which will boot from L2 LIM (0x0800_0000) and
> then boot U-boot FIT image including OpenSBI FW_DYNAMIC firmware
> and U-Boot proper images from 1st partition of MMC boot devices.
>
> SPL related code is leverage from FSBL
> (https://github.com/sifive/freedom-u540-c000-bootloader.git)
>
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> ---
>  board/sifive/fu540/Kconfig            |  8 +++
>  board/sifive/fu540/Makefile           |  4 ++
>  board/sifive/fu540/fu540-memory-map.h | 23 ++++++++
>  board/sifive/fu540/fu540.c            | 24 +++++++++
>  board/sifive/fu540/spl.c              | 78 +++++++++++++++++++++++++++
>  include/configs/sifive-fu540.h        | 18 +++++++
>  6 files changed, 155 insertions(+)
>  create mode 100644 board/sifive/fu540/fu540-memory-map.h
>  create mode 100644 board/sifive/fu540/spl.c
>
> diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
> index 900197bbb2..ebe3472f9a 100644
> --- a/board/sifive/fu540/Kconfig
> +++ b/board/sifive/fu540/Kconfig
> @@ -13,12 +13,20 @@ config SYS_CONFIG_NAME
>         default "sifive-fu540"
>
>  config SYS_TEXT_BASE
> +       default 0x80200000 if SPL
>         default 0x80000000 if !RISCV_SMODE
>         default 0x80200000 if RISCV_SMODE
>
> +config SPL_TEXT_BASE
> +       default 0x08000000
> +
> +config SPL_OPENSBI_LOAD_ADDR
> +       default 0x80000000
> +
>  config BOARD_SPECIFIC_OPTIONS # dummy
>         def_bool y
>         select GENERIC_RISCV
> +       select SUPPORT_SPL
>         imply CMD_DHCP
>         imply CMD_EXT2
>         imply CMD_EXT4
> diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
> index 6e1862c475..b05e2f5807 100644
> --- a/board/sifive/fu540/Makefile
> +++ b/board/sifive/fu540/Makefile
> @@ -3,3 +3,7 @@
>  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
>
>  obj-y  += fu540.o
> +
> +ifdef CONFIG_SPL_BUILD
> +obj-y += spl.o
> +endif
> diff --git a/board/sifive/fu540/fu540-memory-map.h b/board/sifive/fu540/fu540-memory-map.h
> new file mode 100644
> index 0000000000..cba464652b
> --- /dev/null
> +++ b/board/sifive/fu540/fu540-memory-map.h
> @@ -0,0 +1,23 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + */
> +
> +#ifndef FU540_MEMORY_MAP
> +#define FU540_MEMORY_MAP
> +
> +#include <asm/arch/gpio.h>
> +
> +/****************************************************************************
> + * Platform definitions
> + *****************************************************************************/
> +
> +/* Memory map */
> +#define GPIO_CTRL_ADDR                 _AC(0x10060000, UL)
> +
> +/* Helper functions */
> +#define _REG32(p, i)    (*(volatile uint32_t *)((p) + (i)))
> +
> +#define GPIO_REG(offset)      _REG32(GPIO_CTRL_ADDR, offset)
> +
> +#endif /* FU540_MEMORY_MAP */
> diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
> index 6c642b3082..89a65eb3fb 100644
> --- a/board/sifive/fu540/fu540.c
> +++ b/board/sifive/fu540/fu540.c
> @@ -11,6 +11,7 @@
>  #include <linux/delay.h>
>  #include <linux/io.h>
>  #include <misc.h>
> +#include <spl.h>
>
>  /*
>   * This define is a value used for error/unknown serial.
> @@ -114,3 +115,26 @@ int board_init(void)
>
>         return 0;
>  }
> +
> +#ifdef CONFIG_SPL
> +void board_boot_order(u32 *spl_boot_list)
> +{
> +       u8 i;
> +       u32 boot_devices[] = {
> +#ifdef CONFIG_SPL_MMC_SUPPORT
> +               BOOT_DEVICE_MMC1,
> +#endif
> +       };
> +
> +       for (i = 0; i < ARRAY_SIZE(boot_devices); i++)
> +               spl_boot_list[i] = boot_devices[i];
> +}
> +#endif
> +
> +#ifdef CONFIG_SPL_LOAD_FIT
> +int board_fit_config_name_match(const char *name)
> +{
> +       /* boot using first FIT config */
> +       return 0;
> +}
> +#endif
> diff --git a/board/sifive/fu540/spl.c b/board/sifive/fu540/spl.c
> new file mode 100644
> index 0000000000..522bc24753
> --- /dev/null
> +++ b/board/sifive/fu540/spl.c
> @@ -0,0 +1,78 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + */
> +
> +#include <common.h>
> +#include <spl.h>
> +#include <misc.h>
> +#include <dm.h>
> +
> +#include "fu540-memory-map.h"
> +
> +#define DDRCTLPLL_F 55
> +#define DDRCTLPLL_Q 2
> +
> +#define PHY_NRESET 0x1000
> +
> +long nsec_per_cyc = 300; /* 33.333MHz */
> +void nsleep(long nsec)
> +{
> +       long step = nsec_per_cyc * 2;
> +
> +       while (nsec > 0)
> +               nsec -= step;
> +}
> +
> +void init_clk_and_ddr(void)
> +{
> +       int ret;
> +       struct udevice *dev;
> +
> +       /* PRCI init */
> +       ret = uclass_get_device(UCLASS_CLK, 0, &dev);
> +       if (ret) {
> +               debug("Clock init failed: %d\n", ret);
> +               return;
> +       }
> +
> +       ret = uclass_get_device(UCLASS_RAM, 0, &dev);
> +       if (ret) {
> +               printf("DRAM init failed: %d\n", ret);
> +               return;
> +       }
> +

This should be split into two parts:

SoC specific parts should go to arch/riscv/fu540/spl.c, and board
specific parts remain here.

Otherwise it's hard to re-use the same SPL codes for another board
built on top of fu540.

> +       /*
> +        * GEMGXL init VSC8541 PHY reset sequence;
> +        * leave pull-down active for 2ms
> +        */
> +       nsleep(2000000);
> +       /* Set GPIO 12 (PHY NRESET) to OE=1 and OVAL=1 */
> +       GPIO_REG(GPIO_OUTPUT_VAL) |= PHY_NRESET;
> +       GPIO_REG(GPIO_OUTPUT_EN) |= PHY_NRESET;
> +       nsleep(100);
> +
> +       /* Reset PHY again to enter unmanaged mode */
> +       GPIO_REG(GPIO_OUTPUT_VAL) &= ~PHY_NRESET;
> +       nsleep(100);
> +       GPIO_REG(GPIO_OUTPUT_VAL) |= PHY_NRESET;
> +       nsleep(15000000);
> +}
> +
> +void board_init_f(ulong dummy)
> +{
> +       int ret;
> +
> +       ret = spl_early_init();
> +       if (ret)
> +               panic("spl_early_init() failed: %d\n", ret);
> +
> +       arch_cpu_init_dm();
> +
> +       init_clk_and_ddr();
> +
> +       preloader_console_init();
> +}

Regards,
Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 10/14] riscv: sifive: fu540: add SPL configuration
  2020-03-13  8:28   ` Bin Meng
@ 2020-03-17  7:41     ` Pragnesh Patel
  0 siblings, 0 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-17  7:41 UTC (permalink / raw)
  To: u-boot

Hi Bin,

>-----Original Message-----
>From: Bin Meng <bmeng.cn@gmail.com>
>Sent: 13 March 2020 13:58
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Atish Patra
><atish.patra@wdc.com>; Palmer Dabbelt <palmerdabbelt@google.com>; Paul
>Walmsley <paul.walmsley@sifive.com>; Jagan Teki
><jagan@amarulasolutions.com>; Troy Benjegerdes
><troy.benjegerdes@sifive.com>; Anup Patel <anup.patel@wdc.com>; Sagar
>Kadam <sagar.kadam@sifive.com>; Rick Chen <rick@andestech.com>; Palmer
>Dabbelt <palmer@dabbelt.com>
>Subject: Re: [PATCH v5 10/14] riscv: sifive: fu540: add SPL configuration
>
>On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
><pragnesh.patel@sifive.com> wrote:
>>
>> Add a support for SPL which will boot from L2 LIM (0x0800_0000) and
>> then boot U-boot FIT image including OpenSBI FW_DYNAMIC firmware
>
>nits: U-Boot

Will update in v6.

>
>> and U-Boot proper images from 1st partition of MMC boot devices.
>>
>> SPL related code is leverage from FSBL
>> (https://github.com/sifive/freedom-u540-c000-bootloader.git)
>>
>> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
>> ---
>>  board/sifive/fu540/Kconfig            |  8 +++
>>  board/sifive/fu540/Makefile           |  4 ++
>>  board/sifive/fu540/fu540-memory-map.h | 23 ++++++++
>>  board/sifive/fu540/fu540.c            | 24 +++++++++
>>  board/sifive/fu540/spl.c              | 78 +++++++++++++++++++++++++++
>>  include/configs/sifive-fu540.h        | 18 +++++++
>>  6 files changed, 155 insertions(+)
>>  create mode 100644 board/sifive/fu540/fu540-memory-map.h
>>  create mode 100644 board/sifive/fu540/spl.c
>>
>> diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
>> index 900197bbb2..ebe3472f9a 100644
>> --- a/board/sifive/fu540/Kconfig
>> +++ b/board/sifive/fu540/Kconfig
>> @@ -13,12 +13,20 @@ config SYS_CONFIG_NAME
>>         default "sifive-fu540"
>>
>>  config SYS_TEXT_BASE
>> +       default 0x80200000 if SPL
>>         default 0x80000000 if !RISCV_SMODE
>>         default 0x80200000 if RISCV_SMODE
>>
>> +config SPL_TEXT_BASE
>> +       default 0x08000000
>> +
>> +config SPL_OPENSBI_LOAD_ADDR
>> +       default 0x80000000
>> +
>>  config BOARD_SPECIFIC_OPTIONS # dummy
>>         def_bool y
>>         select GENERIC_RISCV
>> +       select SUPPORT_SPL
>>         imply CMD_DHCP
>>         imply CMD_EXT2
>>         imply CMD_EXT4
>> diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
>> index 6e1862c475..b05e2f5807 100644
>> --- a/board/sifive/fu540/Makefile
>> +++ b/board/sifive/fu540/Makefile
>> @@ -3,3 +3,7 @@
>>  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
>>
>>  obj-y  += fu540.o
>> +
>> +ifdef CONFIG_SPL_BUILD
>> +obj-y += spl.o
>> +endif
>> diff --git a/board/sifive/fu540/fu540-memory-map.h
>> b/board/sifive/fu540/fu540-memory-map.h
>> new file mode 100644
>> index 0000000000..cba464652b
>> --- /dev/null
>> +++ b/board/sifive/fu540/fu540-memory-map.h
>
>This file is not needed. See below.
>
>> @@ -0,0 +1,23 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (c) 2019 SiFive, Inc
>> + */
>> +
>> +#ifndef FU540_MEMORY_MAP
>> +#define FU540_MEMORY_MAP
>> +
>> +#include <asm/arch/gpio.h>
>> +
>>
>+/***************************************************************
>*****
>> +********
>> + * Platform definitions
>> +
>>
>+****************************************************************
>*****
>> +********/
>> +
>> +/* Memory map */
>> +#define GPIO_CTRL_ADDR                 _AC(0x10060000, UL)
>> +
>> +/* Helper functions */
>> +#define _REG32(p, i)    (*(volatile uint32_t *)((p) + (i)))
>> +
>> +#define GPIO_REG(offset)      _REG32(GPIO_CTRL_ADDR, offset)
>> +
>> +#endif /* FU540_MEMORY_MAP */
>> diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
>> index 6c642b3082..89a65eb3fb 100644
>> --- a/board/sifive/fu540/fu540.c
>> +++ b/board/sifive/fu540/fu540.c
>> @@ -11,6 +11,7 @@
>>  #include <linux/delay.h>
>>  #include <linux/io.h>
>>  #include <misc.h>
>> +#include <spl.h>
>>
>>  /*
>>   * This define is a value used for error/unknown serial.
>> @@ -114,3 +115,26 @@ int board_init(void)
>>
>>         return 0;
>>  }
>> +
>> +#ifdef CONFIG_SPL
>> +void board_boot_order(u32 *spl_boot_list) {
>> +       u8 i;
>> +       u32 boot_devices[] = {
>> +#ifdef CONFIG_SPL_MMC_SUPPORT
>> +               BOOT_DEVICE_MMC1,
>> +#endif
>> +       };
>> +
>> +       for (i = 0; i < ARRAY_SIZE(boot_devices); i++)
>> +               spl_boot_list[i] = boot_devices[i]; } #endif
>> +
>> +#ifdef CONFIG_SPL_LOAD_FIT
>> +int board_fit_config_name_match(const char *name) {
>> +       /* boot using first FIT config */
>> +       return 0;
>> +}
>> +#endif
>> diff --git a/board/sifive/fu540/spl.c b/board/sifive/fu540/spl.c new
>> file mode 100644 index 0000000000..522bc24753
>> --- /dev/null
>> +++ b/board/sifive/fu540/spl.c
>> @@ -0,0 +1,78 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (c) 2019 SiFive, Inc
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + */
>> +
>> +#include <common.h>
>> +#include <spl.h>
>> +#include <misc.h>
>> +#include <dm.h>
>> +
>> +#include "fu540-memory-map.h"
>> +
>> +#define DDRCTLPLL_F 55
>> +#define DDRCTLPLL_Q 2
>
>These 2 macros are not needed.

Will remove in v6, thanks for highlighting this.

>
>> +
>> +#define PHY_NRESET 0x1000
>> +
>> +long nsec_per_cyc = 300; /* 33.333MHz */ void nsleep(long nsec) {
>> +       long step = nsec_per_cyc * 2;
>> +
>> +       while (nsec > 0)
>> +               nsec -= step;
>> +}
>> +
>> +void init_clk_and_ddr(void)
>> +{
>> +       int ret;
>> +       struct udevice *dev;
>> +
>> +       /* PRCI init */
>> +       ret = uclass_get_device(UCLASS_CLK, 0, &dev);
>> +       if (ret) {
>> +               debug("Clock init failed: %d\n", ret);
>> +               return;
>> +       }
>> +
>> +       ret = uclass_get_device(UCLASS_RAM, 0, &dev);
>> +       if (ret) {
>> +               printf("DRAM init failed: %d\n", ret);
>> +               return;
>> +       }
>> +
>> +       /*
>> +        * GEMGXL init VSC8541 PHY reset sequence;
>> +        * leave pull-down active for 2ms
>> +        */
>> +       nsleep(2000000);
>> +       /* Set GPIO 12 (PHY NRESET) to OE=1 and OVAL=1 */
>> +       GPIO_REG(GPIO_OUTPUT_VAL) |= PHY_NRESET;
>> +       GPIO_REG(GPIO_OUTPUT_EN) |= PHY_NRESET;
>
>Please switch to use DM GPIO APIs to do the PHY reset.

Will update in v6.

>
>> +       nsleep(100);
>> +
>> +       /* Reset PHY again to enter unmanaged mode */
>> +       GPIO_REG(GPIO_OUTPUT_VAL) &= ~PHY_NRESET;
>> +       nsleep(100);
>> +       GPIO_REG(GPIO_OUTPUT_VAL) |= PHY_NRESET;
>> +       nsleep(15000000);
>> +}
>> +
>> +void board_init_f(ulong dummy)
>> +{
>> +       int ret;
>> +
>> +       ret = spl_early_init();
>> +       if (ret)
>> +               panic("spl_early_init() failed: %d\n", ret);
>> +
>> +       arch_cpu_init_dm();
>> +
>> +       init_clk_and_ddr();
>> +
>> +       preloader_console_init();
>> +}
>> diff --git a/include/configs/sifive-fu540.h
>> b/include/configs/sifive-fu540.h index 2756ed5a77..ef3ae9b650 100644
>> --- a/include/configs/sifive-fu540.h
>> +++ b/include/configs/sifive-fu540.h
>> @@ -11,6 +11,22 @@
>>
>>  #include <linux/sizes.h>
>>
>> +#ifdef CONFIG_SPL
>> +
>> +#define CONFIG_SPL_MAX_SIZE            0x00100000
>> +#define CONFIG_SPL_BSS_START_ADDR      0x85000000
>> +#define CONFIG_SPL_BSS_MAX_SIZE                0x00100000
>> +#define CONFIG_SYS_SPL_MALLOC_START
>(CONFIG_SPL_BSS_START_ADDR + \
>> +                                        CONFIG_SPL_BSS_MAX_SIZE)
>> +#define CONFIG_SYS_SPL_MALLOC_SIZE     0x00100000
>> +
>> +#define CONFIG_SPL_LOAD_FIT_ADDRESS    0x84000000
>> +
>> +#define CONFIG_SPL_STACK       (0x08000000 + 0x001D0000 - \
>> +                                GENERATED_GBL_DATA_SIZE)
>> +
>> +#endif
>> +
>>  #define CONFIG_SYS_SDRAM_BASE          0x80000000
>>  #define CONFIG_SYS_INIT_SP_ADDR                (CONFIG_SYS_SDRAM_BASE +
>SZ_2M)
>>
>> @@ -24,6 +40,7 @@
>>
>>  /* Environment options */
>>
>> +#ifndef CONFIG_SPL_BUILD
>>  #define BOOT_TARGET_DEVICES(func) \
>>         func(MMC, mmc, 0) \
>>         func(DHCP, dhcp, na)
>> @@ -43,5 +60,6 @@
>>  #define CONFIG_PREBOOT \
>>         "setenv fdt_addr ${fdtcontroladdr};" \
>>         "fdt addr ${fdtcontroladdr};"
>> +#endif
>>
>>  #endif /* __CONFIG_H */
>> --
>
>Regards,
>Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 10/14] riscv: sifive: fu540: add SPL configuration
  2020-03-13 13:59   ` Bin Meng
@ 2020-03-17  8:04     ` Pragnesh Patel
  0 siblings, 0 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-17  8:04 UTC (permalink / raw)
  To: u-boot


Hi Bin,

>-----Original Message-----
>From: Bin Meng <bmeng.cn@gmail.com>
>Sent: 13 March 2020 19:29
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Atish Patra
><atish.patra@wdc.com>; Palmer Dabbelt <palmerdabbelt@google.com>; Paul
>Walmsley <paul.walmsley@sifive.com>; Jagan Teki
><jagan@amarulasolutions.com>; Troy Benjegerdes
><troy.benjegerdes@sifive.com>; Anup Patel <anup.patel@wdc.com>; Sagar
>Kadam <sagar.kadam@sifive.com>; Rick Chen <rick@andestech.com>; Palmer
>Dabbelt <palmer@dabbelt.com>
>Subject: Re: [PATCH v5 10/14] riscv: sifive: fu540: add SPL configuration
>
>On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
><pragnesh.patel@sifive.com> wrote:
>>
>> Add a support for SPL which will boot from L2 LIM (0x0800_0000) and
>> then boot U-boot FIT image including OpenSBI FW_DYNAMIC firmware and
>> U-Boot proper images from 1st partition of MMC boot devices.
>>
>> SPL related code is leverage from FSBL
>> (https://github.com/sifive/freedom-u540-c000-bootloader.git)
>>
>> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
>> ---
>>  board/sifive/fu540/Kconfig            |  8 +++
>>  board/sifive/fu540/Makefile           |  4 ++
>>  board/sifive/fu540/fu540-memory-map.h | 23 ++++++++
>>  board/sifive/fu540/fu540.c            | 24 +++++++++
>>  board/sifive/fu540/spl.c              | 78 +++++++++++++++++++++++++++
>>  include/configs/sifive-fu540.h        | 18 +++++++
>>  6 files changed, 155 insertions(+)
>>  create mode 100644 board/sifive/fu540/fu540-memory-map.h
>>  create mode 100644 board/sifive/fu540/spl.c
>>
>> diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
>> index 900197bbb2..ebe3472f9a 100644
>> --- a/board/sifive/fu540/Kconfig
>> +++ b/board/sifive/fu540/Kconfig
>> @@ -13,12 +13,20 @@ config SYS_CONFIG_NAME
>>         default "sifive-fu540"
>>
>>  config SYS_TEXT_BASE
>> +       default 0x80200000 if SPL
>>         default 0x80000000 if !RISCV_SMODE
>>         default 0x80200000 if RISCV_SMODE
>>
>> +config SPL_TEXT_BASE
>> +       default 0x08000000
>> +
>> +config SPL_OPENSBI_LOAD_ADDR
>> +       default 0x80000000
>> +
>>  config BOARD_SPECIFIC_OPTIONS # dummy
>>         def_bool y
>>         select GENERIC_RISCV
>> +       select SUPPORT_SPL
>>         imply CMD_DHCP
>>         imply CMD_EXT2
>>         imply CMD_EXT4
>> diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
>> index 6e1862c475..b05e2f5807 100644
>> --- a/board/sifive/fu540/Makefile
>> +++ b/board/sifive/fu540/Makefile
>> @@ -3,3 +3,7 @@
>>  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
>>
>>  obj-y  += fu540.o
>> +
>> +ifdef CONFIG_SPL_BUILD
>> +obj-y += spl.o
>> +endif
>> diff --git a/board/sifive/fu540/fu540-memory-map.h
>> b/board/sifive/fu540/fu540-memory-map.h
>> new file mode 100644
>> index 0000000000..cba464652b
>> --- /dev/null
>> +++ b/board/sifive/fu540/fu540-memory-map.h
>> @@ -0,0 +1,23 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (c) 2019 SiFive, Inc
>> + */
>> +
>> +#ifndef FU540_MEMORY_MAP
>> +#define FU540_MEMORY_MAP
>> +
>> +#include <asm/arch/gpio.h>
>> +
>>
>+/***************************************************************
>*****
>> +********
>> + * Platform definitions
>> +
>>
>+****************************************************************
>*****
>> +********/
>> +
>> +/* Memory map */
>> +#define GPIO_CTRL_ADDR                 _AC(0x10060000, UL)
>> +
>> +/* Helper functions */
>> +#define _REG32(p, i)    (*(volatile uint32_t *)((p) + (i)))
>> +
>> +#define GPIO_REG(offset)      _REG32(GPIO_CTRL_ADDR, offset)
>> +
>> +#endif /* FU540_MEMORY_MAP */
>> diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
>> index 6c642b3082..89a65eb3fb 100644
>> --- a/board/sifive/fu540/fu540.c
>> +++ b/board/sifive/fu540/fu540.c
>> @@ -11,6 +11,7 @@
>>  #include <linux/delay.h>
>>  #include <linux/io.h>
>>  #include <misc.h>
>> +#include <spl.h>
>>
>>  /*
>>   * This define is a value used for error/unknown serial.
>> @@ -114,3 +115,26 @@ int board_init(void)
>>
>>         return 0;
>>  }
>> +
>> +#ifdef CONFIG_SPL
>> +void board_boot_order(u32 *spl_boot_list) {
>> +       u8 i;
>> +       u32 boot_devices[] = {
>> +#ifdef CONFIG_SPL_MMC_SUPPORT
>> +               BOOT_DEVICE_MMC1,
>> +#endif
>> +       };
>> +
>> +       for (i = 0; i < ARRAY_SIZE(boot_devices); i++)
>> +               spl_boot_list[i] = boot_devices[i]; } #endif
>> +
>> +#ifdef CONFIG_SPL_LOAD_FIT
>> +int board_fit_config_name_match(const char *name) {
>> +       /* boot using first FIT config */
>> +       return 0;
>> +}
>> +#endif
>> diff --git a/board/sifive/fu540/spl.c b/board/sifive/fu540/spl.c new
>> file mode 100644 index 0000000000..522bc24753
>> --- /dev/null
>> +++ b/board/sifive/fu540/spl.c
>> @@ -0,0 +1,78 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (c) 2019 SiFive, Inc
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + */
>> +
>> +#include <common.h>
>> +#include <spl.h>
>> +#include <misc.h>
>> +#include <dm.h>
>> +
>> +#include "fu540-memory-map.h"
>> +
>> +#define DDRCTLPLL_F 55
>> +#define DDRCTLPLL_Q 2
>> +
>> +#define PHY_NRESET 0x1000
>> +
>> +long nsec_per_cyc = 300; /* 33.333MHz */ void nsleep(long nsec) {
>> +       long step = nsec_per_cyc * 2;
>> +
>> +       while (nsec > 0)
>> +               nsec -= step;
>> +}
>> +
>> +void init_clk_and_ddr(void)
>> +{
>> +       int ret;
>> +       struct udevice *dev;
>> +
>> +       /* PRCI init */
>> +       ret = uclass_get_device(UCLASS_CLK, 0, &dev);
>> +       if (ret) {
>> +               debug("Clock init failed: %d\n", ret);
>> +               return;
>> +       }
>> +
>> +       ret = uclass_get_device(UCLASS_RAM, 0, &dev);
>> +       if (ret) {
>> +               printf("DRAM init failed: %d\n", ret);
>> +               return;
>> +       }
>> +
>
>This should be split into two parts:
>
>SoC specific parts should go to arch/riscv/fu540/spl.c, and board specific parts
>remain here.
>
>Otherwise it's hard to re-use the same SPL codes for another board built on
>top of fu540.

Yes, you are right. Let me clear this.
PRCI and RAM initialization will go to arch/riscv/fu540/spl.c and VSC8541 PHY reset
should be in board/Sifive/fu540/spl.c
  
>
>> +       /*
>> +        * GEMGXL init VSC8541 PHY reset sequence;
>> +        * leave pull-down active for 2ms
>> +        */
>> +       nsleep(2000000);
>> +       /* Set GPIO 12 (PHY NRESET) to OE=1 and OVAL=1 */
>> +       GPIO_REG(GPIO_OUTPUT_VAL) |= PHY_NRESET;
>> +       GPIO_REG(GPIO_OUTPUT_EN) |= PHY_NRESET;
>> +       nsleep(100);
>> +
>> +       /* Reset PHY again to enter unmanaged mode */
>> +       GPIO_REG(GPIO_OUTPUT_VAL) &= ~PHY_NRESET;
>> +       nsleep(100);
>> +       GPIO_REG(GPIO_OUTPUT_VAL) |= PHY_NRESET;
>> +       nsleep(15000000);
>> +}
>> +
>> +void board_init_f(ulong dummy)
>> +{
>> +       int ret;
>> +
>> +       ret = spl_early_init();
>> +       if (ret)
>> +               panic("spl_early_init() failed: %d\n", ret);
>> +
>> +       arch_cpu_init_dm();
>> +
>> +       init_clk_and_ddr();
>> +
>> +       preloader_console_init();
>> +}
>
>Regards,
>Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 12/14] riscv: sifive: fu540: enable all cache ways from u-boot proper
  2020-03-13 13:49           ` Bin Meng
@ 2020-03-17  9:52             ` Pragnesh Patel
       [not found]               ` <752D002CFF5D0F4FA35C0100F1D73F3FA46E7F97@ATCPCS16.andestech.com>
  0 siblings, 1 reply; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-17  9:52 UTC (permalink / raw)
  To: u-boot


Hi,

>-----Original Message-----
>From: Bin Meng <bmeng.cn@gmail.com>
>Sent: 13 March 2020 19:19
>To: Anup Patel <anup@brainfault.org>
>Cc: Pragnesh Patel <pragnesh.patel@sifive.com>; U-Boot Mailing List <u-
>boot at lists.denx.de>; Atish Patra <atish.patra@wdc.com>; Palmer Dabbelt
><palmerdabbelt@google.com>; Paul Walmsley <paul.walmsley@sifive.com>;
>Jagan Teki <jagan@amarulasolutions.com>; Troy Benjegerdes
><troy.benjegerdes@sifive.com>; Anup Patel <anup.patel@wdc.com>; Sagar
>Kadam <sagar.kadam@sifive.com>; Rick Chen <rick@andestech.com>; Palmer
>Dabbelt <palmer@dabbelt.com>
>Subject: Re: [PATCH v5 12/14] riscv: sifive: fu540: enable all cache ways from
>u-boot proper
>
>Hi Anup,
>
>On Fri, Mar 13, 2020 at 6:49 PM Anup Patel <anup@brainfault.org> wrote:
>>
>> On Fri, Mar 13, 2020 at 3:52 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>> >
>> > Hi Anup,
>> >
>> > On Fri, Mar 13, 2020 at 6:02 PM Anup Patel <anup@brainfault.org> wrote:
>> > >
>> > > On Fri, Mar 13, 2020 at 2:31 PM Bin Meng <bmeng.cn@gmail.com>
>wrote:
>> > > >
>> > > > On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
>> > > > <pragnesh.patel@sifive.com> wrote:
>> > > > >
>> > > > > Enable all cache ways from u-boot proper.
>> > > >
>> > > > U-Boot
>> > > >
>> > > > >
>> > > > > Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
>> > > > > ---
>> > > > >  board/sifive/fu540/Makefile |  1 +
>> > > > > board/sifive/fu540/cache.c  | 20 ++++++++++++++++++++
>> > > > > board/sifive/fu540/cache.h  | 13 +++++++++++++
>> > > > > board/sifive/fu540/fu540.c  |  6 ++++--
>> > > > >  4 files changed, 38 insertions(+), 2 deletions(-)  create
>> > > > > mode 100644 board/sifive/fu540/cache.c  create mode 100644
>> > > > > board/sifive/fu540/cache.h
>> > > > >
>> > > > > diff --git a/board/sifive/fu540/Makefile
>> > > > > b/board/sifive/fu540/Makefile index b05e2f5807..3b867bbd89
>> > > > > 100644
>> > > > > --- a/board/sifive/fu540/Makefile
>> > > > > +++ b/board/sifive/fu540/Makefile
>> > > > > @@ -3,6 +3,7 @@
>> > > > >  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
>> > > > >
>> > > > >  obj-y  += fu540.o
>> > > > > +obj-y  += cache.o
>> > > > >
>> > > > >  ifdef CONFIG_SPL_BUILD
>> > > > >  obj-y += spl.o
>> > > > > diff --git a/board/sifive/fu540/cache.c
>> > > > > b/board/sifive/fu540/cache.c new file mode 100644 index
>> > > > > 0000000000..a0bcd2ba48
>> > > > > --- /dev/null
>> > > > > +++ b/board/sifive/fu540/cache.c
>> > > >
>> > > > This should be put into arch/riscv/cpu/fu540/cache.c
>> > > >
>> > > > > @@ -0,0 +1,20 @@
>> > > > > +// SPDX-License-Identifier: GPL-2.0+
>> > > > > +/*
>> > > > > + * Copyright (c) 2019 SiFive, Inc  */ #include <asm/io.h>
>> > > > > +
>> > > > > +/* Register offsets */
>> > > > > +#define CACHE_ENABLE           0x008
>> > > > > +
>> > > > > +/* Enable ways; allow cache to use these ways */ void
>> > > > > +cache_enable_ways(u64 base_addr, u8 value) {
>> > > > > +       volatile u32 *enable = (volatile u32 *)(base_addr +
>> > > > > +                                         CACHE_ENABLE);
>> > > > > +       /* memory barrier */
>> > > > > +       mb();
>> > > > > +       (*enable) = value;
>> > > > > +       /* memory barrier */
>> > > > > +       mb();
>> > > > > +}
>> > > > > diff --git a/board/sifive/fu540/cache.h
>> > > > > b/board/sifive/fu540/cache.h new file mode 100644 index
>> > > > > 0000000000..425124a23b
>> > > > > --- /dev/null
>> > > > > +++ b/board/sifive/fu540/cache.h
>> > > >
>> > > > arch/riscv/include/asm/arch-fu540/cache.h
>> > >
>> > > Let's not entire FU540 directory under arch/riscv/cpu directory
>> > > just to have cache functions. The arch/riscv/cpu/generic is
>> > > perfectly suitable for FU540.
>> >
>> > I doubt arch/riscv/cpu/generic can be generic if we consider U-Boot
>> > SPL phase. It can be generic for S-mode U-Boot though.
>>
>> Its really very easy to do. We are already doing this in Xvisor.
>>
>> As an example, of DT based operations in a generic board support refer:
>> https://github.com/avpatel/xvisor-next/blob/master/arch/arm/board/gene
>> ric/brd_main.c
>> https://github.com/avpatel/xvisor-next/blob/master/arch/arm/board/gene
>> ric/foundation-v8.c
>
>Yes, this can be easy to do if we have everything written based on DT.
>But we cannot always assume DT is available in SPL. Some SoCs will not allow
>SPL with DT support to run due to constraint resources.
>
>Even for DT, due to SPL initialization codes can be very low-level and specific
>to an SoC, not everything can be properly modeled by DT. Take a look at the
>u-boot/arch/arm directory. Things are not that easy.
>
>>
>> Using the above approach, we are able to boot same Xvisor ARM/ARM64
>> binary on multiple boards.
>>
>
>Yes, I know. The same as what is done in the Linux kernel. Take x86 for
>example, the same kernel image can boot on almost every x86
>desktop/laptop/server we have today. But we have to understand that this is
>built on top of BIOS which does all low-level processor / chipset initialization
>and hide that very well for OS.
>

IMHO just for cache, it's better not to add arch/riscv/cpu/fu540.
If something that we can not handle with arch/riscv/cpu/generic then we will
definitely add arch/riscv/cpu/fu540 dir.

Thanks Bin and Anup for the review.

>> >
>> > >
>> > > If we re-use arch/riscv/cpu/generic as-much as possible then
>> > > arch/riscv will be easy to maintain in future.
>> > >
>> > > We can add arch/riscv/cpu/generic/cache.c which will do things
>> > > FU540 specific based on "#ifdef" or "DT compatible string".
>> > >
>
>Regards,
>Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 06/14] sifive: fu540: add ddr driver
  2020-03-13  7:48   ` Bin Meng
@ 2020-03-17 13:00     ` Pragnesh Patel
  0 siblings, 0 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-17 13:00 UTC (permalink / raw)
  To: u-boot


Hi Bin,

>-----Original Message-----
>From: Bin Meng <bmeng.cn@gmail.com>
>Sent: 13 March 2020 13:18
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Atish Patra
><atish.patra@wdc.com>; Palmer Dabbelt <palmerdabbelt@google.com>; Paul
>Walmsley <paul.walmsley@sifive.com>; Jagan Teki
><jagan@amarulasolutions.com>; Troy Benjegerdes
><troy.benjegerdes@sifive.com>; Anup Patel <anup.patel@wdc.com>; Sagar
>Kadam <sagar.kadam@sifive.com>; Rick Chen <rick@andestech.com>; Kever
>Yang <kever.yang@rock-chips.com>; Giulio Benetti
><giulio.benetti@benettiengineering.com>; Lokesh Vutla
><lokeshvutla@ti.com>; Kevin Scholz <k-scholz@ti.com>; YouMin Chen
><cym@rock-chips.com>
>Subject: Re: [PATCH v5 06/14] sifive: fu540: add ddr driver
>
>On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
><pragnesh.patel@sifive.com> wrote:
>>
>> Add driver for fu540 to support ddr initialization in SPL.
>> This driver is based on FSBL
>> (https://github.com/sifive/freedom-u540-c000-bootloader.git)
>>
>> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
>> ---
>>  drivers/ram/Kconfig              |   7 +
>>  drivers/ram/Makefile             |   2 +
>>  drivers/ram/sifive/Kconfig       |   8 +
>>  drivers/ram/sifive/Makefile      |   6 +
>>  drivers/ram/sifive/sdram_fu540.c | 295
>> +++++++++++++++++++++++++++++++  drivers/ram/sifive/sdram_fu540.h |
>> 94 ++++++++++
>>  6 files changed, 412 insertions(+)
>>  create mode 100644 drivers/ram/sifive/Kconfig  create mode 100644
>> drivers/ram/sifive/Makefile  create mode 100644
>> drivers/ram/sifive/sdram_fu540.c  create mode 100644
>> drivers/ram/sifive/sdram_fu540.h
>>
>> diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig index
>> 56fea7c94c..c60c63204c 100644
>> --- a/drivers/ram/Kconfig
>> +++ b/drivers/ram/Kconfig
>> @@ -73,5 +73,12 @@ config IMXRT_SDRAM
>>           to support external memories like sdram, psram & nand.
>>           This driver is for the sdram memory interface with the SEMC.
>>
>> +config SIFIVE_DDR
>> +       bool "Enable SiFive DDR support"
>> +       depends on RAM
>> +       help
>> +         Enable support for the internal DDR Memory Controller of SiFive SoCs.
>> +
>>  source "drivers/ram/rockchip/Kconfig"
>>  source "drivers/ram/stm32mp1/Kconfig"
>> +source "drivers/ram/sifive/Kconfig"
>> diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile index
>> 5c897410c6..12bf61510b 100644
>> --- a/drivers/ram/Makefile
>> +++ b/drivers/ram/Makefile
>> @@ -17,3 +17,5 @@ obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
>>  obj-$(CONFIG_K3_J721E_DDRSS) += k3-j721e/
>>
>>  obj-$(CONFIG_IMXRT_SDRAM) += imxrt_sdram.o
>> +
>> +obj-$(CONFIG_SIFIVE_DDR) += sifive/
>> diff --git a/drivers/ram/sifive/Kconfig b/drivers/ram/sifive/Kconfig
>> new file mode 100644 index 0000000000..b754700db8
>> --- /dev/null
>> +++ b/drivers/ram/sifive/Kconfig
>> @@ -0,0 +1,8 @@
>> +config SIFIVE_FU540_DDR
>> +       bool "SiFive FU540 DDR driver"
>> +       depends on DM && OF_CONTROL
>> +       select RAM
>
>Do we need this driver for U-Boot proper?

SPL_RAM is depend on RAM that's why select RAM here.

>
>> +       select SPL_RAM if SPL
>> +       select SIFIVE_DDR
>> +       help
>> +         This enables DDR support for the platforms based on SiFive FU540
>SoC.
>> diff --git a/drivers/ram/sifive/Makefile b/drivers/ram/sifive/Makefile
>> new file mode 100644 index 0000000000..0187805199
>> --- /dev/null
>> +++ b/drivers/ram/sifive/Makefile
>> @@ -0,0 +1,6 @@
>> +# SPDX-License-Identifier: GPL-2.0+
>> +#
>> +# Copyright (c) 2020 SiFive, Inc
>> +#
>> +
>> +obj-$(CONFIG_SIFIVE_FU540_DDR) += sdram_fu540.o
>> diff --git a/drivers/ram/sifive/sdram_fu540.c
>> b/drivers/ram/sifive/sdram_fu540.c
>> new file mode 100644
>> index 0000000000..18926dbe15
>> --- /dev/null
>> +++ b/drivers/ram/sifive/sdram_fu540.c
>> @@ -0,0 +1,295 @@
>> +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
>> +/*
>> + * (C) Copyright 2020 SiFive, Inc.
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + */
>> +
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <init.h>
>> +#include <ram.h>
>> +#include <regmap.h>
>> +#include <syscon.h>
>> +#include <asm/io.h>
>> +#include "sdram_fu540.h"
>> +
>> +/* n: Unit bytes */
>> +void sdram_copy_to_reg(volatile u32 *dest, volatile u32 *src, u32 n)
>
>This should be static, also use "int n"?

I agree with static but "n" should be u32 because it tells how many bytes you want to copy.

>
>> +{
>> +       int i;
>> +
>> +       for (i = 0; i < n / sizeof(u32); i++) {
>> +               writel(*src, dest);
>> +               src++;
>> +               dest++;
>> +       }
>> +}
>> +
>> +static void ddr_setuprangeprotection(volatile u32 *ctl, u64 end_addr)
>
>__maybe_unused ? Otherwise use #ifdef #endif ?

Will use it under " #if defined(CONFIG_SPL_BUILD)" and update in v6. 
 
>
>
>> +{
>> +       writel(0x0, DENALI_CTL_209 + ctl);
>> +       u32 end_addr_16kblocks = ((end_addr >> 14) & 0x7FFFFF) - 1;
>
>nits: move the variable declaration

Will do.

>
>> +
>> +       writel(end_addr_16kblocks, DENALI_CTL_210 + ctl);
>> +       writel(0x0, DENALI_CTL_212 + ctl);
>> +       writel(0x0, DENALI_CTL_214 + ctl);
>> +       writel(0x0, DENALI_CTL_216 + ctl);
>> +       setbits_le32(DENALI_CTL_224 + ctl,
>> +                    0x3 << AXI0_RANGE_PROT_BITS_0_OFFSET);
>> +       writel(0xFFFFFFFF, DENALI_CTL_225 + ctl);
>> +       setbits_le32(DENALI_CTL_208 + ctl, 0x1 <<
>AXI0_ADDRESS_RANGE_ENABLE);
>> +       setbits_le32(DENALI_CTL_208 + ctl,
>> +                    0x1 << PORT_ADDR_PROTECTION_EN_OFFSET); }
>> +
>> +static void ddr_start(volatile u32 *ctl, u32 *physical_filter_ctrl,
>> +u64 ddr_end)
>
>__maybe_unused ?

Will use it under " #if defined(CONFIG_SPL_BUILD)" and update in v6.

>
>> +{
>> +       setbits_le32(DENALI_CTL_0 + ctl, 0x1);
>> +       while ((readl(DENALI_CTL_132 + ctl) & (1 <<
>MC_INIT_COMPLETE_OFFSET))
>> +              == 0) {
>> +       }
>> +
>
>Use
>
>do {
>    val = readl(DENALI_CTL_132 + ctl) & (1 << MC_INIT_COMPLETE_OFFSET); }
>while (val == 0)

Thanks for the suggestion, will update in v6.

>
>?
>
>
>> +       // Disable the BusBlocker in front of the controller AXI slave
>> + ports
>
>nits: use /* */

Will do.

>
>> +       volatile u64 *filterreg = (volatile u64
>> + *)physical_filter_ctrl;
>
>Please move the variable declaration to the beginning of this function

Will do.

>
>> +
>> +       filterreg[0] = 0x0f00000000000000UL | (ddr_end >> 2); }
>> +
>> +static u64 ddr_phy_fixup(volatile u32 *ddrphyreg)
>
>__maybe_unused ?

Will use it under " #if defined(CONFIG_SPL_BUILD)" and update in v6.

>
>> +{
>> +       // return bitmask of failed lanes
>
>nits: use /* */

Will do.

>
>> +
>> +       u64 fails     = 0;
>> +       u32 slicebase = 0;
>> +       u32 dq        = 0;
>> +
>> +       // check errata condition
>
>nits: use /* */

Will do.

>
>> +       for (u32 slice = 0; slice < 8; slice++) {
>> +               u32 regbase = slicebase + 34;
>> +
>> +               for (u32 reg = 0; reg < 4; reg++) {
>> +                       u32 updownreg = readl(regbase + reg +
>> + ddrphyreg);
>> +
>> +                       for (u32 bit = 0; bit < 2; bit++) {
>> +                               u32 phy_rx_cal_dqn_0_offset;
>> +
>> +                               if (bit == 0) {
>> +                                       phy_rx_cal_dqn_0_offset =
>> +                                               PHY_RX_CAL_DQ0_0_OFFSET;
>> +                               } else {
>> +                                       phy_rx_cal_dqn_0_offset =
>> +                                               PHY_RX_CAL_DQ1_0_OFFSET;
>> +                               }
>> +
>> +                               u32 down = (updownreg >>
>> +                                           phy_rx_cal_dqn_0_offset) & 0x3F;
>> +                               u32 up   = (updownreg >>
>> +                                           (phy_rx_cal_dqn_0_offset + 6)) &
>> +                                           0x3F;
>> +
>> +                               u8 failc0 = ((down == 0) && (up == 0x3F));
>> +                               u8 failc1 = ((up == 0) && (down ==
>> + 0x3F));
>> +
>> +                               // print error message on failure
>
>nits: use /* */

Will do.

>
>> +                               if (failc0 || failc1) {
>> +                                       if (fails == 0)
>> +                                               printf("DDR error in
>> + fixing up\n");
>> +
>> +                                       fails |= (1 << dq);
>> +
>> +                                       char slicelsc = '0';
>> +                                       char slicemsc = '0';
>> +
>> +                                       slicelsc += (dq % 10);
>> +                                       slicemsc += (dq / 10);
>> +                                       printf("S ");
>> +                                       printf("%c", slicemsc);
>> +                                       printf("%c", slicelsc);
>> +
>> +                                       if (failc0)
>> +                                               printf("U");
>> +                                       else
>> +                                               printf("D");
>> +
>> +                                       printf("\n");
>> +                               }
>> +                               dq++;
>> +                       }
>> +               }
>> +               slicebase += 128;
>> +       }
>> +       return(0);
>> +}
>> +
>> +static u32 ddr_getdramclass(volatile u32 *ctl)
>
>__maybe_unused ?

Sure, will use __ maybe_unused here.

>
>> +{
>> +       u32 reg = readl(DENALI_CTL_0 + ctl);
>> +
>> +       return ((reg >> DRAM_CLASS_OFFSET) & 0xF); }
>> +
>> +static __maybe_unused int fu540_ddr_setup(struct udevice *dev) {
>> +       struct ddr_info *priv = dev_get_priv(dev);
>> +       struct sifive_dmc_plat *plat = dev_get_platdata(dev);
>> +
>> +       int ret, i;
>> +       u32 physet;
>> +
>> +       volatile u32 *denali_ctl =  &priv->ctl->denali_ctl[0];
>> +       volatile u32 *denali_phy =  &priv->phy->denali_phy[0];
>> +
>> +       ret = dev_read_u32_array(dev, "sifive,sdram-params",
>> +                                (u32 *)&plat->sdram_params,
>> +                                sizeof(plat->sdram_params) / sizeof(u32));
>> +       if (ret) {
>> +               printf("%s: Cannot read sifive,sdram-params %d\n",
>> +                      __func__, ret);
>> +               return ret;
>> +       }
>> +
>> +       struct fu540_sdram_params *params = &plat->sdram_params;
>
>Please move the variable declaration to the beginning of this function.

Will do.

>
>> +
>> +       sdram_copy_to_reg(&priv->ctl->denali_ctl[0],
>> +                         &params->pctl_regs.denali_ctl[0],
>> +                         sizeof(struct fu540_ddrctl));
>> +
>> +       /* phy reset */
>> +       for (i = DENALI_PHY_1152; i <= DENALI_PHY_1214; i++) {
>> +               physet = params->phy_regs.denali_phy[i];
>> +               priv->phy->denali_phy[i] = physet;
>> +       }
>> +
>> +       for (i = 0; i < DENALI_PHY_1152; i++) {
>> +               physet = params->phy_regs.denali_phy[i];
>> +               priv->phy->denali_phy[i] = physet;
>> +       }
>> +
>> +       /* Disable read interleave DENALI_CTL_120 */
>> +       setbits_le32(DENALI_CTL_120 + denali_ctl,
>> +                    1 << DISABLE_RD_INTERLEAVE_OFFSET);
>> +
>> +       /* Disable optimal read/modify/write logic DENALI_CTL_21 */
>> +       clrbits_le32(DENALI_CTL_21 + denali_ctl, 1 <<
>> + OPTIMAL_RMODW_EN_OFFSET);
>> +
>> +       /* Enable write Leveling DENALI_CTL_170 */
>> +       setbits_le32(DENALI_CTL_170 + denali_ctl, (1 << WRLVL_EN_OFFSET)
>> +                    | (1 << DFI_PHY_WRLELV_MODE_OFFSET));
>> +
>> +       /* Enable read leveling DENALI_CTL_181 and DENALI_CTL_260 */
>> +       setbits_le32(DENALI_CTL_181 + denali_ctl,
>> +                    1 << DFI_PHY_RDLVL_MODE_OFFSET);
>> +       setbits_le32(DENALI_CTL_260 + denali_ctl, 1 <<
>> + RDLVL_EN_OFFSET);
>> +
>> +       /* Enable read leveling gate DENALI_CTL_260 and DENALI_CTL_182 */
>> +       setbits_le32(DENALI_CTL_260 + denali_ctl, 1 <<
>RDLVL_GATE_EN_OFFSET);
>> +       setbits_le32(DENALI_CTL_182 + denali_ctl,
>> +                    1 << DFI_PHY_RDLVL_GATE_MODE_OFFSET);
>> +
>> +       if (ddr_getdramclass(denali_ctl) == DRAM_CLASS_DDR4) {
>> +               /* Enable vref training DENALI_CTL_184 */
>> +               setbits_le32(DENALI_CTL_184 + denali_ctl, 1 << VREF_EN_OFFSET);
>> +       }
>> +
>> +       /* Mask off leveling completion interrupt DENALI_CTL_136 */
>> +       setbits_le32(DENALI_CTL_136 + denali_ctl,
>> +                    1 << LEVELING_OPERATION_COMPLETED_OFFSET);
>> +
>> +       /* Mask off MC init complete interrupt DENALI_CTL_136 */
>> +       setbits_le32(DENALI_CTL_136 + denali_ctl, 1 <<
>> + MC_INIT_COMPLETE_OFFSET);
>> +
>> +       /* Mask off out of range interrupts DENALI_CTL_136 */
>> +       setbits_le32(DENALI_CTL_136 + denali_ctl, (1 <<
>OUT_OF_RANGE_OFFSET)
>> +                    | (1 << MULTIPLE_OUT_OF_RANGE_OFFSET));
>> +
>> +       /* set up range protection */
>> +       ddr_setuprangeprotection(denali_ctl, DDR_MEM_SIZE);
>> +
>> +       /* Mask off port command error interrupt DENALI_CTL_136 */
>> +       setbits_le32(DENALI_CTL_136 + denali_ctl,
>> +                    1 << PORT_COMMAND_CHANNEL_ERROR_OFFSET);
>> +
>> +       const u64 ddr_size = DDR_MEM_SIZE;
>> +       const u64 ddr_end = PAYLOAD_DEST + ddr_size;
>> +
>
>Please move the variable declaration to the beginning of this function.

Will do.

>
>> +       ddr_start(denali_ctl, priv->physical_filter_ctrl, ddr_end);
>> +
>> +       ddr_phy_fixup(denali_phy);
>> +
>> +       /* check size */
>> +       priv->info.size = get_ram_size((long *)priv->info.base,
>> +                                      DDR_MEM_SIZE);
>> +
>> +       printf("priv->info.size = %lx\n", priv->info.size);
>> +       debug("%s : %lx\n", __func__, priv->info.size);
>> +
>> +       /* check memory access for all memory */
>> +
>> +       if (priv->info.size != DDR_MEM_SIZE) {
>> +               printf("DDR invalid size : 0x%lx, expected 0x%lx\n",
>> +                      priv->info.size, DDR_MEM_SIZE);
>> +               return -EINVAL;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static int fu540_ddr_probe(struct udevice *dev) {
>> +       struct ddr_info *priv = dev_get_priv(dev);
>> +
>> +#if defined(CONFIG_SPL_BUILD)
>> +       struct regmap *map;
>> +       int ret;
>> +
>> +       debug("FU540 DDR probe\n");
>> +       priv->dev = dev;
>> +
>> +       ret = regmap_init_mem(dev_ofnode(dev), &map);
>> +       if (ret)
>> +               return ret;
>> +
>> +       priv->ctl = regmap_get_range(map, 0);
>> +       priv->phy = regmap_get_range(map, 1);
>> +       priv->physical_filter_ctrl = regmap_get_range(map, 2);
>> +
>> +       priv->info.base = CONFIG_SYS_SDRAM_BASE;
>> +
>> +       priv->info.size = 0;
>> +       return fu540_ddr_setup(dev);
>> +#else
>> +       priv->info.base = CONFIG_SYS_SDRAM_BASE;
>> +       priv->info.size = DDR_MEM_SIZE; #endif
>> +       return 0;
>> +}
>> +
>> +static int fu540_ddr_get_info(struct udevice *dev, struct ram_info
>> +*info) {
>> +       struct ddr_info *priv = dev_get_priv(dev);
>> +
>> +       *info = priv->info;
>> +
>> +       return 0;
>> +}
>> +
>> +static struct ram_ops fu540_ddr_ops = {
>> +       .get_info = fu540_ddr_get_info, };
>> +
>> +static const struct udevice_id fu540_ddr_ids[] = {
>> +       { .compatible = "sifive,fu540-ddr" },
>
>"sifive,fu540-c000-ddr" ?

Will update in v6.

>
>> +       { }
>> +};
>> +
>> +U_BOOT_DRIVER(fu540_ddr) = {
>> +       .name = "fu540_ddr",
>> +       .id = UCLASS_RAM,
>> +       .of_match = fu540_ddr_ids,
>> +       .ops = &fu540_ddr_ops,
>> +       .probe = fu540_ddr_probe,
>> +       .priv_auto_alloc_size = sizeof(struct ddr_info),
>> +       .platdata_auto_alloc_size = sizeof(struct sifive_dmc_plat), };
>> diff --git a/drivers/ram/sifive/sdram_fu540.h
>> b/drivers/ram/sifive/sdram_fu540.h
>> new file mode 100644
>> index 0000000000..09693a038e
>> --- /dev/null
>> +++ b/drivers/ram/sifive/sdram_fu540.h
>> @@ -0,0 +1,94 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
>> +/*
>> + * Copyright (C) 2020, SiFive, Inc
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + */
>> +
>> +#define DENALI_CTL_0   0
>> +#define DENALI_CTL_21  21
>> +#define DENALI_CTL_120 120
>> +#define DENALI_CTL_132 132
>> +#define DENALI_CTL_136 136
>> +#define DENALI_CTL_170 170
>> +#define DENALI_CTL_181 181
>> +#define DENALI_CTL_182 182
>> +#define DENALI_CTL_184 184
>> +#define DENALI_CTL_208 208
>> +#define DENALI_CTL_209 209
>> +#define DENALI_CTL_210 210
>> +#define DENALI_CTL_212 212
>> +#define DENALI_CTL_214 214
>> +#define DENALI_CTL_216 216
>> +#define DENALI_CTL_224 224
>> +#define DENALI_CTL_225 225
>> +#define DENALI_CTL_260 260
>> +
>> +#define DENALI_PHY_1152        1152
>> +#define DENALI_PHY_1214        1214
>> +
>> +#define PAYLOAD_DEST   0x80000000
>> +#define DDR_MEM_SIZE   (8UL * 1024UL * 1024UL * 1024UL)
>> +
>> +#define DRAM_CLASS_OFFSET                   8
>> +#define DRAM_CLASS_DDR4                     0xA
>> +#define OPTIMAL_RMODW_EN_OFFSET             0
>> +#define DISABLE_RD_INTERLEAVE_OFFSET        16
>> +#define OUT_OF_RANGE_OFFSET                 1
>> +#define MULTIPLE_OUT_OF_RANGE_OFFSET        2
>> +#define PORT_COMMAND_CHANNEL_ERROR_OFFSET   7
>> +#define MC_INIT_COMPLETE_OFFSET             8
>> +#define LEVELING_OPERATION_COMPLETED_OFFSET 22
>> +#define DFI_PHY_WRLELV_MODE_OFFSET          24
>> +#define DFI_PHY_RDLVL_MODE_OFFSET           24
>> +#define DFI_PHY_RDLVL_GATE_MODE_OFFSET      0
>> +#define VREF_EN_OFFSET                      24
>> +#define PORT_ADDR_PROTECTION_EN_OFFSET      0
>> +#define AXI0_ADDRESS_RANGE_ENABLE           8
>> +#define AXI0_RANGE_PROT_BITS_0_OFFSET       24
>> +#define RDLVL_EN_OFFSET                     16
>> +#define RDLVL_GATE_EN_OFFSET                24
>> +#define WRLVL_EN_OFFSET                     0
>> +
>> +#define PHY_RX_CAL_DQ0_0_OFFSET             0
>> +#define PHY_RX_CAL_DQ1_0_OFFSET             16
>> +
>> +struct fu540_ddrctl {
>> +       volatile u32 denali_ctl[265];
>> +};
>> +
>> +struct fu540_ddrphy {
>> +       volatile u32 denali_phy[1215]; };
>> +
>> +struct fu540_sdram_params {
>> +       struct fu540_ddrctl pctl_regs;
>> +       struct fu540_ddrphy phy_regs;
>> +};
>> +
>> +struct sifive_dmc_plat {
>> +#if CONFIG_IS_ENABLED(OF_PLATDATA)
>> +       struct dtd_sifive_fu540_dmc dtplat;
>
>Do we use this for SPL?

Yes, will update in v6.

>
>> +#else
>> +       struct fu540_sdram_params sdram_params; #endif };
>> +
>> +/**
>> + * struct ddr_info
>> + *
>> + * @dev                                : pointer for the device
>> + * @info                       : UCLASS RAM information
>> + * @ctl                                : DDR controleur base address
>
>typo: controller

Thanks, will update.

>
>> + * @phy                                : DDR PHY base address
>> + * @ctrl                       : DDR control base address
>> + * @physical_filter_ctrl       : DDR physical filter control base address
>> + */
>> +struct ddr_info {
>> +       struct udevice *dev;
>> +       struct ram_info info;
>> +       struct fu540_ddrctl *ctl;
>> +       struct fu540_ddrphy *phy;
>> +       u32 *physical_filter_ctrl;
>> +};
>> --
>
>Regards,
>Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 06/14] sifive: fu540: add ddr driver
  2020-03-13 11:56   ` Giulio Benetti
@ 2020-03-17 13:05     ` Pragnesh Patel
  0 siblings, 0 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-17 13:05 UTC (permalink / raw)
  To: u-boot

Hi,

>-----Original Message-----
>From: Giulio Benetti <giulio.benetti@benettiengineering.com>
>Sent: 13 March 2020 17:26
>To: Pragnesh Patel <pragnesh.patel@sifive.com>; u-boot at lists.denx.de
>Cc: atish.patra at wdc.com; palmerdabbelt at google.com;
>bmeng.cn at gmail.com; Paul Walmsley <paul.walmsley@sifive.com>;
>jagan at amarulasolutions.com; Troy Benjegerdes
><troy.benjegerdes@sifive.com>; anup.patel at wdc.com; Sagar Kadam
><sagar.kadam@sifive.com>; rick at andestech.com; Kever Yang
><kever.yang@rock-chips.com>; Lokesh Vutla <lokeshvutla@ti.com>; Kevin
>Scholz <k-scholz@ti.com>; YouMin Chen <cym@rock-chips.com>
>Subject: Re: [PATCH v5 06/14] sifive: fu540: add ddr driver
>
>Hi Pragnesh,
>
>On 3/11/20 8:03 AM, Pragnesh Patel wrote:
>> Add driver for fu540 to support ddr initialization in SPL.
>> This driver is based on FSBL
>> (https://github.com/sifive/freedom-u540-c000-bootloader.git)
>>
>> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
>> ---
>>   drivers/ram/Kconfig              |   7 +
>>   drivers/ram/Makefile             |   2 +
>>   drivers/ram/sifive/Kconfig       |   8 +
>>   drivers/ram/sifive/Makefile      |   6 +
>>   drivers/ram/sifive/sdram_fu540.c | 295
>+++++++++++++++++++++++++++++++
>>   drivers/ram/sifive/sdram_fu540.h |  94 ++++++++++
>>   6 files changed, 412 insertions(+)
>>   create mode 100644 drivers/ram/sifive/Kconfig
>>   create mode 100644 drivers/ram/sifive/Makefile
>>   create mode 100644 drivers/ram/sifive/sdram_fu540.c
>>   create mode 100644 drivers/ram/sifive/sdram_fu540.h
>>
>> diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig index
>> 56fea7c94c..c60c63204c 100644
>> --- a/drivers/ram/Kconfig
>> +++ b/drivers/ram/Kconfig
>> @@ -73,5 +73,12 @@ config IMXRT_SDRAM
>>   	  to support external memories like sdram, psram & nand.
>>   	  This driver is for the sdram memory interface with the SEMC.
>>
>> +config SIFIVE_DDR
>> +	bool "Enable SiFive DDR support"
>> +	depends on RAM
>> +	help
>> +	  Enable support for the internal DDR Memory Controller of SiFive
>SoCs.
>> +
>>   source "drivers/ram/rockchip/Kconfig"
>>   source "drivers/ram/stm32mp1/Kconfig"
>> +source "drivers/ram/sifive/Kconfig"
>> diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile index
>> 5c897410c6..12bf61510b 100644
>> --- a/drivers/ram/Makefile
>> +++ b/drivers/ram/Makefile
>> @@ -17,3 +17,5 @@ obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
>>   obj-$(CONFIG_K3_J721E_DDRSS) += k3-j721e/
>>
>>   obj-$(CONFIG_IMXRT_SDRAM) += imxrt_sdram.o
>> +
>> +obj-$(CONFIG_SIFIVE_DDR) += sifive/
>> diff --git a/drivers/ram/sifive/Kconfig b/drivers/ram/sifive/Kconfig
>> new file mode 100644 index 0000000000..b754700db8
>> --- /dev/null
>> +++ b/drivers/ram/sifive/Kconfig
>> @@ -0,0 +1,8 @@
>> +config SIFIVE_FU540_DDR
>> +	bool "SiFive FU540 DDR driver"
>> +	depends on DM && OF_CONTROL
>> +	select RAM
>> +	select SPL_RAM if SPL
>> +	select SIFIVE_DDR
>> +	help
>> +	  This enables DDR support for the platforms based on SiFive FU540
>SoC.
>> diff --git a/drivers/ram/sifive/Makefile b/drivers/ram/sifive/Makefile
>> new file mode 100644 index 0000000000..0187805199
>> --- /dev/null
>> +++ b/drivers/ram/sifive/Makefile
>> @@ -0,0 +1,6 @@
>> +# SPDX-License-Identifier: GPL-2.0+
>> +#
>> +# Copyright (c) 2020 SiFive, Inc
>> +#
>> +
>> +obj-$(CONFIG_SIFIVE_FU540_DDR) += sdram_fu540.o
>> diff --git a/drivers/ram/sifive/sdram_fu540.c
>> b/drivers/ram/sifive/sdram_fu540.c
>> new file mode 100644
>> index 0000000000..18926dbe15
>> --- /dev/null
>> +++ b/drivers/ram/sifive/sdram_fu540.c
>> @@ -0,0 +1,295 @@
>> +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
>> +/*
>> + * (C) Copyright 2020 SiFive, Inc.
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + */
>> +
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <init.h>
>> +#include <ram.h>
>> +#include <regmap.h>
>> +#include <syscon.h>
>> +#include <asm/io.h>
>> +#include "sdram_fu540.h"
>> +
>> +/* n: Unit bytes */
>> +void sdram_copy_to_reg(volatile u32 *dest, volatile u32 *src, u32 n)
>> +{
>> +	int i;
>> +
>> +	for (i = 0; i < n / sizeof(u32); i++) {
>> +		writel(*src, dest);
>> +		src++;
>> +		dest++;
>> +	}
>> +}
>> +
>> +static void ddr_setuprangeprotection(volatile u32 *ctl, u64 end_addr)
>> +{
>> +	writel(0x0, DENALI_CTL_209 + ctl);
>> +	u32 end_addr_16kblocks = ((end_addr >> 14) & 0x7FFFFF) - 1;
>> +
>> +	writel(end_addr_16kblocks, DENALI_CTL_210 + ctl);
>> +	writel(0x0, DENALI_CTL_212 + ctl);
>> +	writel(0x0, DENALI_CTL_214 + ctl);
>> +	writel(0x0, DENALI_CTL_216 + ctl);
>> +	setbits_le32(DENALI_CTL_224 + ctl,
>> +		     0x3 << AXI0_RANGE_PROT_BITS_0_OFFSET);
>> +	writel(0xFFFFFFFF, DENALI_CTL_225 + ctl);
>> +	setbits_le32(DENALI_CTL_208 + ctl, 0x1 <<
>AXI0_ADDRESS_RANGE_ENABLE);
>> +	setbits_le32(DENALI_CTL_208 + ctl,
>> +		     0x1 << PORT_ADDR_PROTECTION_EN_OFFSET); }
>> +
>> +static void ddr_start(volatile u32 *ctl, u32 *physical_filter_ctrl,
>> +u64 ddr_end) {
>> +	setbits_le32(DENALI_CTL_0 + ctl, 0x1);
>> +	while ((readl(DENALI_CTL_132 + ctl) & (1 <<
>MC_INIT_COMPLETE_OFFSET))
>> +	       == 0) {
>> +	}
>> +
>> +	// Disable the BusBlocker in front of the controller AXI slave ports
>> +	volatile u64 *filterreg = (volatile u64 *)physical_filter_ctrl;
>> +
>> +	filterreg[0] = 0x0f00000000000000UL | (ddr_end >> 2); }
>> +
>> +static u64 ddr_phy_fixup(volatile u32 *ddrphyreg) {
>> +	// return bitmask of failed lanes
>> +
>> +	u64 fails     = 0;
>> +	u32 slicebase = 0;
>> +	u32 dq        = 0;
>> +
>> +	// check errata condition
>> +	for (u32 slice = 0; slice < 8; slice++) {
>> +		u32 regbase = slicebase + 34;
>> +
>> +		for (u32 reg = 0; reg < 4; reg++) {
>> +			u32 updownreg = readl(regbase + reg + ddrphyreg);
>> +
>> +			for (u32 bit = 0; bit < 2; bit++) {
>> +				u32 phy_rx_cal_dqn_0_offset;
>> +
>> +				if (bit == 0) {
>> +					phy_rx_cal_dqn_0_offset =
>> +						PHY_RX_CAL_DQ0_0_OFFSET;
>> +				} else {
>> +					phy_rx_cal_dqn_0_offset =
>> +						PHY_RX_CAL_DQ1_0_OFFSET;
>> +				}
>> +
>> +				u32 down = (updownreg >>
>> +					    phy_rx_cal_dqn_0_offset) & 0x3F;
>> +				u32 up   = (updownreg >>
>> +					    (phy_rx_cal_dqn_0_offset + 6)) &
>> +					    0x3F;
>> +
>> +				u8 failc0 = ((down == 0) && (up == 0x3F));
>> +				u8 failc1 = ((up == 0) && (down == 0x3F));
>> +
>> +				// print error message on failure
>> +				if (failc0 || failc1) {
>> +					if (fails == 0)
>> +						printf("DDR error in fixing
>up\n");
>> +
>> +					fails |= (1 << dq);
>> +
>> +					char slicelsc = '0';
>> +					char slicemsc = '0';
>> +
>> +					slicelsc += (dq % 10);
>> +					slicemsc += (dq / 10);
>> +					printf("S ");
>> +					printf("%c", slicemsc);
>> +					printf("%c", slicelsc);
>> +
>> +					if (failc0)
>> +						printf("U");
>> +					else
>> +						printf("D");
>> +
>> +					printf("\n");
>> +				}
>
>Here you've nested 5 times. Can you try to break up all these iterations? At
>least moving some code to external static functions. It is difficult to read these
>3 nested for cycles plus other 2 nested if conditions. And for sure keep declare
>variables at the top.

I think you are right, Will check and update.

>
>> +				dq++;
>> +			}
>> +		}
>> +		slicebase += 128;
>> +	}
>> +	return(0);
>> +}
>> +
>> +static u32 ddr_getdramclass(volatile u32 *ctl) {
>> +	u32 reg = readl(DENALI_CTL_0 + ctl);
>> +
>> +	return ((reg >> DRAM_CLASS_OFFSET) & 0xF); }
>> +
>> +static __maybe_unused int fu540_ddr_setup(struct udevice *dev) {
>> +	struct ddr_info *priv = dev_get_priv(dev);
>> +	struct sifive_dmc_plat *plat = dev_get_platdata(dev);
>> +
>> +	int ret, i;
>> +	u32 physet;
>> +
>> +	volatile u32 *denali_ctl =  &priv->ctl->denali_ctl[0];
>> +	volatile u32 *denali_phy =  &priv->phy->denali_phy[0];
>> +
>> +	ret = dev_read_u32_array(dev, "sifive,sdram-params",
>> +				 (u32 *)&plat->sdram_params,
>> +				 sizeof(plat->sdram_params) / sizeof(u32));
>> +	if (ret) {
>> +		printf("%s: Cannot read sifive,sdram-params %d\n",
>> +		       __func__, ret);
>> +		return ret;
>> +	}
>> +
>> +	struct fu540_sdram_params *params = &plat->sdram_params;
>> +
>> +	sdram_copy_to_reg(&priv->ctl->denali_ctl[0],
>> +			  &params->pctl_regs.denali_ctl[0],
>> +			  sizeof(struct fu540_ddrctl));
>> +
>> +	/* phy reset */
>> +	for (i = DENALI_PHY_1152; i <= DENALI_PHY_1214; i++) {
>> +		physet = params->phy_regs.denali_phy[i];
>> +		priv->phy->denali_phy[i] = physet;
>> +	}
>> +
>> +	for (i = 0; i < DENALI_PHY_1152; i++) {
>> +		physet = params->phy_regs.denali_phy[i];
>> +		priv->phy->denali_phy[i] = physet;
>> +	}
>> +
>> +	/* Disable read interleave DENALI_CTL_120 */
>> +	setbits_le32(DENALI_CTL_120 + denali_ctl,
>> +		     1 << DISABLE_RD_INTERLEAVE_OFFSET);
>> +
>> +	/* Disable optimal read/modify/write logic DENALI_CTL_21 */
>> +	clrbits_le32(DENALI_CTL_21 + denali_ctl, 1 <<
>> +OPTIMAL_RMODW_EN_OFFSET);
>> +
>> +	/* Enable write Leveling DENALI_CTL_170 */
>> +	setbits_le32(DENALI_CTL_170 + denali_ctl, (1 << WRLVL_EN_OFFSET)
>> +		     | (1 << DFI_PHY_WRLELV_MODE_OFFSET));
>> +
>> +	/* Enable read leveling DENALI_CTL_181 and DENALI_CTL_260 */
>> +	setbits_le32(DENALI_CTL_181 + denali_ctl,
>> +		     1 << DFI_PHY_RDLVL_MODE_OFFSET);
>> +	setbits_le32(DENALI_CTL_260 + denali_ctl, 1 << RDLVL_EN_OFFSET);
>> +
>> +	/* Enable read leveling gate DENALI_CTL_260 and DENALI_CTL_182 */
>> +	setbits_le32(DENALI_CTL_260 + denali_ctl, 1 <<
>RDLVL_GATE_EN_OFFSET);
>> +	setbits_le32(DENALI_CTL_182 + denali_ctl,
>> +		     1 << DFI_PHY_RDLVL_GATE_MODE_OFFSET);
>> +
>> +	if (ddr_getdramclass(denali_ctl) == DRAM_CLASS_DDR4) {
>> +		/* Enable vref training DENALI_CTL_184 */
>> +		setbits_le32(DENALI_CTL_184 + denali_ctl, 1 <<
>VREF_EN_OFFSET);
>> +	}
>> +
>> +	/* Mask off leveling completion interrupt DENALI_CTL_136 */
>> +	setbits_le32(DENALI_CTL_136 + denali_ctl,
>> +		     1 << LEVELING_OPERATION_COMPLETED_OFFSET);
>> +
>> +	/* Mask off MC init complete interrupt DENALI_CTL_136 */
>> +	setbits_le32(DENALI_CTL_136 + denali_ctl, 1 <<
>> +MC_INIT_COMPLETE_OFFSET);
>> +
>> +	/* Mask off out of range interrupts DENALI_CTL_136 */
>> +	setbits_le32(DENALI_CTL_136 + denali_ctl, (1 <<
>OUT_OF_RANGE_OFFSET)
>> +		     | (1 << MULTIPLE_OUT_OF_RANGE_OFFSET));
>> +
>> +	/* set up range protection */
>> +	ddr_setuprangeprotection(denali_ctl, DDR_MEM_SIZE);
>> +
>> +	/* Mask off port command error interrupt DENALI_CTL_136 */
>> +	setbits_le32(DENALI_CTL_136 + denali_ctl,
>> +		     1 << PORT_COMMAND_CHANNEL_ERROR_OFFSET);
>> +
>> +	const u64 ddr_size = DDR_MEM_SIZE;
>> +	const u64 ddr_end = PAYLOAD_DEST + ddr_size;
>> +
>> +	ddr_start(denali_ctl, priv->physical_filter_ctrl, ddr_end);
>> +
>> +	ddr_phy_fixup(denali_phy);
>> +
>> +	/* check size */
>> +	priv->info.size = get_ram_size((long *)priv->info.base,
>> +				       DDR_MEM_SIZE);
>> +
>> +	printf("priv->info.size = %lx\n", priv->info.size);
>> +	debug("%s : %lx\n", __func__, priv->info.size);
>> +
>> +	/* check memory access for all memory */
>> +
>> +	if (priv->info.size != DDR_MEM_SIZE) {
>> +		printf("DDR invalid size : 0x%lx, expected 0x%lx\n",
>> +		       priv->info.size, DDR_MEM_SIZE);
>> +		return -EINVAL;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int fu540_ddr_probe(struct udevice *dev) {
>> +	struct ddr_info *priv = dev_get_priv(dev);
>> +
>> +#if defined(CONFIG_SPL_BUILD)
>> +	struct regmap *map;
>> +	int ret;
>> +
>> +	debug("FU540 DDR probe\n");
>> +	priv->dev = dev;
>> +
>> +	ret = regmap_init_mem(dev_ofnode(dev), &map);
>> +	if (ret)
>> +		return ret;
>> +
>> +	priv->ctl = regmap_get_range(map, 0);
>> +	priv->phy = regmap_get_range(map, 1);
>> +	priv->physical_filter_ctrl = regmap_get_range(map, 2);
>> +
>> +	priv->info.base = CONFIG_SYS_SDRAM_BASE;
>> +
>> +	priv->info.size = 0;
>> +	return fu540_ddr_setup(dev);
>> +#else
>> +	priv->info.base = CONFIG_SYS_SDRAM_BASE;
>> +	priv->info.size = DDR_MEM_SIZE;
>> +#endif
>> +	return 0;
>> +}
>> +
>> +static int fu540_ddr_get_info(struct udevice *dev, struct ram_info
>> +*info) {
>> +	struct ddr_info *priv = dev_get_priv(dev);
>> +
>> +	*info = priv->info;
>> +
>> +	return 0;
>> +}
>> +
>> +static struct ram_ops fu540_ddr_ops = {
>> +	.get_info = fu540_ddr_get_info,
>> +};
>> +
>> +static const struct udevice_id fu540_ddr_ids[] = {
>> +	{ .compatible = "sifive,fu540-ddr" },
>> +	{ }
>> +};
>> +
>> +U_BOOT_DRIVER(fu540_ddr) = {
>> +	.name = "fu540_ddr",
>> +	.id = UCLASS_RAM,
>> +	.of_match = fu540_ddr_ids,
>> +	.ops = &fu540_ddr_ops,
>> +	.probe = fu540_ddr_probe,
>> +	.priv_auto_alloc_size = sizeof(struct ddr_info),
>> +	.platdata_auto_alloc_size = sizeof(struct sifive_dmc_plat), };
>> diff --git a/drivers/ram/sifive/sdram_fu540.h
>> b/drivers/ram/sifive/sdram_fu540.h
>> new file mode 100644
>> index 0000000000..09693a038e
>> --- /dev/null
>> +++ b/drivers/ram/sifive/sdram_fu540.h
>> @@ -0,0 +1,94 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
>> +/*
>> + * Copyright (C) 2020, SiFive, Inc
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + */
>> +
>> +#define DENALI_CTL_0	0
>> +#define DENALI_CTL_21	21
>> +#define DENALI_CTL_120	120
>> +#define DENALI_CTL_132	132
>> +#define DENALI_CTL_136	136
>> +#define DENALI_CTL_170	170
>> +#define DENALI_CTL_181	181
>> +#define DENALI_CTL_182	182
>> +#define DENALI_CTL_184	184
>> +#define DENALI_CTL_208	208
>> +#define DENALI_CTL_209	209
>> +#define DENALI_CTL_210	210
>> +#define DENALI_CTL_212	212
>> +#define DENALI_CTL_214	214
>> +#define DENALI_CTL_216	216
>> +#define DENALI_CTL_224	224
>> +#define DENALI_CTL_225	225
>> +#define DENALI_CTL_260	260
>> +
>> +#define DENALI_PHY_1152	1152
>> +#define DENALI_PHY_1214	1214
>> +
>> +#define PAYLOAD_DEST	0x80000000
>> +#define DDR_MEM_SIZE	(8UL * 1024UL * 1024UL * 1024UL)
>> +
>> +#define DRAM_CLASS_OFFSET                   8
>> +#define DRAM_CLASS_DDR4                     0xA
>> +#define OPTIMAL_RMODW_EN_OFFSET             0
>> +#define DISABLE_RD_INTERLEAVE_OFFSET        16
>> +#define OUT_OF_RANGE_OFFSET                 1
>> +#define MULTIPLE_OUT_OF_RANGE_OFFSET        2
>> +#define PORT_COMMAND_CHANNEL_ERROR_OFFSET   7
>> +#define MC_INIT_COMPLETE_OFFSET             8
>> +#define LEVELING_OPERATION_COMPLETED_OFFSET 22
>> +#define DFI_PHY_WRLELV_MODE_OFFSET          24
>> +#define DFI_PHY_RDLVL_MODE_OFFSET           24
>> +#define DFI_PHY_RDLVL_GATE_MODE_OFFSET      0
>> +#define VREF_EN_OFFSET                      24
>> +#define PORT_ADDR_PROTECTION_EN_OFFSET      0
>> +#define AXI0_ADDRESS_RANGE_ENABLE           8
>> +#define AXI0_RANGE_PROT_BITS_0_OFFSET       24
>> +#define RDLVL_EN_OFFSET                     16
>> +#define RDLVL_GATE_EN_OFFSET                24
>> +#define WRLVL_EN_OFFSET                     0
>> +
>> +#define PHY_RX_CAL_DQ0_0_OFFSET             0
>> +#define PHY_RX_CAL_DQ1_0_OFFSET             16
>> +
>> +struct fu540_ddrctl {
>> +	volatile u32 denali_ctl[265];
>> +};
>> +
>> +struct fu540_ddrphy {
>> +	volatile u32 denali_phy[1215];
>> +};
>> +
>> +struct fu540_sdram_params {
>> +	struct fu540_ddrctl pctl_regs;
>> +	struct fu540_ddrphy phy_regs;
>> +};
>> +
>> +struct sifive_dmc_plat {
>> +#if CONFIG_IS_ENABLED(OF_PLATDATA)
>> +	struct dtd_sifive_fu540_dmc dtplat;
>> +#else
>> +	struct fu540_sdram_params sdram_params; #endif };
>> +
>> +/**
>> + * struct ddr_info
>> + *
>> + * @dev				: pointer for the device
>> + * @info			: UCLASS RAM information
>> + * @ctl				: DDR controleur base address
>> + * @phy				: DDR PHY base address
>> + * @ctrl			: DDR control base address
>> + * @physical_filter_ctrl	: DDR physical filter control base address
>> + */
>> +struct ddr_info {
>> +	struct udevice *dev;
>> +	struct ram_info info;
>> +	struct fu540_ddrctl *ctl;
>> +	struct fu540_ddrphy *phy;
>> +	u32 *physical_filter_ctrl;
>> +};
>>
>
>IMHO I would keep all these structs and define in driver's .c file, I mean you
>should keep them private if not used outside. And then add to dt-bindings the
>define needed by dts files.

This structures are already private in driver and will move them to driver's .c file.

>
>Best regards
>--
>Giulio Benetti
>Benetti Engineering sas

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 14/14] doc: update FU540 RISC-V documentation
  2020-03-13  9:22   ` Bin Meng
@ 2020-03-17 14:31     ` Pragnesh Patel
  0 siblings, 0 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-17 14:31 UTC (permalink / raw)
  To: u-boot



Hi Bin,

>-----Original Message-----
>From: Bin Meng <bmeng.cn@gmail.com>
>Sent: 13 March 2020 14:52
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Atish Patra
><atish.patra@wdc.com>; Palmer Dabbelt <palmerdabbelt@google.com>; Paul
>Walmsley <paul.walmsley@sifive.com>; Jagan Teki
><jagan@amarulasolutions.com>; Troy Benjegerdes
><troy.benjegerdes@sifive.com>; Anup Patel <anup.patel@wdc.com>; Sagar
>Kadam <sagar.kadam@sifive.com>; Rick Chen <rick@andestech.com>; Joe
>Hershberger <joe.hershberger@ni.com>
>Subject: Re: [PATCH v5 14/14] doc: update FU540 RISC-V documentation
>
>On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
><pragnesh.patel@sifive.com> wrote:
>>
>> Add descriptions about U-Boot SPL feature and how to build and run.
>>
>> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
>> ---
>>  doc/board/sifive/fu540.rst | 409
>> ++++++++++++++++++++++++++++++++++---
>>  1 file changed, 385 insertions(+), 24 deletions(-)
>>
>> diff --git a/doc/board/sifive/fu540.rst b/doc/board/sifive/fu540.rst
>> index 3937222c6c..e5414f4eef 100644
>> --- a/doc/board/sifive/fu540.rst
>> +++ b/doc/board/sifive/fu540.rst
>> @@ -42,8 +42,60 @@ Building
>>     export ARCH=riscv
>>     export CROSS_COMPILE=<riscv64 toolchain prefix>
>>
>> -3. make sifive_fu540_defconfig
>> -4. make
>> +User can use FSBL or u-boot-spl as a 1st stage bootloader.
>> +
>> +1) Use FSBL as a 1st stage bootloader
>
>The 1st stage. Please fix this globally in this file.

Will update in v6.

>
>> +
>> +.. code-block:: console
>> +
>> +       git clone https://github.com/sifive/freedom-u540-c000-bootloader.git
>> +       cd freedom-u540-c000-bootloader
>> +       make
>> +
>> +       cd <u-boot-dir>
>> +       make sifive_fu540_defconfig
>> +       make
>> +
>> +       git clone https://github.com/riscv/opensbi.git
>> +       cd opensbi
>> +       make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=<path to
>> + u-boot.bin>
>
>It should be u-boot-dtb.bin

u-boot.bin and u-boot-dtb.bin are of same size.

For CONFIG_OF_SEPARATE (doc/README.fdt-control)
U-Boot creates u-boot-dtb.bin which does the above step for you also. Resulting
u-boot.bin is a copy of u-boot-dtb.bin in this case.

For user's understanding, will use "u-boot-dtb.bin" and update in v6, thanks for the review.

>
>> +
>> +This will generate a
>> +fw_payload.bin(build/platform/sifive/fu540/firmware/fw_payload.bin)
>
>nits: needs one space after fw_payload.bin

Will do.

>
>> +
>> +u-boot.bin is used as a payload of the OpenSBI FW_PAYLOAD firmware.
>
>u-boot-dtb.bin

Will do.

>
>> +
>> +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)
>> +
>> +2) Use u-boot-spl as a 1st stage bootloader
>> +
>> +Before building U-Boot SPL, OpenSBI must be build first. OpenSBI can
>> +be
>
>must be built

Will update in v6.

>
>> +cloned and build for FU540 as below:
>
>built

Will do.

>
>> +
>> +.. code-block:: console
>> +
>> +       git clone https://github.com/riscv/opensbi.git
>> +       cd opensbi
>> +       make PLATFORM=sifive/fu540
>> +
>> +Copy OpenSBI FW_DYNAMIC image
>> +(build/platform/sifive/fu540/firmware/fw_dynamic.bin)
>> +into U-Boot root directory
>> +
>> +.. code-block:: console
>> +
>> +       cp build/platform/sifive/fu540/firmware/fw_dynamic.bin
>> + <u-boot-dir>
>> +
>> +Now build the u-boot-spl and u-boot proper
>
>nits: U-Boot proper

Will do.

>
>> +
>> +.. code-block:: console
>> +
>> +       cd <u-boot-dir>
>> +       make sifive_fu540_defconfig
>> +       make
>> +
>> +This will generate spl/u-boot-spl.bin and FIT image(u-boot.itb)
>
>need one space after image

Will do.

>
>> +
>>
>>  Flashing
>>  --------
>> @@ -53,28 +105,55 @@ The current U-Boot port is supported in S-mode
>only and loaded from DRAM.
>>  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.
>>
>> -Currently, the u-boot.bin is used as a payload of the OpenSBI
>> FW_PAYLOAD -firmware. We need to compile OpenSBI with below
>command:
>> +1) Use FSBL as a 1st stage bootloader
>> +
>> +ZSBL loads the FSBL(fsbl.bin) from a partition with GUID type
>
>need one space after FSBL

Will do.

>
>> +5B193300-FC78-40CD-8002-E86C45580B47
>> +
>> +FSBL loads the fw_payload.bin from a partition with GUID type
>> +2E54B353-1271-4842-806F-E436D6AF6985
>> +
>> +Once the prior stage firmware/bootloader binary is generated, it
>> +should be copied to the first partition of the sdcard.
>>
>>  .. code-block:: none
>>
>> -make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=<path to u-boot-
>dtb.bin>
>> +     sudo dd if=fsbl.bin of=/dev/disk2s4 bs=1024
>> +     sudo dd if=fw_payload.bin of=/dev/disk2s1 bs=1024
>>
>> -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)
>> +Assuming that /dev/disk2s4 partition is of GUID type
>> +5B193300-FC78-40CD-8002-E86C45580B47 and /dev/disk2s1 partition is of
>> +GUID type 2E54B353-1271-4842-806F-E436D6AF6985
>> +
>> +2) Use u-boot-spl as a 1st stage bootloader
>> +
>> +ZSBL loads the U-boot SPL(u-boot-spl.bin) from a partition with GUID
>> +type
>
>U-Boot, and need one space after SPL

Will do.

>
>> +5B193300-FC78-40CD-8002-E86C45580B47
>> +
>> +U-boot SPL expects a u-boot FIT image(u-boot.itb) from 1st
>> +partition(/dev/sdc1)
>
>U-Boot, and need one space after image

Will do.

>
>> +of SD card irrespective of GUID
>> +
>> +FIT image(u-boot.itb) is a combination of fw_dynamic.bin,
>> +u-boot-nodtb.bin and
>
>need one space after image

Will do.

>
>> +device tree blob(hifive-unleashed-a00.dtb)
>
>need one space after blob

Will update.

>
>>
>>  Once the prior stage firmware/bootloader binary is generated, it
>> should be  copied to the first partition of the sdcard.
>>
>>  .. code-block:: none
>>
>> -    sudo dd if=<prior_stage_firmware_binary> of=/dev/disk2s1 bs=1024
>> +    sudo dd if=spl/u-boot-spl.bin of=/dev/disk2s4 bs=1024
>> +    sudo dd if=u-boot.itb of=/dev/disk2s1 bs=1024
>> +
>> +Assuming that /dev/disk2s4 partition is of GUID type
>> +5B193300-FC78-40CD-8002-E86C45580B47 and /dev/disk2s1 is of any GUID
>> +type raw partition.
>>
>>  Booting
>>  -------
>>  Once you plugin the sdcard and power up, you should see the U-Boot
>prompt.
>>
>> +1) Use FSBL as a 1st stage bootloader
>> +
>>  Sample boot log from HiFive Unleashed board
>>  -------------------------------------------
>>
>> @@ -145,19 +224,6 @@ load uImage.
>>     Filename '/sifive/fu540/Image'.
>>     Load address: 0x84000000
>>     Loading:
>#################################################################
>> -
>#################################################################
>> -
>#################################################################
>> -
>#################################################################
>> -
>#################################################################
>> -
>#################################################################
>> -
>#################################################################
>> -
>#################################################################
>> -
>#################################################################
>> -
>#################################################################
>> -
>#################################################################
>> -
>#################################################################
>> -
>#################################################################
>> -
>#################################################################
>>
>#################################################################
>>
>#################################################################
>>
>>
>#################################################################
>> @@ -184,8 +250,6 @@ load uImage.
>>     Filename '/sifive/fu540/uRamdisk'.
>>     Load address: 0x88300000
>>     Loading:
>#################################################################
>> -
>#################################################################
>> -
>#################################################################
>>
>#################################################################
>>
>#################################################################
>>
>>
>#################################################################
>> @@ -363,3 +427,300 @@ load uImage.
>>
>>     Please press Enter to activate this console.
>>     / #
>> +
>> +
>> +2) Use u-boot-spl as a 1st stage bootloader
>> +
>> +The U-Boot SPL will boot in M mode and load the FIT image which
>> +include OpenSBI and U-Boot proper images. After loading progress, it
>> +will jump to OpenSBI first and then U-Boot proper which will run in S mode.
>> +
>> +Sample boot log from HiFive Unleashed board
>> +-------------------------------------------
>> +
>> +.. code-block:: none
>> +
>> +   U-Boot SPL 2020.04-rc1-00212-g375b0a2dad-dirty (Feb 13 2020 - 17:45:44
>+0530)
>> +   Trying to boot from MMC1
>> +
>> +
>> +   U-Boot 2020.04-rc1-00212-g375b0a2dad-dirty (Feb 13 2020 - 17:45:44
>> + +0530)
>> +
>> +   CPU:   rv64imafdc
>> +   Model: SiFive HiFive Unleashed A00
>> +   DRAM:  8 GiB
>> +   MMC:   spi at 10050000:mmc at 0: 0
>> +   In:    serial at 10010000
>> +   Out:   serial at 10010000
>> +   Err:   serial at 10010000
>> +   Board serial number should not be 0 !!
>
>Something is wrong with the OTP driver?

No, I tried to overwrite my Board serial number that's why this happened.
It works well on other HiFive Unleashed Board.

>
>> +   Net:
>> +   Warning: ethernet at 10090000 (eth0) using random MAC address -
>92:79:17:2d:7b:b7
>> +   eth0: ethernet at 10090000
>> +   Hit any key to stop autoboot:  0
>> +   => version
>> +   U-Boot 2020.04-rc1-00212-g375b0a2dad-dirty (Feb 13 2020 - 17:45:44
>> + +0530)
>> +
>> +   riscv64-unknown-linux-gnu-gcc (crosstool-NG 1.24.0.37-3f461da) 9.2.0
>> +   GNU ld (crosstool-NG 1.24.0.37-3f461da) 2.32
>> +   => mmc info
>> +   Device: spi at 10050000:mmc at 0
>> +   Manufacturer ID: 3
>> +   OEM: 5344
>> +   Name: SC16G
>> +   Bus Speed: 20000000
>> +   Mode: SD Legacy
>> +   Rd Block Len: 512
>> +   SD version 2.0
>> +   High Capacity: Yes
>> +   Capacity: 14.8 GiB
>> +   Bus Width: 1-bit
>> +   Erase Group Size: 512 Bytes
>> +   => mmc part
>> +
>> +   Partition Map for MMC device 0  --   Partition Type: EFI
>> +
>> +   Part    Start LBA       End LBA         Name
>> +   Attributes
>> +   Type GUID
>> +   Partition GUID
>> +   1     0x00000800      0x000107ff      "SiFive bare-metal (or stage 2 loader"
>> +   attrs:  0x0000000000000000
>> +   type:   2e54b353-1271-4842-806f-e436d6af6985
>> +   guid:   3c9eabe1-b16b-4a2e-9b4e-f065c740bb86
>> +   2     0x00040800      0x00ecdfde      "Linux filesystem"
>> +   attrs:  0x0000000000000000
>> +   type:   0fc63daf-8483-4772-8e79-3d69d8477de4
>> +   guid:   ad9309ff-d204-42f0-9f99-f3275a83f565
>> +
>> +Now you can configure your networking, tftp server and use tftp boot
>> +method to load uImage.
>> +
>> +.. code-block:: none
>> +
>> +   => setenv serverip 172.16.35.74
>> +   => setenv ipaddr 172.16.35.40
>> +   => tftpboot 0x83000000 fit.itb
>> +   ethernet at 10090000: PHY present at 0
>> +   ethernet at 10090000: Starting autonegotiation...
>> +   ethernet at 10090000: Autonegotiation complete
>> +   ethernet at 10090000: link up, 100Mbps full-duplex (lpa: 0x41e1)
>> +   Using ethernet at 10090000 device
>> +   TFTP from server 172.16.35.74; our IP address is 172.16.35.40
>> +   Filename 'fit.itb'.
>> +   Load address: 0x83000000
>> +   Loading:
>#################################################################
>> +
>#################################################################
>> +
>#################################################################
>> +
>#################################################################
>> +
>#################################################################
>> +
>#################################################################
>> +
>#################################################################
>> +
>#################################################################
>> +
>#################################################################
>> +
>#################################################################
>> +
>#################################################################
>> +
>#################################################################
>> +
>#################################################################
>> +
>#################################################################
>> +
>#################################################################
>> +
>#################################################################
>> +
>#################################################################
>> +
>#################################################################
>> +
>################################################################
>> +   ###################################
>> +   878.9 KiB/s
>> +   done
>> +   Bytes transferred = 13823823 (d2ef4f hex)
>> +   => bootm 0x83000000
>> +   ## Loading kernel from FIT Image at 83000000 ...
>> +   Using 'config-1' configuration
>> +   Trying 'kernel at 1' kernel subimage
>> +   Description:  Linux kernel
>> +   Type:         Kernel Image
>> +   Compression:  uncompressed
>> +   Data Start:   0x830000d8
>> +   Data Size:    9247260 Bytes = 8.8 MiB
>> +   Architecture: RISC-V
>> +   OS:           Linux
>> +   Load Address: 0x80200000
>> +   Entry Point:  0x80200000
>> +   Verifying Hash Integrity ... OK
>> +   ## Loading ramdisk from FIT Image at 83000000 ...
>> +   Using 'config-1' configuration
>> +   Trying 'ramdisk at 1' ramdisk subimage
>> +   Description:  ramdisk
>> +   Type:         RAMDisk Image
>> +   Compression:  gzip compressed
>> +   Data Start:   0x838d3378
>> +   Data Size:    4568674 Bytes = 4.4 MiB
>> +   Architecture: RISC-V
>> +   OS:           Linux
>> +   Load Address: 0x82000000
>> +   Entry Point:  unavailable
>> +   Verifying Hash Integrity ... OK
>> +   Loading ramdisk from 0x838d3378 to 0x82000000
>> +   WARNING: 'compression' nodes for ramdisks are deprecated, please fix
>your .its file!
>> +   ## Loading fdt from FIT Image at 83000000 ...
>> +   Using 'config-1' configuration
>> +   Trying 'fdt at 1' fdt subimage
>> +   Description:  unavailable
>> +   Type:         Flat Device Tree
>> +   Compression:  uncompressed
>> +   Data Start:   0x838d1b80
>> +   Data Size:    6023 Bytes = 5.9 KiB
>> +   Architecture: RISC-V
>> +   Verifying Hash Integrity ... OK
>> +   Booting using the fdt blob at 0x838d1b80
>> +   Loading Kernel Image
>> +   Using Device Tree in place at 00000000838d1b80, end
>> + 00000000838d6306
>> +
>> +   Starting kernel ...
>> +
>> +   [    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
>> +   [    0.000000] Linux version 5.3.0-13236-g97f9a3c4eee5
>(pragneshp at sachinj2-OptiPlex-7010) (gcc version 8.2.0 (Buildroot 2018.11-
>rc2-00003-ga0787e9
>> +   [    0.000000] earlycon: sifive0 at MMIO 0x0000000010010000 (options '')
>> +   [    0.000000] printk: bootconsole [sifive0] enabled
>> +   [    0.000000] Initial ramdisk at: 0x(____ptrval____) (4568674 bytes)
>> +   [    0.000000] Zone ranges:
>> +   [    0.000000]   DMA32    [mem 0x0000000080200000-0x00000000ffffffff]
>> +   [    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 is not available
>> +   [    0.000000] CPU with hartid=0 is not available
>> +   [    0.000000] elf_hwcap is 0x112d
>> +   [    0.000000] percpu: Embedded 17 pages/cpu s30680 r8192 d30760
>u69632
>> +   [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 2067975
>> +   [    0.000000] Kernel command line: earlycon=sifive,0x10010000
>console=ttySIF0,115200
>> +   [    0.000000] Dentry cache hash table entries: 1048576 (order: 11,
>8388608 bytes, linear)
>> +   [    0.000000] Inode-cache hash table entries: 524288 (order: 10, 4194304
>bytes, linear)
>> +   [    0.000000] Sorting __ex_table...
>> +   [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
>> +   [    0.000000] Memory: 8179828K/8386560K available (6081K kernel code,
>388K rwdata, 2025K rodata, 209K init, 307K bss, 206732K reserved, 0K cma-r)
>> +   [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4,
>Nodes=1
>> +   [    0.000000] rcu: Hierarchical RCU implementation.
>> +   [    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 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 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.000006] sched_clock: 64 bits at 1000kHz, resolution 1000ns, wraps
>every 2199023255500ns
>> +   [    0.008467] Console: colour dummy device 80x25
>> +   [    0.012819] Calibrating delay loop (skipped), value calculated using
>timer frequency.. 2.00 BogoMIPS (lpj=4000)
>> +   [    0.022844] pid_max: default: 32768 minimum: 301
>> +   [    0.027915] Mount-cache hash table entries: 16384 (order: 5, 131072
>bytes, linear)
>> +   [    0.035332] Mountpoint-cache hash table entries: 16384 (order: 5,
>131072 bytes, linear)
>> +   [    0.044791] rcu: Hierarchical SRCU implementation.
>> +   [    0.049255] smp: Bringing up secondary CPUs ...
>> +   [    0.055034] smp: Brought up 1 node, 4 CPUs
>> +   [    0.059664] devtmpfs: initialized
>> +   [    0.063818] random: get_random_u32 called from
>bucket_table_alloc.isra.29+0x4e/0x160 with crng_init=0
>> +   [    0.072588] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff,
>max_idle_ns: 7645041785100000 ns
>> +   [    0.082000] futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
>> +   [    0.089513] NET: Registered protocol family 16
>> +   [    0.105911] vgaarb: loaded
>> +   [    0.108166] SCSI subsystem initialized
>> +   [    0.111946] usbcore: registered new interface driver usbfs
>> +   [    0.117105] usbcore: registered new interface driver hub
>> +   [    0.122486] usbcore: registered new device driver usb
>> +   [    0.128073] clocksource: Switched to clocksource riscv_clocksource
>> +   [    0.140277] NET: Registered protocol family 2
>> +   [    0.144449] tcp_listen_portaddr_hash hash table entries: 4096 (order: 4,
>65536 bytes, linear)
>> +   [    0.152620] TCP established hash table entries: 65536 (order: 7, 524288
>bytes, linear)
>> +   [    0.162238] TCP bind hash table entries: 65536 (order: 8, 1048576 bytes,
>linear)
>> +   [    0.172159] TCP: Hash tables configured (established 65536 bind 65536)
>> +   [    0.178343] UDP hash table entries: 4096 (order: 5, 131072 bytes, linear)
>> +   [    0.185140] UDP-Lite hash table entries: 4096 (order: 5, 131072 bytes,
>linear)
>> +   [    0.192553] NET: Registered protocol family 1
>> +   [    0.196752] RPC: Registered named UNIX socket transport module.
>> +   [    0.202145] RPC: Registered udp transport module.
>> +   [    0.206828] RPC: Registered tcp transport module.
>> +   [    0.211512] RPC: Registered tcp NFSv4.1 backchannel transport module.
>> +   [    0.217939] PCI: CLS 0 bytes, default 64
>> +   [    0.222139] Unpacking initramfs...
>> +   [    0.578803] Freeing initrd memory: 4460K
>> +   [    0.582972] workingset: timestamp_bits=62 max_order=21
>bucket_order=0
>> +   [    0.596643] NFS: Registering the id_resolver key type
>> +   [    0.600950] Key type id_resolver registered
>> +   [    0.605134] Key type id_legacy registered
>> +   [    0.609090] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
>> +   [    0.615928] 9p: Installing v9fs 9p2000 file system support
>> +   [    0.621581] NET: Registered protocol family 38
>> +   [    0.625700] Block layer SCSI generic (bsg) driver version 0.4 loaded
>(major 253)
>> +   [    0.633051] io scheduler mq-deadline registered
>> +   [    0.637559] io scheduler kyber registered
>> +   [    0.685592] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
>> +   [    0.692184] 10010000.serial: ttySIF0 at MMIO 0x10010000 (irq = 4,
>base_baud = 0) is a SiFive UART v0
>> +   [    0.700566] printk: console [ttySIF0] enabled
>> +   [    0.700566] printk: console [ttySIF0] enabled
>> +   [    0.709228] printk: bootconsole [sifive0] disabled
>> +   [    0.709228] printk: bootconsole [sifive0] disabled
>> +   [    0.719030] 10011000.serial: ttySIF1 at MMIO 0x10011000 (irq = 1,
>base_baud = 0) is a SiFive UART v0
>> +   [    0.728364] [drm] radeon kernel modesetting enabled.
>> +   [    0.745292] loop: module loaded
>> +   [    0.748208] sifive_spi 10040000.spi: mapped; irq=3, cs=1
>> +   [    0.753490] sifive_spi 10050000.spi: mapped; irq=5, cs=1
>> +   [    0.758811] libphy: Fixed MDIO Bus: probed
>> +   [    0.762886] macb 10090000.ethernet: Registered clk switch 'sifive-
>gemgxl-mgmt'
>> +   [    0.769643] macb: GEM doesn't support hardware ptp.
>> +   [    0.774532] libphy: MACB_mii_bus: probed
>> +   [    0.940349] Microsemi VSC8541 SyncE 10090000.ethernet-ffffffff:00:
>attached PHY driver [Microsemi VSC8541 SyncE]
>(mii_bus:phy_addr=10090000.et)
>> +   [    0.954893] macb 10090000.ethernet eth0: Cadence GEM rev
>0x10070109 at 0x10090000 irq 6 (92:79:17:2d:7b:b7)
>> +   [    0.964698] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
>> +   [    0.970417] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
>> +   [    0.976410] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
>> +   [    0.982832] ehci-pci: EHCI PCI platform driver
>> +   [    0.987288] ehci-platform: EHCI generic platform driver
>> +   [    0.992547] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
>> +   [    0.998646] ohci-pci: OHCI PCI platform driver
>> +   [    1.003092] ohci-platform: OHCI generic platform driver
>> +   [    1.008557] usbcore: registered new interface driver uas
>> +   [    1.013621] usbcore: registered new interface driver usb-storage
>> +   [    1.019695] mousedev: PS/2 mouse device common for all mice
>> +   [    1.050569] mmc_spi spi1.0: SD/MMC host mmc0, no DMA, no WP, no
>poweroff, cd polling
>> +   [    1.057714] usbcore: registered new interface driver usbhid
>> +   [    1.063098] usbhid: USB HID core driver
>> +   [    1.067805] NET: Registered protocol family 10
>> +   [    1.072421] Segment Routing with IPv6
>> +   [    1.075367] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
>> +   [    1.081745] NET: Registered protocol family 17
>> +   [    1.085867] 9pnet: Installing 9P2000 support
>> +   [    1.089951] Key type dns_resolver registered
>> +   [    1.096367] Freeing unused kernel memory: 208K
>> +   [    1.100023] This architecture does not have kernel memory protection.
>> +   [    1.106468] Run /init as init process
>> +   Starting syslogd: OK
>> +   Starting klogd: OK
>> +   Starting mdev...
>> +   /etc/init.d/S10mdev: line 9: can't create /proc/sys/kernel/hotplug:
>nonexistent directory
>> +   [    1.167972] mmc0: host does not support reading read-only switch,
>assuming write-enable
>> +   [    1.175224] mmc0: new SDHC card on SPI
>> +   [    1.180428] mmcblk0: mmc0:0000 SC16G 14.8 GiB
>> +   [    1.214935]  mmcblk0: p1 p2 p4
>> +   modprobe: can't change directory to '/lib/modules': No such file or
>directory
>> +   Initializing random number generator... [    1.664435] random: dd:
>uninitialized urandom read (512 bytes read)
>> +   done.
>> +   Starting network: udhcpc: started, v1.29.3
>> +   udhcpc: sending discover
>> +   [    3.756700] macb 10090000.ethernet eth0: link up (100/Full)
>> +   [    3.761515] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes
>ready
>> +   udhcpc: sending discover
>> +   udhcpc: sending select for 172.16.35.4
>> +   udhcpc: lease of 172.16.35.4 obtained, lease time 3600
>> +   deleting routers
>> +   adding dns 172.16.34.75
>> +   adding dns 172.16.24.25
>> +   OK
>> +   Starting dropbear sshd: [    4.893179] random: dropbear: uninitialized
>urandom read (32 bytes read)
>> +   OK
>> +
>> +   Welcome to Buildroot
>> +   buildroot login: root
>> +   Password:
>> +   #
>
>Regards,
>Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 11/14] configs: fu540: Add config options for U-boot SPL
  2020-03-13  8:48   ` Bin Meng
@ 2020-03-17 14:45     ` Pragnesh Patel
  0 siblings, 0 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-17 14:45 UTC (permalink / raw)
  To: u-boot

Hi Bin,

>-----Original Message-----
>From: Bin Meng <bmeng.cn@gmail.com>
>Sent: 13 March 2020 14:19
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Atish Patra
><atish.patra@wdc.com>; Palmer Dabbelt <palmerdabbelt@google.com>; Paul
>Walmsley <paul.walmsley@sifive.com>; Jagan Teki
><jagan@amarulasolutions.com>; Troy Benjegerdes
><troy.benjegerdes@sifive.com>; Anup Patel <anup.patel@wdc.com>; Sagar
>Kadam <sagar.kadam@sifive.com>; Rick Chen <rick@andestech.com>; Palmer
>Dabbelt <palmer@dabbelt.com>
>Subject: Re: [PATCH v5 11/14] configs: fu540: Add config options for U-boot
>SPL
>
>On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
><pragnesh.patel@sifive.com> wrote:
>>
>> With sifive_fu540_defconfig:
>
>Please use "U-Boot" in the commit title

Will update.

>
>>
>> User can use FSBL or u-boot-spl.bin anyone at a time.
>>
>> For FSBL,
>> fsbl->fw_payload.bin(opensbi+u-boot)
>>
>> For u-boot-spl.bin,
>> u-boot-spl.bin->FIT image(opensbi+u-boot+dtb)
>>
>> U-Boot SPL will be loaded by ZSBL from SD card (replace fsbl.bin with
>> u-boot-spl.bin) and runs in L2 LIM in machine mode and then load FIT
>> image u-boot.itb from 1st partition of SD card (replace fw_payload.bin
>> with u-boot.itb) into RAM.
>>
>> U-boot SPL expects u-boot.itb FIT image in the 1st partition of SD
>
>U-Boot

Will update

>
>> card irrespective of GUID
>>
>> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
>> ---
>>  configs/sifive_fu540_defconfig | 11 +++++++++++
>>  1 file changed, 11 insertions(+)
>>
>> diff --git a/configs/sifive_fu540_defconfig
>> b/configs/sifive_fu540_defconfig index 6d61e6c960..1b33c81be4 100644
>> --- a/configs/sifive_fu540_defconfig
>> +++ b/configs/sifive_fu540_defconfig
>> @@ -12,3 +12,14 @@ CONFIG_DISPLAY_BOARDINFO=y
>> CONFIG_DEFAULT_DEVICE_TREE="hifive-unleashed-a00"
>>  CONFIG_SYS_RELOC_GD_ENV_ADDR=y
>>  CONFIG_DM_MTD=y
>> +CONFIG_SPL_SEPARATE_BSS=y
>> +CONFIG_SPL=y
>> +CONFIG_SPL_MMC_SUPPORT=y
>> +CONFIG_SPL_SPI_SUPPORT=y
>> +CONFIG_SPL_YMODEM_SUPPORT=y
>> +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y
>> +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=1
>> +CONFIG_SPL_CLK=y
>> +CONFIG_SPL_PAYLOAD="u-boot.itb"
>> +CONFIG_SYS_MALLOC_F_LEN=0x3000
>> +CONFIG_SIFIVE_FU540_DDR=y
>> --
>
>Please make sure this is exactly the same as:
>
>$ make sifive_fu540_defconfig
>$ make savedefconfig
>
>Compare the generated defconfig with sifive_fu540_defconfig

There is only 1 difference.
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=1

CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION is 1 by default, so remove it from configs/sifive_fu540_defconfig

>
>Regards,
>Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 07/14] sifive: dts: fu540: Add DDR controller and phy register settings
  2020-03-13  7:51   ` Bin Meng
@ 2020-03-17 15:35     ` Pragnesh Patel
  0 siblings, 0 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-17 15:35 UTC (permalink / raw)
  To: u-boot

Hi Bin,

>-----Original Message-----
>From: Bin Meng <bmeng.cn@gmail.com>
>Sent: 13 March 2020 13:21
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Atish Patra
><atish.patra@wdc.com>; Palmer Dabbelt <palmerdabbelt@google.com>; Paul
>Walmsley <paul.walmsley@sifive.com>; Jagan Teki
><jagan@amarulasolutions.com>; Troy Benjegerdes
><troy.benjegerdes@sifive.com>; Anup Patel <anup.patel@wdc.com>; Sagar
>Kadam <sagar.kadam@sifive.com>; Rick Chen <rick@andestech.com>
>Subject: Re: [PATCH v5 07/14] sifive: dts: fu540: Add DDR controller and phy
>register settings
>
>On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
><pragnesh.patel@sifive.com> wrote:
>>
>> Add DDR controller and phy register settings, taken from fsbl
>> (https://github.com/sifive/freedom-u540-c000-bootloader.git)
>>
>> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
>> ---
>>  arch/riscv/dts/fu540-c000-u-boot.dtsi         |    7 +
>>  arch/riscv/dts/fu540-sdram-ddr4.dtsi          | 1489 +++++++++++++++++
>>  .../dts/hifive-unleashed-a00-u-boot.dtsi      |    1 +
>>  3 files changed, 1497 insertions(+)
>>  create mode 100644 arch/riscv/dts/fu540-sdram-ddr4.dtsi
>>
>> diff --git a/arch/riscv/dts/fu540-c000-u-boot.dtsi
>> b/arch/riscv/dts/fu540-c000-u-boot.dtsi
>> index 2d3d62801f..b8cef67885 100644
>> --- a/arch/riscv/dts/fu540-c000-u-boot.dtsi
>> +++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
>> @@ -40,6 +40,13 @@
>>                         reg = <0x0 0x2000000 0x0 0xc0000>;
>>                         u-boot,dm-spl;
>>                 };
>> +               dmc: dmc at 100b0000 {
>> +                       compatible = "sifive,fu540-ddr";
>> +                       reg = <0x0 0x100b0000 0x0 0x0800
>> +                              0x0 0x100b2000 0x0 0x2000
>> +                              0x0 0x100b8000 0x0 0x0fff>;
>> +                       u-boot,dm-spl;
>> +               };
>>         };
>>  };
>>
>> diff --git a/arch/riscv/dts/fu540-sdram-ddr4.dtsi
>> b/arch/riscv/dts/fu540-sdram-ddr4.dtsi
>> new file mode 100644
>> index 0000000000..370c53800d
>> --- /dev/null
>> +++ b/arch/riscv/dts/fu540-sdram-ddr4.dtsi
>> @@ -0,0 +1,1489 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * (C) Copyright 2020 SiFive, Inc
>> + */
>> +
>> +&dmc {
>> +       sifive,sdram-params = <
>
>Are these parameter values SoC specific, or board specific? If it's board
>specific, it should be renamed to hifive-unleashed-a00_sdram_ddr4.dtsi, or
>put it directly into hifive-unleashed-a00-u-boot.dtsi

As far as I know, it's a board specific. I will rename it to hifive-unleashed-a00_sdram_ddr4.dtsi.

>
>> +               0x00000a00      /* DENALI_CTL_00_DATA */
>> +               0x00000000      /* DENALI_CTL_01_DATA */
>> +               0x00000000      /* DENALI_CTL_02_DATA */
>> +               0x00000000      /* DENALI_CTL_03_DATA */
>> +               0x00000000      /* DENALI_CTL_04_DATA */
>> +               0x00000000      /* DENALI_CTL_05_DATA */
>> +               0x0000000a      /* DENALI_CTL_06_DATA */
>> +               0x0002d362      /* DENALI_CTL_07_DATA */
>> +               0x00071073      /* DENALI_CTL_08_DATA */
>> +               0x0a1c0255      /* DENALI_CTL_09_DATA */
>> +               0x1c1c0400      /* DENALI_CTL_10_DATA */
>
>[snip]
>
>Regards,
>Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 02/14] riscv: sifive: fu540: Use OTP DM driver for serial environment variable
  2020-03-11 14:52     ` Bin Meng
@ 2020-03-17 15:45       ` Pragnesh Patel
  0 siblings, 0 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-17 15:45 UTC (permalink / raw)
  To: u-boot

Hi Bin,

>-----Original Message-----
>From: Bin Meng <bmeng.cn@gmail.com>
>Sent: 11 March 2020 20:23
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Atish Patra
><atish.patra@wdc.com>; Palmer Dabbelt <palmerdabbelt@google.com>; Paul
>Walmsley <paul.walmsley@sifive.com>; Jagan Teki
><jagan@amarulasolutions.com>; Troy Benjegerdes
><troy.benjegerdes@sifive.com>; Anup Patel <anup.patel@wdc.com>; Sagar
>Kadam <sagar.kadam@sifive.com>; Rick Chen <rick@andestech.com>; Palmer
>Dabbelt <palmer@dabbelt.com>
>Subject: Re: [PATCH v5 02/14] riscv: sifive: fu540: Use OTP DM driver for serial
>environment variable
>
>On Wed, Mar 11, 2020 at 9:32 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>>
>> On Wed, Mar 11, 2020 at 3:03 PM Pragnesh Patel
>> <pragnesh.patel@sifive.com> wrote:
>> >
>> > Use the OTP DM driver to set the serial environment variable.
>> >
>> > Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
>> > ---
>> >  arch/riscv/dts/fu540-c000-u-boot.dtsi         |  14 +++
>> >  .../dts/hifive-unleashed-a00-u-boot.dtsi      |   6 +
>> >  board/sifive/fu540/Kconfig                    |   2 +
>> >  board/sifive/fu540/fu540.c                    | 113 +++++++-----------
>> >  4 files changed, 62 insertions(+), 73 deletions(-)  create mode
>> > 100644 arch/riscv/dts/fu540-c000-u-boot.dtsi
>> >  create mode 100644 arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>> >
>> > diff --git a/arch/riscv/dts/fu540-c000-u-boot.dtsi
>> > b/arch/riscv/dts/fu540-c000-u-boot.dtsi
>> > new file mode 100644
>> > index 0000000000..31fd113c7d
>> > --- /dev/null
>> > +++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
>> > @@ -0,0 +1,14 @@
>> > +// SPDX-License-Identifier: GPL-2.0+
>> > +/*
>> > + * (C) Copyright 2019 SiFive, Inc
>>
>> nits: 2020?

This is something I have written in December,2019. 
V1 patch also submitted in 2019, so i think it's fine to have 2019 here.

>>
>> > + */
>> > +
>> > +/ {
>> > +       soc {
>> > +               otp: otp at 10070000 {
>> > +                       compatible = "sifive,fu540-otp";
>> > +                       reg = <0x0 0x10070000 0x0 0x0FFF>;
>> > +                       fuse-count = <0x1000>;
>>
>> Add status = "disabled" here?
>
>After reviewing patch 5 in this series, I think we can leave without adding
>"status" property here.
>
>>
>> > +               };
>> > +       };
>> > +};
>> > diff --git a/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>> > b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>> > new file mode 100644
>> > index 0000000000..bec0d19134
>> > --- /dev/null
>> > +++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>> > @@ -0,0 +1,6 @@
>> > +// SPDX-License-Identifier: GPL-2.0+
>> > +/*
>> > + * Copyright (C) 2019 SiFive, Inc
>>
>> nits: 2020?

Same as above

>>
>> > + */
>> > +
>> > +#include "fu540-c000-u-boot.dtsi"
>>
>> Add
>>
>> &otp {
>> status = "okay";
>> }
>>
>> here?
>
>After reviewing patch 5 in this series, I think we can leave without adding
>"status" property here.
>
>Regards,
>Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 05/14] riscv: sifive: dts: fu540: Add board -u-boot.dtsi files
  2020-03-11 14:51   ` Bin Meng
@ 2020-03-17 16:44     ` Pragnesh Patel
  0 siblings, 0 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-17 16:44 UTC (permalink / raw)
  To: u-boot

Hi Bin,

>-----Original Message-----
>From: Bin Meng <bmeng.cn@gmail.com>
>Sent: 11 March 2020 20:21
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Atish Patra
><atish.patra@wdc.com>; Palmer Dabbelt <palmerdabbelt@google.com>; Paul
>Walmsley <paul.walmsley@sifive.com>; Jagan Teki
><jagan@amarulasolutions.com>; Troy Benjegerdes
><troy.benjegerdes@sifive.com>; Anup Patel <anup.patel@wdc.com>; Sagar
>Kadam <sagar.kadam@sifive.com>; Rick Chen <rick@andestech.com>
>Subject: Re: [PATCH v5 05/14] riscv: sifive: dts: fu540: Add board -u-boot.dtsi
>files
>
>On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
><pragnesh.patel@sifive.com> wrote:
>>
>> Devicetree files in FU540 platform is synced from Linux, like other
>> platforms does. Apart from these u-boot in FU540 would also require
>
>nits: U-Boot
>
>> some u-boot specific node like clint.
>
>ditto
>
>>
>> So, create board specific -u-boot.dtsi files. This would help of
>> maintain u-boot specific changes separately without touching Linux
>
>ditto

Will update all in v6.

>
>> dts(i) files which indeed easy for syncing from Linux between
>> releases.
>>
>> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
>> Reviewed-by: Anup Patel <anup.patel@wdc.com>
>> ---
>>  arch/riscv/dts/fu540-c000-u-boot.dtsi         | 42 +++++++++++++++++++
>>  .../dts/hifive-unleashed-a00-u-boot.dtsi      | 16 +++++++
>>  2 files changed, 58 insertions(+)
>>
>> diff --git a/arch/riscv/dts/fu540-c000-u-boot.dtsi
>> b/arch/riscv/dts/fu540-c000-u-boot.dtsi
>> index 31fd113c7d..2d3d62801f 100644
>> --- a/arch/riscv/dts/fu540-c000-u-boot.dtsi
>> +++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
>> @@ -4,11 +4,53 @@
>>   */
>>
>>  / {
>> +       cpus {
>> +               u-boot,dm-spl;
>> +               cpu0: cpu at 0 {
>> +                       u-boot,dm-spl;
>> +                       status = "okay";
>> +                       cpu0_intc: interrupt-controller {
>> +                               u-boot,dm-spl;
>> +                       };
>> +               };
>> +               cpu1: cpu at 1 {
>> +                       u-boot,dm-spl;
>> +               };
>> +               cpu2: cpu at 2 {
>> +                       u-boot,dm-spl;
>> +               };
>> +               cpu3: cpu at 3 {
>> +                       u-boot,dm-spl;
>> +               };
>> +               cpu4: cpu at 4 {
>> +                       u-boot,dm-spl;
>> +               };
>> +       };
>> +
>>         soc {
>> +               u-boot,dm-spl;
>>                 otp: otp at 10070000 {
>>                         compatible = "sifive,fu540-otp";
>>                         reg = <0x0 0x10070000 0x0 0x0FFF>;
>>                         fuse-count = <0x1000>;
>>                 };
>> +               clint at 2000000 {
>> +                       compatible = "riscv,clint0";
>> +                       interrupts-extended = <&cpu0_intc 3 &cpu0_intc
>> + 7 >;
>
>Looks this property value is incomplete: missing cpu1/2/3/4_intc ?

Yes, will update in v6, thanks for reviewing the patch.

>
>> +                       reg = <0x0 0x2000000 0x0 0xc0000>;
>> +                       u-boot,dm-spl;
>> +               };
>>         };
>>  };
>> +
>> +&prci {
>> +       u-boot,dm-spl;
>> +};
>> +
>> +&uart0 {
>> +       u-boot,dm-spl;
>> +};
>> +
>> +&qspi2 {
>> +       u-boot,dm-spl;
>> +};
>> diff --git a/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>> b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>> index bec0d19134..cce1bd943e 100644
>> --- a/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>> +++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>> @@ -4,3 +4,19 @@
>>   */
>>
>>  #include "fu540-c000-u-boot.dtsi"
>> +
>> +/ {
>> +       hfclk {
>> +               u-boot,dm-spl;
>> +       };
>> +
>> +       rtcclk {
>> +               u-boot,dm-spl;
>> +       };
>> +};
>> +
>> +&qspi2 {
>> +       mmc at 0 {
>> +               u-boot,dm-spl;
>> +       };
>> +};
>> --
>
>Looks good otherwise
>
>Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 04/14] lib: Makefile: build crc7.c when CONFIG_MMC_SPI
  2020-03-11 13:52   ` Bin Meng
@ 2020-03-17 16:47     ` Pragnesh Patel
  0 siblings, 0 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-17 16:47 UTC (permalink / raw)
  To: u-boot

Hi Bin,

>-----Original Message-----
>From: Bin Meng <bmeng.cn@gmail.com>
>Sent: 11 March 2020 19:22
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Atish Patra
><atish.patra@wdc.com>; Palmer Dabbelt <palmerdabbelt@google.com>; Paul
>Walmsley <paul.walmsley@sifive.com>; Jagan Teki
><jagan@amarulasolutions.com>; Troy Benjegerdes
><troy.benjegerdes@sifive.com>; Anup Patel <anup.patel@wdc.com>; Sagar
>Kadam <sagar.kadam@sifive.com>; Rick Chen <rick@andestech.com>; Lukasz
>Majewski <lukma@denx.de>; Simon Goldschmidt
><simon.k.r.goldschmidt@gmail.com>; Simon Glass <sjg@chromium.org>;
>Markus Klotzbuecher <markus.klotzbuecher@kistler.com>; Baruch Siach
><baruch@tkos.co.il>; Anatolij Gustschin <agust@denx.de>; Thomas Hebb
><tommyhebb@gmail.com>; AKASHI Takahiro <takahiro.akashi@linaro.org>;
>Marek Beh?n <marek.behun@nic.cz>; Philippe Reynes
><philippe.reynes@softathome.com>; Heinrich Schuchardt
><xypron.glpk@gmx.de>; Peng Fan <peng.fan@nxp.com>
>Subject: Re: [PATCH v5 04/14] lib: Makefile: build crc7.c when
>CONFIG_MMC_SPI
>
>On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
><pragnesh.patel@sifive.com> wrote:
>>
>> When build U-boot SPL, meet an issue of undefined reference to
>
>nits: U-Boot

Will update.

>
>> 'crc7' for drivers/mmc/mmc_spi.c, so let's compile crc7.c when
>> CONFIG_MMC_SPI selected.
>>
>> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
>> ---
>>  common/spl/Kconfig | 7 +++++++
>>  lib/Makefile       | 1 +
>>  2 files changed, 8 insertions(+)
>>
>> diff --git a/common/spl/Kconfig b/common/spl/Kconfig index
>> b03a476b9f..f93f552f5e 100644
>> --- a/common/spl/Kconfig
>> +++ b/common/spl/Kconfig
>> @@ -401,6 +401,13 @@ config SPL_CRC32_SUPPORT
>>           for detected accidental image corruption. For secure applications you
>>           should consider SHA1 or SHA256.
>>
>> +config SPL_CRC7_SUPPORT
>> +       bool "Support CRC7"
>> +       default y if MMC_SPI
>
>This dependency should be set in the MMPC_SPI driver with a "select".
>The driver cannot work without it.

Okay, will update in v6. Thanks for the review.

>
>> +       help
>> +         Enable CRC7 hashing for drivers which are using in SPL.
>> +         This is a 32-bit checksum value that can be used to verify images.
>> +
>>  config SPL_MD5_SUPPORT
>>         bool "Support MD5"
>>         depends on SPL_FIT
>> diff --git a/lib/Makefile b/lib/Makefile index 15259d0473..7a50aa56ef
>> 100644
>> --- a/lib/Makefile
>> +++ b/lib/Makefile
>> @@ -78,6 +78,7 @@ endif
>>
>>  ifdef CONFIG_SPL_BUILD
>>  obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o
>> +obj-$(CONFIG_SPL_CRC7_SUPPORT) += crc7.o
>>  obj-$(CONFIG_$(SPL_TPL_)HASH_SUPPORT) += crc16.o  obj-y +=
>> net_utils.o  endif
>> --
>
>Regards,
>Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 01/14] misc: add driver for the SiFive otp controller
  2020-03-11 10:25   ` Bin Meng
@ 2020-03-17 17:30     ` Pragnesh Patel
  0 siblings, 0 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-17 17:30 UTC (permalink / raw)
  To: u-boot

Hi Bin,

>-----Original Message-----
>From: Bin Meng <bmeng.cn@gmail.com>
>Sent: 11 March 2020 15:55
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Atish Patra
><atish.patra@wdc.com>; Palmer Dabbelt <palmerdabbelt@google.com>; Paul
>Walmsley <paul.walmsley@sifive.com>; Jagan Teki
><jagan@amarulasolutions.com>; Troy Benjegerdes
><troy.benjegerdes@sifive.com>; Anup Patel <anup.patel@wdc.com>; Sagar
>Kadam <sagar.kadam@sifive.com>; Rick Chen <rick@andestech.com>; Simon
>Glass <sjg@chromium.org>; Eugen Hristev <eugen.hristev@microchip.com>;
>Lukasz Majewski <lukma@denx.de>; Heiko Stuebner
><heiko.stuebner@theobroma-systems.com>; Adam Ford
><aford173@gmail.com>; Peng Fan <peng.fan@nxp.com>; Finley Xiao
><finley.xiao@rock-chips.com>; Tero Kristo <t-kristo@ti.com>; Kever Yang
><kever.yang@rock-chips.com>
>Subject: Re: [PATCH v5 01/14] misc: add driver for the SiFive otp controller
>
>On Wed, Mar 11, 2020 at 3:03 PM Pragnesh Patel
><pragnesh.patel@sifive.com> wrote:
>>
>> Added a misc driver to handle OTP memory in SiFive SoCs.
>>
>> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
>> ---
>>  drivers/misc/Kconfig      |   7 ++
>>  drivers/misc/Makefile     |   1 +
>>  drivers/misc/sifive-otp.c | 241
>> ++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 249 insertions(+)
>>  create mode 100644 drivers/misc/sifive-otp.c
>>
>> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index
>> f18aa8f7ba..fcb45c63d4 100644
>> --- a/drivers/misc/Kconfig
>> +++ b/drivers/misc/Kconfig
>> @@ -68,6 +68,13 @@ config ROCKCHIP_OTP
>>           addressing and a length or through child-nodes that are generated
>>           based on the e-fuse map retrieved from the DTS.
>>
>> +config SIFIVE_OTP
>> +       bool "SiFive Ememory OTP driver"
>
>nits: eMemory
>
>> +       depends on RISCV && MISC
>> +       help
>> +         Enable support for reading and writing the ememory OTP on
>> + the
>
>nits: eMemory

Will update all in v6.

>
>> +         SiFive SoCs.
>> +
>>  config VEXPRESS_CONFIG
>>         bool "Enable support for Arm Versatile Express config bus"
>>         depends on MISC
>> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index
>> 2b843de93c..ee888631b6 100644
>> --- a/drivers/misc/Makefile
>> +++ b/drivers/misc/Makefile
>> @@ -58,6 +58,7 @@ obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
>>  obj-$(CONFIG_QFW) += qfw.o
>>  obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
>>  obj-$(CONFIG_ROCKCHIP_OTP) += rockchip-otp.o
>> +obj-$(CONFIG_SIFIVE_OTP) += sifive-otp.o
>>  obj-$(CONFIG_SANDBOX) += syscon_sandbox.o misc_sandbox.o
>>  obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o
>>  obj-$(CONFIG_SMSC_SIO1007) += smsc_sio1007.o diff --git
>> a/drivers/misc/sifive-otp.c b/drivers/misc/sifive-otp.c new file mode
>> 100644 index 0000000000..1e6c1a11b2
>> --- /dev/null
>> +++ b/drivers/misc/sifive-otp.c
>> @@ -0,0 +1,241 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * This is a driver for the eMemory EG004K32TQ028XW01 NeoFuse
>> + * One-Time-Programmable (OTP) memory used within the SiFive FU540.
>> + * It is documented in the FU540 manual here:
>> + *
>> +https://www.sifive.com/documentation/chips/freedom-u540-c000-
>manual/
>> + *
>> + * Copyright (C) 2018 Philipp Hug <philipp@hug.cx>
>> + * Copyright (C) 2018 Joey Hewitt <joey@joeyhewitt.com>
>> + *
>> + * Copyright (C) 2020 SiFive, Inc
>> + */
>> +
>> +/*
>> + * The FU540 stores 4096x32 bit (16KiB) values.
>> + * Index 0x00-0xff are reserved for SiFive internal use. (first 1KiB)
>> + * Right now first 1KB is used to store only serial number.
>
>nits: 1KiB

Will update.

>
>> + */
>> +
>> +#include <common.h>
>> +#include <dm/device.h>
>> +#include <dm/read.h>
>> +#include <linux/io.h>
>> +#include <misc.h>
>> +
>> +#define BYTES_PER_FUSE         4
>> +
>> +#define PA_RESET_VAL           0x00
>> +#define PAS_RESET_VAL          0x00
>> +#define PAIO_RESET_VAL         0x00
>> +#define PDIN_RESET_VAL         0x00
>> +#define PTM_RESET_VAL          0x00
>> +
>> +#define PCLK_ENABLE_VAL                        BIT(0)
>> +#define PCLK_DISABLE_VAL               0x00
>> +
>> +#define PWE_WRITE_ENABLE               BIT(0)
>> +#define PWE_WRITE_DISABLE              0x00
>> +
>> +#define PTM_FUSE_PROGRAM_VAL           BIT(1)
>> +
>> +#define PCE_ENABLE_INPUT               BIT(0)
>> +#define PCE_DISABLE_INPUT              0x00
>> +
>> +#define PPROG_ENABLE_INPUT             BIT(0)
>> +#define PPROG_DISABLE_INPUT            0x00
>> +
>> +#define PTRIM_ENABLE_INPUT             BIT(0)
>> +#define PTRIM_DISABLE_INPUT            0x00
>> +
>> +#define PDSTB_DEEP_STANDBY_ENABLE      BIT(0)
>> +#define PDSTB_DEEP_STANDBY_DISABLE     0x00
>> +
>> +struct sifive_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;
>
>__packed is not needed

Will update.

>
>> +
>> +struct sifive_otp_platdata {
>> +       struct sifive_otp_regs __iomem *regs;
>> +       u32 total_fuses;
>> +};
>> +
>> +/*
>> + * offset and size are assumed aligned to the size of the fuses (32bit).
>
>nits: 32-bit

Will update.

>
>> + */
>> +static int sifive_otp_read(struct udevice *dev, int offset,
>> +                          void *buf, int size) {
>> +       struct sifive_otp_platdata *plat = dev_get_platdata(dev);
>> +       struct sifive_otp_regs *regs = (struct sifive_otp_regs
>> +*)plat->regs;
>> +
>> +       int fuseidx = offset / BYTES_PER_FUSE;
>> +       int fusecount = size / BYTES_PER_FUSE;
>
>Should we check whether offset and size are multiple of BYTES_PER_FUSE?

Will add a code for this and update in v6.

>
>> +       u32 fusebuf[fusecount];
>
>This utilizes C99 VLA. What is the largest fusecount this function could aspect?
>If it's a large one we might have a stack overflow problem.

Will add a check here.

>
>> +
>> +       /* check bounds */
>> +       if (offset < 0 || size < 0)
>> +               return -EINVAL;
>> +       if (fuseidx >= plat->total_fuses)
>> +               return -EINVAL;
>> +       if ((fuseidx + fusecount) > plat->total_fuses)
>> +               return -EINVAL;
>> +
>> +       /* init OTP */
>> +       iowrite32(PDSTB_DEEP_STANDBY_ENABLE, &regs->pdstb);
>
>Use writel()?

iowrite32() will anyway call writel(), so I think it's fine to use iowrite32() here.

>
>> +       iowrite32(PTRIM_ENABLE_INPUT, &regs->ptrim);
>> +       iowrite32(PCE_ENABLE_INPUT, &regs->pce);
>> +
>> +       /* read all requested fuses */
>> +       for (unsigned int i = 0; i < fusecount; i++, fuseidx++) {
>> +               iowrite32(fuseidx, &regs->pa);
>> +
>> +               /* cycle clock to read */
>> +               iowrite32(PCLK_ENABLE_VAL, &regs->pclk);
>> +               mdelay(1);
>> +               iowrite32(PCLK_DISABLE_VAL, &regs->pclk);
>> +               mdelay(1);
>> +
>> +               /* read the value */
>> +               fusebuf[i] = ioread32(&regs->pdout);
>> +       }
>> +
>> +       /* shut down */
>> +       iowrite32(PCE_DISABLE_INPUT, &regs->pce);
>> +       iowrite32(PTRIM_DISABLE_INPUT, &regs->ptrim);
>> +       iowrite32(PDSTB_DEEP_STANDBY_DISABLE, &regs->pdstb);
>> +
>> +       // copy out
>
>Should use /* */ comment format

Will update.

>
>> +       memcpy(buf, fusebuf, size);
>> +
>> +       return size;
>> +}
>> +
>> +/*
>> + * Caution:
>> + * OTP can be written only once, so use carefully.
>> + *
>> + * offset and size are assumed aligned to the size of the fuses (32bit).
>
>nits: 32-bit

Will update.

>
>> + */
>> +static int sifive_otp_write(struct udevice *dev, int offset,
>> +                           const void *buf, int size) {
>> +       struct sifive_otp_platdata *plat = dev_get_platdata(dev);
>> +       struct sifive_otp_regs *regs = (struct sifive_otp_regs
>> +*)plat->regs;
>> +
>> +       int fuseidx = offset / BYTES_PER_FUSE;
>> +       int fusecount = size / BYTES_PER_FUSE;
>> +       u32 *write_buf = (u32 *)buf;
>> +       u32 write_data;
>> +       int i, pas, bit;
>> +
>> +       /* check bounds */
>> +       if (offset < 0 || size < 0)
>> +               return -EINVAL;
>> +       if (fuseidx >= plat->total_fuses)
>> +               return -EINVAL;
>> +       if ((fuseidx + fusecount) > plat->total_fuses)
>> +               return -EINVAL;
>> +
>> +       /* init OTP */
>> +       iowrite32(PDSTB_DEEP_STANDBY_ENABLE, &regs->pdstb);
>> +       iowrite32(PTRIM_ENABLE_INPUT, &regs->ptrim);
>> +
>> +       /* reset registers */
>> +       iowrite32(PCLK_DISABLE_VAL, &regs->pclk);
>> +       iowrite32(PA_RESET_VAL, &regs->pa);
>> +       iowrite32(PAS_RESET_VAL, &regs->pas);
>> +       iowrite32(PAIO_RESET_VAL, &regs->paio);
>> +       iowrite32(PDIN_RESET_VAL, &regs->pdin);
>> +       iowrite32(PWE_WRITE_DISABLE, &regs->pwe);
>> +       iowrite32(PTM_FUSE_PROGRAM_VAL, &regs->ptm);
>> +       mdelay(1);
>> +
>> +       iowrite32(PCE_ENABLE_INPUT, &regs->pce);
>> +       iowrite32(PPROG_ENABLE_INPUT, &regs->pprog);
>> +       iowrite32(PTRIM_ENABLE_INPUT, &regs->ptrim);
>
>This is already enabled a few lines above, in the /* init OTP */ section.

Will check and update.

>
>> +
>> +       /* write all requested fuses */
>> +       for (i = 0; i < fusecount; i++, fuseidx++) {
>> +               iowrite32(fuseidx, &regs->pa);
>> +               write_data = *(write_buf++);
>> +
>> +               for (pas = 0; pas < 2; pas++) {
>> +                       iowrite32(pas, &regs->pas);
>> +
>> +                       for (bit = 0; bit < 32; bit++) {
>> +                               iowrite32(bit, &regs->paio);
>> +                               iowrite32(((write_data >> bit) & 1),
>> +                                         &regs->pdin);
>> +                               mdelay(1);
>> +
>> +                               iowrite32(PWE_WRITE_ENABLE, &regs->pwe);
>> +                               mdelay(1);
>> +                               iowrite32(PWE_WRITE_DISABLE, &regs->pwe);
>> +                               mdelay(1);
>> +                       }
>> +               }
>> +
>> +               iowrite32(PAS_RESET_VAL, &regs->pas);
>> +       }
>> +
>> +       /* shut down */
>> +       iowrite32(PWE_WRITE_DISABLE, &regs->pwe);
>> +       iowrite32(PPROG_DISABLE_INPUT, &regs->pprog);
>> +       iowrite32(PCE_DISABLE_INPUT, &regs->pce);
>> +       iowrite32(PTM_RESET_VAL, &regs->ptm);
>> +
>> +       iowrite32(PTRIM_DISABLE_INPUT, &regs->ptrim);
>> +       iowrite32(PDSTB_DEEP_STANDBY_DISABLE, &regs->pdstb);
>> +
>> +       return size;
>> +}
>> +
>> +static int sifive_otp_ofdata_to_platdata(struct udevice *dev) {
>> +       struct sifive_otp_platdata *plat = dev_get_platdata(dev);
>> +       int ret;
>> +
>> +       plat->regs = dev_read_addr_ptr(dev);
>> +
>> +       ret = dev_read_u32(dev, "fuse-count", &plat->total_fuses);
>> +       if (ret < 0) {
>> +               pr_err("\"fuse-count\" not found\n");
>> +               return ret;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static const struct misc_ops sifive_otp_ops = {
>> +       .read = sifive_otp_read,
>> +       .write = sifive_otp_write,
>> +};
>> +
>> +static const struct udevice_id sifive_otp_ids[] = {
>> +       { .compatible = "sifive,fu540-otp" },
>
>Based on other existing compatible strings, I think this should be named as
>"sifive,fu540-c000-otp".

Will update.

>
>> +       {}
>> +};
>> +
>> +U_BOOT_DRIVER(sifive_otp) = {
>> +       .name = "sifive_otp",
>> +       .id = UCLASS_MISC,
>> +       .of_match = sifive_otp_ids,
>> +       .ofdata_to_platdata = sifive_otp_ofdata_to_platdata,
>> +       .platdata_auto_alloc_size = sizeof(struct sifive_otp_platdata),
>> +       .ops = &sifive_otp_ops,
>> +};
>> --
>
>Regards,
>Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 02/14] riscv: sifive: fu540: Use OTP DM driver for serial environment variable
  2020-03-11 15:00   ` Bin Meng
@ 2020-03-17 17:36     ` Pragnesh Patel
  0 siblings, 0 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-17 17:36 UTC (permalink / raw)
  To: u-boot

Hi Bin,

>-----Original Message-----
>From: Bin Meng <bmeng.cn@gmail.com>
>Sent: 11 March 2020 20:30
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Atish Patra
><atish.patra@wdc.com>; Palmer Dabbelt <palmerdabbelt@google.com>; Paul
>Walmsley <paul.walmsley@sifive.com>; Jagan Teki
><jagan@amarulasolutions.com>; Troy Benjegerdes
><troy.benjegerdes@sifive.com>; Anup Patel <anup.patel@wdc.com>; Sagar
>Kadam <sagar.kadam@sifive.com>; Rick Chen <rick@andestech.com>; Palmer
>Dabbelt <palmer@dabbelt.com>
>Subject: Re: [PATCH v5 02/14] riscv: sifive: fu540: Use OTP DM driver for serial
>environment variable
>
>On Wed, Mar 11, 2020 at 3:03 PM Pragnesh Patel
><pragnesh.patel@sifive.com> wrote:
>>
>> Use the OTP DM driver to set the serial environment variable.
>>
>> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
>> ---
>>  arch/riscv/dts/fu540-c000-u-boot.dtsi         |  14 +++
>>  .../dts/hifive-unleashed-a00-u-boot.dtsi      |   6 +
>>  board/sifive/fu540/Kconfig                    |   2 +
>>  board/sifive/fu540/fu540.c                    | 113 +++++++-----------
>>  4 files changed, 62 insertions(+), 73 deletions(-)  create mode
>> 100644 arch/riscv/dts/fu540-c000-u-boot.dtsi
>>  create mode 100644 arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>>
>> diff --git a/arch/riscv/dts/fu540-c000-u-boot.dtsi
>> b/arch/riscv/dts/fu540-c000-u-boot.dtsi
>> new file mode 100644
>> index 0000000000..31fd113c7d
>> --- /dev/null
>> +++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
>> @@ -0,0 +1,14 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>
>Missed one thing:
>
>I believe this file should be dual-licensed, like fu540-c000.dtsi

Yes, will update in v6.

>
>> +/*
>> + * (C) Copyright 2019 SiFive, Inc
>> + */
>> +
>> +/ {
>> +       soc {
>> +               otp: otp at 10070000 {
>> +                       compatible = "sifive,fu540-otp";
>> +                       reg = <0x0 0x10070000 0x0 0x0FFF>;
>> +                       fuse-count = <0x1000>;
>> +               };
>> +       };
>> +};
>> diff --git a/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>> b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>> new file mode 100644
>> index 0000000000..bec0d19134
>> --- /dev/null
>> +++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>> @@ -0,0 +1,6 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>
>And this one dual-licensed too

Will update.

>
>> +/*
>> + * Copyright (C) 2019 SiFive, Inc
>> + */
>> +
>
>Regards,
>Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 09/14] clk: sifive: fu540-prci: Add clock initialization for SPL
  2020-03-13  8:11   ` Bin Meng
@ 2020-03-17 17:47     ` Pragnesh Patel
  0 siblings, 0 replies; 53+ messages in thread
From: Pragnesh Patel @ 2020-03-17 17:47 UTC (permalink / raw)
  To: u-boot

Hi Bin,

>-----Original Message-----
>From: Bin Meng <bmeng.cn@gmail.com>
>Sent: 13 March 2020 13:41
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Atish Patra
><atish.patra@wdc.com>; Palmer Dabbelt <palmerdabbelt@google.com>; Paul
>Walmsley <paul.walmsley@sifive.com>; Jagan Teki
><jagan@amarulasolutions.com>; Troy Benjegerdes
><troy.benjegerdes@sifive.com>; Anup Patel <anup.patel@wdc.com>; Sagar
>Kadam <sagar.kadam@sifive.com>; Rick Chen <rick@andestech.com>; Lukasz
>Majewski <lukma@denx.de>; Anatolij Gustschin <agust@denx.de>; Simon
>Glass <sjg@chromium.org>
>Subject: Re: [PATCH v5 09/14] clk: sifive: fu540-prci: Add clock initialization for
>SPL
>
>On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
><pragnesh.patel@sifive.com> wrote:
>>
>> Set corepll, ddrpll and ethernet PLL for u-boot-spl
>>
>> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
>> ---
>>  drivers/clk/sifive/fu540-prci.c | 94
>> +++++++++++++++++++++++++++++++++
>>  1 file changed, 94 insertions(+)
>>
>> diff --git a/drivers/clk/sifive/fu540-prci.c
>> b/drivers/clk/sifive/fu540-prci.c index c02c0466a8..f043b0eccb 100644
>> --- a/drivers/clk/sifive/fu540-prci.c
>> +++ b/drivers/clk/sifive/fu540-prci.c
>> @@ -41,6 +41,10 @@
>>  #include <linux/clk/analogbits-wrpll-cln28hpc.h>
>>  #include <dt-bindings/clock/sifive-fu540-prci.h>
>>
>> +#define DDRCTLPLL_F    55
>> +#define DDRCTLPLL_Q    2
>> +#define MHz            1000000
>> +
>>  /*
>>   * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver
>expects:
>>   *     hfclk and rtcclk
>> @@ -152,6 +156,27 @@
>>  #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK \
>>                         (0x1 <<
>> PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
>>
>> +/* PROCMONCFG */
>> +#define PRCI_PROCMONCFG_OFFSET                 0xF0
>> +#define PRCI_PROCMONCFG_CORE_CLOCK_SHIFT       24
>> +#define PRCI_PROCMONCFG_CORE_CLOCK_MASK \
>> +                       (0x1 << PRCI_PROCMONCFG_CORE_CLOCK_SHIFT)
>> +
>> +#define PLL_R(x) \
>> +       ((x) << PRCI_DDRPLLCFG0_DIVR_SHIFT) &
>> +PRCI_DDRPLLCFG0_DIVR_MASK #define PLL_F(x) \
>> +       ((x) << PRCI_DDRPLLCFG0_DIVF_SHIFT) &
>> +PRCI_DDRPLLCFG0_DIVF_MASK #define PLL_Q(x) \
>> +       ((x) << PRCI_DDRPLLCFG0_DIVQ_SHIFT) &
>> +PRCI_DDRPLLCFG0_DIVQ_MASK #define PLL_RANGE(x) \
>> +       ((x) << PRCI_DDRPLLCFG0_RANGE_SHIFT) &
>> +PRCI_DDRPLLCFG0_RANGE_MASK #define PLL_BYPASS(x) \
>> +       ((x) << PRCI_DDRPLLCFG0_BYPASS_SHIFT) &
>> +PRCI_DDRPLLCFG0_BYPASS_MASK #define PLL_FSE(x) \
>> +       ((x) << PRCI_DDRPLLCFG0_FSE_SHIFT) & PRCI_DDRPLLCFG0_FSE_MASK
>> +#define PLL_LOCK(x) \
>> +       ((x) << PRCI_DDRPLLCFG0_LOCK_SHIFT) &
>> +PRCI_DDRPLLCFG0_LOCK_MASK
>> +
>>  /*
>>   * Private structures
>>   */
>> @@ -672,6 +697,75 @@ static int sifive_fu540_prci_probe(struct udevice
>*dev)
>>                         __prci_wrpll_read_cfg(pd, pc->pwd);
>>         }
>>
>> +#ifdef CONFIG_SPL_BUILD
>
>I think the correct way is to add clocks property to each device node that use
>the clock, e.g.:
>
>    clocks = <&prci PRCI_CLK_COREPLL>;
>
>Then we don't need anything added here, instead we call clk_enable() from
>the device driver to enable their clock.

I think some basic clock initialization should be done by SPL and that should be done in probe function.
Most of clock driver uses this method to do clock initialization.
e.g. - drivers/clk/rockchip/clk_rk3399.c = rkclk_init()

>
>> +       u32 v;
>> +       struct clk clock;
>> +
>> +       v = __prci_readl(pd, PRCI_CLKMUXSTATUSREG_OFFSET);
>> +       v &= PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK;
>> +
>> +       clock.id = PRCI_CLK_COREPLL;
>> +
>> +       if (v) {
>> +               /* corepll 500 Mhz */
>> +               sifive_fu540_prci_set_rate(&clock, 500UL * MHz);
>> +       } else {
>> +               /* corepll 1 Ghz */
>> +               sifive_fu540_prci_set_rate(&clock, 1000UL * MHz);
>> +       }
>> +
>> +       sifive_fu540_prci_clock_enable(&__prci_init_clocks[clock.id],
>> + 1);
>> +
>> +       //DDR init
>> +       u32 ddrctlmhz =
>> +               (PLL_R(0)) |
>> +               (PLL_F(DDRCTLPLL_F)) |
>> +               (PLL_Q(DDRCTLPLL_Q)) |
>> +               (PLL_RANGE(0x4)) |
>> +               (PLL_BYPASS(0)) |
>> +               (PLL_FSE(1));
>> +       __prci_writel(ddrctlmhz, PRCI_DDRPLLCFG0_OFFSET, pd);
>> +
>> +       clock.id = PRCI_CLK_DDRPLL;
>> +       sifive_fu540_prci_clock_enable(&__prci_init_clocks[clock.id],
>> + 1);
>> +
>> +       /* Release DDR reset */
>> +       v = __prci_readl(pd, PRCI_DEVICESRESETREG_OFFSET);
>> +       v |= PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK;
>> +       __prci_writel(v, PRCI_DEVICESRESETREG_OFFSET, pd);
>> +
>> +       // HACK to get the '1 full controller clock cycle'.
>> +       asm volatile ("fence");
>> +       v = __prci_readl(pd, PRCI_DEVICESRESETREG_OFFSET);
>> +       v |= (PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK |
>> +             PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK |
>> +             PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK);
>> +       __prci_writel(v, PRCI_DEVICESRESETREG_OFFSET, pd);
>> +       // HACK to get the '1 full controller clock cycle'.
>> +       asm volatile ("fence");
>> +
>> +       /* These take like 16 cycles to actually propagate. We can't go sending
>> +        * stuff before they come out of reset. So wait. (TODO: Add a register
>> +        * to read the current reset states, or DDR Control device?)
>> +        */
>> +       for (int i = 0; i < 256; i++)
>> +               asm volatile ("nop");
>> +
>> +       /* GEMGXL init */
>> +       clock.id = PRCI_CLK_GEMGXLPLL;
>> +       sifive_fu540_prci_set_rate(&clock, 125UL * MHz);
>> +       sifive_fu540_prci_clock_enable(&__prci_init_clocks[clock.id],
>> + 1);
>> +
>> +       /* Release GEMGXL reset */
>> +       v = __prci_readl(pd, PRCI_DEVICESRESETREG_OFFSET);
>> +       v |= PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK;
>> +       __prci_writel(v, PRCI_DEVICESRESETREG_OFFSET, pd);
>> +
>> +       /* Procmon => core clock */
>> +       __prci_writel(PRCI_PROCMONCFG_CORE_CLOCK_MASK,
>PRCI_PROCMONCFG_OFFSET,
>> +                     pd);
>> +#endif
>> +
>>         return 0;
>>  }
>
>Regards,
>Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PATCH v5 12/14] riscv: sifive: fu540: enable all cache ways from u-boot proper
       [not found]               ` <752D002CFF5D0F4FA35C0100F1D73F3FA46E7F97@ATCPCS16.andestech.com>
@ 2020-03-18  2:27                 ` Rick Chen
  0 siblings, 0 replies; 53+ messages in thread
From: Rick Chen @ 2020-03-18  2:27 UTC (permalink / raw)
  To: u-boot

Hi Pragnesh

> From: Pragnesh Patel [mailto:pragnesh.patel at sifive.com]
> Sent: Tuesday, March 17, 2020 5:52 PM
> To: Bin Meng; Anup Patel
> Cc: U-Boot Mailing List; Atish Patra; Palmer Dabbelt; Paul Walmsley; Jagan Teki; Troy Benjegerdes; Anup Patel; Sagar Kadam; Rick Jian-Zhi Chen(???); Palmer Dabbelt
> Subject: RE: [PATCH v5 12/14] riscv: sifive: fu540: enable all cache ways from u-boot proper
>
>
> Hi,
>
> >-----Original Message-----
> >From: Bin Meng <bmeng.cn@gmail.com>
> >Sent: 13 March 2020 19:19
> >To: Anup Patel <anup@brainfault.org>
> >Cc: Pragnesh Patel <pragnesh.patel@sifive.com>; U-Boot Mailing List <u-
> >boot at lists.denx.de>; Atish Patra <atish.patra@wdc.com>; Palmer Dabbelt
> ><palmerdabbelt@google.com>; Paul Walmsley <paul.walmsley@sifive.com>;
> >Jagan Teki <jagan@amarulasolutions.com>; Troy Benjegerdes
> ><troy.benjegerdes@sifive.com>; Anup Patel <anup.patel@wdc.com>; Sagar
> >Kadam <sagar.kadam@sifive.com>; Rick Chen <rick@andestech.com>; Palmer
> >Dabbelt <palmer@dabbelt.com>
> >Subject: Re: [PATCH v5 12/14] riscv: sifive: fu540: enable all cache
> >ways from u-boot proper
> >
> >Hi Anup,
> >
> >On Fri, Mar 13, 2020 at 6:49 PM Anup Patel <anup@brainfault.org> wrote:
> >>
> >> On Fri, Mar 13, 2020 at 3:52 PM Bin Meng <bmeng.cn@gmail.com> wrote:
> >> >
> >> > Hi Anup,
> >> >
> >> > On Fri, Mar 13, 2020 at 6:02 PM Anup Patel <anup@brainfault.org> wrote:
> >> > >
> >> > > On Fri, Mar 13, 2020 at 2:31 PM Bin Meng <bmeng.cn@gmail.com>
> >wrote:
> >> > > >
> >> > > > On Wed, Mar 11, 2020 at 3:04 PM Pragnesh Patel
> >> > > > <pragnesh.patel@sifive.com> wrote:
> >> > > > >
> >> > > > > Enable all cache ways from u-boot proper.
> >> > > >
> >> > > > U-Boot
> >> > > >
> >> > > > >
> >> > > > > Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> >> > > > > ---
> >> > > > >  board/sifive/fu540/Makefile |  1 +
> >> > > > > board/sifive/fu540/cache.c  | 20 ++++++++++++++++++++
> >> > > > > board/sifive/fu540/cache.h  | 13 +++++++++++++
> >> > > > > board/sifive/fu540/fu540.c  |  6 ++++--
> >> > > > >  4 files changed, 38 insertions(+), 2 deletions(-)  create
> >> > > > > mode 100644 board/sifive/fu540/cache.c  create mode 100644
> >> > > > > board/sifive/fu540/cache.h
> >> > > > >
> >> > > > > diff --git a/board/sifive/fu540/Makefile
> >> > > > > b/board/sifive/fu540/Makefile index b05e2f5807..3b867bbd89
> >> > > > > 100644
> >> > > > > --- a/board/sifive/fu540/Makefile
> >> > > > > +++ b/board/sifive/fu540/Makefile
> >> > > > > @@ -3,6 +3,7 @@
> >> > > > >  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
> >> > > > >
> >> > > > >  obj-y  += fu540.o
> >> > > > > +obj-y  += cache.o
> >> > > > >
> >> > > > >  ifdef CONFIG_SPL_BUILD
> >> > > > >  obj-y += spl.o
> >> > > > > diff --git a/board/sifive/fu540/cache.c
> >> > > > > b/board/sifive/fu540/cache.c new file mode 100644 index
> >> > > > > 0000000000..a0bcd2ba48
> >> > > > > --- /dev/null
> >> > > > > +++ b/board/sifive/fu540/cache.c
> >> > > >
> >> > > > This should be put into arch/riscv/cpu/fu540/cache.c
> >> > > >
> >> > > > > @@ -0,0 +1,20 @@
> >> > > > > +// SPDX-License-Identifier: GPL-2.0+
> >> > > > > +/*
> >> > > > > + * Copyright (c) 2019 SiFive, Inc  */ #include <asm/io.h>
> >> > > > > +
> >> > > > > +/* Register offsets */
> >> > > > > +#define CACHE_ENABLE           0x008
> >> > > > > +
> >> > > > > +/* Enable ways; allow cache to use these ways */ void
> >> > > > > +cache_enable_ways(u64 base_addr, u8 value) {
> >> > > > > +       volatile u32 *enable = (volatile u32 *)(base_addr +
> >> > > > > +                                         CACHE_ENABLE);
> >> > > > > +       /* memory barrier */
> >> > > > > +       mb();
> >> > > > > +       (*enable) = value;
> >> > > > > +       /* memory barrier */
> >> > > > > +       mb();
> >> > > > > +}
> >> > > > > diff --git a/board/sifive/fu540/cache.h
> >> > > > > b/board/sifive/fu540/cache.h new file mode 100644 index
> >> > > > > 0000000000..425124a23b
> >> > > > > --- /dev/null
> >> > > > > +++ b/board/sifive/fu540/cache.h
> >> > > >
> >> > > > arch/riscv/include/asm/arch-fu540/cache.h
> >> > >
> >> > > Let's not entire FU540 directory under arch/riscv/cpu directory
> >> > > just to have cache functions. The arch/riscv/cpu/generic is
> >> > > perfectly suitable for FU540.
> >> >
> >> > I doubt arch/riscv/cpu/generic can be generic if we consider U-Boot
> >> > SPL phase. It can be generic for S-mode U-Boot though.
> >>
> >> Its really very easy to do. We are already doing this in Xvisor.
> >>
> >> As an example, of DT based operations in a generic board support refer:
> >> https://github.com/avpatel/xvisor-next/blob/master/arch/arm/board/gen
> >> e
> >> ric/brd_main.c
> >> https://github.com/avpatel/xvisor-next/blob/master/arch/arm/board/gen
> >> e
> >> ric/foundation-v8.c
> >
> >Yes, this can be easy to do if we have everything written based on DT.
> >But we cannot always assume DT is available in SPL. Some SoCs will not
> >allow SPL with DT support to run due to constraint resources.
> >
> >Even for DT, due to SPL initialization codes can be very low-level and
> >specific to an SoC, not everything can be properly modeled by DT. Take
> >a look at the u-boot/arch/arm directory. Things are not that easy.
> >
> >>
> >> Using the above approach, we are able to boot same Xvisor ARM/ARM64
> >> binary on multiple boards.
> >>
> >
> >Yes, I know. The same as what is done in the Linux kernel. Take x86 for
> >example, the same kernel image can boot on almost every x86
> >desktop/laptop/server we have today. But we have to understand that
> >this is built on top of BIOS which does all low-level processor /
> >chipset initialization and hide that very well for OS.
> >
>
> IMHO just for cache, it's better not to add arch/riscv/cpu/fu540.
> If something that we can not handle with arch/riscv/cpu/generic then we will definitely add arch/riscv/cpu/fu540 dir.
>
> Thanks Bin and Anup for the review.

You shall consider to put it in drivers/cache dir
And parse the cache register base from DT instead of hard code
(#define CACHE_CTRL_ADDR               _AC(0x2010000, UL))
Also parse number of ways instead of hard code (15) //
cache_enable_ways(CACHE_CTRL_ADDR, 15);
It is a legacy way to define register base with hard code, better not
doing that way.

Thanks
Rick

>
> >> >
> >> > >
> >> > > If we re-use arch/riscv/cpu/generic as-much as possible then
> >> > > arch/riscv will be easy to maintain in future.
> >> > >
> >> > > We can add arch/riscv/cpu/generic/cache.c which will do things
> >> > > FU540 specific based on "#ifdef" or "DT compatible string".
> >> > >
> >
> >Regards,
> >Bin

^ permalink raw reply	[flat|nested] 53+ messages in thread

end of thread, other threads:[~2020-03-18  2:27 UTC | newest]

Thread overview: 53+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-11  7:03 [PATCH v5 00/14] RISC-V SiFive FU540 support SPL Pragnesh Patel
2020-03-11  7:03 ` [PATCH v5 01/14] misc: add driver for the SiFive otp controller Pragnesh Patel
2020-03-11 10:25   ` Bin Meng
2020-03-17 17:30     ` Pragnesh Patel
2020-03-11  7:03 ` [PATCH v5 02/14] riscv: sifive: fu540: Use OTP DM driver for serial environment variable Pragnesh Patel
2020-03-11 13:32   ` Bin Meng
2020-03-11 14:52     ` Bin Meng
2020-03-17 15:45       ` Pragnesh Patel
2020-03-11 15:00   ` Bin Meng
2020-03-17 17:36     ` Pragnesh Patel
2020-03-11  7:03 ` [PATCH v5 03/14] riscv: Add _image_binary_end for SPL Pragnesh Patel
2020-03-11  7:03 ` [PATCH v5 04/14] lib: Makefile: build crc7.c when CONFIG_MMC_SPI Pragnesh Patel
2020-03-11 13:52   ` Bin Meng
2020-03-17 16:47     ` Pragnesh Patel
2020-03-11  7:03 ` [PATCH v5 05/14] riscv: sifive: dts: fu540: Add board -u-boot.dtsi files Pragnesh Patel
2020-03-11 14:51   ` Bin Meng
2020-03-17 16:44     ` Pragnesh Patel
2020-03-11  7:03 ` [PATCH v5 06/14] sifive: fu540: add ddr driver Pragnesh Patel
2020-03-13  7:48   ` Bin Meng
2020-03-17 13:00     ` Pragnesh Patel
2020-03-13 11:56   ` Giulio Benetti
2020-03-17 13:05     ` Pragnesh Patel
2020-03-11  7:03 ` [PATCH v5 07/14] sifive: dts: fu540: Add DDR controller and phy register settings Pragnesh Patel
2020-03-13  7:51   ` Bin Meng
2020-03-17 15:35     ` Pragnesh Patel
2020-03-11  7:03 ` [PATCH v5 08/14] clk: sifive: fu540-prci: Add clock enable and disable ops Pragnesh Patel
2020-03-13  7:57   ` Bin Meng
2020-03-13  8:15     ` Pragnesh Patel
2020-03-11  7:03 ` [PATCH v5 09/14] clk: sifive: fu540-prci: Add clock initialization for SPL Pragnesh Patel
2020-03-13  8:11   ` Bin Meng
2020-03-17 17:47     ` Pragnesh Patel
2020-03-11  7:03 ` [PATCH v5 10/14] riscv: sifive: fu540: add SPL configuration Pragnesh Patel
2020-03-13  8:28   ` Bin Meng
2020-03-17  7:41     ` Pragnesh Patel
2020-03-13 13:59   ` Bin Meng
2020-03-17  8:04     ` Pragnesh Patel
2020-03-11  7:03 ` [PATCH v5 11/14] configs: fu540: Add config options for U-boot SPL Pragnesh Patel
2020-03-13  8:48   ` Bin Meng
2020-03-17 14:45     ` Pragnesh Patel
2020-03-11  7:03 ` [PATCH v5 12/14] riscv: sifive: fu540: enable all cache ways from u-boot proper Pragnesh Patel
2020-03-13  9:01   ` Bin Meng
2020-03-13 10:02     ` Anup Patel
2020-03-13 10:22       ` Bin Meng
2020-03-13 10:49         ` Anup Patel
2020-03-13 13:49           ` Bin Meng
2020-03-17  9:52             ` Pragnesh Patel
     [not found]               ` <752D002CFF5D0F4FA35C0100F1D73F3FA46E7F97@ATCPCS16.andestech.com>
2020-03-18  2:27                 ` Rick Chen
2020-03-13 10:54         ` Anup Patel
2020-03-11  7:03 ` [PATCH v5 13/14] sifive: fix palmer's email address Pragnesh Patel
2020-03-13  9:01   ` Bin Meng
2020-03-11  7:03 ` [PATCH v5 14/14] doc: update FU540 RISC-V documentation Pragnesh Patel
2020-03-13  9:22   ` Bin Meng
2020-03-17 14:31     ` Pragnesh Patel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.