All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] RISC-V SiFive FU540 support SPL
@ 2019-12-31  6:30 Pragnesh Patel
  2019-12-31  6:30 ` [PATCH 1/3] riscv: Add place-holder for FU540 clk and gpio Pragnesh Patel
                   ` (3 more replies)
  0 siblings, 4 replies; 19+ messages in thread
From: Pragnesh Patel @ 2019-12-31  6:30 UTC (permalink / raw)
  To: u-boot

This series add support for SPL to FU540. This series depends on
https://patchwork.ozlabs.org/patch/1196703/
(riscv: dts: Add hifive-unleashed-a00 dts from Linux)

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_spl_defconfig
5) make all
6) SD card partition which contains "fw_payload.bin" previously
        /dev/sdc1 - SiFive bare-metal (or s     ->5202)
   should be now of
        /dev/sdc1 - 8300  Linux filesystem.
6) sudo dd if=spl/u-boot-spl.bin of=/dev/sdc4 bs=1M
7) sudo dd if=u-boot.itb of=/dev/sdc1 bs=1M

Following are the boot messages on FU540 five cores SMP platform:

HiFive-U serial #: 05374581

U-Boot SPL 2020.01-rc5-00007-g4a96c4e4ac-dirty (Dec 23 2019 - 16:49:18 +0530)
Trying to boot from MMC1


U-Boot 2020.01-rc5-00007-g4a96c4e4ac-dirty (Dec 23 2019 - 16:49:18 +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
Net:   eth0: ethernet at 10090000
Hit any key to stop autoboot:  0 
=> 
=> setenv serverip 172.16.35.74;setenv ipaddr 172.16.35.40;tftpboot 0x83000000 fit.itb;bootm 0x83000000
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: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ###################################
         876 KiB/s
done
Bytes transferred = 13823823 (d2ef4f hex)
## 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 [1]
[    0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x1d854df40, max_idle_ns: 3526361616960 ns
[    0.000007] sched_clock: 64 bits at 1000kHz, resolution 1000ns, wraps every 2199023255500ns
[    0.008475] Console: colour dummy device 80x25
[    0.012817] Calibrating delay loop (skipped), value calculated using timer frequency.. 2.00 BogoMIPS (lpj=4000)
[    0.022843] pid_max: default: 32768 minimum: 301
[    0.027914] Mount-cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
[    0.035329] Mountpoint-cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
[    0.044790] rcu: Hierarchical SRCU implementation.
[    0.049254] smp: Bringing up secondary CPUs ...
[    0.055029] smp: Brought up 1 node, 4 CPUs
[    0.059661] devtmpfs: initialized
[    0.063822] random: get_random_u32 called from bucket_table_alloc.isra.29+0x4e/0x160 with crng_init=0
[    0.072594] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[    0.082004] futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
[    0.089515] NET: Registered protocol family 16
[    0.105942] vgaarb: loaded
[    0.108197] SCSI subsystem initialized
[    0.111980] usbcore: registered new interface driver usbfs
[    0.117135] usbcore: registered new interface driver hub
[    0.122519] usbcore: registered new device driver usb
[    0.128108] clocksource: Switched to clocksource riscv_clocksource
[    0.140305] NET: Registered protocol family 2
[    0.144473] tcp_listen_portaddr_hash hash table entries: 4096 (order: 4, 65536 bytes, linear)
[    0.152647] TCP established hash table entries: 65536 (order: 7, 524288 bytes, linear)
[    0.162267] TCP bind hash table entries: 65536 (order: 8, 1048576 bytes, linear)
[    0.172183] TCP: Hash tables configured (established 65536 bind 65536)
[    0.178366] UDP hash table entries: 4096 (order: 5, 131072 bytes, linear)
[    0.185164] UDP-Lite hash table entries: 4096 (order: 5, 131072 bytes, linear)
[    0.192575] NET: Registered protocol family 1
[    0.196784] RPC: Registered named UNIX socket transport module.
[    0.202175] RPC: Registered udp transport module.
[    0.206857] RPC: Registered tcp transport module.
[    0.211533] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    0.217963] PCI: CLS 0 bytes, default 64
[    0.222163] Unpacking initramfs...
[    0.578809] Freeing initrd memory: 4460K
[    0.582984] workingset: timestamp_bits=62 max_order=21 bucket_order=0
[    0.596653] NFS: Registering the id_resolver key type
[    0.600998] Key type id_resolver registered
[    0.605099] Key type id_legacy registered
[    0.609098] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[    0.615937] 9p: Installing v9fs 9p2000 file system support
[    0.621588] NET: Registered protocol family 38
[    0.625709] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
[    0.633058] io scheduler mq-deadline registered
[    0.637568] io scheduler kyber registered
[    0.685647] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[    0.692241] 10010000.serial: ttySIF0 at MMIO 0x10010000 (irq = 4, base_baud = 0) is a SiFive UART v0
[    0.700625] printk: console [ttySIF0] enabled
[    0.700625] printk: console [ttySIF0] enabled
[    0.709285] printk: bootconsole [sifive0] disabled
[    0.709285] printk: bootconsole [sifive0] disabled
[    0.719077] 10011000.serial: ttySIF1 at MMIO 0x10011000 (irq = 1, base_baud = 0) is a SiFive UART v0
[    0.728423] [drm] radeon kernel modesetting enabled.
[    0.745353] loop: module loaded
[    0.748269] sifive_spi 10040000.spi: mapped; irq=3, cs=1
[    0.753551] sifive_spi 10050000.spi: mapped; irq=5, cs=1
[    0.758874] libphy: Fixed MDIO Bus: probed
[    0.762947] macb 10090000.ethernet: Registered clk switch 'sifive-gemgxl-mgmt'
[    0.769704] macb: GEM doesn't support hardware ptp.
[    0.774587] libphy: MACB_mii_bus: probed
[    0.940397] Microsemi VSC8541 SyncE 10090000.ethernet-ffffffff:00: attached PHY driver [Microsemi VSC8541 SyncE] (mii_bus:phy_addr=10090000.et)
[    0.954941] macb 10090000.ethernet eth0: Cadence GEM rev 0x10070109 at 0x10090000 irq 6 (70:b3:d5:b7:f5:81)
[    0.964744] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
[    0.970464] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
[    0.976458] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    0.982880] ehci-pci: EHCI PCI platform driver
[    0.987336] ehci-platform: EHCI generic platform driver
[    0.992593] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[    0.998695] ohci-pci: OHCI PCI platform driver
[    1.003140] ohci-platform: OHCI generic platform driver
[    1.008604] usbcore: registered new interface driver uas
[    1.013666] usbcore: registered new interface driver usb-storage
[    1.019742] mousedev: PS/2 mouse device common for all mice
[    1.050616] mmc_spi spi1.0: SD/MMC host mmc0, no DMA, no WP, no poweroff, cd polling
[    1.057762] usbcore: registered new interface driver usbhid
[    1.063145] usbhid: USB HID core driver
[    1.067858] NET: Registered protocol family 10
[    1.072475] Segment Routing with IPv6
[    1.075421] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[    1.081800] NET: Registered protocol family 17
[    1.085918] 9pnet: Installing 9P2000 support
[    1.090013] Key type dns_resolver registered
[    1.096438] Freeing unused kernel memory: 208K
[    1.100122] This architecture does not have kernel memory protection.
[    1.106536] 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.175230] mmc0: new SDHC card on SPI
[    1.180257] mmcblk0: mmc0:0000 SC16G 14.8 GiB 
[    1.214677]  mmcblk0: p1 p2 p4
modprobe: can't change directory to '/lib/modules': No such file or directory
Initializing random number generator... [    1.666442] random: dd: uninitialized urandom read (512 bytes read)
done.
Starting network: udhcpc: started, v1.29.3
udhcpc: sending discover
[    3.756777] macb 10090000.ethernet eth0: link up (100/Full)
[    3.761593] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
udhcpc: sending discover
udhcpc: sending select for 172.16.35.21
udhcpc: lease of 172.16.35.21 obtained, lease time 28800
deleting routers
adding dns 172.16.34.150
adding dns 172.16.24.25
OK
Starting dropbear sshd: [    4.457029] random: dropbear: uninitialized urandom read (32 bytes read)
OK

Welcome to Buildroot
buildroot login: root
Password: 
# 


Pragnesh Patel (3):
  riscv: Add place-holder for FU540 clk and gpio
  riscv: Add FU540 specific includes
  riscv: sifive: fu540: add SPL configuration

 arch/riscv/cpu/u-boot-spl.lds                 |    1 +
 arch/riscv/dts/fu540-c000-u-boot.dtsi         |   65 +
 .../dts/hifive-unleashed-a00-u-boot.dtsi      |   24 +
 arch/riscv/include/asm/arch-fu540/cache.h     |   43 +
 arch/riscv/include/asm/arch-fu540/clint.h     |   20 +
 arch/riscv/include/asm/arch-fu540/clk.h       |   14 +
 arch/riscv/include/asm/arch-fu540/gpio.h      |   42 +
 arch/riscv/include/asm/arch-fu540/i2c.h       |   48 +
 arch/riscv/include/asm/arch-fu540/otp.h       |   80 ++
 arch/riscv/include/asm/arch-fu540/spi.h       |   86 ++
 arch/riscv/include/asm/arch-fu540/uart.h      |   35 +
 arch/riscv/include/asm/arch-generic/gpio.h    |   32 +-
 arch/riscv/include/asm/csr.h                  |    2 +
 board/sifive/fu540/Kconfig                    |   11 +
 board/sifive/fu540/MAINTAINERS                |    1 +
 board/sifive/fu540/Makefile                   |    6 +
 board/sifive/fu540/ememoryotp.c               |  143 ++
 board/sifive/fu540/fu540.c                    |   31 +-
 board/sifive/fu540/include/ccache.h           |   47 +
 board/sifive/fu540/include/clkutils.h         |   75 +
 board/sifive/fu540/include/ddrregs.h          |  622 +++++++++
 board/sifive/fu540/include/ememoryotp.h       |   24 +
 board/sifive/fu540/include/fu540-memory-map.h |  427 ++++++
 board/sifive/fu540/include/i2c.h              |   49 +
 board/sifive/fu540/include/regconfig-ctl.h    |  274 ++++
 board/sifive/fu540/include/regconfig-phy.h    | 1224 +++++++++++++++++
 board/sifive/fu540/include/spi.h              |  233 ++++
 board/sifive/fu540/include/uart.h             |   54 +
 board/sifive/fu540/include/ux00ddr.h          |  268 ++++
 board/sifive/fu540/include/ux00prci.h         |  206 +++
 board/sifive/fu540/spl.c                      |  321 +++++
 board/sifive/fu540/uart.c                     |   64 +
 configs/sifive_fu540_spl_defconfig            |   23 +
 include/configs/sifive-fu540.h                |   17 +
 lib/Makefile                                  |    1 +
 35 files changed, 4583 insertions(+), 30 deletions(-)
 create mode 100644 arch/riscv/dts/fu540-c000-u-boot.dtsi
 create mode 100644 arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
 create mode 100644 arch/riscv/include/asm/arch-fu540/cache.h
 create mode 100644 arch/riscv/include/asm/arch-fu540/clint.h
 create mode 100644 arch/riscv/include/asm/arch-fu540/clk.h
 create mode 100644 arch/riscv/include/asm/arch-fu540/gpio.h
 create mode 100644 arch/riscv/include/asm/arch-fu540/i2c.h
 create mode 100644 arch/riscv/include/asm/arch-fu540/otp.h
 create mode 100644 arch/riscv/include/asm/arch-fu540/spi.h
 create mode 100644 arch/riscv/include/asm/arch-fu540/uart.h
 create mode 100644 board/sifive/fu540/ememoryotp.c
 create mode 100644 board/sifive/fu540/include/ccache.h
 create mode 100644 board/sifive/fu540/include/clkutils.h
 create mode 100644 board/sifive/fu540/include/ddrregs.h
 create mode 100644 board/sifive/fu540/include/ememoryotp.h
 create mode 100644 board/sifive/fu540/include/fu540-memory-map.h
 create mode 100644 board/sifive/fu540/include/i2c.h
 create mode 100644 board/sifive/fu540/include/regconfig-ctl.h
 create mode 100644 board/sifive/fu540/include/regconfig-phy.h
 create mode 100644 board/sifive/fu540/include/spi.h
 create mode 100644 board/sifive/fu540/include/uart.h
 create mode 100644 board/sifive/fu540/include/ux00ddr.h
 create mode 100644 board/sifive/fu540/include/ux00prci.h
 create mode 100644 board/sifive/fu540/spl.c
 create mode 100644 board/sifive/fu540/uart.c
 create mode 100644 configs/sifive_fu540_spl_defconfig

-- 
2.17.1

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

* [PATCH 1/3] riscv: Add place-holder for FU540 clk and gpio
  2019-12-31  6:30 [PATCH 0/3] RISC-V SiFive FU540 support SPL Pragnesh Patel
@ 2019-12-31  6:30 ` Pragnesh Patel
  2020-01-03 14:47   ` Bin Meng
  2019-12-31  6:30 ` [PATCH 2/3] riscv: Add FU540 specific includes Pragnesh Patel
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 19+ messages in thread
From: Pragnesh Patel @ 2019-12-31  6:30 UTC (permalink / raw)
  To: u-boot

Added FU540 place-holder so that SoC specific values
will be kept here.

Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
---
 arch/riscv/include/asm/arch-fu540/clk.h    | 14 ++++++++
 arch/riscv/include/asm/arch-fu540/gpio.h   | 42 ++++++++++++++++++++++
 arch/riscv/include/asm/arch-generic/gpio.h | 32 ++---------------
 board/sifive/fu540/Kconfig                 |  3 ++
 4 files changed, 62 insertions(+), 29 deletions(-)
 create mode 100644 arch/riscv/include/asm/arch-fu540/clk.h
 create mode 100644 arch/riscv/include/asm/arch-fu540/gpio.h

diff --git a/arch/riscv/include/asm/arch-fu540/clk.h b/arch/riscv/include/asm/arch-fu540/clk.h
new file mode 100644
index 0000000000..b39f5b55c9
--- /dev/null
+++ b/arch/riscv/include/asm/arch-fu540/clk.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2019 SiFive, Inc.
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ */
+
+#ifndef _CLK_FU540_H
+#define _CLK_FU540_H
+
+/* Note: This is a placeholder header for driver compilation. */
+
+#endif
diff --git a/arch/riscv/include/asm/arch-fu540/gpio.h b/arch/riscv/include/asm/arch-fu540/gpio.h
new file mode 100644
index 0000000000..f8ddd75852
--- /dev/null
+++ b/arch/riscv/include/asm/arch-fu540/gpio.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019 SiFive, Inc.
+ *
+ * Authors:
+ *   Sagar Shrikant Kadam <sagar.kadam@sifive.com>
+ */
+
+#ifndef _GPIO_FU540_H
+#define _GPIO_FU540_H
+
+#define GPIO_INPUT_VAL  (0x00)
+#define GPIO_INPUT_EN   (0x04)
+#define GPIO_OUTPUT_EN  (0x08)
+#define GPIO_OUTPUT_VAL (0x0C)
+#define GPIO_PULLUP_EN  (0x10)
+#define GPIO_DRIVE      (0x14)
+#define GPIO_RISE_IE    (0x18)
+#define GPIO_RISE_IP    (0x1C)
+#define GPIO_FALL_IE    (0x20)
+#define GPIO_FALL_IP    (0x24)
+#define GPIO_HIGH_IE    (0x28)
+#define GPIO_HIGH_IP    (0x2C)
+#define GPIO_LOW_IE     (0x30)
+#define GPIO_LOW_IP     (0x34)
+#define GPIO_IOF_EN     (0x38)
+#define GPIO_IOF_SEL    (0x3C)
+#define GPIO_OUTPUT_XOR    (0x40)
+
+#define NR_GPIOS       16
+
+enum gpio_state {
+	LOW,
+	HIGH
+};
+
+/* Details about a GPIO bank */
+struct sifive_gpio_platdata {
+	void *base;     /* address of registers in physical memory */
+};
+
+#endif /* _GPIO_FU540_H */
diff --git a/arch/riscv/include/asm/arch-generic/gpio.h b/arch/riscv/include/asm/arch-generic/gpio.h
index dfcb753051..5f0dc0a801 100644
--- a/arch/riscv/include/asm/arch-generic/gpio.h
+++ b/arch/riscv/include/asm/arch-generic/gpio.h
@@ -3,33 +3,7 @@
  * Copyright (C) 2019 SiFive, Inc.
  */
 
-#ifndef _GPIO_SIFIVE_H
-#define _GPIO_SIFIVE_H
+#ifndef __ASM_RISCV_ARCH_GPIO_H
+#define __ASM_RISCV_ARCH_GPIO_H
 
-#define GPIO_INPUT_VAL	0x00
-#define GPIO_INPUT_EN	0x04
-#define GPIO_OUTPUT_EN	0x08
-#define GPIO_OUTPUT_VAL	0x0C
-#define GPIO_RISE_IE	0x18
-#define GPIO_RISE_IP	0x1C
-#define GPIO_FALL_IE	0x20
-#define GPIO_FALL_IP	0x24
-#define GPIO_HIGH_IE	0x28
-#define GPIO_HIGH_IP	0x2C
-#define GPIO_LOW_IE	0x30
-#define GPIO_LOW_IP	0x34
-#define GPIO_OUTPUT_XOR	0x40
-
-#define NR_GPIOS	16
-
-enum gpio_state {
-	LOW,
-	HIGH
-};
-
-/* Details about a GPIO bank */
-struct sifive_gpio_platdata {
-	void *base;     /* address of registers in physical memory */
-};
-
-#endif /* _GPIO_SIFIVE_H */
+#endif /* __ASM_RISCV_ARCH_GPIO_H */
diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
index 5ca21474de..816a135b21 100644
--- a/board/sifive/fu540/Kconfig
+++ b/board/sifive/fu540/Kconfig
@@ -12,6 +12,9 @@ config SYS_CPU
 config SYS_CONFIG_NAME
 	default "sifive-fu540"
 
+config SYS_SOC
+	default "fu540"
+
 config SYS_TEXT_BASE
 	default 0x80000000 if !RISCV_SMODE
 	default 0x80200000 if RISCV_SMODE
-- 
2.17.1

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

* [PATCH 2/3] riscv: Add FU540 specific includes
  2019-12-31  6:30 [PATCH 0/3] RISC-V SiFive FU540 support SPL Pragnesh Patel
  2019-12-31  6:30 ` [PATCH 1/3] riscv: Add place-holder for FU540 clk and gpio Pragnesh Patel
@ 2019-12-31  6:30 ` Pragnesh Patel
  2020-01-03 14:51   ` Bin Meng
  2019-12-31  6:30 ` [PATCH 3/3] riscv: sifive: fu540: add SPL configuration Pragnesh Patel
  2020-01-14  5:10 ` [PATCH 0/3] RISC-V SiFive FU540 support SPL Anup Patel
  3 siblings, 1 reply; 19+ messages in thread
From: Pragnesh Patel @ 2019-12-31  6:30 UTC (permalink / raw)
  To: u-boot

Added headers needed by upcoming SPL support of FU540.

This headers are leveraged from FSBL
(https://github.com/sifive/freedom-u540-c000-bootloader.git)

Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
---
 arch/riscv/include/asm/arch-fu540/cache.h | 43 ++++++++++++
 arch/riscv/include/asm/arch-fu540/clint.h | 20 ++++++
 arch/riscv/include/asm/arch-fu540/i2c.h   | 48 +++++++++++++
 arch/riscv/include/asm/arch-fu540/otp.h   | 80 +++++++++++++++++++++
 arch/riscv/include/asm/arch-fu540/spi.h   | 86 +++++++++++++++++++++++
 arch/riscv/include/asm/arch-fu540/uart.h  | 35 +++++++++
 6 files changed, 312 insertions(+)
 create mode 100644 arch/riscv/include/asm/arch-fu540/cache.h
 create mode 100644 arch/riscv/include/asm/arch-fu540/clint.h
 create mode 100644 arch/riscv/include/asm/arch-fu540/i2c.h
 create mode 100644 arch/riscv/include/asm/arch-fu540/otp.h
 create mode 100644 arch/riscv/include/asm/arch-fu540/spi.h
 create mode 100644 arch/riscv/include/asm/arch-fu540/uart.h

diff --git a/arch/riscv/include/asm/arch-fu540/cache.h b/arch/riscv/include/asm/arch-fu540/cache.h
new file mode 100644
index 0000000000..9043779650
--- /dev/null
+++ b/arch/riscv/include/asm/arch-fu540/cache.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019 SiFive, Inc.
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#ifndef _CACHE_FU540_H
+#define _CACHE_FU540_H
+
+/* Register offsets */
+#define CCACHE_INFO         0x000
+#define CCACHE_ENABLE       0x008
+#define CCACHE_INJECT       0x040
+#define CCACHE_META_FIX     0x100
+#define CCACHE_DATA_FIX     0x140
+#define CCACHE_DATA_FAIL    0x160
+#define CCACHE_FLUSH64      0x200
+#define CCACHE_FLUSH32      0x240
+#define CCACHE_WAYS         0x800
+
+/* Bytes inside the INFO field */
+#define CCACHE_INFO_BANKS           0
+#define CCACHE_INFO_WAYS            1
+#define CCACHE_INFO_LG_SETS         2
+#define CCACHE_INFO_LG_BLOCKBYTES   3
+
+/* INJECT types */
+#define CCACHE_ECC_TOGGLE_DATA  0x00000
+#define CCACHE_ECC_TOGGLE_META  0x10000
+
+/* Offsets per FIX/FAIL */
+#define CCACHE_ECC_ADDR     0x0
+#define CCACHE_ECC_COUNT    0x8
+
+/* Interrupt Number offsets from Base */
+#define CCACHE_INT_META_FIX     0
+#define CCACHE_INT_DATA_FIX     1
+#define CCACHE_INT_DATA_FAIL    2
+
+#endif /* _CACHE_FU540_H */
diff --git a/arch/riscv/include/asm/arch-fu540/clint.h b/arch/riscv/include/asm/arch-fu540/clint.h
new file mode 100644
index 0000000000..f740f30f2d
--- /dev/null
+++ b/arch/riscv/include/asm/arch-fu540/clint.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019 SiFive, Inc.
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#ifndef _CLINT_FU540_H
+#define _CLINT_FU540_H
+
+#define CLINT_MSIP 0x0000
+#define CLINT_MSIP_size   0x4
+#define CLINT_MTIMECMP 0x4000
+#define CLINT_MTIMECMP_size 0x8
+#define CLINT_MTIME 0xBFF8
+#define CLINT_MTIME_size 0x8
+
+#endif /* _CLINT_FU540_H */
diff --git a/arch/riscv/include/asm/arch-fu540/i2c.h b/arch/riscv/include/asm/arch-fu540/i2c.h
new file mode 100644
index 0000000000..66cc3edd94
--- /dev/null
+++ b/arch/riscv/include/asm/arch-fu540/i2c.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019 SiFive, Inc.
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#ifndef _I2C_FU540_H
+#define _I2C_FU540_H
+
+// CHECK: word vs byte alignment
+// OC I2C Linux driver defines registers w/o alignment:
+// http://lxr.free-electrons.com/source/drivers/i2c/busses/i2c-ocores.c?v=4.6#L46
+//
+// However, register accessor functions use reg_shift value
+// http://lxr.free-electrons.com/source/drivers/i2c/busses/i2c-ocores.c?v=4.6#L80
+// which is platform specific:
+// http://lxr.free-electrons.com/source/drivers/i2c/busses/i2c-ocores.c?v=4.6#L346
+
+#define I2C_PRESCALER_LO  (0x00)
+#define I2C_PRESCALER_HI  (0x04)
+#define I2C_CONTROL       (0x08)
+#define I2C_DATA          (0x0C)
+#define I2C_CMD           (0x10) /* write only */
+#define I2C_STATUS        (0x10) /* read only, same address as I2C_CMD */
+
+// I2C_CONTROL register
+#define I2C_CONTROL_CORE_EN(x)  (((x) & 0x1) << 7)
+#define I2C_CONTROL_INT_EN(x)   (((x) & 0x1) << 6)
+
+// I2C_CMD register
+#define I2C_CMD_START(x)              (((x) & 0x1) << 7)
+#define I2C_CMD_STOP(x)               (((x) & 0x1) << 6)
+#define I2C_CMD_READ(x)               (((x) & 0x1) << 5)
+#define I2C_CMD_WRITE(x)              (((x) & 0x1) << 4)
+#define I2C_CMD_NACK(x)               (((x) & 0x1) << 3)
+#define I2C_CMD_IRQ_ACK(x)            (((x) & 0x1))
+
+// I2C_STATUS register
+#define I2C_STATUS_RECEIVED_NACK(x)   (((x) & 0x80) >> 7)
+#define I2C_STATUS_BUSY(x)            (((x) & 0x40) >> 6)
+#define I2C_STATUS_ARB_LOST(x)        (((x) & 0x20) >> 5)
+#define I2C_STATUS_TRS_INPROGRESS(x)  (((x) & 0x02) >> 1)
+#define I2C_STATUS_IRQ_FLAG(x)        (((x) & 0x01))
+
+#endif /* _I2C_FU540_H */
diff --git a/arch/riscv/include/asm/arch-fu540/otp.h b/arch/riscv/include/asm/arch-fu540/otp.h
new file mode 100644
index 0000000000..588e525765
--- /dev/null
+++ b/arch/riscv/include/asm/arch-fu540/otp.h
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019 SiFive, Inc.
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#ifndef _OTP_FU540_H
+#define _OTP_FU540_H
+
+/* Register offsets */
+
+#define EMEMORYOTP_PA                 0x00
+#define EMEMORYOTP_PAIO               0x04
+#define EMEMORYOTP_PAS                0x08
+#define EMEMORYOTP_PCE                0x0C
+#define EMEMORYOTP_PCLK               0x10
+#define EMEMORYOTP_PDIN               0x14
+#define EMEMORYOTP_PDOUT              0x18
+#define EMEMORYOTP_PDSTB              0x1C
+#define EMEMORYOTP_PPROG              0x20
+#define EMEMORYOTP_PTC                0x24
+#define EMEMORYOTP_PTM                0x28
+#define EMEMORYOTP_PTM_REP            0x2C
+#define EMEMORYOTP_PTR                0x30
+#define EMEMORYOTP_PTRIM              0x34
+#define EMEMORYOTP_PWE                0x38
+
+/* Timing delays (in us)
+ * MIN indicates that there is no maximum.
+ * TYP indicates that there is a maximum
+ * that should not be exceeded.
+ * When the minimums are < 1us, I just put 1us.
+ */
+
+#define EMEMORYOTP_MIN_TVDS      1
+#define EMEMORYOTP_MIN_TSAS      2
+#define EMEMORYOTP_MIN_TTAS      50
+#define EMEMORYOTP_MIN_TTAH      1
+#define EMEMORYOTP_MIN_TASH      1
+#define EMEMORYOTP_MIN_TMS       1
+#define EMEMORYOTP_MIN_TCS       10
+#define EMEMORYOTP_MIN_TMH       1
+#define EMEMORYOTP_MIN_TAS       50
+
+#define EMEMORYOTP_MAX_TCD       1
+#define EMEMORYOTP_MIN_TKH       1
+
+// Note: This has an upper limit of 100.
+#define EMEMORYOTP_MIN_TCSP      10
+#define EMEMORYOTP_TYP_TCSP      11
+
+// This has an upper limit of 20.
+#define EMEMORYOTP_MIN_TPPS      5
+#define EMEMORYOTP_TYP_TPPS      6
+
+// This has an upper limit of 20.
+#define EMEMORYOTP_MIN_TPPH      1
+#define EMEMORYOTP_TYP_TPPH      2
+
+// This has upper limit of 100.
+#define EMEMORYOTP_MIN_TPPR      5
+#define EMEMORYOTP_TYP_TPPR      6
+
+// This has upper limit of 20
+#define EMEMORYOTP_MIN_TPW       10
+#define EMEMORYOTP_TYP_TPW       11
+
+#define EMEMORYOTP_MIN_TASP      1
+#define EMEMORYOTP_MIN_TDSP      1
+
+#define EMEMORYOTP_MIN_TAHP      1
+#define EMEMORYOTP_MIN_TDHP      1
+// This has a max of 5!
+#define EMEMORYOTP_MIN_TPWI      1
+#define EMEMORYOTP_TYP_TPWI      2
+
+#endif /* _OTP_FU540_H */
diff --git a/arch/riscv/include/asm/arch-fu540/spi.h b/arch/riscv/include/asm/arch-fu540/spi.h
new file mode 100644
index 0000000000..ea3f5344b7
--- /dev/null
+++ b/arch/riscv/include/asm/arch-fu540/spi.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019 SiFive, Inc.
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#ifndef _SPI_FU540_H
+#define _SPI_FU540_H
+
+/* Register offsets */
+
+#define SPI_REG_SCKDIV          0x00
+#define SPI_REG_SCKMODE         0x04
+#define SPI_REG_CSID            0x10
+#define SPI_REG_CSDEF           0x14
+#define SPI_REG_CSMODE          0x18
+
+#define SPI_REG_DCSSCK          0x28
+#define SPI_REG_DSCKCS          0x2a
+#define SPI_REG_DINTERCS        0x2c
+#define SPI_REG_DINTERXFR       0x2e
+
+#define SPI_REG_FMT             0x40
+#define SPI_REG_TXFIFO          0x48
+#define SPI_REG_RXFIFO          0x4c
+#define SPI_REG_TXCTRL          0x50
+#define SPI_REG_RXCTRL          0x54
+
+#define SPI_REG_FCTRL           0x60
+#define SPI_REG_FFMT            0x64
+
+#define SPI_REG_IE              0x70
+#define SPI_REG_IP              0x74
+
+/* Fields */
+
+#define SPI_SCK_PHA             0x1
+#define SPI_SCK_POL             0x2
+
+#define SPI_FMT_PROTO(x)        ((x) & 0x3)
+#define SPI_FMT_ENDIAN(x)       (((x) & 0x1) << 2)
+#define SPI_FMT_DIR(x)          (((x) & 0x1) << 3)
+#define SPI_FMT_LEN(x)          (((x) & 0xf) << 16)
+
+/* TXCTRL register */
+#define SPI_TXWM(x)             ((x) & 0xffff)
+/* RXCTRL register */
+#define SPI_RXWM(x)             ((x) & 0xffff)
+
+#define SPI_IP_TXWM             0x1
+#define SPI_IP_RXWM             0x2
+
+#define SPI_FCTRL_EN            0x1
+
+#define SPI_INSN_CMD_EN         0x1
+#define SPI_INSN_ADDR_LEN(x)    (((x) & 0x7) << 1)
+#define SPI_INSN_PAD_CNT(x)     (((x) & 0xf) << 4)
+#define SPI_INSN_CMD_PROTO(x)   (((x) & 0x3) << 8)
+#define SPI_INSN_ADDR_PROTO(x)  (((x) & 0x3) << 10)
+#define SPI_INSN_DATA_PROTO(x)  (((x) & 0x3) << 12)
+#define SPI_INSN_CMD_CODE(x)    (((x) & 0xff) << 16)
+#define SPI_INSN_PAD_CODE(x)    (((x) & 0xff) << 24)
+
+#define SPI_TXFIFO_FULL  BIT(31)
+#define SPI_RXFIFO_EMPTY BIT(31)
+
+/* Values */
+
+#define SPI_CSMODE_AUTO         0
+#define SPI_CSMODE_HOLD         2
+#define SPI_CSMODE_OFF          3
+
+#define SPI_DIR_RX              0
+#define SPI_DIR_TX              1
+
+#define SPI_PROTO_S             0
+#define SPI_PROTO_D             1
+#define SPI_PROTO_Q             2
+
+#define SPI_ENDIAN_MSB          0
+#define SPI_ENDIAN_LSB          1
+
+#endif /* _SPI_FU540_H */
diff --git a/arch/riscv/include/asm/arch-fu540/uart.h b/arch/riscv/include/asm/arch-fu540/uart.h
new file mode 100644
index 0000000000..31ae079a18
--- /dev/null
+++ b/arch/riscv/include/asm/arch-fu540/uart.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019 SiFive, Inc.
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#ifndef _UART_FU540_H
+#define _UART_FU540_H
+
+/* Register offsets */
+#define UART_REG_TXFIFO         0x00
+#define UART_REG_RXFIFO         0x04
+#define UART_REG_TXCTRL         0x08
+#define UART_REG_RXCTRL         0x0c
+#define UART_REG_IE             0x10
+#define UART_REG_IP             0x14
+#define UART_REG_DIV            0x18
+
+/* TXCTRL register */
+#define UART_TXEN               0x1
+#define UART_TXNSTOP            0x2
+#define UART_TXWM(x)            (((x) & 0xffff) << 16)
+
+/* RXCTRL register */
+#define UART_RXEN               0x1
+#define UART_RXWM(x)            (((x) & 0xffff) << 16)
+
+/* IP register */
+#define UART_IP_TXWM            0x1
+#define UART_IP_RXWM            0x2
+
+#endif /* _UART_FU540_H */
-- 
2.17.1

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

* [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
  2019-12-31  6:30 [PATCH 0/3] RISC-V SiFive FU540 support SPL Pragnesh Patel
  2019-12-31  6:30 ` [PATCH 1/3] riscv: Add place-holder for FU540 clk and gpio Pragnesh Patel
  2019-12-31  6:30 ` [PATCH 2/3] riscv: Add FU540 specific includes Pragnesh Patel
@ 2019-12-31  6:30 ` Pragnesh Patel
  2019-12-31 17:18   ` Amit Tomer
                     ` (2 more replies)
  2020-01-14  5:10 ` [PATCH 0/3] RISC-V SiFive FU540 support SPL Anup Patel
  3 siblings, 3 replies; 19+ messages in thread
From: Pragnesh Patel @ 2019-12-31  6:30 UTC (permalink / raw)
  To: u-boot

This patch provides sifive_fu540_spl_defconfig which can support
U-boot SPL to boot from L2 LIM (0x0800_0000) and then boot FIT
image including OpenSBI FW_DYNAMIC firmware and U-Boot proper
images from MMC boot devices.

With sifive_fu540_spl_defconfig:

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 SD card (replace fw_payload.bin with u-boot.itb)
into RAM.

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>
---
 arch/riscv/cpu/u-boot-spl.lds                 |    1 +
 arch/riscv/dts/fu540-c000-u-boot.dtsi         |   65 +
 .../dts/hifive-unleashed-a00-u-boot.dtsi      |   24 +
 arch/riscv/include/asm/csr.h                  |    2 +
 board/sifive/fu540/Kconfig                    |    8 +
 board/sifive/fu540/MAINTAINERS                |    1 +
 board/sifive/fu540/Makefile                   |    6 +
 board/sifive/fu540/ememoryotp.c               |  143 ++
 board/sifive/fu540/fu540.c                    |   31 +-
 board/sifive/fu540/include/ccache.h           |   47 +
 board/sifive/fu540/include/clkutils.h         |   75 +
 board/sifive/fu540/include/ddrregs.h          |  622 +++++++++
 board/sifive/fu540/include/ememoryotp.h       |   24 +
 board/sifive/fu540/include/fu540-memory-map.h |  427 ++++++
 board/sifive/fu540/include/i2c.h              |   49 +
 board/sifive/fu540/include/regconfig-ctl.h    |  274 ++++
 board/sifive/fu540/include/regconfig-phy.h    | 1224 +++++++++++++++++
 board/sifive/fu540/include/spi.h              |  233 ++++
 board/sifive/fu540/include/uart.h             |   54 +
 board/sifive/fu540/include/ux00ddr.h          |  268 ++++
 board/sifive/fu540/include/ux00prci.h         |  206 +++
 board/sifive/fu540/spl.c                      |  321 +++++
 board/sifive/fu540/uart.c                     |   64 +
 configs/sifive_fu540_spl_defconfig            |   23 +
 include/configs/sifive-fu540.h                |   17 +
 lib/Makefile                                  |    1 +
 26 files changed, 4209 insertions(+), 1 deletion(-)
 create mode 100644 arch/riscv/dts/fu540-c000-u-boot.dtsi
 create mode 100644 arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
 create mode 100644 board/sifive/fu540/ememoryotp.c
 create mode 100644 board/sifive/fu540/include/ccache.h
 create mode 100644 board/sifive/fu540/include/clkutils.h
 create mode 100644 board/sifive/fu540/include/ddrregs.h
 create mode 100644 board/sifive/fu540/include/ememoryotp.h
 create mode 100644 board/sifive/fu540/include/fu540-memory-map.h
 create mode 100644 board/sifive/fu540/include/i2c.h
 create mode 100644 board/sifive/fu540/include/regconfig-ctl.h
 create mode 100644 board/sifive/fu540/include/regconfig-phy.h
 create mode 100644 board/sifive/fu540/include/spi.h
 create mode 100644 board/sifive/fu540/include/uart.h
 create mode 100644 board/sifive/fu540/include/ux00ddr.h
 create mode 100644 board/sifive/fu540/include/ux00prci.h
 create mode 100644 board/sifive/fu540/spl.c
 create mode 100644 board/sifive/fu540/uart.c
 create mode 100644 configs/sifive_fu540_spl_defconfig

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 = .;
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..b86cdfb38d
--- /dev/null
+++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 SiFive, Inc
+ */
+
+/ {
+	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;
+			cpu1_intc: interrupt-controller {
+				u-boot,dm-spl;
+			};
+		};
+		cpu2: cpu at 2 {
+			u-boot,dm-spl;
+			cpu2_intc: interrupt-controller {
+				u-boot,dm-spl;
+			};
+		};
+		cpu3: cpu at 3 {
+			u-boot,dm-spl;
+			cpu3_intc: interrupt-controller {
+				u-boot,dm-spl;
+			};
+		};
+		cpu4: cpu at 4 {
+			u-boot,dm-spl;
+			cpu4_intc: interrupt-controller {
+				u-boot,dm-spl;
+			};
+		};
+	};
+
+	soc {
+		u-boot,dm-spl;
+		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
new file mode 100644
index 0000000000..9b59f4ee14
--- /dev/null
+++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 SiFive, Inc
+ */
+
+#include "fu540-c000-u-boot.dtsi"
+
+/ {
+	hfclk {
+		u-boot,dm-spl;
+	};
+
+	rtcclk {
+		u-boot,dm-spl;
+	};
+};
+
+&qspi2 {
+
+	mmc at 0 {
+		u-boot,dm-spl;
+	};
+
+};
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index d1520743a2..125c05dd8a 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -103,6 +103,8 @@
 #define CSR_TIMEH		0xc81
 #define CSR_INSTRETH		0xc82
 #define CSR_MHARTID		0xf14
+#define CSR_MCYCLE		0xb00
+#define CSR_MCYCLEH		0xb80
 
 #ifndef __ASSEMBLY__
 
diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
index 816a135b21..ac7c6bff37 100644
--- a/board/sifive/fu540/Kconfig
+++ b/board/sifive/fu540/Kconfig
@@ -16,12 +16,20 @@ config SYS_SOC
 	default "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/MAINTAINERS b/board/sifive/fu540/MAINTAINERS
index 702d803ad8..42c3f3deb0 100644
--- a/board/sifive/fu540/MAINTAINERS
+++ b/board/sifive/fu540/MAINTAINERS
@@ -7,3 +7,4 @@ S:	Maintained
 F:	board/sifive/fu540/
 F:	include/configs/sifive-fu540.h
 F:	configs/sifive_fu540_defconfig
+F:	configs/sifive_fu540_spl_defconfig
diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
index 6e1862c475..e532beb9d5 100644
--- a/board/sifive/fu540/Makefile
+++ b/board/sifive/fu540/Makefile
@@ -3,3 +3,9 @@
 # Copyright (c) 2019 Western Digital Corporation or its affiliates.
 
 obj-y	+= fu540.o
+
+ifdef CONFIG_SPL_BUILD
+obj-y += spl.o
+obj-y += ememoryotp.o
+obj-y += uart.o
+endif
diff --git a/board/sifive/fu540/ememoryotp.c b/board/sifive/fu540/ememoryotp.c
new file mode 100644
index 0000000000..994724af37
--- /dev/null
+++ b/board/sifive/fu540/ememoryotp.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#include <stdint.h>
+#include "include/fu540-memory-map.h"
+#include "include/clkutils.h"
+#include "include/ememoryotp.h"
+
+#define max(x, y) ((x) > (y) ? (x) : (y))
+
+extern inline void clkutils_delay_ns(int delay_ns);
+
+void ememory_otp_power_up_sequence(void)
+{
+	// Probably don't need to do this, since
+	// all the other stuff has been happening.
+	// But it is on the wave form.
+	clkutils_delay_ns(EMEMORYOTP_MIN_TVDS * 1000);
+
+	EMEMORYOTP_REG(EMEMORYOTP_PDSTB) = 1;
+	clkutils_delay_ns(EMEMORYOTP_MIN_TSAS * 1000);
+
+	EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 1;
+	clkutils_delay_ns(EMEMORYOTP_MIN_TTAS * 1000);
+}
+
+void ememory_otp_power_down_sequence(void)
+{
+	clkutils_delay_ns(EMEMORYOTP_MIN_TTAH * 1000);
+	EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 0;
+	clkutils_delay_ns(EMEMORYOTP_MIN_TASH * 1000);
+	EMEMORYOTP_REG(EMEMORYOTP_PDSTB) = 0;
+	// No delay indicated after this
+}
+
+void ememory_otp_begin_read(void)
+{
+	// Initialize
+	EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
+	EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
+	EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
+	EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
+	EMEMORYOTP_REG(EMEMORYOTP_PTM) = 0;
+	clkutils_delay_ns(EMEMORYOTP_MIN_TMS * 1000);
+
+	// Enable chip select
+
+	EMEMORYOTP_REG(EMEMORYOTP_PCE) = 1;
+	clkutils_delay_ns(EMEMORYOTP_MIN_TCS * 1000);
+}
+
+void ememory_otp_exit_read(void)
+{
+	EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
+	EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
+	EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
+	EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
+	// Disable chip select
+	EMEMORYOTP_REG(EMEMORYOTP_PCE) = 0;
+	// Wait before changing PTM
+	clkutils_delay_ns(EMEMORYOTP_MIN_TMH * 1000);
+}
+
+unsigned int ememory_otp_read(int address)
+{
+	unsigned int read_value;
+
+	EMEMORYOTP_REG(EMEMORYOTP_PA) = address;
+	// Toggle clock
+	clkutils_delay_ns(EMEMORYOTP_MIN_TAS * 1000);
+	EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 1;
+	// Insert delay until data is ready.
+	// There are lots of delays
+	// on the chart, but I think this is the most relevant.
+	int delay = max(EMEMORYOTP_MAX_TCD, EMEMORYOTP_MIN_TKH);
+
+	clkutils_delay_ns(delay * 1000);
+	EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
+	read_value = EMEMORYOTP_REG(EMEMORYOTP_PDOUT);
+	// Could check here for things like TCYC < TAH + TCD
+	return read_value;
+}
+
+void ememory_otp_pgm_entry(void)
+{
+	EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
+	EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
+	EMEMORYOTP_REG(EMEMORYOTP_PAS) = 0;
+	EMEMORYOTP_REG(EMEMORYOTP_PAIO) = 0;
+	EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
+	EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
+	EMEMORYOTP_REG(EMEMORYOTP_PTM) = 2;
+	clkutils_delay_ns(EMEMORYOTP_MIN_TMS * 1000);
+	EMEMORYOTP_REG(EMEMORYOTP_PCE) = 1;
+	clkutils_delay_ns(EMEMORYOTP_TYP_TCSP * 1000);
+	EMEMORYOTP_REG(EMEMORYOTP_PPROG) = 1;
+	clkutils_delay_ns(EMEMORYOTP_TYP_TPPS * 1000);
+	EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 1;
+}
+
+void ememory_otp_pgm_exit(void)
+{
+	EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
+	clkutils_delay_ns(EMEMORYOTP_TYP_TPPH * 1000);
+	EMEMORYOTP_REG(EMEMORYOTP_PPROG) = 0;
+	clkutils_delay_ns(EMEMORYOTP_TYP_TPPR * 1000);
+	EMEMORYOTP_REG(EMEMORYOTP_PCE) = 0;
+	clkutils_delay_ns(EMEMORYOTP_MIN_TMH * 1000);
+	EMEMORYOTP_REG(EMEMORYOTP_PTM) = 0;
+}
+
+void ememory_otp_pgm_access(int address, unsigned int write_data)
+{
+	int i;
+
+	EMEMORYOTP_REG(EMEMORYOTP_PA) = address;
+	for (int pas = 0; pas < 2; pas++) {
+		EMEMORYOTP_REG(EMEMORYOTP_PAS) = pas;
+		for (i = 0; i < 32; i++) {
+			EMEMORYOTP_REG(EMEMORYOTP_PAIO) = i;
+			EMEMORYOTP_REG(EMEMORYOTP_PDIN) = ((write_data >> i) &
+							   1);
+
+			int delay = max(EMEMORYOTP_MIN_TASP,
+					EMEMORYOTP_MIN_TDSP);
+
+			clkutils_delay_ns(delay * 1000);
+			EMEMORYOTP_REG(EMEMORYOTP_PWE) = 1;
+			clkutils_delay_ns(EMEMORYOTP_TYP_TPW * 1000);
+			EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
+			delay = max(EMEMORYOTP_MIN_TAHP, EMEMORYOTP_MIN_TDHP);
+			delay = max(delay, EMEMORYOTP_TYP_TPWI);
+			clkutils_delay_ns(delay * 1000);
+		}
+	}
+	EMEMORYOTP_REG(EMEMORYOTP_PAS) = 0;
+}
diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
index 47a2090251..e91418a88a 100644
--- a/board/sifive/fu540/fu540.c
+++ b/board/sifive/fu540/fu540.c
@@ -10,6 +10,9 @@
 #include <dm.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <spl.h>
+#include "include/ccache.h"
+#include "include/fu540-memory-map.h"
 
 #ifdef CONFIG_MISC_INIT_R
 
@@ -143,7 +146,33 @@ int misc_init_r(void)
 
 int board_init(void)
 {
-	/* For now nothing to do here. */
+	/* enable all cache ways */
+	ccache_enable_ways(CCACHE_CTRL_ADDR, 15);
+	return 0;
+}
+
+#ifdef CONFIG_SPL
+void board_boot_order(u32 *spl_boot_list)
+{
+	u8 i;
+	u32 boot_devices[] = {
+#ifdef CONFIG_SPL_RAM_SUPPORT
+		BOOT_DEVICE_RAM,
+#endif
+#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/include/ccache.h b/board/sifive/fu540/include/ccache.h
new file mode 100644
index 0000000000..c7978ebdee
--- /dev/null
+++ b/board/sifive/fu540/include/ccache.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#ifndef FU540_CCACHE_H
+#define FU540_CCACHE_H
+
+#include <asm/arch/cache.h>
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+#include <stdatomic.h>
+#include <linux/types.h>
+
+// Block memory access until operation completed
+static inline void ccache_barrier_0(void)
+{
+	asm volatile("fence rw, io" : : : "memory");
+}
+
+static inline void ccache_barrier_1(void)
+{
+	asm volatile("fence io, rw" : : : "memory");
+}
+
+// Enable ways; allow cache to use these ways
+static inline u8 ccache_enable_ways(u64 base_addr, u8 value)
+{
+	u32 old;
+
+	volatile _Atomic(u32) * enable = (_Atomic(u32) *)(base_addr +
+					  CCACHE_ENABLE);
+	ccache_barrier_0();
+	old = atomic_exchange_explicit(enable, value, memory_order_relaxed);
+	ccache_barrier_1();
+	return old;
+}
+
+#endif
+
+#endif /* FU540_CCACHE_H */
diff --git a/board/sifive/fu540/include/clkutils.h b/board/sifive/fu540/include/clkutils.h
new file mode 100644
index 0000000000..dbb260a1c3
--- /dev/null
+++ b/board/sifive/fu540/include/clkutils.h
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+#include <asm/encoding.h>
+#include "fu540-memory-map.h"
+
+// Inlining header functions in C
+// https://stackoverflow.com/a/23699777/7433423
+inline u64 clkutils_read_mtime(void)
+{
+#if __riscv_xlen == 32
+	u32 mtime_hi_0;
+	u32 mtime_lo;
+	u32 mtime_hi_1;
+
+	do {
+		mtime_hi_0 = CLINT_REG(CLINT_MTIME + 4);
+		mtime_lo   = CLINT_REG(CLINT_MTIME + 0);
+		mtime_hi_1 = CLINT_REG(CLINT_MTIME + 4);
+	} while (mtime_hi_0 != mtime_hi_1);
+
+	return (((u64)mtime_hi_1 << 32) | ((u64)mtime_lo));
+#else
+	return CLINT_REG64(CLINT_MTIME);
+#endif
+}
+
+static inline u64 clkutils_read_mcycle(void)
+{
+#if __riscv_xlen == 32
+	u32 mcycle_hi_0;
+	u32 mcycle_lo;
+	u32 mcycle_hi_1;
+
+	do {
+		mcycle_hi_0 = read_csr(mcycleh);
+		mcycle_lo   = read_csr(mcycle);
+		mcycle_hi_1 = read_csr(mcycleh);
+	} while (mcycle_hi_0 != mcycle_hi_1);
+
+	return (((u64)mcycle_hi_1 << 32) | ((u64)mcycle_lo));
+#else
+	return csr_read(CSR_MCYCLE);
+#endif
+}
+
+// Note that since this runs off RTC, which is
+// currently ~1-10MHz, this function is
+// not acccurate for small delays.
+// In the future, we may want to determine whether to
+// use RTC vs mcycle, or create a different function
+// based off mcycle.
+// We add 1 to the then value because otherwise, if you wanted
+// to delay up to RTC_PERIOD_NS-1 (for example), you wouldn't delay
+// at all. So this function delays AT LEAST delay_ns.
+inline void clkutils_delay_ns(int delay_ns)
+{
+	u64 now = clkutils_read_mtime();
+	u64 then = now + delay_ns / RTC_PERIOD_NS + 1;
+
+	do {
+		now = clkutils_read_mtime();
+	} while (now < then);
+}
+
+#endif /* !__ASSEMBLER__ */
diff --git a/board/sifive/fu540/include/ddrregs.h b/board/sifive/fu540/include/ddrregs.h
new file mode 100644
index 0000000000..e436496d87
--- /dev/null
+++ b/board/sifive/fu540/include/ddrregs.h
@@ -0,0 +1,622 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#include <stdint.h>
+
+u32 DENALI_PHY_DATA[1215] = {
+	DENALI_PHY_00_DATA, DENALI_PHY_01_DATA, DENALI_PHY_02_DATA,
+	DENALI_PHY_03_DATA, DENALI_PHY_04_DATA, DENALI_PHY_05_DATA,
+	DENALI_PHY_06_DATA, DENALI_PHY_07_DATA, DENALI_PHY_08_DATA,
+	DENALI_PHY_09_DATA,
+	DENALI_PHY_10_DATA, DENALI_PHY_11_DATA, DENALI_PHY_12_DATA,
+	DENALI_PHY_13_DATA, DENALI_PHY_14_DATA, DENALI_PHY_15_DATA,
+	DENALI_PHY_16_DATA, DENALI_PHY_17_DATA, DENALI_PHY_18_DATA,
+	DENALI_PHY_19_DATA,
+	DENALI_PHY_20_DATA, DENALI_PHY_21_DATA, DENALI_PHY_22_DATA,
+	DENALI_PHY_23_DATA, DENALI_PHY_24_DATA, DENALI_PHY_25_DATA,
+	DENALI_PHY_26_DATA, DENALI_PHY_27_DATA, DENALI_PHY_28_DATA,
+	DENALI_PHY_29_DATA,
+	DENALI_PHY_30_DATA, DENALI_PHY_31_DATA, DENALI_PHY_32_DATA,
+	DENALI_PHY_33_DATA, DENALI_PHY_34_DATA, DENALI_PHY_35_DATA,
+	DENALI_PHY_36_DATA, DENALI_PHY_37_DATA, DENALI_PHY_38_DATA,
+	DENALI_PHY_39_DATA,
+	DENALI_PHY_40_DATA, DENALI_PHY_41_DATA, DENALI_PHY_42_DATA,
+	DENALI_PHY_43_DATA, DENALI_PHY_44_DATA, DENALI_PHY_45_DATA,
+	DENALI_PHY_46_DATA, DENALI_PHY_47_DATA, DENALI_PHY_48_DATA,
+	DENALI_PHY_49_DATA,
+	DENALI_PHY_50_DATA, DENALI_PHY_51_DATA, DENALI_PHY_52_DATA,
+	DENALI_PHY_53_DATA, DENALI_PHY_54_DATA, DENALI_PHY_55_DATA,
+	DENALI_PHY_56_DATA, DENALI_PHY_57_DATA, DENALI_PHY_58_DATA,
+	DENALI_PHY_59_DATA,
+	DENALI_PHY_60_DATA, DENALI_PHY_61_DATA, DENALI_PHY_62_DATA,
+	DENALI_PHY_63_DATA, DENALI_PHY_64_DATA, DENALI_PHY_65_DATA,
+	DENALI_PHY_66_DATA, DENALI_PHY_67_DATA, DENALI_PHY_68_DATA,
+	DENALI_PHY_69_DATA,
+	DENALI_PHY_70_DATA, DENALI_PHY_71_DATA, DENALI_PHY_72_DATA,
+	DENALI_PHY_73_DATA, DENALI_PHY_74_DATA, DENALI_PHY_75_DATA,
+	DENALI_PHY_76_DATA, DENALI_PHY_77_DATA, DENALI_PHY_78_DATA,
+	DENALI_PHY_79_DATA,
+	DENALI_PHY_80_DATA, DENALI_PHY_81_DATA, DENALI_PHY_82_DATA,
+	DENALI_PHY_83_DATA, DENALI_PHY_84_DATA, DENALI_PHY_85_DATA,
+	DENALI_PHY_86_DATA, DENALI_PHY_87_DATA, DENALI_PHY_88_DATA,
+	DENALI_PHY_89_DATA,
+	DENALI_PHY_90_DATA, DENALI_PHY_91_DATA, DENALI_PHY_92_DATA,
+	DENALI_PHY_93_DATA, DENALI_PHY_94_DATA, DENALI_PHY_95_DATA,
+	DENALI_PHY_96_DATA, DENALI_PHY_97_DATA, DENALI_PHY_98_DATA,
+	DENALI_PHY_99_DATA,
+
+	DENALI_PHY_100_DATA, DENALI_PHY_101_DATA, DENALI_PHY_102_DATA,
+	DENALI_PHY_103_DATA, DENALI_PHY_104_DATA, DENALI_PHY_105_DATA,
+	DENALI_PHY_106_DATA, DENALI_PHY_107_DATA, DENALI_PHY_108_DATA,
+	DENALI_PHY_109_DATA,
+	DENALI_PHY_110_DATA, DENALI_PHY_111_DATA, DENALI_PHY_112_DATA,
+	DENALI_PHY_113_DATA, DENALI_PHY_114_DATA, DENALI_PHY_115_DATA,
+	DENALI_PHY_116_DATA, DENALI_PHY_117_DATA, DENALI_PHY_118_DATA,
+	DENALI_PHY_119_DATA,
+	DENALI_PHY_120_DATA, DENALI_PHY_121_DATA, DENALI_PHY_122_DATA,
+	DENALI_PHY_123_DATA, DENALI_PHY_124_DATA, DENALI_PHY_125_DATA,
+	DENALI_PHY_126_DATA, DENALI_PHY_127_DATA, DENALI_PHY_128_DATA,
+	DENALI_PHY_129_DATA,
+	DENALI_PHY_130_DATA, DENALI_PHY_131_DATA, DENALI_PHY_132_DATA,
+	DENALI_PHY_133_DATA, DENALI_PHY_134_DATA, DENALI_PHY_135_DATA,
+	DENALI_PHY_136_DATA, DENALI_PHY_137_DATA, DENALI_PHY_138_DATA,
+	DENALI_PHY_139_DATA,
+	DENALI_PHY_140_DATA, DENALI_PHY_141_DATA, DENALI_PHY_142_DATA,
+	DENALI_PHY_143_DATA, DENALI_PHY_144_DATA, DENALI_PHY_145_DATA,
+	DENALI_PHY_146_DATA, DENALI_PHY_147_DATA, DENALI_PHY_148_DATA,
+	DENALI_PHY_149_DATA,
+	DENALI_PHY_150_DATA, DENALI_PHY_151_DATA, DENALI_PHY_152_DATA,
+	DENALI_PHY_153_DATA, DENALI_PHY_154_DATA, DENALI_PHY_155_DATA,
+	DENALI_PHY_156_DATA, DENALI_PHY_157_DATA, DENALI_PHY_158_DATA,
+	DENALI_PHY_159_DATA,
+	DENALI_PHY_160_DATA, DENALI_PHY_161_DATA, DENALI_PHY_162_DATA,
+	DENALI_PHY_163_DATA, DENALI_PHY_164_DATA, DENALI_PHY_165_DATA,
+	DENALI_PHY_166_DATA, DENALI_PHY_167_DATA, DENALI_PHY_168_DATA,
+	DENALI_PHY_169_DATA,
+	DENALI_PHY_170_DATA, DENALI_PHY_171_DATA, DENALI_PHY_172_DATA,
+	DENALI_PHY_173_DATA, DENALI_PHY_174_DATA, DENALI_PHY_175_DATA,
+	DENALI_PHY_176_DATA, DENALI_PHY_177_DATA, DENALI_PHY_178_DATA,
+	DENALI_PHY_179_DATA,
+	DENALI_PHY_180_DATA, DENALI_PHY_181_DATA, DENALI_PHY_182_DATA,
+	DENALI_PHY_183_DATA, DENALI_PHY_184_DATA, DENALI_PHY_185_DATA,
+	DENALI_PHY_186_DATA, DENALI_PHY_187_DATA, DENALI_PHY_188_DATA,
+	DENALI_PHY_189_DATA,
+	DENALI_PHY_190_DATA, DENALI_PHY_191_DATA, DENALI_PHY_192_DATA,
+	DENALI_PHY_193_DATA, DENALI_PHY_194_DATA, DENALI_PHY_195_DATA,
+	DENALI_PHY_196_DATA, DENALI_PHY_197_DATA, DENALI_PHY_198_DATA,
+	DENALI_PHY_199_DATA,
+
+	DENALI_PHY_200_DATA, DENALI_PHY_201_DATA, DENALI_PHY_202_DATA,
+	DENALI_PHY_203_DATA, DENALI_PHY_204_DATA, DENALI_PHY_205_DATA,
+	DENALI_PHY_206_DATA, DENALI_PHY_207_DATA, DENALI_PHY_208_DATA,
+	DENALI_PHY_209_DATA,
+	DENALI_PHY_210_DATA, DENALI_PHY_211_DATA, DENALI_PHY_212_DATA,
+	DENALI_PHY_213_DATA, DENALI_PHY_214_DATA, DENALI_PHY_215_DATA,
+	DENALI_PHY_216_DATA, DENALI_PHY_217_DATA, DENALI_PHY_218_DATA,
+	DENALI_PHY_219_DATA,
+	DENALI_PHY_220_DATA, DENALI_PHY_221_DATA, DENALI_PHY_222_DATA,
+	DENALI_PHY_223_DATA, DENALI_PHY_224_DATA, DENALI_PHY_225_DATA,
+	DENALI_PHY_226_DATA, DENALI_PHY_227_DATA, DENALI_PHY_228_DATA,
+	DENALI_PHY_229_DATA,
+	DENALI_PHY_230_DATA, DENALI_PHY_231_DATA, DENALI_PHY_232_DATA,
+	DENALI_PHY_233_DATA, DENALI_PHY_234_DATA, DENALI_PHY_235_DATA,
+	DENALI_PHY_236_DATA, DENALI_PHY_237_DATA, DENALI_PHY_238_DATA,
+	DENALI_PHY_239_DATA,
+	DENALI_PHY_240_DATA, DENALI_PHY_241_DATA, DENALI_PHY_242_DATA,
+	DENALI_PHY_243_DATA, DENALI_PHY_244_DATA, DENALI_PHY_245_DATA,
+	DENALI_PHY_246_DATA, DENALI_PHY_247_DATA, DENALI_PHY_248_DATA,
+	DENALI_PHY_249_DATA,
+	DENALI_PHY_250_DATA, DENALI_PHY_251_DATA, DENALI_PHY_252_DATA,
+	DENALI_PHY_253_DATA, DENALI_PHY_254_DATA, DENALI_PHY_255_DATA,
+	DENALI_PHY_256_DATA, DENALI_PHY_257_DATA, DENALI_PHY_258_DATA,
+	DENALI_PHY_259_DATA,
+	DENALI_PHY_260_DATA, DENALI_PHY_261_DATA, DENALI_PHY_262_DATA,
+	DENALI_PHY_263_DATA, DENALI_PHY_264_DATA, DENALI_PHY_265_DATA,
+	DENALI_PHY_266_DATA, DENALI_PHY_267_DATA, DENALI_PHY_268_DATA,
+	DENALI_PHY_269_DATA,
+	DENALI_PHY_270_DATA, DENALI_PHY_271_DATA, DENALI_PHY_272_DATA,
+	DENALI_PHY_273_DATA, DENALI_PHY_274_DATA, DENALI_PHY_275_DATA,
+	DENALI_PHY_276_DATA, DENALI_PHY_277_DATA, DENALI_PHY_278_DATA,
+	DENALI_PHY_279_DATA,
+	DENALI_PHY_280_DATA, DENALI_PHY_281_DATA, DENALI_PHY_282_DATA,
+	DENALI_PHY_283_DATA, DENALI_PHY_284_DATA, DENALI_PHY_285_DATA,
+	DENALI_PHY_286_DATA, DENALI_PHY_287_DATA, DENALI_PHY_288_DATA,
+	DENALI_PHY_289_DATA,
+	DENALI_PHY_290_DATA, DENALI_PHY_291_DATA, DENALI_PHY_292_DATA,
+	DENALI_PHY_293_DATA, DENALI_PHY_294_DATA, DENALI_PHY_295_DATA,
+	DENALI_PHY_296_DATA, DENALI_PHY_297_DATA, DENALI_PHY_298_DATA,
+	DENALI_PHY_299_DATA,
+
+	DENALI_PHY_300_DATA, DENALI_PHY_301_DATA, DENALI_PHY_302_DATA,
+	DENALI_PHY_303_DATA, DENALI_PHY_304_DATA, DENALI_PHY_305_DATA,
+	DENALI_PHY_306_DATA, DENALI_PHY_307_DATA, DENALI_PHY_308_DATA,
+	DENALI_PHY_309_DATA,
+	DENALI_PHY_310_DATA, DENALI_PHY_311_DATA, DENALI_PHY_312_DATA,
+	DENALI_PHY_313_DATA, DENALI_PHY_314_DATA, DENALI_PHY_315_DATA,
+	DENALI_PHY_316_DATA, DENALI_PHY_317_DATA, DENALI_PHY_318_DATA,
+	DENALI_PHY_319_DATA,
+	DENALI_PHY_320_DATA, DENALI_PHY_321_DATA, DENALI_PHY_322_DATA,
+	DENALI_PHY_323_DATA, DENALI_PHY_324_DATA, DENALI_PHY_325_DATA,
+	DENALI_PHY_326_DATA, DENALI_PHY_327_DATA, DENALI_PHY_328_DATA,
+	DENALI_PHY_329_DATA,
+	DENALI_PHY_330_DATA, DENALI_PHY_331_DATA, DENALI_PHY_332_DATA,
+	DENALI_PHY_333_DATA, DENALI_PHY_334_DATA, DENALI_PHY_335_DATA,
+	DENALI_PHY_336_DATA, DENALI_PHY_337_DATA, DENALI_PHY_338_DATA,
+	DENALI_PHY_339_DATA,
+	DENALI_PHY_340_DATA, DENALI_PHY_341_DATA, DENALI_PHY_342_DATA,
+	DENALI_PHY_343_DATA, DENALI_PHY_344_DATA, DENALI_PHY_345_DATA,
+	DENALI_PHY_346_DATA, DENALI_PHY_347_DATA, DENALI_PHY_348_DATA,
+	DENALI_PHY_349_DATA,
+	DENALI_PHY_350_DATA, DENALI_PHY_351_DATA, DENALI_PHY_352_DATA,
+	DENALI_PHY_353_DATA, DENALI_PHY_354_DATA, DENALI_PHY_355_DATA,
+	DENALI_PHY_356_DATA, DENALI_PHY_357_DATA, DENALI_PHY_358_DATA,
+	DENALI_PHY_359_DATA,
+	DENALI_PHY_360_DATA, DENALI_PHY_361_DATA, DENALI_PHY_362_DATA,
+	DENALI_PHY_363_DATA, DENALI_PHY_364_DATA, DENALI_PHY_365_DATA,
+	DENALI_PHY_366_DATA, DENALI_PHY_367_DATA, DENALI_PHY_368_DATA,
+	DENALI_PHY_369_DATA,
+	DENALI_PHY_370_DATA, DENALI_PHY_371_DATA, DENALI_PHY_372_DATA,
+	DENALI_PHY_373_DATA, DENALI_PHY_374_DATA, DENALI_PHY_375_DATA,
+	DENALI_PHY_376_DATA, DENALI_PHY_377_DATA, DENALI_PHY_378_DATA,
+	DENALI_PHY_379_DATA,
+	DENALI_PHY_380_DATA, DENALI_PHY_381_DATA, DENALI_PHY_382_DATA,
+	DENALI_PHY_383_DATA, DENALI_PHY_384_DATA, DENALI_PHY_385_DATA,
+	DENALI_PHY_386_DATA, DENALI_PHY_387_DATA, DENALI_PHY_388_DATA,
+	DENALI_PHY_389_DATA,
+	DENALI_PHY_390_DATA, DENALI_PHY_391_DATA, DENALI_PHY_392_DATA,
+	DENALI_PHY_393_DATA, DENALI_PHY_394_DATA, DENALI_PHY_395_DATA,
+	DENALI_PHY_396_DATA, DENALI_PHY_397_DATA, DENALI_PHY_398_DATA,
+	DENALI_PHY_399_DATA,
+
+	DENALI_PHY_400_DATA, DENALI_PHY_401_DATA, DENALI_PHY_402_DATA,
+	DENALI_PHY_403_DATA, DENALI_PHY_404_DATA, DENALI_PHY_405_DATA,
+	DENALI_PHY_406_DATA, DENALI_PHY_407_DATA, DENALI_PHY_408_DATA,
+	DENALI_PHY_409_DATA,
+	DENALI_PHY_410_DATA, DENALI_PHY_411_DATA, DENALI_PHY_412_DATA,
+	DENALI_PHY_413_DATA, DENALI_PHY_414_DATA, DENALI_PHY_415_DATA,
+	DENALI_PHY_416_DATA, DENALI_PHY_417_DATA, DENALI_PHY_418_DATA,
+	DENALI_PHY_419_DATA,
+	DENALI_PHY_420_DATA, DENALI_PHY_421_DATA, DENALI_PHY_422_DATA,
+	DENALI_PHY_423_DATA, DENALI_PHY_424_DATA, DENALI_PHY_425_DATA,
+	DENALI_PHY_426_DATA, DENALI_PHY_427_DATA, DENALI_PHY_428_DATA,
+	DENALI_PHY_429_DATA,
+	DENALI_PHY_430_DATA, DENALI_PHY_431_DATA, DENALI_PHY_432_DATA,
+	DENALI_PHY_433_DATA, DENALI_PHY_434_DATA, DENALI_PHY_435_DATA,
+	DENALI_PHY_436_DATA, DENALI_PHY_437_DATA, DENALI_PHY_438_DATA,
+	DENALI_PHY_439_DATA,
+	DENALI_PHY_440_DATA, DENALI_PHY_441_DATA, DENALI_PHY_442_DATA,
+	DENALI_PHY_443_DATA, DENALI_PHY_444_DATA, DENALI_PHY_445_DATA,
+	DENALI_PHY_446_DATA, DENALI_PHY_447_DATA, DENALI_PHY_448_DATA,
+	DENALI_PHY_449_DATA,
+	DENALI_PHY_450_DATA, DENALI_PHY_451_DATA, DENALI_PHY_452_DATA,
+	DENALI_PHY_453_DATA, DENALI_PHY_454_DATA, DENALI_PHY_455_DATA,
+	DENALI_PHY_456_DATA, DENALI_PHY_457_DATA, DENALI_PHY_458_DATA,
+	DENALI_PHY_459_DATA,
+	DENALI_PHY_460_DATA, DENALI_PHY_461_DATA, DENALI_PHY_462_DATA,
+	DENALI_PHY_463_DATA, DENALI_PHY_464_DATA, DENALI_PHY_465_DATA,
+	DENALI_PHY_466_DATA, DENALI_PHY_467_DATA, DENALI_PHY_468_DATA,
+	DENALI_PHY_469_DATA,
+	DENALI_PHY_470_DATA, DENALI_PHY_471_DATA, DENALI_PHY_472_DATA,
+	DENALI_PHY_473_DATA, DENALI_PHY_474_DATA, DENALI_PHY_475_DATA,
+	DENALI_PHY_476_DATA, DENALI_PHY_477_DATA, DENALI_PHY_478_DATA,
+	DENALI_PHY_479_DATA,
+	DENALI_PHY_480_DATA, DENALI_PHY_481_DATA, DENALI_PHY_482_DATA,
+	DENALI_PHY_483_DATA, DENALI_PHY_484_DATA, DENALI_PHY_485_DATA,
+	DENALI_PHY_486_DATA, DENALI_PHY_487_DATA, DENALI_PHY_488_DATA,
+	DENALI_PHY_489_DATA,
+	DENALI_PHY_490_DATA, DENALI_PHY_491_DATA, DENALI_PHY_492_DATA,
+	DENALI_PHY_493_DATA, DENALI_PHY_494_DATA, DENALI_PHY_495_DATA,
+	DENALI_PHY_496_DATA, DENALI_PHY_497_DATA, DENALI_PHY_498_DATA,
+	DENALI_PHY_499_DATA,
+
+	DENALI_PHY_500_DATA, DENALI_PHY_501_DATA, DENALI_PHY_502_DATA,
+	DENALI_PHY_503_DATA, DENALI_PHY_504_DATA, DENALI_PHY_505_DATA,
+	DENALI_PHY_506_DATA, DENALI_PHY_507_DATA, DENALI_PHY_508_DATA,
+	DENALI_PHY_509_DATA,
+	DENALI_PHY_510_DATA, DENALI_PHY_511_DATA, DENALI_PHY_512_DATA,
+	DENALI_PHY_513_DATA, DENALI_PHY_514_DATA, DENALI_PHY_515_DATA,
+	DENALI_PHY_516_DATA, DENALI_PHY_517_DATA, DENALI_PHY_518_DATA,
+	DENALI_PHY_519_DATA,
+	DENALI_PHY_520_DATA, DENALI_PHY_521_DATA, DENALI_PHY_522_DATA,
+	DENALI_PHY_523_DATA, DENALI_PHY_524_DATA, DENALI_PHY_525_DATA,
+	DENALI_PHY_526_DATA, DENALI_PHY_527_DATA, DENALI_PHY_528_DATA,
+	DENALI_PHY_529_DATA,
+	DENALI_PHY_530_DATA, DENALI_PHY_531_DATA, DENALI_PHY_532_DATA,
+	DENALI_PHY_533_DATA, DENALI_PHY_534_DATA, DENALI_PHY_535_DATA,
+	DENALI_PHY_536_DATA, DENALI_PHY_537_DATA, DENALI_PHY_538_DATA,
+	DENALI_PHY_539_DATA,
+	DENALI_PHY_540_DATA, DENALI_PHY_541_DATA, DENALI_PHY_542_DATA,
+	DENALI_PHY_543_DATA, DENALI_PHY_544_DATA, DENALI_PHY_545_DATA,
+	DENALI_PHY_546_DATA, DENALI_PHY_547_DATA, DENALI_PHY_548_DATA,
+	DENALI_PHY_549_DATA,
+	DENALI_PHY_550_DATA, DENALI_PHY_551_DATA, DENALI_PHY_552_DATA,
+	DENALI_PHY_553_DATA, DENALI_PHY_554_DATA, DENALI_PHY_555_DATA,
+	DENALI_PHY_556_DATA, DENALI_PHY_557_DATA, DENALI_PHY_558_DATA,
+	DENALI_PHY_559_DATA,
+	DENALI_PHY_560_DATA, DENALI_PHY_561_DATA, DENALI_PHY_562_DATA,
+	DENALI_PHY_563_DATA, DENALI_PHY_564_DATA, DENALI_PHY_565_DATA,
+	DENALI_PHY_566_DATA, DENALI_PHY_567_DATA, DENALI_PHY_568_DATA,
+	DENALI_PHY_569_DATA,
+	DENALI_PHY_570_DATA, DENALI_PHY_571_DATA, DENALI_PHY_572_DATA,
+	DENALI_PHY_573_DATA, DENALI_PHY_574_DATA, DENALI_PHY_575_DATA,
+	DENALI_PHY_576_DATA, DENALI_PHY_577_DATA, DENALI_PHY_578_DATA,
+	DENALI_PHY_579_DATA,
+	DENALI_PHY_580_DATA, DENALI_PHY_581_DATA, DENALI_PHY_582_DATA,
+	DENALI_PHY_583_DATA, DENALI_PHY_584_DATA, DENALI_PHY_585_DATA,
+	DENALI_PHY_586_DATA, DENALI_PHY_587_DATA, DENALI_PHY_588_DATA,
+	DENALI_PHY_589_DATA,
+	DENALI_PHY_590_DATA, DENALI_PHY_591_DATA, DENALI_PHY_592_DATA,
+	DENALI_PHY_593_DATA, DENALI_PHY_594_DATA, DENALI_PHY_595_DATA,
+	DENALI_PHY_596_DATA, DENALI_PHY_597_DATA, DENALI_PHY_598_DATA,
+	DENALI_PHY_599_DATA,
+
+	DENALI_PHY_600_DATA, DENALI_PHY_601_DATA, DENALI_PHY_602_DATA,
+	DENALI_PHY_603_DATA, DENALI_PHY_604_DATA, DENALI_PHY_605_DATA,
+	DENALI_PHY_606_DATA, DENALI_PHY_607_DATA, DENALI_PHY_608_DATA,
+	DENALI_PHY_609_DATA,
+	DENALI_PHY_610_DATA, DENALI_PHY_611_DATA, DENALI_PHY_612_DATA,
+	DENALI_PHY_613_DATA, DENALI_PHY_614_DATA, DENALI_PHY_615_DATA,
+	DENALI_PHY_616_DATA, DENALI_PHY_617_DATA, DENALI_PHY_618_DATA,
+	DENALI_PHY_619_DATA,
+	DENALI_PHY_620_DATA, DENALI_PHY_621_DATA, DENALI_PHY_622_DATA,
+	DENALI_PHY_623_DATA, DENALI_PHY_624_DATA, DENALI_PHY_625_DATA,
+	DENALI_PHY_626_DATA, DENALI_PHY_627_DATA, DENALI_PHY_628_DATA,
+	DENALI_PHY_629_DATA,
+	DENALI_PHY_630_DATA, DENALI_PHY_631_DATA, DENALI_PHY_632_DATA,
+	DENALI_PHY_633_DATA, DENALI_PHY_634_DATA, DENALI_PHY_635_DATA,
+	DENALI_PHY_636_DATA, DENALI_PHY_637_DATA, DENALI_PHY_638_DATA,
+	DENALI_PHY_639_DATA,
+	DENALI_PHY_640_DATA, DENALI_PHY_641_DATA, DENALI_PHY_642_DATA,
+	DENALI_PHY_643_DATA, DENALI_PHY_644_DATA, DENALI_PHY_645_DATA,
+	DENALI_PHY_646_DATA, DENALI_PHY_647_DATA, DENALI_PHY_648_DATA,
+	DENALI_PHY_649_DATA,
+	DENALI_PHY_650_DATA, DENALI_PHY_651_DATA, DENALI_PHY_652_DATA,
+	DENALI_PHY_653_DATA, DENALI_PHY_654_DATA, DENALI_PHY_655_DATA,
+	DENALI_PHY_656_DATA, DENALI_PHY_657_DATA, DENALI_PHY_658_DATA,
+	DENALI_PHY_659_DATA,
+	DENALI_PHY_660_DATA, DENALI_PHY_661_DATA, DENALI_PHY_662_DATA,
+	DENALI_PHY_663_DATA, DENALI_PHY_664_DATA, DENALI_PHY_665_DATA,
+	DENALI_PHY_666_DATA, DENALI_PHY_667_DATA, DENALI_PHY_668_DATA,
+	DENALI_PHY_669_DATA,
+	DENALI_PHY_670_DATA, DENALI_PHY_671_DATA, DENALI_PHY_672_DATA,
+	DENALI_PHY_673_DATA, DENALI_PHY_674_DATA, DENALI_PHY_675_DATA,
+	DENALI_PHY_676_DATA, DENALI_PHY_677_DATA, DENALI_PHY_678_DATA,
+	DENALI_PHY_679_DATA,
+	DENALI_PHY_680_DATA, DENALI_PHY_681_DATA, DENALI_PHY_682_DATA,
+	DENALI_PHY_683_DATA, DENALI_PHY_684_DATA, DENALI_PHY_685_DATA,
+	DENALI_PHY_686_DATA, DENALI_PHY_687_DATA, DENALI_PHY_688_DATA,
+	DENALI_PHY_689_DATA,
+	DENALI_PHY_690_DATA, DENALI_PHY_691_DATA, DENALI_PHY_692_DATA,
+	DENALI_PHY_693_DATA, DENALI_PHY_694_DATA, DENALI_PHY_695_DATA,
+	DENALI_PHY_696_DATA, DENALI_PHY_697_DATA, DENALI_PHY_698_DATA,
+	DENALI_PHY_699_DATA,
+
+	DENALI_PHY_700_DATA, DENALI_PHY_701_DATA, DENALI_PHY_702_DATA,
+	DENALI_PHY_703_DATA, DENALI_PHY_704_DATA, DENALI_PHY_705_DATA,
+	DENALI_PHY_706_DATA, DENALI_PHY_707_DATA, DENALI_PHY_708_DATA,
+	DENALI_PHY_709_DATA,
+	DENALI_PHY_710_DATA, DENALI_PHY_711_DATA, DENALI_PHY_712_DATA,
+	DENALI_PHY_713_DATA, DENALI_PHY_714_DATA, DENALI_PHY_715_DATA,
+	DENALI_PHY_716_DATA, DENALI_PHY_717_DATA, DENALI_PHY_718_DATA,
+	DENALI_PHY_719_DATA,
+	DENALI_PHY_720_DATA, DENALI_PHY_721_DATA, DENALI_PHY_722_DATA,
+	DENALI_PHY_723_DATA, DENALI_PHY_724_DATA, DENALI_PHY_725_DATA,
+	DENALI_PHY_726_DATA, DENALI_PHY_727_DATA, DENALI_PHY_728_DATA,
+	DENALI_PHY_729_DATA,
+	DENALI_PHY_730_DATA, DENALI_PHY_731_DATA, DENALI_PHY_732_DATA,
+	DENALI_PHY_733_DATA, DENALI_PHY_734_DATA, DENALI_PHY_735_DATA,
+	DENALI_PHY_736_DATA, DENALI_PHY_737_DATA, DENALI_PHY_738_DATA,
+	DENALI_PHY_739_DATA,
+	DENALI_PHY_740_DATA, DENALI_PHY_741_DATA, DENALI_PHY_742_DATA,
+	DENALI_PHY_743_DATA, DENALI_PHY_744_DATA, DENALI_PHY_745_DATA,
+	DENALI_PHY_746_DATA, DENALI_PHY_747_DATA, DENALI_PHY_748_DATA,
+	DENALI_PHY_749_DATA,
+	DENALI_PHY_750_DATA, DENALI_PHY_751_DATA, DENALI_PHY_752_DATA,
+	DENALI_PHY_753_DATA, DENALI_PHY_754_DATA, DENALI_PHY_755_DATA,
+	DENALI_PHY_756_DATA, DENALI_PHY_757_DATA, DENALI_PHY_758_DATA,
+	DENALI_PHY_759_DATA,
+	DENALI_PHY_760_DATA, DENALI_PHY_761_DATA, DENALI_PHY_762_DATA,
+	DENALI_PHY_763_DATA, DENALI_PHY_764_DATA, DENALI_PHY_765_DATA,
+	DENALI_PHY_766_DATA, DENALI_PHY_767_DATA, DENALI_PHY_768_DATA,
+	DENALI_PHY_769_DATA,
+	DENALI_PHY_770_DATA, DENALI_PHY_771_DATA, DENALI_PHY_772_DATA,
+	DENALI_PHY_773_DATA, DENALI_PHY_774_DATA, DENALI_PHY_775_DATA,
+	DENALI_PHY_776_DATA, DENALI_PHY_777_DATA, DENALI_PHY_778_DATA,
+	DENALI_PHY_779_DATA,
+	DENALI_PHY_780_DATA, DENALI_PHY_781_DATA, DENALI_PHY_782_DATA,
+	DENALI_PHY_783_DATA, DENALI_PHY_784_DATA, DENALI_PHY_785_DATA,
+	DENALI_PHY_786_DATA, DENALI_PHY_787_DATA, DENALI_PHY_788_DATA,
+	DENALI_PHY_789_DATA,
+	DENALI_PHY_790_DATA, DENALI_PHY_791_DATA, DENALI_PHY_792_DATA,
+	DENALI_PHY_793_DATA, DENALI_PHY_794_DATA, DENALI_PHY_795_DATA,
+	DENALI_PHY_796_DATA, DENALI_PHY_797_DATA, DENALI_PHY_798_DATA,
+	DENALI_PHY_799_DATA,
+
+	DENALI_PHY_800_DATA, DENALI_PHY_801_DATA, DENALI_PHY_802_DATA,
+	DENALI_PHY_803_DATA, DENALI_PHY_804_DATA, DENALI_PHY_805_DATA,
+	DENALI_PHY_806_DATA, DENALI_PHY_807_DATA, DENALI_PHY_808_DATA,
+	DENALI_PHY_809_DATA,
+	DENALI_PHY_810_DATA, DENALI_PHY_811_DATA, DENALI_PHY_812_DATA,
+	DENALI_PHY_813_DATA, DENALI_PHY_814_DATA, DENALI_PHY_815_DATA,
+	DENALI_PHY_816_DATA, DENALI_PHY_817_DATA, DENALI_PHY_818_DATA,
+	DENALI_PHY_819_DATA,
+	DENALI_PHY_820_DATA, DENALI_PHY_821_DATA, DENALI_PHY_822_DATA,
+	DENALI_PHY_823_DATA, DENALI_PHY_824_DATA, DENALI_PHY_825_DATA,
+	DENALI_PHY_826_DATA, DENALI_PHY_827_DATA, DENALI_PHY_828_DATA,
+	DENALI_PHY_829_DATA,
+	DENALI_PHY_830_DATA, DENALI_PHY_831_DATA, DENALI_PHY_832_DATA,
+	DENALI_PHY_833_DATA, DENALI_PHY_834_DATA, DENALI_PHY_835_DATA,
+	DENALI_PHY_836_DATA, DENALI_PHY_837_DATA, DENALI_PHY_838_DATA,
+	DENALI_PHY_839_DATA,
+	DENALI_PHY_840_DATA, DENALI_PHY_841_DATA, DENALI_PHY_842_DATA,
+	DENALI_PHY_843_DATA, DENALI_PHY_844_DATA, DENALI_PHY_845_DATA,
+	DENALI_PHY_846_DATA, DENALI_PHY_847_DATA, DENALI_PHY_848_DATA,
+	DENALI_PHY_849_DATA,
+	DENALI_PHY_850_DATA, DENALI_PHY_851_DATA, DENALI_PHY_852_DATA,
+	DENALI_PHY_853_DATA, DENALI_PHY_854_DATA, DENALI_PHY_855_DATA,
+	DENALI_PHY_856_DATA, DENALI_PHY_857_DATA, DENALI_PHY_858_DATA,
+	DENALI_PHY_859_DATA,
+	DENALI_PHY_860_DATA, DENALI_PHY_861_DATA, DENALI_PHY_862_DATA,
+	DENALI_PHY_863_DATA, DENALI_PHY_864_DATA, DENALI_PHY_865_DATA,
+	DENALI_PHY_866_DATA, DENALI_PHY_867_DATA, DENALI_PHY_868_DATA,
+	DENALI_PHY_869_DATA,
+	DENALI_PHY_870_DATA, DENALI_PHY_871_DATA, DENALI_PHY_872_DATA,
+	DENALI_PHY_873_DATA, DENALI_PHY_874_DATA, DENALI_PHY_875_DATA,
+	DENALI_PHY_876_DATA, DENALI_PHY_877_DATA, DENALI_PHY_878_DATA,
+	DENALI_PHY_879_DATA,
+	DENALI_PHY_880_DATA, DENALI_PHY_881_DATA, DENALI_PHY_882_DATA,
+	DENALI_PHY_883_DATA, DENALI_PHY_884_DATA, DENALI_PHY_885_DATA,
+	DENALI_PHY_886_DATA, DENALI_PHY_887_DATA, DENALI_PHY_888_DATA,
+	DENALI_PHY_889_DATA,
+	DENALI_PHY_890_DATA, DENALI_PHY_891_DATA, DENALI_PHY_892_DATA,
+	DENALI_PHY_893_DATA, DENALI_PHY_894_DATA, DENALI_PHY_895_DATA,
+	DENALI_PHY_896_DATA, DENALI_PHY_897_DATA, DENALI_PHY_898_DATA,
+	DENALI_PHY_899_DATA,
+
+	DENALI_PHY_900_DATA, DENALI_PHY_901_DATA, DENALI_PHY_902_DATA,
+	DENALI_PHY_903_DATA, DENALI_PHY_904_DATA, DENALI_PHY_905_DATA,
+	DENALI_PHY_906_DATA, DENALI_PHY_907_DATA, DENALI_PHY_908_DATA,
+	DENALI_PHY_909_DATA,
+	DENALI_PHY_910_DATA, DENALI_PHY_911_DATA, DENALI_PHY_912_DATA,
+	DENALI_PHY_913_DATA, DENALI_PHY_914_DATA, DENALI_PHY_915_DATA,
+	DENALI_PHY_916_DATA, DENALI_PHY_917_DATA, DENALI_PHY_918_DATA,
+	DENALI_PHY_919_DATA,
+	DENALI_PHY_920_DATA, DENALI_PHY_921_DATA, DENALI_PHY_922_DATA,
+	DENALI_PHY_923_DATA, DENALI_PHY_924_DATA, DENALI_PHY_925_DATA,
+	DENALI_PHY_926_DATA, DENALI_PHY_927_DATA, DENALI_PHY_928_DATA,
+	DENALI_PHY_929_DATA,
+	DENALI_PHY_930_DATA, DENALI_PHY_931_DATA, DENALI_PHY_932_DATA,
+	DENALI_PHY_933_DATA, DENALI_PHY_934_DATA, DENALI_PHY_935_DATA,
+	DENALI_PHY_936_DATA, DENALI_PHY_937_DATA, DENALI_PHY_938_DATA,
+	DENALI_PHY_939_DATA,
+	DENALI_PHY_940_DATA, DENALI_PHY_941_DATA, DENALI_PHY_942_DATA,
+	DENALI_PHY_943_DATA, DENALI_PHY_944_DATA, DENALI_PHY_945_DATA,
+	DENALI_PHY_946_DATA, DENALI_PHY_947_DATA, DENALI_PHY_948_DATA,
+	DENALI_PHY_949_DATA,
+	DENALI_PHY_950_DATA, DENALI_PHY_951_DATA, DENALI_PHY_952_DATA,
+	DENALI_PHY_953_DATA, DENALI_PHY_954_DATA, DENALI_PHY_955_DATA,
+	DENALI_PHY_956_DATA, DENALI_PHY_957_DATA, DENALI_PHY_958_DATA,
+	DENALI_PHY_959_DATA,
+	DENALI_PHY_960_DATA, DENALI_PHY_961_DATA, DENALI_PHY_962_DATA,
+	DENALI_PHY_963_DATA, DENALI_PHY_964_DATA, DENALI_PHY_965_DATA,
+	DENALI_PHY_966_DATA, DENALI_PHY_967_DATA, DENALI_PHY_968_DATA,
+	DENALI_PHY_969_DATA,
+	DENALI_PHY_970_DATA, DENALI_PHY_971_DATA, DENALI_PHY_972_DATA,
+	DENALI_PHY_973_DATA, DENALI_PHY_974_DATA, DENALI_PHY_975_DATA,
+	DENALI_PHY_976_DATA, DENALI_PHY_977_DATA, DENALI_PHY_978_DATA,
+	DENALI_PHY_979_DATA,
+	DENALI_PHY_980_DATA, DENALI_PHY_981_DATA, DENALI_PHY_982_DATA,
+	DENALI_PHY_983_DATA, DENALI_PHY_984_DATA, DENALI_PHY_985_DATA,
+	DENALI_PHY_986_DATA, DENALI_PHY_987_DATA, DENALI_PHY_988_DATA,
+	DENALI_PHY_989_DATA,
+	DENALI_PHY_990_DATA, DENALI_PHY_991_DATA, DENALI_PHY_992_DATA,
+	DENALI_PHY_993_DATA, DENALI_PHY_994_DATA, DENALI_PHY_995_DATA,
+	DENALI_PHY_996_DATA, DENALI_PHY_997_DATA, DENALI_PHY_998_DATA,
+	DENALI_PHY_999_DATA,
+
+	DENALI_PHY_1000_DATA, DENALI_PHY_1001_DATA, DENALI_PHY_1002_DATA,
+	DENALI_PHY_1003_DATA, DENALI_PHY_1004_DATA, DENALI_PHY_1005_DATA,
+	DENALI_PHY_1006_DATA, DENALI_PHY_1007_DATA, DENALI_PHY_1008_DATA,
+	DENALI_PHY_1009_DATA,
+	DENALI_PHY_1010_DATA, DENALI_PHY_1011_DATA, DENALI_PHY_1012_DATA,
+	DENALI_PHY_1013_DATA, DENALI_PHY_1014_DATA, DENALI_PHY_1015_DATA,
+	DENALI_PHY_1016_DATA, DENALI_PHY_1017_DATA, DENALI_PHY_1018_DATA,
+	DENALI_PHY_1019_DATA,
+	DENALI_PHY_1020_DATA, DENALI_PHY_1021_DATA, DENALI_PHY_1022_DATA,
+	DENALI_PHY_1023_DATA, DENALI_PHY_1024_DATA, DENALI_PHY_1025_DATA,
+	DENALI_PHY_1026_DATA, DENALI_PHY_1027_DATA, DENALI_PHY_1028_DATA,
+	DENALI_PHY_1029_DATA,
+	DENALI_PHY_1030_DATA, DENALI_PHY_1031_DATA, DENALI_PHY_1032_DATA,
+	DENALI_PHY_1033_DATA, DENALI_PHY_1034_DATA, DENALI_PHY_1035_DATA,
+	DENALI_PHY_1036_DATA, DENALI_PHY_1037_DATA, DENALI_PHY_1038_DATA,
+	DENALI_PHY_1039_DATA,
+	DENALI_PHY_1040_DATA, DENALI_PHY_1041_DATA, DENALI_PHY_1042_DATA,
+	DENALI_PHY_1043_DATA, DENALI_PHY_1044_DATA, DENALI_PHY_1045_DATA,
+	DENALI_PHY_1046_DATA, DENALI_PHY_1047_DATA, DENALI_PHY_1048_DATA,
+	DENALI_PHY_1049_DATA,
+	DENALI_PHY_1050_DATA, DENALI_PHY_1051_DATA, DENALI_PHY_1052_DATA,
+	DENALI_PHY_1053_DATA, DENALI_PHY_1054_DATA, DENALI_PHY_1055_DATA,
+	DENALI_PHY_1056_DATA, DENALI_PHY_1057_DATA, DENALI_PHY_1058_DATA,
+	DENALI_PHY_1059_DATA,
+	DENALI_PHY_1060_DATA, DENALI_PHY_1061_DATA, DENALI_PHY_1062_DATA,
+	DENALI_PHY_1063_DATA, DENALI_PHY_1064_DATA, DENALI_PHY_1065_DATA,
+	DENALI_PHY_1066_DATA, DENALI_PHY_1067_DATA, DENALI_PHY_1068_DATA,
+	DENALI_PHY_1069_DATA,
+	DENALI_PHY_1070_DATA, DENALI_PHY_1071_DATA, DENALI_PHY_1072_DATA,
+	DENALI_PHY_1073_DATA, DENALI_PHY_1074_DATA, DENALI_PHY_1075_DATA,
+	DENALI_PHY_1076_DATA, DENALI_PHY_1077_DATA, DENALI_PHY_1078_DATA,
+	DENALI_PHY_1079_DATA,
+	DENALI_PHY_1080_DATA, DENALI_PHY_1081_DATA, DENALI_PHY_1082_DATA,
+	DENALI_PHY_1083_DATA, DENALI_PHY_1084_DATA, DENALI_PHY_1085_DATA,
+	DENALI_PHY_1086_DATA, DENALI_PHY_1087_DATA, DENALI_PHY_1088_DATA,
+	DENALI_PHY_1089_DATA,
+	DENALI_PHY_1090_DATA, DENALI_PHY_1091_DATA, DENALI_PHY_1092_DATA,
+	DENALI_PHY_1093_DATA, DENALI_PHY_1094_DATA, DENALI_PHY_1095_DATA,
+	DENALI_PHY_1096_DATA, DENALI_PHY_1097_DATA, DENALI_PHY_1098_DATA,
+	DENALI_PHY_1099_DATA,
+
+	DENALI_PHY_1100_DATA, DENALI_PHY_1101_DATA, DENALI_PHY_1102_DATA,
+	DENALI_PHY_1103_DATA, DENALI_PHY_1104_DATA, DENALI_PHY_1105_DATA,
+	DENALI_PHY_1106_DATA, DENALI_PHY_1107_DATA, DENALI_PHY_1108_DATA,
+	DENALI_PHY_1109_DATA,
+	DENALI_PHY_1110_DATA, DENALI_PHY_1111_DATA, DENALI_PHY_1112_DATA,
+	DENALI_PHY_1113_DATA, DENALI_PHY_1114_DATA, DENALI_PHY_1115_DATA,
+	DENALI_PHY_1116_DATA, DENALI_PHY_1117_DATA, DENALI_PHY_1118_DATA,
+	DENALI_PHY_1119_DATA,
+	DENALI_PHY_1120_DATA, DENALI_PHY_1121_DATA, DENALI_PHY_1122_DATA,
+	DENALI_PHY_1123_DATA, DENALI_PHY_1124_DATA, DENALI_PHY_1125_DATA,
+	DENALI_PHY_1126_DATA, DENALI_PHY_1127_DATA, DENALI_PHY_1128_DATA,
+	DENALI_PHY_1129_DATA,
+	DENALI_PHY_1130_DATA, DENALI_PHY_1131_DATA, DENALI_PHY_1132_DATA,
+	DENALI_PHY_1133_DATA, DENALI_PHY_1134_DATA, DENALI_PHY_1135_DATA,
+	DENALI_PHY_1136_DATA, DENALI_PHY_1137_DATA, DENALI_PHY_1138_DATA,
+	DENALI_PHY_1139_DATA,
+	DENALI_PHY_1140_DATA, DENALI_PHY_1141_DATA, DENALI_PHY_1142_DATA,
+	DENALI_PHY_1143_DATA, DENALI_PHY_1144_DATA, DENALI_PHY_1145_DATA,
+	DENALI_PHY_1146_DATA, DENALI_PHY_1147_DATA, DENALI_PHY_1148_DATA,
+	DENALI_PHY_1149_DATA,
+	DENALI_PHY_1150_DATA, DENALI_PHY_1151_DATA, DENALI_PHY_1152_DATA,
+	DENALI_PHY_1153_DATA, DENALI_PHY_1154_DATA, DENALI_PHY_1155_DATA,
+	DENALI_PHY_1156_DATA, DENALI_PHY_1157_DATA, DENALI_PHY_1158_DATA,
+	DENALI_PHY_1159_DATA,
+	DENALI_PHY_1160_DATA, DENALI_PHY_1161_DATA, DENALI_PHY_1162_DATA,
+	DENALI_PHY_1163_DATA, DENALI_PHY_1164_DATA, DENALI_PHY_1165_DATA,
+	DENALI_PHY_1166_DATA, DENALI_PHY_1167_DATA, DENALI_PHY_1168_DATA,
+	DENALI_PHY_1169_DATA,
+	DENALI_PHY_1170_DATA, DENALI_PHY_1171_DATA, DENALI_PHY_1172_DATA,
+	DENALI_PHY_1173_DATA, DENALI_PHY_1174_DATA, DENALI_PHY_1175_DATA,
+	DENALI_PHY_1176_DATA, DENALI_PHY_1177_DATA, DENALI_PHY_1178_DATA,
+	DENALI_PHY_1179_DATA,
+	DENALI_PHY_1180_DATA, DENALI_PHY_1181_DATA, DENALI_PHY_1182_DATA,
+	DENALI_PHY_1183_DATA, DENALI_PHY_1184_DATA, DENALI_PHY_1185_DATA,
+	DENALI_PHY_1186_DATA, DENALI_PHY_1187_DATA, DENALI_PHY_1188_DATA,
+	DENALI_PHY_1189_DATA,
+	DENALI_PHY_1190_DATA, DENALI_PHY_1191_DATA, DENALI_PHY_1192_DATA,
+	DENALI_PHY_1193_DATA, DENALI_PHY_1194_DATA, DENALI_PHY_1195_DATA,
+	DENALI_PHY_1196_DATA, DENALI_PHY_1197_DATA, DENALI_PHY_1198_DATA,
+	DENALI_PHY_1199_DATA,
+
+	DENALI_PHY_1200_DATA, DENALI_PHY_1201_DATA, DENALI_PHY_1202_DATA,
+	DENALI_PHY_1203_DATA, DENALI_PHY_1204_DATA, DENALI_PHY_1205_DATA,
+	DENALI_PHY_1206_DATA, DENALI_PHY_1207_DATA, DENALI_PHY_1208_DATA,
+	DENALI_PHY_1209_DATA,
+	DENALI_PHY_1210_DATA, DENALI_PHY_1211_DATA, DENALI_PHY_1212_DATA,
+	DENALI_PHY_1213_DATA, DENALI_PHY_1214_DATA
+};
+
+u32 DENALI_CTL_DATA[265] = {
+	DENALI_CTL_00_DATA, DENALI_CTL_01_DATA, DENALI_CTL_02_DATA,
+	DENALI_CTL_03_DATA, DENALI_CTL_04_DATA, DENALI_CTL_05_DATA,
+	DENALI_CTL_06_DATA, DENALI_CTL_07_DATA, DENALI_CTL_08_DATA,
+	DENALI_CTL_09_DATA,
+	DENALI_CTL_10_DATA, DENALI_CTL_11_DATA, DENALI_CTL_12_DATA,
+	DENALI_CTL_13_DATA, DENALI_CTL_14_DATA, DENALI_CTL_15_DATA,
+	DENALI_CTL_16_DATA, DENALI_CTL_17_DATA, DENALI_CTL_18_DATA,
+	DENALI_CTL_19_DATA,
+	DENALI_CTL_20_DATA, DENALI_CTL_21_DATA, DENALI_CTL_22_DATA,
+	DENALI_CTL_23_DATA, DENALI_CTL_24_DATA, DENALI_CTL_25_DATA,
+	DENALI_CTL_26_DATA, DENALI_CTL_27_DATA, DENALI_CTL_28_DATA,
+	DENALI_CTL_29_DATA,
+	DENALI_CTL_30_DATA, DENALI_CTL_31_DATA, DENALI_CTL_32_DATA,
+	DENALI_CTL_33_DATA, DENALI_CTL_34_DATA, DENALI_CTL_35_DATA,
+	DENALI_CTL_36_DATA, DENALI_CTL_37_DATA, DENALI_CTL_38_DATA,
+	DENALI_CTL_39_DATA,
+	DENALI_CTL_40_DATA, DENALI_CTL_41_DATA, DENALI_CTL_42_DATA,
+	DENALI_CTL_43_DATA, DENALI_CTL_44_DATA, DENALI_CTL_45_DATA,
+	DENALI_CTL_46_DATA, DENALI_CTL_47_DATA, DENALI_CTL_48_DATA,
+	DENALI_CTL_49_DATA,
+	DENALI_CTL_50_DATA, DENALI_CTL_51_DATA, DENALI_CTL_52_DATA,
+	DENALI_CTL_53_DATA, DENALI_CTL_54_DATA, DENALI_CTL_55_DATA,
+	DENALI_CTL_56_DATA, DENALI_CTL_57_DATA, DENALI_CTL_58_DATA,
+	DENALI_CTL_59_DATA,
+	DENALI_CTL_60_DATA, DENALI_CTL_61_DATA, DENALI_CTL_62_DATA,
+	DENALI_CTL_63_DATA, DENALI_CTL_64_DATA, DENALI_CTL_65_DATA,
+	DENALI_CTL_66_DATA, DENALI_CTL_67_DATA, DENALI_CTL_68_DATA,
+	DENALI_CTL_69_DATA,
+	DENALI_CTL_70_DATA, DENALI_CTL_71_DATA, DENALI_CTL_72_DATA,
+	DENALI_CTL_73_DATA, DENALI_CTL_74_DATA, DENALI_CTL_75_DATA,
+	DENALI_CTL_76_DATA, DENALI_CTL_77_DATA, DENALI_CTL_78_DATA,
+	DENALI_CTL_79_DATA,
+	DENALI_CTL_80_DATA, DENALI_CTL_81_DATA, DENALI_CTL_82_DATA,
+	DENALI_CTL_83_DATA, DENALI_CTL_84_DATA, DENALI_CTL_85_DATA,
+	DENALI_CTL_86_DATA, DENALI_CTL_87_DATA, DENALI_CTL_88_DATA,
+	DENALI_CTL_89_DATA,
+	DENALI_CTL_90_DATA, DENALI_CTL_91_DATA, DENALI_CTL_92_DATA,
+	DENALI_CTL_93_DATA, DENALI_CTL_94_DATA, DENALI_CTL_95_DATA,
+	DENALI_CTL_96_DATA, DENALI_CTL_97_DATA, DENALI_CTL_98_DATA,
+	DENALI_CTL_99_DATA,
+
+	DENALI_CTL_100_DATA, DENALI_CTL_101_DATA, DENALI_CTL_102_DATA,
+	DENALI_CTL_103_DATA, DENALI_CTL_104_DATA, DENALI_CTL_105_DATA,
+	DENALI_CTL_106_DATA, DENALI_CTL_107_DATA, DENALI_CTL_108_DATA,
+	DENALI_CTL_109_DATA,
+	DENALI_CTL_110_DATA, DENALI_CTL_111_DATA, DENALI_CTL_112_DATA,
+	DENALI_CTL_113_DATA, DENALI_CTL_114_DATA, DENALI_CTL_115_DATA,
+	DENALI_CTL_116_DATA, DENALI_CTL_117_DATA, DENALI_CTL_118_DATA,
+	DENALI_CTL_119_DATA,
+	DENALI_CTL_120_DATA, DENALI_CTL_121_DATA, DENALI_CTL_122_DATA,
+	DENALI_CTL_123_DATA, DENALI_CTL_124_DATA, DENALI_CTL_125_DATA,
+	DENALI_CTL_126_DATA, DENALI_CTL_127_DATA, DENALI_CTL_128_DATA,
+	DENALI_CTL_129_DATA,
+	DENALI_CTL_130_DATA, DENALI_CTL_131_DATA, DENALI_CTL_132_DATA,
+	DENALI_CTL_133_DATA, DENALI_CTL_134_DATA, DENALI_CTL_135_DATA,
+	DENALI_CTL_136_DATA, DENALI_CTL_137_DATA, DENALI_CTL_138_DATA,
+	DENALI_CTL_139_DATA,
+	DENALI_CTL_140_DATA, DENALI_CTL_141_DATA, DENALI_CTL_142_DATA,
+	DENALI_CTL_143_DATA, DENALI_CTL_144_DATA, DENALI_CTL_145_DATA,
+	DENALI_CTL_146_DATA, DENALI_CTL_147_DATA, DENALI_CTL_148_DATA,
+	DENALI_CTL_149_DATA,
+	DENALI_CTL_150_DATA, DENALI_CTL_151_DATA, DENALI_CTL_152_DATA,
+	DENALI_CTL_153_DATA, DENALI_CTL_154_DATA, DENALI_CTL_155_DATA,
+	DENALI_CTL_156_DATA, DENALI_CTL_157_DATA, DENALI_CTL_158_DATA,
+	DENALI_CTL_159_DATA,
+	DENALI_CTL_160_DATA, DENALI_CTL_161_DATA, DENALI_CTL_162_DATA,
+	DENALI_CTL_163_DATA, DENALI_CTL_164_DATA, DENALI_CTL_165_DATA,
+	DENALI_CTL_166_DATA, DENALI_CTL_167_DATA, DENALI_CTL_168_DATA,
+	DENALI_CTL_169_DATA,
+	DENALI_CTL_170_DATA, DENALI_CTL_171_DATA, DENALI_CTL_172_DATA,
+	DENALI_CTL_173_DATA, DENALI_CTL_174_DATA, DENALI_CTL_175_DATA,
+	DENALI_CTL_176_DATA, DENALI_CTL_177_DATA, DENALI_CTL_178_DATA,
+	DENALI_CTL_179_DATA,
+	DENALI_CTL_180_DATA, DENALI_CTL_181_DATA, DENALI_CTL_182_DATA,
+	DENALI_CTL_183_DATA, DENALI_CTL_184_DATA, DENALI_CTL_185_DATA,
+	DENALI_CTL_186_DATA, DENALI_CTL_187_DATA, DENALI_CTL_188_DATA,
+	DENALI_CTL_189_DATA,
+	DENALI_CTL_190_DATA, DENALI_CTL_191_DATA, DENALI_CTL_192_DATA,
+	DENALI_CTL_193_DATA, DENALI_CTL_194_DATA, DENALI_CTL_195_DATA,
+	DENALI_CTL_196_DATA, DENALI_CTL_197_DATA, DENALI_CTL_198_DATA,
+	DENALI_CTL_199_DATA,
+
+	DENALI_CTL_200_DATA, DENALI_CTL_201_DATA, DENALI_CTL_202_DATA,
+	DENALI_CTL_203_DATA, DENALI_CTL_204_DATA, DENALI_CTL_205_DATA,
+	DENALI_CTL_206_DATA, DENALI_CTL_207_DATA, DENALI_CTL_208_DATA,
+	DENALI_CTL_209_DATA,
+	DENALI_CTL_210_DATA, DENALI_CTL_211_DATA, DENALI_CTL_212_DATA,
+	DENALI_CTL_213_DATA, DENALI_CTL_214_DATA, DENALI_CTL_215_DATA,
+	DENALI_CTL_216_DATA, DENALI_CTL_217_DATA, DENALI_CTL_218_DATA,
+	DENALI_CTL_219_DATA,
+	DENALI_CTL_220_DATA, DENALI_CTL_221_DATA, DENALI_CTL_222_DATA,
+	DENALI_CTL_223_DATA, DENALI_CTL_224_DATA, DENALI_CTL_225_DATA,
+	DENALI_CTL_226_DATA, DENALI_CTL_227_DATA, DENALI_CTL_228_DATA,
+	DENALI_CTL_229_DATA,
+	DENALI_CTL_230_DATA, DENALI_CTL_231_DATA, DENALI_CTL_232_DATA,
+	DENALI_CTL_233_DATA, DENALI_CTL_234_DATA, DENALI_CTL_235_DATA,
+	DENALI_CTL_236_DATA, DENALI_CTL_237_DATA, DENALI_CTL_238_DATA,
+	DENALI_CTL_239_DATA,
+	DENALI_CTL_240_DATA, DENALI_CTL_241_DATA, DENALI_CTL_242_DATA,
+	DENALI_CTL_243_DATA, DENALI_CTL_244_DATA, DENALI_CTL_245_DATA,
+	DENALI_CTL_246_DATA, DENALI_CTL_247_DATA, DENALI_CTL_248_DATA,
+	DENALI_CTL_249_DATA,
+	DENALI_CTL_250_DATA, DENALI_CTL_251_DATA, DENALI_CTL_252_DATA,
+	DENALI_CTL_253_DATA, DENALI_CTL_254_DATA, DENALI_CTL_255_DATA,
+	DENALI_CTL_256_DATA, DENALI_CTL_257_DATA, DENALI_CTL_258_DATA,
+	DENALI_CTL_259_DATA,
+	DENALI_CTL_260_DATA, DENALI_CTL_261_DATA, DENALI_CTL_262_DATA,
+	DENALI_CTL_263_DATA, DENALI_CTL_264_DATA
+};
diff --git a/board/sifive/fu540/include/ememoryotp.h b/board/sifive/fu540/include/ememoryotp.h
new file mode 100644
index 0000000000..274283c4db
--- /dev/null
+++ b/board/sifive/fu540/include/ememoryotp.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#ifndef FU540_EMEMORYOTP_H
+#define FU540_EMEMORYOTP_H
+
+#include <asm/arch/otp.h>
+
+void ememory_otp_power_up_sequence(void);
+void ememory_otp_power_down_sequence(void);
+void ememory_otp_begin_read(void);
+void ememory_otp_exit_read(void);
+unsigned int ememory_otp_read(int address);
+void ememory_otp_pgm_entry(void);
+void ememory_otp_pgm_exit(void);
+void ememory_otp_pgm_access(int address, unsigned int write_data);
+
+#endif /* FU540_EMEMORYOTP_H */
diff --git a/board/sifive/fu540/include/fu540-memory-map.h b/board/sifive/fu540/include/fu540-memory-map.h
new file mode 100644
index 0000000000..071ee3d1d9
--- /dev/null
+++ b/board/sifive/fu540/include/fu540-memory-map.h
@@ -0,0 +1,427 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#ifndef FU540_MEMORY_MAP
+#define FU540_MEMORY_MAP
+
+#include <linux/const.h>
+#include <asm/arch/clint.h>
+#include <asm/arch/gpio.h>
+#include "ememoryotp.h"
+#include "ccache.h"
+#include "i2c.h"
+#include "spi.h"
+#include "uart.h"
+#include "ux00prci.h"
+
+/****************************************************************************
+ * Platform definitions
+ *****************************************************************************/
+
+// CPU info
+#define NUM_CORES                      5
+#define MAX_HART_ID                    4
+#define GLOBAL_INT_SIZE                59
+#define GLOBAL_INT_MAX_PRIORITY        7
+#define RTC_FREQUENCY_HZ               _AC(1000000, UL)
+#define RTC_PERIOD_NS                  _AC(1000, UL)
+
+// Memory map
+#define BUSERROR0_CTRL_ADDR            _AC(0x1700000, UL)
+#define BUSERROR0_CTRL_SIZE            _AC(0x1000, UL)
+#define BUSERROR1_CTRL_ADDR            _AC(0x1701000, UL)
+#define BUSERROR1_CTRL_SIZE            _AC(0x1000, UL)
+#define BUSERROR2_CTRL_ADDR            _AC(0x1702000, UL)
+#define BUSERROR2_CTRL_SIZE            _AC(0x1000, UL)
+#define BUSERROR3_CTRL_ADDR            _AC(0x1703000, UL)
+#define BUSERROR3_CTRL_SIZE            _AC(0x1000, UL)
+#define BUSERROR4_CTRL_ADDR            _AC(0x1704000, UL)
+#define BUSERROR4_CTRL_SIZE            _AC(0x1000, UL)
+#ifndef BUSERROR_CTRL_ADDR
+#define BUSERROR_CTRL_ADDR             BUSERROR0_CTRL_ADDR
+#endif
+#ifndef BUSERROR_CTRL_SIZE
+#define BUSERROR_CTRL_SIZE             BUSERROR0_CTRL_SIZE
+#endif
+
+#define CACHEABLE_ZERO_MEM_ADDR        _AC(0xa000000, UL)
+#define CACHEABLE_ZERO_MEM_SIZE        _AC(0x2000000, UL)
+#define CADENCEDDRMGMT_CTRL_ADDR       _AC(0x100c0000, UL)
+#define CADENCEDDRMGMT_CTRL_SIZE       _AC(0x1000, UL)
+#define CADENCEGEMGXLMGMT_CTRL_ADDR    _AC(0x100a0000, UL)
+#define CADENCEGEMGXLMGMT_CTRL_SIZE    _AC(0x1000, UL)
+#define CCACHE_CTRL_ADDR               _AC(0x2010000, UL)
+#define CCACHE_CTRL_SIZE               _AC(0x1000, UL)
+#define CCACHE_SIDEBAND_ADDR           _AC(0x8000000, UL)
+#define CCACHE_SIDEBAND_SIZE           _AC(0x1e0000, UL)
+
+#define CHIPLINK_MEM0_ADDR             _AC(0x40000000, UL)
+#define CHIPLINK_MEM0_SIZE             _AC(0x10000000, UL)
+#define CHIPLINK_MEM1_ADDR             _AC(0x60000000, UL)
+#define CHIPLINK_MEM1_SIZE             _AC(0x10000000, UL)
+#define CHIPLINK_MEM2_ADDR             _AC(0x2000000000, UL)
+#define CHIPLINK_MEM2_SIZE             _AC(0x20000000, UL)
+#define CHIPLINK_MEM3_ADDR             _AC(0x2080000000, UL)
+#define CHIPLINK_MEM3_SIZE             _AC(0x180000000, UL)
+#define CHIPLINK_MEM4_ADDR             _AC(0x3000000000, UL)
+#define CHIPLINK_MEM4_SIZE             _AC(0x20000000, UL)
+
+#define CLINT_CTRL_ADDR                _AC(0x2000000, UL)
+#define CLINT_CTRL_SIZE                _AC(0x10000, UL)
+#define DEBUG_CTRL_ADDR                _AC(0x0, UL)
+#define DEBUG_CTRL_SIZE                _AC(0x1000, UL)
+#define DMA_CTRL_ADDR                  _AC(0x3000000, UL)
+#define DMA_CTRL_SIZE                  _AC(0x100000, UL)
+#define DTIM_MEM_ADDR                  _AC(0x1000000, UL)
+#define DTIM_MEM_SIZE                  _AC(0x2000, UL)
+#define EMEMORYOTP_CTRL_ADDR           _AC(0x10070000, UL)
+#define EMEMORYOTP_CTRL_SIZE           _AC(0x1000, UL)
+#define ERROR_MEM_ADDR                 _AC(0x18000000, UL)
+#define ERROR_MEM_SIZE                 _AC(0x8000000, UL)
+#define GPIO_CTRL_ADDR                 _AC(0x10060000, UL)
+#define GPIO_CTRL_SIZE                 _AC(0x1000, UL)
+#define I2C_CTRL_ADDR                  _AC(0x10030000, UL)
+#define I2C_CTRL_SIZE                  _AC(0x1000, UL)
+
+#define ITIM0_MEM_ADDR                 _AC(0x1800000, UL)
+#define ITIM0_MEM_SIZE                 _AC(0x2000, UL)
+#define ITIM1_MEM_ADDR                 _AC(0x1808000, UL)
+#define ITIM1_MEM_SIZE                 _AC(0x7000, UL)
+#define ITIM2_MEM_ADDR                 _AC(0x1810000, UL)
+#define ITIM2_MEM_SIZE                 _AC(0x7000, UL)
+#define ITIM3_MEM_ADDR                 _AC(0x1818000, UL)
+#define ITIM3_MEM_SIZE                 _AC(0x7000, UL)
+#define ITIM4_MEM_ADDR                 _AC(0x1820000, UL)
+#define ITIM4_MEM_SIZE                 _AC(0x7000, UL)
+#ifndef ITIM_MEM_ADDR
+#define ITIM_MEM_ADDR                  ITIM0_MEM_ADDR
+#endif
+#ifndef ITIM_MEM_SIZE
+#define ITIM_MEM_SIZE                  ITIM0_MEM_SIZE
+#endif
+
+#define MAC_CTRL_ADDR                  _AC(0x10090000, UL)
+#define MAC_CTRL_SIZE                  _AC(0x2000, UL)
+#define MASKROM_MEM_ADDR               _AC(0x10000, UL)
+#define MASKROM_MEM_SIZE               _AC(0x8000, UL)
+#define MEMORY_MEM_ADDR                _AC(0x80000000, UL)
+#define MEMORY_MEM_SIZE                _AC(0x80000000, UL)
+#define MODESELECT_MEM_ADDR            _AC(0x1000, UL)
+#define MODESELECT_MEM_SIZE            _AC(0x1000, UL)
+#define MSI_CTRL_ADDR                  _AC(0x2020000, UL)
+#define MSI_CTRL_SIZE                  _AC(0x1000, UL)
+#define ORDER_OGLER_CTRL_ADDR          _AC(0x10100000, UL)
+#define ORDER_OGLER_CTRL_SIZE          _AC(0x1000, UL)
+#define PHYSICAL_FILTER_CTRL_ADDR      _AC(0x100b8000, UL)
+#define PHYSICAL_FILTER_CTRL_SIZE      _AC(0x1000, UL)
+#define PINCTRL_CTRL_ADDR              _AC(0x10080000, UL)
+#define PINCTRL_CTRL_SIZE              _AC(0x1000, UL)
+#define PLIC_CTRL_ADDR                 _AC(0xc000000, UL)
+#define PLIC_CTRL_SIZE                 _AC(0x4000000, UL)
+
+#define PWM0_CTRL_ADDR                 _AC(0x10020000, UL)
+#define PWM0_CTRL_SIZE                 _AC(0x1000, UL)
+#define PWM1_CTRL_ADDR                 _AC(0x10021000, UL)
+#define PWM1_CTRL_SIZE                 _AC(0x1000, UL)
+#ifndef PWM_CTRL_ADDR
+#define PWM_CTRL_ADDR                  PWM0_CTRL_ADDR
+#endif
+#ifndef PWM_CTRL_SIZE
+#define PWM_CTRL_SIZE                  PWM0_CTRL_SIZE
+#endif
+
+#define SPI0_CTRL_ADDR                 _AC(0x10040000, UL)
+#define SPI0_CTRL_SIZE                 _AC(0x1000, UL)
+#define SPI0_MEM_ADDR                  _AC(0x20000000, UL)
+#define SPI0_MEM_SIZE                  _AC(0x10000000, UL)
+#define SPI1_CTRL_ADDR                 _AC(0x10041000, UL)
+#define SPI1_CTRL_SIZE                 _AC(0x1000, UL)
+#define SPI1_MEM_ADDR                  _AC(0x30000000, UL)
+#define SPI1_MEM_SIZE                  _AC(0x10000000, UL)
+#define SPI2_CTRL_ADDR                 _AC(0x10050000, UL)
+#define SPI2_CTRL_SIZE                 _AC(0x1000, UL)
+#ifndef SPI_CTRL_ADDR
+#define SPI_CTRL_ADDR                  SPI0_CTRL_ADDR
+#endif
+#ifndef SPI_CTRL_SIZE
+#define SPI_CTRL_SIZE                  SPI0_CTRL_SIZE
+#endif
+#ifndef SPI_MEM_ADDR
+#define SPI_MEM_ADDR                   SPI0_MEM_ADDR
+#endif
+#ifndef SPI_MEM_SIZE
+#define SPI_MEM_SIZE                   SPI0_MEM_SIZE
+#endif
+
+#define TEST_CTRL_ADDR                 _AC(0x4000, UL)
+#define TEST_CTRL_SIZE                 _AC(0x1000, UL)
+#define UART0_CTRL_ADDR                _AC(0x10010000, UL)
+#define UART0_CTRL_SIZE                _AC(0x1000, UL)
+#define UART1_CTRL_ADDR                _AC(0x10011000, UL)
+#define UART1_CTRL_SIZE                _AC(0x1000, UL)
+#ifndef UART_CTRL_ADDR
+#define UART_CTRL_ADDR                 UART0_CTRL_ADDR
+#endif
+#ifndef UART_CTRL_SIZE
+#define UART_CTRL_SIZE                 UART0_CTRL_SIZE
+#endif
+#define UX00DDR_CTRL_ADDR              _AC(0x100b0000, UL)
+#define UX00DDR_CTRL_SIZE              _AC(0x4000, UL)
+#define UX00PRCI_CTRL_ADDR             _AC(0x10000000, UL)
+#define UX00PRCI_CTRL_SIZE             _AC(0x1000, UL)
+
+// IOF masks
+// Interrupt numbers
+#define CCACHE_INT_BASE       1
+#define UART0_INT_BASE        5
+#define UART1_INT_BASE        6
+#define SPI2_INT_BASE         7
+#define GPIO_INT_BASE         8
+#define DMA_INT_BASE          24
+#define UX00DDR_INT_BASE      32
+#define MSI_INT_BASE          33
+#define PWM0_INT_BASE         43
+#define PWM1_INT_BASE         47
+#define I2C_INT_BASE          51
+#define SPI0_INT_BASE         52
+#define SPI1_INT_BASE         53
+#define MAC_INT_BASE          54
+#define BUSERROR0_INT_BASE    55
+#define BUSERROR1_INT_BASE    56
+#define BUSERROR2_INT_BASE    57
+#define BUSERROR3_INT_BASE    58
+#define BUSERROR4_INT_BASE    59
+#ifndef BUSERROR_INT_BASE
+#define BUSERROR_INT_BASE     BUSERROR0_INT_BASE
+#endif
+#ifndef PWM_INT_BASE
+#define PWM_INT_BASE          PWM0_INT_BASE
+#endif
+#ifndef SPI_INT_BASE
+#define SPI_INT_BASE          SPI0_INT_BASE
+#endif
+#ifndef UART_INT_BASE
+#define UART_INT_BASE         UART0_INT_BASE
+#endif
+
+// Helper functions
+#define _REG64(p, i)    (*(volatile uint64_t *)((p) + (i)))
+#define _REG32(p, i)    (*(volatile uint32_t *)((p) + (i)))
+#define _REG16(p, i)    (*(volatile uint16_t *)((p) + (i)))
+// Bulk set bits in `reg` to either 0 or 1.
+// E.g. SET_BITS(MY_REG, 0x00000007, 0) would generate MY_REG &= ~0x7
+// E.g. SET_BITS(MY_REG, 0x00000007, 1) would generate MY_REG |= 0x7
+#define SET_BITS(reg, mask, value)         \
+	if ((value) == 0)	\
+		(reg) &= ~(mask);	\
+	else	{\
+		(reg) |= (mask); }
+
+#ifndef BUSERROR_REG
+#define BUSERROR_REG(offset)      BUSERROR0_REG(offset)
+#endif
+#ifndef BUSERROR_REG64
+#define BUSERROR_REG64(offset)    BUSERROR0_REG64(offset)
+#endif
+#ifndef ITIM_REG
+#define ITIM_REG(offset)          ITIM0_REG(offset)
+#endif
+#ifndef ITIM_REG64
+#define ITIM_REG64(offset)        ITIM0_REG64(offset)
+#endif
+#ifndef PWM_REG
+#define PWM_REG(offset)           PWM0_REG(offset)
+#endif
+#ifndef PWM_REG64
+#define PWM_REG64(offset)         PWM0_REG64(offset)
+#endif
+#ifndef SPI_REG
+#define SPI_REG(offset)           SPI0_REG(offset)
+#endif
+#ifndef SPI_REG64
+#define SPI_REG64(offset)         SPI0_REG64(offset)
+#endif
+#ifndef UART_REG
+#define UART_REG(offset)          UART0_REG(offset)
+#endif
+#ifndef UART_REG64
+#define UART_REG64(offset)        UART0_REG64(offset)
+#endif
+#define BUSERROR0_REG(offset)  \
+	_REG32(BUSERROR0_CTRL_ADDR, \
+			offset)
+#define BUSERROR1_REG(offset)  \
+	_REG32(BUSERROR1_CTRL_ADDR, \
+			offset)
+#define BUSERROR2_REG(offset)  \
+	_REG32(BUSERROR2_CTRL_ADDR, \
+			offset)
+#define BUSERROR3_REG(offset)  \
+	_REG32(BUSERROR3_CTRL_ADDR, \
+			offset)
+#define BUSERROR4_REG(offset)  \
+	_REG32(BUSERROR4_CTRL_ADDR, \
+			offset)
+#define CACHEABLE_ZERO_REG(offset)  \
+	_REG32(CACHEABLE_ZERO_CTRL_ADDR, \
+			offset)
+#define CADENCEDDRMGMT_REG(offset)  \
+	_REG32(CADENCEDDRMGMT_CTRL_ADDR, \
+			offset)
+#define CADENCEGEMGXLMGMT_REG(offset) \
+	_REG32(                            \
+			CADENCEGEMGXLMGMT_CTRL_ADDR, offset)
+#define CCACHE_REG(offset)    _REG32(CCACHE_CTRL_ADDR, offset)
+#define CHIPLINK_REG(offset)  \
+	_REG32(CHIPLINK_CTRL_ADDR, \
+			offset)
+#define CLINT_REG(offset)     _REG32(CLINT_CTRL_ADDR, offset)
+#define DEBUG_REG(offset)     _REG32(DEBUG_CTRL_ADDR, offset)
+#define DMA_REG(offset)       _REG32(DMA_CTRL_ADDR, offset)
+#define DTIM_REG(offset)      _REG32(DTIM_CTRL_ADDR, offset)
+#define EMEMORYOTP_REG(offset)  \
+	_REG32(EMEMORYOTP_CTRL_ADDR, \
+			offset)
+#define ERROR_REG(offset)     _REG32(ERROR_CTRL_ADDR, offset)
+#define GPIO_REG(offset)      _REG32(GPIO_CTRL_ADDR, offset)
+#define I2C_REG(offset)       _REG32(I2C_CTRL_ADDR, offset)
+#define ITIM0_REG(offset)     _REG32(ITIM0_CTRL_ADDR, offset)
+#define ITIM1_REG(offset)     _REG32(ITIM1_CTRL_ADDR, offset)
+#define ITIM2_REG(offset)     _REG32(ITIM2_CTRL_ADDR, offset)
+#define ITIM3_REG(offset)     _REG32(ITIM3_CTRL_ADDR, offset)
+#define ITIM4_REG(offset)     _REG32(ITIM4_CTRL_ADDR, offset)
+#define MAC_REG(offset)       _REG32(MAC_CTRL_ADDR, offset)
+#define MASKROM_REG(offset)  \
+	_REG32(MASKROM_CTRL_ADDR, \
+			offset)
+#define MEMORY_REG(offset)    _REG32(MEMORY_CTRL_ADDR, offset)
+#define MODESELECT_REG(offset)  \
+	_REG32(MODESELECT_CTRL_ADDR, \
+			offset)
+#define MSI_REG(offset)       _REG32(MSI_CTRL_ADDR, offset)
+#define ORDER_OGLER_REG(offset)  \
+	_REG32(ORDER_OGLER_CTRL_ADDR, \
+			offset)
+#define PHYSICAL_FILTER_REG(offset) \
+	_REG32(                          \
+			PHYSICAL_FILTER_CTRL_ADDR, offset)
+#define PINCTRL_REG(offset)  \
+	_REG32(PINCTRL_CTRL_ADDR, \
+			offset)
+#define PLIC_REG(offset)     _REG32(PLIC_CTRL_ADDR, offset)
+#define PWM0_REG(offset)     _REG32(PWM0_CTRL_ADDR, offset)
+#define PWM1_REG(offset)     _REG32(PWM1_CTRL_ADDR, offset)
+#define SPI0_REG(offset)     _REG32(SPI0_CTRL_ADDR, offset)
+#define SPI1_REG(offset)     _REG32(SPI1_CTRL_ADDR, offset)
+#define SPI2_REG(offset)     _REG32(SPI2_CTRL_ADDR, offset)
+#define TEST_REG(offset)     _REG32(TEST_CTRL_ADDR, offset)
+#define UART0_REG(offset)    _REG32(UART0_CTRL_ADDR, offset)
+#define UART1_REG(offset)    _REG32(UART1_CTRL_ADDR, offset)
+#define UX00DDR_REG(offset)  \
+	_REG32(UX00DDR_CTRL_ADDR, \
+			offset)
+#define UX00PRCI_REG(offset)  \
+	_REG32(UX00PRCI_CTRL_ADDR, \
+			offset)
+#define BUSERROR0_REG64(offset) \
+	_REG64(BUSERROR0_CTRL_ADDR,  \
+			offset)
+#define BUSERROR1_REG64(offset) \
+	_REG64(BUSERROR1_CTRL_ADDR,  \
+			offset)
+#define BUSERROR2_REG64(offset) \
+	_REG64(BUSERROR2_CTRL_ADDR,  \
+			offset)
+#define BUSERROR3_REG64(offset) \
+	_REG64(BUSERROR3_CTRL_ADDR,  \
+			offset)
+#define BUSERROR4_REG64(offset) \
+	_REG64(BUSERROR4_CTRL_ADDR,  \
+			offset)
+#define CACHEABLE_ZERO_REG64(offset) \
+	_REG64(CACHEABLE_ZERO_CTRL_ADDR,  \
+			offset)
+#define CADENCEDDRMGMT_REG64(offset) \
+	_REG64(CADENCEDDRMGMT_CTRL_ADDR,  \
+			offset)
+#define CADENCEGEMGXLMGMT_REG64(offset) \
+	_REG64(                              \
+			CADENCEGEMGXLMGMT_CTRL_ADDR, offset)
+#define CCACHE_REG64(offset)    _REG64(CCACHE_CTRL_ADDR, offset)
+#define CHIPLINK_REG64(offset) \
+	_REG64(CHIPLINK_CTRL_ADDR,  \
+			offset)
+#define CLINT_REG64(offset)     _REG64(CLINT_CTRL_ADDR, offset)
+#define DEBUG_REG64(offset)     _REG64(DEBUG_CTRL_ADDR, offset)
+#define DMA_REG64(offset)       _REG64(DMA_CTRL_ADDR, offset)
+#define DTIM_REG64(offset)      _REG64(DTIM_CTRL_ADDR, offset)
+#define EMEMORYOTP_REG64(offset) \
+	_REG64(EMEMORYOTP_CTRL_ADDR,  \
+			offset)
+#define ERROR_REG64(offset)     _REG64(ERROR_CTRL_ADDR, offset)
+#define GPIO_REG64(offset)      _REG64(GPIO_CTRL_ADDR, offset)
+#define I2C_REG64(offset)       _REG64(I2C_CTRL_ADDR, offset)
+#define ITIM0_REG64(offset)     _REG64(ITIM0_CTRL_ADDR, offset)
+#define ITIM1_REG64(offset)     _REG64(ITIM1_CTRL_ADDR, offset)
+#define ITIM2_REG64(offset)     _REG64(ITIM2_CTRL_ADDR, offset)
+#define ITIM3_REG64(offset)     _REG64(ITIM3_CTRL_ADDR, offset)
+#define ITIM4_REG64(offset)     _REG64(ITIM4_CTRL_ADDR, offset)
+#define MAC_REG64(offset)       _REG64(MAC_CTRL_ADDR, offset)
+#define MASKROM_REG64(offset) \
+	_REG64(MASKROM_CTRL_ADDR,  \
+			offset)
+#define MEMORY_REG64(offset)    _REG64(MEMORY_CTRL_ADDR, offset)
+#define MODESELECT_REG64(offset) \
+	_REG64(MODESELECT_CTRL_ADDR,  \
+			offset)
+#define MSI_REG64(offset)       _REG64(MSI_CTRL_ADDR, offset)
+#define ORDER_OGLER_REG64(offset) \
+	_REG64(ORDER_OGLER_CTRL_ADDR,  \
+			offset)
+#define PHYSICAL_FILTER_REG64(offset) \
+	_REG64(                            \
+			PHYSICAL_FILTER_CTRL_ADDR, offset)
+#define PINCTRL_REG64(offset) \
+	_REG64(PINCTRL_CTRL_ADDR,  \
+			offset)
+#define PLIC_REG64(offset)     _REG64(PLIC_CTRL_ADDR, offset)
+#define PWM0_REG64(offset)     _REG64(PWM0_CTRL_ADDR, offset)
+#define PWM1_REG64(offset)     _REG64(PWM1_CTRL_ADDR, offset)
+#define SPI0_REG64(offset)     _REG64(SPI0_CTRL_ADDR, offset)
+#define SPI1_REG64(offset)     _REG64(SPI1_CTRL_ADDR, offset)
+#define SPI2_REG64(offset)     _REG64(SPI2_CTRL_ADDR, offset)
+#define TEST_REG64(offset)     _REG64(TEST_CTRL_ADDR, offset)
+#define UART0_REG64(offset)    _REG64(UART0_CTRL_ADDR, offset)
+#define UART1_REG64(offset)    _REG64(UART1_CTRL_ADDR, offset)
+#define UX00DDR_REG64(offset) \
+	_REG64(UX00DDR_CTRL_ADDR,  \
+			offset)
+#define UX00PRCI_REG64(offset) \
+	_REG64(UX00PRCI_CTRL_ADDR,  \
+			offset)
+// Helpers for getting and setting individual bit fields, shifting the values
+// for you.
+#define GET_FIELD(reg, mask)     \
+	(((reg) & (mask)) / ((mask) & \
+		~((mask) << 1)))
+#define SET_FIELD(reg, mask, val) \
+	(((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask)))
+
+// Misc
+#define ALOE
+#define SPI0_CS_WIDTH        1
+#define SPI0_SCKDIV_WIDTH    16
+#define SPI1_CS_WIDTH        4
+#define SPI1_SCKDIV_WIDTH    16
+#define SPI2_CS_WIDTH        1
+#define SPI2_SCKDIV_WIDTH    16
+#define GPIO_WIDTH           16
+
+#endif /* FU540_MEMORY_MAP */
diff --git a/board/sifive/fu540/include/i2c.h b/board/sifive/fu540/include/i2c.h
new file mode 100644
index 0000000000..89c81f6b92
--- /dev/null
+++ b/board/sifive/fu540/include/i2c.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#ifndef FU540_I2C_H
+#define FU540_I2C_H
+
+#include <asm/arch/i2c.h>
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+/*
+ * Get smallest clock prescaler that divides input_khz to a quotient less
+ * than or equal to max_target_khz;
+ */
+static inline uint16_t i2c_min_clk_prescaler(unsigned int input_khz,
+					     unsigned int max_target_khz)
+{
+	// f_sck = f_in / (2 * (div + 1)) => div = (f_in / (2*f_sck)) - 1
+	// prescale = (f_in / (5*f_scl)) - 1
+	//
+	// The nearest integer solution for div requires
+	// rounding up as to not exceed max_target_khz.
+	//
+	// div = ceil(f_in / (5*f_scl)) - 1
+	//     = floor((f_in - 1 + 5*f_scl) / (5*f_scl)) - 1
+	//
+	// This should not overflow as long as (f_in - 1 + 5*f_scl) does not
+	// exceed 2^32 - 1, which is unlikely since we represent frequencies
+	// in kHz.
+	unsigned int quotient = (input_khz + 5 * max_target_khz - 1) / (5 *
+				 max_target_khz);
+	// Avoid underflow
+	if (quotient == 0)
+		return 0;
+	else
+		return quotient - 1;
+}
+
+#endif /* !__ASSEMBLER__ */
+
+#endif /* FU540_I2C_H */
diff --git a/board/sifive/fu540/include/regconfig-ctl.h b/board/sifive/fu540/include/regconfig-ctl.h
new file mode 100644
index 0000000000..19a52e7996
--- /dev/null
+++ b/board/sifive/fu540/include/regconfig-ctl.h
@@ -0,0 +1,274 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#define               DENALI_CTL_00_DATA 0x00000a00
+#define               DENALI_CTL_01_DATA 0x00000000
+#define               DENALI_CTL_02_DATA 0x00000000
+#define               DENALI_CTL_03_DATA 0x00000000
+#define               DENALI_CTL_04_DATA 0x00000000
+#define               DENALI_CTL_05_DATA 0x00000000
+#define               DENALI_CTL_06_DATA 0x0000000a
+#define               DENALI_CTL_07_DATA 0x0002d362
+#define               DENALI_CTL_08_DATA 0x00071073
+#define               DENALI_CTL_09_DATA 0x0a1c0255
+#define               DENALI_CTL_10_DATA 0x1c1c0400
+#define               DENALI_CTL_11_DATA 0x0404990b
+#define               DENALI_CTL_12_DATA 0x2b050405
+#define               DENALI_CTL_13_DATA 0x0e0c081e
+#define               DENALI_CTL_14_DATA 0x08090914
+#define               DENALI_CTL_15_DATA 0x00fde718
+#define               DENALI_CTL_16_DATA 0x00180a05
+#define               DENALI_CTL_17_DATA 0x008b130e
+#define               DENALI_CTL_18_DATA 0x01000118
+#define               DENALI_CTL_19_DATA 0x0e032101
+#define               DENALI_CTL_20_DATA 0x00000000
+#define               DENALI_CTL_21_DATA 0x00000101
+#define               DENALI_CTL_22_DATA 0x00000000
+#define               DENALI_CTL_23_DATA 0x0a000000
+#define               DENALI_CTL_24_DATA 0x00000000
+#define               DENALI_CTL_25_DATA 0x01450100
+#define               DENALI_CTL_26_DATA 0x00001c36
+#define               DENALI_CTL_27_DATA 0x00000005
+#define               DENALI_CTL_28_DATA 0x00170006
+#define               DENALI_CTL_29_DATA 0x014e0300
+#define               DENALI_CTL_30_DATA 0x03010000
+#define               DENALI_CTL_31_DATA 0x000a0e00
+#define               DENALI_CTL_32_DATA 0x04030200
+#define               DENALI_CTL_33_DATA 0x0000031f
+#define               DENALI_CTL_34_DATA 0x00070004
+#define               DENALI_CTL_35_DATA 0x00000000
+#define               DENALI_CTL_36_DATA 0x00000000
+#define               DENALI_CTL_37_DATA 0x00000000
+#define               DENALI_CTL_38_DATA 0x00000000
+#define               DENALI_CTL_39_DATA 0x00000000
+#define               DENALI_CTL_40_DATA 0x00000000
+#define               DENALI_CTL_41_DATA 0x00000000
+#define               DENALI_CTL_42_DATA 0x00000000
+#define               DENALI_CTL_43_DATA 0x00000000
+#define               DENALI_CTL_44_DATA 0x00000000
+#define               DENALI_CTL_45_DATA 0x00000000
+#define               DENALI_CTL_46_DATA 0x00000000
+#define               DENALI_CTL_47_DATA 0x00000000
+#define               DENALI_CTL_48_DATA 0x00000000
+#define               DENALI_CTL_49_DATA 0x00000000
+#define               DENALI_CTL_50_DATA 0x00000000
+#define               DENALI_CTL_51_DATA 0x00000000
+#define               DENALI_CTL_52_DATA 0x00000000
+#define               DENALI_CTL_53_DATA 0x00000000
+#define               DENALI_CTL_54_DATA 0x00000000
+#define               DENALI_CTL_55_DATA 0x00000000
+#define               DENALI_CTL_56_DATA 0x00000000
+#define               DENALI_CTL_57_DATA 0x00000000
+#define               DENALI_CTL_58_DATA 0x00000000
+#define               DENALI_CTL_59_DATA 0x00000000
+#define               DENALI_CTL_60_DATA 0x00000424
+#define               DENALI_CTL_61_DATA 0x00000201
+#define               DENALI_CTL_62_DATA 0x00001008
+#define               DENALI_CTL_63_DATA 0x00000000
+#define               DENALI_CTL_64_DATA 0x00000200
+#define               DENALI_CTL_65_DATA 0x00000000
+#define               DENALI_CTL_66_DATA 0x00000481
+#define               DENALI_CTL_67_DATA 0x00000400
+#define               DENALI_CTL_68_DATA 0x00000424
+#define               DENALI_CTL_69_DATA 0x00000201
+#define               DENALI_CTL_70_DATA 0x00001008
+#define               DENALI_CTL_71_DATA 0x00000000
+#define               DENALI_CTL_72_DATA 0x00000200
+#define               DENALI_CTL_73_DATA 0x00000000
+#define               DENALI_CTL_74_DATA 0x00000481
+#define               DENALI_CTL_75_DATA 0x00000400
+#define               DENALI_CTL_76_DATA 0x01010000
+#define               DENALI_CTL_77_DATA 0x00000000
+#define               DENALI_CTL_78_DATA 0x00000000
+#define               DENALI_CTL_79_DATA 0x00000000
+#define               DENALI_CTL_80_DATA 0x00000000
+#define               DENALI_CTL_81_DATA 0x00000000
+#define               DENALI_CTL_82_DATA 0x00000000
+#define               DENALI_CTL_83_DATA 0x00000000
+#define               DENALI_CTL_84_DATA 0x00000000
+#define               DENALI_CTL_85_DATA 0x00000000
+#define               DENALI_CTL_86_DATA 0x00000000
+#define               DENALI_CTL_87_DATA 0x00000000
+#define               DENALI_CTL_88_DATA 0x00000000
+#define               DENALI_CTL_89_DATA 0x00000000
+#define               DENALI_CTL_90_DATA 0x00000000
+#define               DENALI_CTL_91_DATA 0x00000000
+#define               DENALI_CTL_92_DATA 0x00000000
+#define               DENALI_CTL_93_DATA 0x00000000
+#define               DENALI_CTL_94_DATA 0x00000000
+#define               DENALI_CTL_95_DATA 0x00000000
+#define               DENALI_CTL_96_DATA 0x00000000
+#define               DENALI_CTL_97_DATA 0x00000000
+#define               DENALI_CTL_98_DATA 0x00000000
+#define               DENALI_CTL_99_DATA 0x00000000
+#define              DENALI_CTL_100_DATA 0x00000000
+#define              DENALI_CTL_101_DATA 0x00000000
+#define              DENALI_CTL_102_DATA 0x00000000
+#define              DENALI_CTL_103_DATA 0x00000000
+#define              DENALI_CTL_104_DATA 0x00000000
+#define              DENALI_CTL_105_DATA 0x00000003
+#define              DENALI_CTL_106_DATA 0x00000000
+#define              DENALI_CTL_107_DATA 0x00000000
+#define              DENALI_CTL_108_DATA 0x00000000
+#define              DENALI_CTL_109_DATA 0x00000000
+#define              DENALI_CTL_110_DATA 0x01000000
+#define              DENALI_CTL_111_DATA 0x00040000
+#define              DENALI_CTL_112_DATA 0x00800200
+#define              DENALI_CTL_113_DATA 0x00000200
+#define              DENALI_CTL_114_DATA 0x00000040
+#define              DENALI_CTL_115_DATA 0x01000100
+#define              DENALI_CTL_116_DATA 0x0a000002
+#define              DENALI_CTL_117_DATA 0x0101ffff
+#define              DENALI_CTL_118_DATA 0x01010101
+#define              DENALI_CTL_119_DATA 0x01010101
+#define              DENALI_CTL_120_DATA 0x0000010b
+#define              DENALI_CTL_121_DATA 0x00000c01
+#define              DENALI_CTL_122_DATA 0x00000000
+#define              DENALI_CTL_123_DATA 0x00000000
+#define              DENALI_CTL_124_DATA 0x00000000
+#define              DENALI_CTL_125_DATA 0x00000000
+#define              DENALI_CTL_126_DATA 0x00030300
+#define              DENALI_CTL_127_DATA 0x00000000
+#define              DENALI_CTL_128_DATA 0x00010001
+#define              DENALI_CTL_129_DATA 0x00000000
+#define              DENALI_CTL_130_DATA 0x00000000
+#define              DENALI_CTL_131_DATA 0x00000000
+#define              DENALI_CTL_132_DATA 0x00000000
+#define              DENALI_CTL_133_DATA 0x00000000
+#define              DENALI_CTL_134_DATA 0x00000000
+#define              DENALI_CTL_135_DATA 0x00000000
+#define              DENALI_CTL_136_DATA 0x00000000
+#define              DENALI_CTL_137_DATA 0x00000000
+#define              DENALI_CTL_138_DATA 0x00000000
+#define              DENALI_CTL_139_DATA 0x00000000
+#define              DENALI_CTL_140_DATA 0x00000000
+#define              DENALI_CTL_141_DATA 0x00000000
+#define              DENALI_CTL_142_DATA 0x00000000
+#define              DENALI_CTL_143_DATA 0x00000000
+#define              DENALI_CTL_144_DATA 0x00000000
+#define              DENALI_CTL_145_DATA 0x00000000
+#define              DENALI_CTL_146_DATA 0x00000000
+#define              DENALI_CTL_147_DATA 0x00000000
+#define              DENALI_CTL_148_DATA 0x00000000
+#define              DENALI_CTL_149_DATA 0x00000000
+#define              DENALI_CTL_150_DATA 0x00000000
+#define              DENALI_CTL_151_DATA 0x00000000
+#define              DENALI_CTL_152_DATA 0x00000000
+#define              DENALI_CTL_153_DATA 0x00000000
+#define              DENALI_CTL_154_DATA 0x00000000
+#define              DENALI_CTL_155_DATA 0x00000000
+#define              DENALI_CTL_156_DATA 0x00000000
+#define              DENALI_CTL_157_DATA 0x00000000
+#define              DENALI_CTL_158_DATA 0x00000000
+#define              DENALI_CTL_159_DATA 0x00000000
+#define              DENALI_CTL_160_DATA 0x00000000
+#define              DENALI_CTL_161_DATA 0x02010102
+#define              DENALI_CTL_162_DATA 0x0107070d
+#define              DENALI_CTL_163_DATA 0x04040400
+#define              DENALI_CTL_164_DATA 0x03000503
+#define              DENALI_CTL_165_DATA 0x00000000
+#define              DENALI_CTL_166_DATA 0x00000000
+#define              DENALI_CTL_167_DATA 0x00000000
+#define              DENALI_CTL_168_DATA 0x00000000
+#define              DENALI_CTL_169_DATA 0x280d0000
+#define              DENALI_CTL_170_DATA 0x01000000
+#define              DENALI_CTL_171_DATA 0x00000000
+#define              DENALI_CTL_172_DATA 0x00010001
+#define              DENALI_CTL_173_DATA 0x00000000
+#define              DENALI_CTL_174_DATA 0x00000000
+#define              DENALI_CTL_175_DATA 0x00000000
+#define              DENALI_CTL_176_DATA 0x00000000
+#define              DENALI_CTL_177_DATA 0x00000000
+#define              DENALI_CTL_178_DATA 0x00000000
+#define              DENALI_CTL_179_DATA 0x00000000
+#define              DENALI_CTL_180_DATA 0x00000000
+#define              DENALI_CTL_181_DATA 0x01000000
+#define              DENALI_CTL_182_DATA 0x00000001
+#define              DENALI_CTL_183_DATA 0x00000100
+#define              DENALI_CTL_184_DATA 0x00000101
+#define              DENALI_CTL_185_DATA 0x67676701
+#define              DENALI_CTL_186_DATA 0x67676767
+#define              DENALI_CTL_187_DATA 0x67676767
+#define              DENALI_CTL_188_DATA 0x67676767
+#define              DENALI_CTL_189_DATA 0x67676767
+#define              DENALI_CTL_190_DATA 0x67676767
+#define              DENALI_CTL_191_DATA 0x67676767
+#define              DENALI_CTL_192_DATA 0x67676767
+#define              DENALI_CTL_193_DATA 0x67676767
+#define              DENALI_CTL_194_DATA 0x01000067
+#define              DENALI_CTL_195_DATA 0x00000001
+#define              DENALI_CTL_196_DATA 0x00000101
+#define              DENALI_CTL_197_DATA 0x00000000
+#define              DENALI_CTL_198_DATA 0x00000000
+#define              DENALI_CTL_199_DATA 0x00000000
+#define              DENALI_CTL_200_DATA 0x00000000
+#define              DENALI_CTL_201_DATA 0x00000000
+#define              DENALI_CTL_202_DATA 0x00000000
+#define              DENALI_CTL_203_DATA 0x00000000
+#define              DENALI_CTL_204_DATA 0x00000000
+#define              DENALI_CTL_205_DATA 0x00000000
+#define              DENALI_CTL_206_DATA 0x00000000
+#define              DENALI_CTL_207_DATA 0x00000000
+#define              DENALI_CTL_208_DATA 0x00000001
+#define              DENALI_CTL_209_DATA 0x00000000
+#define              DENALI_CTL_210_DATA 0x007fffff
+#define              DENALI_CTL_211_DATA 0x00000000
+#define              DENALI_CTL_212_DATA 0x007fffff
+#define              DENALI_CTL_213_DATA 0x00000000
+#define              DENALI_CTL_214_DATA 0x007fffff
+#define              DENALI_CTL_215_DATA 0x00000000
+#define              DENALI_CTL_216_DATA 0x007fffff
+#define              DENALI_CTL_217_DATA 0x00000000
+#define              DENALI_CTL_218_DATA 0x007fffff
+#define              DENALI_CTL_219_DATA 0x00000000
+#define              DENALI_CTL_220_DATA 0x007fffff
+#define              DENALI_CTL_221_DATA 0x00000000
+#define              DENALI_CTL_222_DATA 0x007fffff
+#define              DENALI_CTL_223_DATA 0x00000000
+#define              DENALI_CTL_224_DATA 0x037fffff
+#define              DENALI_CTL_225_DATA 0xffffffff
+#define              DENALI_CTL_226_DATA 0x000f000f
+#define              DENALI_CTL_227_DATA 0x00ffff03
+#define              DENALI_CTL_228_DATA 0x000fffff
+#define              DENALI_CTL_229_DATA 0x0003000f
+#define              DENALI_CTL_230_DATA 0xffffffff
+#define              DENALI_CTL_231_DATA 0x000f000f
+#define              DENALI_CTL_232_DATA 0x00ffff03
+#define              DENALI_CTL_233_DATA 0x000fffff
+#define              DENALI_CTL_234_DATA 0x0003000f
+#define              DENALI_CTL_235_DATA 0xffffffff
+#define              DENALI_CTL_236_DATA 0x000f000f
+#define              DENALI_CTL_237_DATA 0x00ffff03
+#define              DENALI_CTL_238_DATA 0x000fffff
+#define              DENALI_CTL_239_DATA 0x0003000f
+#define              DENALI_CTL_240_DATA 0xffffffff
+#define              DENALI_CTL_241_DATA 0x000f000f
+#define              DENALI_CTL_242_DATA 0x00ffff03
+#define              DENALI_CTL_243_DATA 0x000fffff
+#define              DENALI_CTL_244_DATA 0x6407000f
+#define              DENALI_CTL_245_DATA 0x01640001
+#define              DENALI_CTL_246_DATA 0x00000000
+#define              DENALI_CTL_247_DATA 0x00000000
+#define              DENALI_CTL_248_DATA 0x00001700
+#define              DENALI_CTL_249_DATA 0x00386c05
+#define              DENALI_CTL_250_DATA 0x02000200
+#define              DENALI_CTL_251_DATA 0x02000200
+#define              DENALI_CTL_252_DATA 0x0000386c
+#define              DENALI_CTL_253_DATA 0x00023438
+#define              DENALI_CTL_254_DATA 0x02020d10
+#define              DENALI_CTL_255_DATA 0x00140303
+#define              DENALI_CTL_256_DATA 0x00000000
+#define              DENALI_CTL_257_DATA 0x00000000
+#define              DENALI_CTL_258_DATA 0x00001403
+#define              DENALI_CTL_259_DATA 0x00000000
+#define              DENALI_CTL_260_DATA 0x00000000
+#define              DENALI_CTL_261_DATA 0x00000000
+#define              DENALI_CTL_262_DATA 0x00000000
+#define              DENALI_CTL_263_DATA 0x0d010000
+#define              DENALI_CTL_264_DATA 0x00000008
diff --git a/board/sifive/fu540/include/regconfig-phy.h b/board/sifive/fu540/include/regconfig-phy.h
new file mode 100644
index 0000000000..3450aecdf1
--- /dev/null
+++ b/board/sifive/fu540/include/regconfig-phy.h
@@ -0,0 +1,1224 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#define               DENALI_PHY_00_DATA 0x31706542
+#define               DENALI_PHY_01_DATA 0x0004c008
+#define               DENALI_PHY_02_DATA 0x000000da
+#define               DENALI_PHY_03_DATA 0x00000000
+#define               DENALI_PHY_04_DATA 0x00000000
+#define               DENALI_PHY_05_DATA 0x00010000
+#define               DENALI_PHY_06_DATA 0x01DDDD90
+#define               DENALI_PHY_07_DATA 0x01DDDD90
+#define               DENALI_PHY_08_DATA 0x01030000
+#define               DENALI_PHY_09_DATA 0x01000000
+#define               DENALI_PHY_10_DATA 0x00c00000
+#define               DENALI_PHY_11_DATA 0x00000007
+#define               DENALI_PHY_12_DATA 0x00000000
+#define               DENALI_PHY_13_DATA 0x00000000
+#define               DENALI_PHY_14_DATA 0x04000408
+#define               DENALI_PHY_15_DATA 0x00000408
+#define               DENALI_PHY_16_DATA 0x00e4e400
+#define               DENALI_PHY_17_DATA 0x00000000
+#define               DENALI_PHY_18_DATA 0x00000000
+#define               DENALI_PHY_19_DATA 0x00000000
+#define               DENALI_PHY_20_DATA 0x00000000
+#define               DENALI_PHY_21_DATA 0x00000000
+#define               DENALI_PHY_22_DATA 0x00000000
+#define               DENALI_PHY_23_DATA 0x00000000
+#define               DENALI_PHY_24_DATA 0x00000000
+#define               DENALI_PHY_25_DATA 0x00000000
+#define               DENALI_PHY_26_DATA 0x00000000
+#define               DENALI_PHY_27_DATA 0x00000000
+#define               DENALI_PHY_28_DATA 0x00000000
+#define               DENALI_PHY_29_DATA 0x00000000
+#define               DENALI_PHY_30_DATA 0x00000000
+#define               DENALI_PHY_31_DATA 0x00000000
+#define               DENALI_PHY_32_DATA 0x00000000
+#define               DENALI_PHY_33_DATA 0x00200000
+#define               DENALI_PHY_34_DATA 0x00000000
+#define               DENALI_PHY_35_DATA 0x00000000
+#define               DENALI_PHY_36_DATA 0x00000000
+#define               DENALI_PHY_37_DATA 0x00000000
+#define               DENALI_PHY_38_DATA 0x00000000
+#define               DENALI_PHY_39_DATA 0x00000000
+#define               DENALI_PHY_40_DATA 0x02800280
+#define               DENALI_PHY_41_DATA 0x02800280
+#define               DENALI_PHY_42_DATA 0x02800280
+#define               DENALI_PHY_43_DATA 0x02800280
+#define               DENALI_PHY_44_DATA 0x00000280
+#define               DENALI_PHY_45_DATA 0x00000000
+#define               DENALI_PHY_46_DATA 0x00000000
+#define               DENALI_PHY_47_DATA 0x00000000
+#define               DENALI_PHY_48_DATA 0x00000000
+#define               DENALI_PHY_49_DATA 0x00000000
+#define               DENALI_PHY_50_DATA 0x00800080
+#define               DENALI_PHY_51_DATA 0x00800080
+#define               DENALI_PHY_52_DATA 0x00800080
+#define               DENALI_PHY_53_DATA 0x00800080
+#define               DENALI_PHY_54_DATA 0x00800080
+#define               DENALI_PHY_55_DATA 0x00800080
+#define               DENALI_PHY_56_DATA 0x00800080
+#define               DENALI_PHY_57_DATA 0x00800080
+#define               DENALI_PHY_58_DATA 0x00800080
+#define               DENALI_PHY_59_DATA 0x000100da
+#define               DENALI_PHY_60_DATA 0x01000200
+#define               DENALI_PHY_61_DATA 0x00000000
+#define               DENALI_PHY_62_DATA 0x00000000
+#define               DENALI_PHY_63_DATA 0x00000002
+#define               DENALI_PHY_64_DATA 0x51313152
+#define               DENALI_PHY_65_DATA 0x80013130
+#define               DENALI_PHY_66_DATA 0x02000080
+#define               DENALI_PHY_67_DATA 0x00100001
+#define               DENALI_PHY_68_DATA 0x0c064208
+#define               DENALI_PHY_69_DATA 0x000f0c0f
+#define               DENALI_PHY_70_DATA 0x01000140
+#define               DENALI_PHY_71_DATA 0x0000000c
+#define               DENALI_PHY_72_DATA 0x00000000
+#define               DENALI_PHY_73_DATA 0x00000000
+#define               DENALI_PHY_74_DATA 0x00000000
+#define               DENALI_PHY_75_DATA 0x00000000
+#define               DENALI_PHY_76_DATA 0x00000000
+#define               DENALI_PHY_77_DATA 0x00000000
+#define               DENALI_PHY_78_DATA 0x00000000
+#define               DENALI_PHY_79_DATA 0x00000000
+#define               DENALI_PHY_80_DATA 0x00000000
+#define               DENALI_PHY_81_DATA 0x00000000
+#define               DENALI_PHY_82_DATA 0x00000000
+#define               DENALI_PHY_83_DATA 0x00000000
+#define               DENALI_PHY_84_DATA 0x00000000
+#define               DENALI_PHY_85_DATA 0x00000000
+#define               DENALI_PHY_86_DATA 0x00000000
+#define               DENALI_PHY_87_DATA 0x00000000
+#define               DENALI_PHY_88_DATA 0x00000000
+#define               DENALI_PHY_89_DATA 0x00000000
+#define               DENALI_PHY_90_DATA 0x00000000
+#define               DENALI_PHY_91_DATA 0x00000000
+#define               DENALI_PHY_92_DATA 0x00000000
+#define               DENALI_PHY_93_DATA 0x00000000
+#define               DENALI_PHY_94_DATA 0x00000000
+#define               DENALI_PHY_95_DATA 0x00000000
+#define               DENALI_PHY_96_DATA 0x00000000
+#define               DENALI_PHY_97_DATA 0x00000000
+#define               DENALI_PHY_98_DATA 0x00000000
+#define               DENALI_PHY_99_DATA 0x00000000
+#define              DENALI_PHY_100_DATA 0x00000000
+#define              DENALI_PHY_101_DATA 0x00000000
+#define              DENALI_PHY_102_DATA 0x00000000
+#define              DENALI_PHY_103_DATA 0x00000000
+#define              DENALI_PHY_104_DATA 0x00000000
+#define              DENALI_PHY_105_DATA 0x00000000
+#define              DENALI_PHY_106_DATA 0x00000000
+#define              DENALI_PHY_107_DATA 0x00000000
+#define              DENALI_PHY_108_DATA 0x00000000
+#define              DENALI_PHY_109_DATA 0x00000000
+#define              DENALI_PHY_110_DATA 0x00000000
+#define              DENALI_PHY_111_DATA 0x00000000
+#define              DENALI_PHY_112_DATA 0x00000000
+#define              DENALI_PHY_113_DATA 0x00000000
+#define              DENALI_PHY_114_DATA 0x00000000
+#define              DENALI_PHY_115_DATA 0x00000000
+#define              DENALI_PHY_116_DATA 0x00000000
+#define              DENALI_PHY_117_DATA 0x00000000
+#define              DENALI_PHY_118_DATA 0x00000000
+#define              DENALI_PHY_119_DATA 0x00000000
+#define              DENALI_PHY_120_DATA 0x00000000
+#define              DENALI_PHY_121_DATA 0x00000000
+#define              DENALI_PHY_122_DATA 0x00000000
+#define              DENALI_PHY_123_DATA 0x00000000
+#define              DENALI_PHY_124_DATA 0x00000000
+#define              DENALI_PHY_125_DATA 0x00000000
+#define              DENALI_PHY_126_DATA 0x00000000
+#define              DENALI_PHY_127_DATA 0x00000000
+#define              DENALI_PHY_128_DATA 0x40263571
+#define              DENALI_PHY_129_DATA 0x0004c008
+#define              DENALI_PHY_130_DATA 0x000000da
+#define              DENALI_PHY_131_DATA 0x00000000
+#define              DENALI_PHY_132_DATA 0x00000000
+#define              DENALI_PHY_133_DATA 0x00010000
+#define              DENALI_PHY_134_DATA 0x01DDDD90
+#define              DENALI_PHY_135_DATA 0x01DDDD90
+#define              DENALI_PHY_136_DATA 0x01030000
+#define              DENALI_PHY_137_DATA 0x01000000
+#define              DENALI_PHY_138_DATA 0x00c00000
+#define              DENALI_PHY_139_DATA 0x00000007
+#define              DENALI_PHY_140_DATA 0x00000000
+#define              DENALI_PHY_141_DATA 0x00000000
+#define              DENALI_PHY_142_DATA 0x04000408
+#define              DENALI_PHY_143_DATA 0x00000408
+#define              DENALI_PHY_144_DATA 0x00e4e400
+#define              DENALI_PHY_145_DATA 0x00000000
+#define              DENALI_PHY_146_DATA 0x00000000
+#define              DENALI_PHY_147_DATA 0x00000000
+#define              DENALI_PHY_148_DATA 0x00000000
+#define              DENALI_PHY_149_DATA 0x00000000
+#define              DENALI_PHY_150_DATA 0x00000000
+#define              DENALI_PHY_151_DATA 0x00000000
+#define              DENALI_PHY_152_DATA 0x00000000
+#define              DENALI_PHY_153_DATA 0x00000000
+#define              DENALI_PHY_154_DATA 0x00000000
+#define              DENALI_PHY_155_DATA 0x00000000
+#define              DENALI_PHY_156_DATA 0x00000000
+#define              DENALI_PHY_157_DATA 0x00000000
+#define              DENALI_PHY_158_DATA 0x00000000
+#define              DENALI_PHY_159_DATA 0x00000000
+#define              DENALI_PHY_160_DATA 0x00000000
+#define              DENALI_PHY_161_DATA 0x00200000
+#define              DENALI_PHY_162_DATA 0x00000000
+#define              DENALI_PHY_163_DATA 0x00000000
+#define              DENALI_PHY_164_DATA 0x00000000
+#define              DENALI_PHY_165_DATA 0x00000000
+#define              DENALI_PHY_166_DATA 0x00000000
+#define              DENALI_PHY_167_DATA 0x00000000
+#define              DENALI_PHY_168_DATA 0x02800280
+#define              DENALI_PHY_169_DATA 0x02800280
+#define              DENALI_PHY_170_DATA 0x02800280
+#define              DENALI_PHY_171_DATA 0x02800280
+#define              DENALI_PHY_172_DATA 0x00000280
+#define              DENALI_PHY_173_DATA 0x00000000
+#define              DENALI_PHY_174_DATA 0x00000000
+#define              DENALI_PHY_175_DATA 0x00000000
+#define              DENALI_PHY_176_DATA 0x00000000
+#define              DENALI_PHY_177_DATA 0x00000000
+#define              DENALI_PHY_178_DATA 0x00800080
+#define              DENALI_PHY_179_DATA 0x00800080
+#define              DENALI_PHY_180_DATA 0x00800080
+#define              DENALI_PHY_181_DATA 0x00800080
+#define              DENALI_PHY_182_DATA 0x00800080
+#define              DENALI_PHY_183_DATA 0x00800080
+#define              DENALI_PHY_184_DATA 0x00800080
+#define              DENALI_PHY_185_DATA 0x00800080
+#define              DENALI_PHY_186_DATA 0x00800080
+#define              DENALI_PHY_187_DATA 0x000100da
+#define              DENALI_PHY_188_DATA 0x01000200
+#define              DENALI_PHY_189_DATA 0x00000000
+#define              DENALI_PHY_190_DATA 0x00000000
+#define              DENALI_PHY_191_DATA 0x00000002
+#define              DENALI_PHY_192_DATA 0x51313152
+#define              DENALI_PHY_193_DATA 0x80013130
+#define              DENALI_PHY_194_DATA 0x02000080
+#define              DENALI_PHY_195_DATA 0x00100001
+#define              DENALI_PHY_196_DATA 0x0c064208
+#define              DENALI_PHY_197_DATA 0x000f0c0f
+#define              DENALI_PHY_198_DATA 0x01000140
+#define              DENALI_PHY_199_DATA 0x0000000c
+#define              DENALI_PHY_200_DATA 0x00000000
+#define              DENALI_PHY_201_DATA 0x00000000
+#define              DENALI_PHY_202_DATA 0x00000000
+#define              DENALI_PHY_203_DATA 0x00000000
+#define              DENALI_PHY_204_DATA 0x00000000
+#define              DENALI_PHY_205_DATA 0x00000000
+#define              DENALI_PHY_206_DATA 0x00000000
+#define              DENALI_PHY_207_DATA 0x00000000
+#define              DENALI_PHY_208_DATA 0x00000000
+#define              DENALI_PHY_209_DATA 0x00000000
+#define              DENALI_PHY_210_DATA 0x00000000
+#define              DENALI_PHY_211_DATA 0x00000000
+#define              DENALI_PHY_212_DATA 0x00000000
+#define              DENALI_PHY_213_DATA 0x00000000
+#define              DENALI_PHY_214_DATA 0x00000000
+#define              DENALI_PHY_215_DATA 0x00000000
+#define              DENALI_PHY_216_DATA 0x00000000
+#define              DENALI_PHY_217_DATA 0x00000000
+#define              DENALI_PHY_218_DATA 0x00000000
+#define              DENALI_PHY_219_DATA 0x00000000
+#define              DENALI_PHY_220_DATA 0x00000000
+#define              DENALI_PHY_221_DATA 0x00000000
+#define              DENALI_PHY_222_DATA 0x00000000
+#define              DENALI_PHY_223_DATA 0x00000000
+#define              DENALI_PHY_224_DATA 0x00000000
+#define              DENALI_PHY_225_DATA 0x00000000
+#define              DENALI_PHY_226_DATA 0x00000000
+#define              DENALI_PHY_227_DATA 0x00000000
+#define              DENALI_PHY_228_DATA 0x00000000
+#define              DENALI_PHY_229_DATA 0x00000000
+#define              DENALI_PHY_230_DATA 0x00000000
+#define              DENALI_PHY_231_DATA 0x00000000
+#define              DENALI_PHY_232_DATA 0x00000000
+#define              DENALI_PHY_233_DATA 0x00000000
+#define              DENALI_PHY_234_DATA 0x00000000
+#define              DENALI_PHY_235_DATA 0x00000000
+#define              DENALI_PHY_236_DATA 0x00000000
+#define              DENALI_PHY_237_DATA 0x00000000
+#define              DENALI_PHY_238_DATA 0x00000000
+#define              DENALI_PHY_239_DATA 0x00000000
+#define              DENALI_PHY_240_DATA 0x00000000
+#define              DENALI_PHY_241_DATA 0x00000000
+#define              DENALI_PHY_242_DATA 0x00000000
+#define              DENALI_PHY_243_DATA 0x00000000
+#define              DENALI_PHY_244_DATA 0x00000000
+#define              DENALI_PHY_245_DATA 0x00000000
+#define              DENALI_PHY_246_DATA 0x00000000
+#define              DENALI_PHY_247_DATA 0x00000000
+#define              DENALI_PHY_248_DATA 0x00000000
+#define              DENALI_PHY_249_DATA 0x00000000
+#define              DENALI_PHY_250_DATA 0x00000000
+#define              DENALI_PHY_251_DATA 0x00000000
+#define              DENALI_PHY_252_DATA 0x00000000
+#define              DENALI_PHY_253_DATA 0x00000000
+#define              DENALI_PHY_254_DATA 0x00000000
+#define              DENALI_PHY_255_DATA 0x00000000
+#define              DENALI_PHY_256_DATA 0x46052371
+#define              DENALI_PHY_257_DATA 0x0004c008
+#define              DENALI_PHY_258_DATA 0x000000da
+#define              DENALI_PHY_259_DATA 0x00000000
+#define              DENALI_PHY_260_DATA 0x00000000
+#define              DENALI_PHY_261_DATA 0x00010000
+#define              DENALI_PHY_262_DATA 0x01DDDD90
+#define              DENALI_PHY_263_DATA 0x01DDDD90
+#define              DENALI_PHY_264_DATA 0x01030000
+#define              DENALI_PHY_265_DATA 0x01000000
+#define              DENALI_PHY_266_DATA 0x00c00000
+#define              DENALI_PHY_267_DATA 0x00000007
+#define              DENALI_PHY_268_DATA 0x00000000
+#define              DENALI_PHY_269_DATA 0x00000000
+#define              DENALI_PHY_270_DATA 0x04000408
+#define              DENALI_PHY_271_DATA 0x00000408
+#define              DENALI_PHY_272_DATA 0x00e4e400
+#define              DENALI_PHY_273_DATA 0x00000000
+#define              DENALI_PHY_274_DATA 0x00000000
+#define              DENALI_PHY_275_DATA 0x00000000
+#define              DENALI_PHY_276_DATA 0x00000000
+#define              DENALI_PHY_277_DATA 0x00000000
+#define              DENALI_PHY_278_DATA 0x00000000
+#define              DENALI_PHY_279_DATA 0x00000000
+#define              DENALI_PHY_280_DATA 0x00000000
+#define              DENALI_PHY_281_DATA 0x00000000
+#define              DENALI_PHY_282_DATA 0x00000000
+#define              DENALI_PHY_283_DATA 0x00000000
+#define              DENALI_PHY_284_DATA 0x00000000
+#define              DENALI_PHY_285_DATA 0x00000000
+#define              DENALI_PHY_286_DATA 0x00000000
+#define              DENALI_PHY_287_DATA 0x00000000
+#define              DENALI_PHY_288_DATA 0x00000000
+#define              DENALI_PHY_289_DATA 0x00200000
+#define              DENALI_PHY_290_DATA 0x00000000
+#define              DENALI_PHY_291_DATA 0x00000000
+#define              DENALI_PHY_292_DATA 0x00000000
+#define              DENALI_PHY_293_DATA 0x00000000
+#define              DENALI_PHY_294_DATA 0x00000000
+#define              DENALI_PHY_295_DATA 0x00000000
+#define              DENALI_PHY_296_DATA 0x02800280
+#define              DENALI_PHY_297_DATA 0x02800280
+#define              DENALI_PHY_298_DATA 0x02800280
+#define              DENALI_PHY_299_DATA 0x02800280
+#define              DENALI_PHY_300_DATA 0x00000280
+#define              DENALI_PHY_301_DATA 0x00000000
+#define              DENALI_PHY_302_DATA 0x00000000
+#define              DENALI_PHY_303_DATA 0x00000000
+#define              DENALI_PHY_304_DATA 0x00000000
+#define              DENALI_PHY_305_DATA 0x00000000
+#define              DENALI_PHY_306_DATA 0x00800080
+#define              DENALI_PHY_307_DATA 0x00800080
+#define              DENALI_PHY_308_DATA 0x00800080
+#define              DENALI_PHY_309_DATA 0x00800080
+#define              DENALI_PHY_310_DATA 0x00800080
+#define              DENALI_PHY_311_DATA 0x00800080
+#define              DENALI_PHY_312_DATA 0x00800080
+#define              DENALI_PHY_313_DATA 0x00800080
+#define              DENALI_PHY_314_DATA 0x00800080
+#define              DENALI_PHY_315_DATA 0x000100da
+#define              DENALI_PHY_316_DATA 0x00000200
+#define              DENALI_PHY_317_DATA 0x00000000
+#define              DENALI_PHY_318_DATA 0x00000000
+#define              DENALI_PHY_319_DATA 0x00000002
+#define              DENALI_PHY_320_DATA 0x51313152
+#define              DENALI_PHY_321_DATA 0x80013130
+#define              DENALI_PHY_322_DATA 0x02000080
+#define              DENALI_PHY_323_DATA 0x00100001
+#define              DENALI_PHY_324_DATA 0x0c064208
+#define              DENALI_PHY_325_DATA 0x000f0c0f
+#define              DENALI_PHY_326_DATA 0x01000140
+#define              DENALI_PHY_327_DATA 0x0000000c
+#define              DENALI_PHY_328_DATA 0x00000000
+#define              DENALI_PHY_329_DATA 0x00000000
+#define              DENALI_PHY_330_DATA 0x00000000
+#define              DENALI_PHY_331_DATA 0x00000000
+#define              DENALI_PHY_332_DATA 0x00000000
+#define              DENALI_PHY_333_DATA 0x00000000
+#define              DENALI_PHY_334_DATA 0x00000000
+#define              DENALI_PHY_335_DATA 0x00000000
+#define              DENALI_PHY_336_DATA 0x00000000
+#define              DENALI_PHY_337_DATA 0x00000000
+#define              DENALI_PHY_338_DATA 0x00000000
+#define              DENALI_PHY_339_DATA 0x00000000
+#define              DENALI_PHY_340_DATA 0x00000000
+#define              DENALI_PHY_341_DATA 0x00000000
+#define              DENALI_PHY_342_DATA 0x00000000
+#define              DENALI_PHY_343_DATA 0x00000000
+#define              DENALI_PHY_344_DATA 0x00000000
+#define              DENALI_PHY_345_DATA 0x00000000
+#define              DENALI_PHY_346_DATA 0x00000000
+#define              DENALI_PHY_347_DATA 0x00000000
+#define              DENALI_PHY_348_DATA 0x00000000
+#define              DENALI_PHY_349_DATA 0x00000000
+#define              DENALI_PHY_350_DATA 0x00000000
+#define              DENALI_PHY_351_DATA 0x00000000
+#define              DENALI_PHY_352_DATA 0x00000000
+#define              DENALI_PHY_353_DATA 0x00000000
+#define              DENALI_PHY_354_DATA 0x00000000
+#define              DENALI_PHY_355_DATA 0x00000000
+#define              DENALI_PHY_356_DATA 0x00000000
+#define              DENALI_PHY_357_DATA 0x00000000
+#define              DENALI_PHY_358_DATA 0x00000000
+#define              DENALI_PHY_359_DATA 0x00000000
+#define              DENALI_PHY_360_DATA 0x00000000
+#define              DENALI_PHY_361_DATA 0x00000000
+#define              DENALI_PHY_362_DATA 0x00000000
+#define              DENALI_PHY_363_DATA 0x00000000
+#define              DENALI_PHY_364_DATA 0x00000000
+#define              DENALI_PHY_365_DATA 0x00000000
+#define              DENALI_PHY_366_DATA 0x00000000
+#define              DENALI_PHY_367_DATA 0x00000000
+#define              DENALI_PHY_368_DATA 0x00000000
+#define              DENALI_PHY_369_DATA 0x00000000
+#define              DENALI_PHY_370_DATA 0x00000000
+#define              DENALI_PHY_371_DATA 0x00000000
+#define              DENALI_PHY_372_DATA 0x00000000
+#define              DENALI_PHY_373_DATA 0x00000000
+#define              DENALI_PHY_374_DATA 0x00000000
+#define              DENALI_PHY_375_DATA 0x00000000
+#define              DENALI_PHY_376_DATA 0x00000000
+#define              DENALI_PHY_377_DATA 0x00000000
+#define              DENALI_PHY_378_DATA 0x00000000
+#define              DENALI_PHY_379_DATA 0x00000000
+#define              DENALI_PHY_380_DATA 0x00000000
+#define              DENALI_PHY_381_DATA 0x00000000
+#define              DENALI_PHY_382_DATA 0x00000000
+#define              DENALI_PHY_383_DATA 0x00000000
+#define              DENALI_PHY_384_DATA 0x37654120
+#define              DENALI_PHY_385_DATA 0x0004c008
+#define              DENALI_PHY_386_DATA 0x000000da
+#define              DENALI_PHY_387_DATA 0x00000000
+#define              DENALI_PHY_388_DATA 0x00000000
+#define              DENALI_PHY_389_DATA 0x00010000
+#define              DENALI_PHY_390_DATA 0x01DDDD90
+#define              DENALI_PHY_391_DATA 0x01DDDD90
+#define              DENALI_PHY_392_DATA 0x01030000
+#define              DENALI_PHY_393_DATA 0x01000000
+#define              DENALI_PHY_394_DATA 0x00c00000
+#define              DENALI_PHY_395_DATA 0x00000007
+#define              DENALI_PHY_396_DATA 0x00000000
+#define              DENALI_PHY_397_DATA 0x00000000
+#define              DENALI_PHY_398_DATA 0x04000408
+#define              DENALI_PHY_399_DATA 0x00000408
+#define              DENALI_PHY_400_DATA 0x00e4e400
+#define              DENALI_PHY_401_DATA 0x00000000
+#define              DENALI_PHY_402_DATA 0x00000000
+#define              DENALI_PHY_403_DATA 0x00000000
+#define              DENALI_PHY_404_DATA 0x00000000
+#define              DENALI_PHY_405_DATA 0x00000000
+#define              DENALI_PHY_406_DATA 0x00000000
+#define              DENALI_PHY_407_DATA 0x00000000
+#define              DENALI_PHY_408_DATA 0x00000000
+#define              DENALI_PHY_409_DATA 0x00000000
+#define              DENALI_PHY_410_DATA 0x00000000
+#define              DENALI_PHY_411_DATA 0x00000000
+#define              DENALI_PHY_412_DATA 0x00000000
+#define              DENALI_PHY_413_DATA 0x00000000
+#define              DENALI_PHY_414_DATA 0x00000000
+#define              DENALI_PHY_415_DATA 0x00000000
+#define              DENALI_PHY_416_DATA 0x00000000
+#define              DENALI_PHY_417_DATA 0x00200000
+#define              DENALI_PHY_418_DATA 0x00000000
+#define              DENALI_PHY_419_DATA 0x00000000
+#define              DENALI_PHY_420_DATA 0x00000000
+#define              DENALI_PHY_421_DATA 0x00000000
+#define              DENALI_PHY_422_DATA 0x00000000
+#define              DENALI_PHY_423_DATA 0x00000000
+#define              DENALI_PHY_424_DATA 0x02800280
+#define              DENALI_PHY_425_DATA 0x02800280
+#define              DENALI_PHY_426_DATA 0x02800280
+#define              DENALI_PHY_427_DATA 0x02800280
+#define              DENALI_PHY_428_DATA 0x00000280
+#define              DENALI_PHY_429_DATA 0x00000000
+#define              DENALI_PHY_430_DATA 0x00000000
+#define              DENALI_PHY_431_DATA 0x00000000
+#define              DENALI_PHY_432_DATA 0x00000000
+#define              DENALI_PHY_433_DATA 0x00000000
+#define              DENALI_PHY_434_DATA 0x00800080
+#define              DENALI_PHY_435_DATA 0x00800080
+#define              DENALI_PHY_436_DATA 0x00800080
+#define              DENALI_PHY_437_DATA 0x00800080
+#define              DENALI_PHY_438_DATA 0x00800080
+#define              DENALI_PHY_439_DATA 0x00800080
+#define              DENALI_PHY_440_DATA 0x00800080
+#define              DENALI_PHY_441_DATA 0x00800080
+#define              DENALI_PHY_442_DATA 0x00800080
+#define              DENALI_PHY_443_DATA 0x000100da
+#define              DENALI_PHY_444_DATA 0x00000200
+#define              DENALI_PHY_445_DATA 0x00000000
+#define              DENALI_PHY_446_DATA 0x00000000
+#define              DENALI_PHY_447_DATA 0x00000002
+#define              DENALI_PHY_448_DATA 0x51313152
+#define              DENALI_PHY_449_DATA 0x80013130
+#define              DENALI_PHY_450_DATA 0x02000080
+#define              DENALI_PHY_451_DATA 0x00100001
+#define              DENALI_PHY_452_DATA 0x0c064208
+#define              DENALI_PHY_453_DATA 0x000f0c0f
+#define              DENALI_PHY_454_DATA 0x01000140
+#define              DENALI_PHY_455_DATA 0x0000000c
+#define              DENALI_PHY_456_DATA 0x00000000
+#define              DENALI_PHY_457_DATA 0x00000000
+#define              DENALI_PHY_458_DATA 0x00000000
+#define              DENALI_PHY_459_DATA 0x00000000
+#define              DENALI_PHY_460_DATA 0x00000000
+#define              DENALI_PHY_461_DATA 0x00000000
+#define              DENALI_PHY_462_DATA 0x00000000
+#define              DENALI_PHY_463_DATA 0x00000000
+#define              DENALI_PHY_464_DATA 0x00000000
+#define              DENALI_PHY_465_DATA 0x00000000
+#define              DENALI_PHY_466_DATA 0x00000000
+#define              DENALI_PHY_467_DATA 0x00000000
+#define              DENALI_PHY_468_DATA 0x00000000
+#define              DENALI_PHY_469_DATA 0x00000000
+#define              DENALI_PHY_470_DATA 0x00000000
+#define              DENALI_PHY_471_DATA 0x00000000
+#define              DENALI_PHY_472_DATA 0x00000000
+#define              DENALI_PHY_473_DATA 0x00000000
+#define              DENALI_PHY_474_DATA 0x00000000
+#define              DENALI_PHY_475_DATA 0x00000000
+#define              DENALI_PHY_476_DATA 0x00000000
+#define              DENALI_PHY_477_DATA 0x00000000
+#define              DENALI_PHY_478_DATA 0x00000000
+#define              DENALI_PHY_479_DATA 0x00000000
+#define              DENALI_PHY_480_DATA 0x00000000
+#define              DENALI_PHY_481_DATA 0x00000000
+#define              DENALI_PHY_482_DATA 0x00000000
+#define              DENALI_PHY_483_DATA 0x00000000
+#define              DENALI_PHY_484_DATA 0x00000000
+#define              DENALI_PHY_485_DATA 0x00000000
+#define              DENALI_PHY_486_DATA 0x00000000
+#define              DENALI_PHY_487_DATA 0x00000000
+#define              DENALI_PHY_488_DATA 0x00000000
+#define              DENALI_PHY_489_DATA 0x00000000
+#define              DENALI_PHY_490_DATA 0x00000000
+#define              DENALI_PHY_491_DATA 0x00000000
+#define              DENALI_PHY_492_DATA 0x00000000
+#define              DENALI_PHY_493_DATA 0x00000000
+#define              DENALI_PHY_494_DATA 0x00000000
+#define              DENALI_PHY_495_DATA 0x00000000
+#define              DENALI_PHY_496_DATA 0x00000000
+#define              DENALI_PHY_497_DATA 0x00000000
+#define              DENALI_PHY_498_DATA 0x00000000
+#define              DENALI_PHY_499_DATA 0x00000000
+#define              DENALI_PHY_500_DATA 0x00000000
+#define              DENALI_PHY_501_DATA 0x00000000
+#define              DENALI_PHY_502_DATA 0x00000000
+#define              DENALI_PHY_503_DATA 0x00000000
+#define              DENALI_PHY_504_DATA 0x00000000
+#define              DENALI_PHY_505_DATA 0x00000000
+#define              DENALI_PHY_506_DATA 0x00000000
+#define              DENALI_PHY_507_DATA 0x00000000
+#define              DENALI_PHY_508_DATA 0x00000000
+#define              DENALI_PHY_509_DATA 0x00000000
+#define              DENALI_PHY_510_DATA 0x00000000
+#define              DENALI_PHY_511_DATA 0x00000000
+#define              DENALI_PHY_512_DATA 0x24316750
+#define              DENALI_PHY_513_DATA 0x0004c008
+#define              DENALI_PHY_514_DATA 0x000000da
+#define              DENALI_PHY_515_DATA 0x00000000
+#define              DENALI_PHY_516_DATA 0x00000000
+#define              DENALI_PHY_517_DATA 0x00010000
+#define              DENALI_PHY_518_DATA 0x01DDDD90
+#define              DENALI_PHY_519_DATA 0x01DDDD90
+#define              DENALI_PHY_520_DATA 0x01030000
+#define              DENALI_PHY_521_DATA 0x01000000
+#define              DENALI_PHY_522_DATA 0x00c00000
+#define              DENALI_PHY_523_DATA 0x00000007
+#define              DENALI_PHY_524_DATA 0x00000000
+#define              DENALI_PHY_525_DATA 0x00000000
+#define              DENALI_PHY_526_DATA 0x04000408
+#define              DENALI_PHY_527_DATA 0x00000408
+#define              DENALI_PHY_528_DATA 0x00e4e400
+#define              DENALI_PHY_529_DATA 0x00000000
+#define              DENALI_PHY_530_DATA 0x00000000
+#define              DENALI_PHY_531_DATA 0x00000000
+#define              DENALI_PHY_532_DATA 0x00000000
+#define              DENALI_PHY_533_DATA 0x00000000
+#define              DENALI_PHY_534_DATA 0x00000000
+#define              DENALI_PHY_535_DATA 0x00000000
+#define              DENALI_PHY_536_DATA 0x00000000
+#define              DENALI_PHY_537_DATA 0x00000000
+#define              DENALI_PHY_538_DATA 0x00000000
+#define              DENALI_PHY_539_DATA 0x00000000
+#define              DENALI_PHY_540_DATA 0x00000000
+#define              DENALI_PHY_541_DATA 0x00000000
+#define              DENALI_PHY_542_DATA 0x00000000
+#define              DENALI_PHY_543_DATA 0x00000000
+#define              DENALI_PHY_544_DATA 0x00000000
+#define              DENALI_PHY_545_DATA 0x00200000
+#define              DENALI_PHY_546_DATA 0x00000000
+#define              DENALI_PHY_547_DATA 0x00000000
+#define              DENALI_PHY_548_DATA 0x00000000
+#define              DENALI_PHY_549_DATA 0x00000000
+#define              DENALI_PHY_550_DATA 0x00000000
+#define              DENALI_PHY_551_DATA 0x00000000
+#define              DENALI_PHY_552_DATA 0x02800280
+#define              DENALI_PHY_553_DATA 0x02800280
+#define              DENALI_PHY_554_DATA 0x02800280
+#define              DENALI_PHY_555_DATA 0x02800280
+#define              DENALI_PHY_556_DATA 0x00000280
+#define              DENALI_PHY_557_DATA 0x00000000
+#define              DENALI_PHY_558_DATA 0x00000000
+#define              DENALI_PHY_559_DATA 0x00000000
+#define              DENALI_PHY_560_DATA 0x00000000
+#define              DENALI_PHY_561_DATA 0x00000000
+#define              DENALI_PHY_562_DATA 0x00800080
+#define              DENALI_PHY_563_DATA 0x00800080
+#define              DENALI_PHY_564_DATA 0x00800080
+#define              DENALI_PHY_565_DATA 0x00800080
+#define              DENALI_PHY_566_DATA 0x00800080
+#define              DENALI_PHY_567_DATA 0x00800080
+#define              DENALI_PHY_568_DATA 0x00800080
+#define              DENALI_PHY_569_DATA 0x00800080
+#define              DENALI_PHY_570_DATA 0x00800080
+#define              DENALI_PHY_571_DATA 0x000100da
+#define              DENALI_PHY_572_DATA 0x00000200
+#define              DENALI_PHY_573_DATA 0x00000000
+#define              DENALI_PHY_574_DATA 0x00000000
+#define              DENALI_PHY_575_DATA 0x00000002
+#define              DENALI_PHY_576_DATA 0x51313152
+#define              DENALI_PHY_577_DATA 0x80013130
+#define              DENALI_PHY_578_DATA 0x02000080
+#define              DENALI_PHY_579_DATA 0x00100001
+#define              DENALI_PHY_580_DATA 0x0c064208
+#define              DENALI_PHY_581_DATA 0x000f0c0f
+#define              DENALI_PHY_582_DATA 0x01000140
+#define              DENALI_PHY_583_DATA 0x0000000c
+#define              DENALI_PHY_584_DATA 0x00000000
+#define              DENALI_PHY_585_DATA 0x00000000
+#define              DENALI_PHY_586_DATA 0x00000000
+#define              DENALI_PHY_587_DATA 0x00000000
+#define              DENALI_PHY_588_DATA 0x00000000
+#define              DENALI_PHY_589_DATA 0x00000000
+#define              DENALI_PHY_590_DATA 0x00000000
+#define              DENALI_PHY_591_DATA 0x00000000
+#define              DENALI_PHY_592_DATA 0x00000000
+#define              DENALI_PHY_593_DATA 0x00000000
+#define              DENALI_PHY_594_DATA 0x00000000
+#define              DENALI_PHY_595_DATA 0x00000000
+#define              DENALI_PHY_596_DATA 0x00000000
+#define              DENALI_PHY_597_DATA 0x00000000
+#define              DENALI_PHY_598_DATA 0x00000000
+#define              DENALI_PHY_599_DATA 0x00000000
+#define              DENALI_PHY_600_DATA 0x00000000
+#define              DENALI_PHY_601_DATA 0x00000000
+#define              DENALI_PHY_602_DATA 0x00000000
+#define              DENALI_PHY_603_DATA 0x00000000
+#define              DENALI_PHY_604_DATA 0x00000000
+#define              DENALI_PHY_605_DATA 0x00000000
+#define              DENALI_PHY_606_DATA 0x00000000
+#define              DENALI_PHY_607_DATA 0x00000000
+#define              DENALI_PHY_608_DATA 0x00000000
+#define              DENALI_PHY_609_DATA 0x00000000
+#define              DENALI_PHY_610_DATA 0x00000000
+#define              DENALI_PHY_611_DATA 0x00000000
+#define              DENALI_PHY_612_DATA 0x00000000
+#define              DENALI_PHY_613_DATA 0x00000000
+#define              DENALI_PHY_614_DATA 0x00000000
+#define              DENALI_PHY_615_DATA 0x00000000
+#define              DENALI_PHY_616_DATA 0x00000000
+#define              DENALI_PHY_617_DATA 0x00000000
+#define              DENALI_PHY_618_DATA 0x00000000
+#define              DENALI_PHY_619_DATA 0x00000000
+#define              DENALI_PHY_620_DATA 0x00000000
+#define              DENALI_PHY_621_DATA 0x00000000
+#define              DENALI_PHY_622_DATA 0x00000000
+#define              DENALI_PHY_623_DATA 0x00000000
+#define              DENALI_PHY_624_DATA 0x00000000
+#define              DENALI_PHY_625_DATA 0x00000000
+#define              DENALI_PHY_626_DATA 0x00000000
+#define              DENALI_PHY_627_DATA 0x00000000
+#define              DENALI_PHY_628_DATA 0x00000000
+#define              DENALI_PHY_629_DATA 0x00000000
+#define              DENALI_PHY_630_DATA 0x00000000
+#define              DENALI_PHY_631_DATA 0x00000000
+#define              DENALI_PHY_632_DATA 0x00000000
+#define              DENALI_PHY_633_DATA 0x00000000
+#define              DENALI_PHY_634_DATA 0x00000000
+#define              DENALI_PHY_635_DATA 0x00000000
+#define              DENALI_PHY_636_DATA 0x00000000
+#define              DENALI_PHY_637_DATA 0x00000000
+#define              DENALI_PHY_638_DATA 0x00000000
+#define              DENALI_PHY_639_DATA 0x00000000
+#define              DENALI_PHY_640_DATA 0x35174620
+#define              DENALI_PHY_641_DATA 0x0004c008
+#define              DENALI_PHY_642_DATA 0x000000da
+#define              DENALI_PHY_643_DATA 0x00000000
+#define              DENALI_PHY_644_DATA 0x00000000
+#define              DENALI_PHY_645_DATA 0x00010000
+#define              DENALI_PHY_646_DATA 0x01DDDD90
+#define              DENALI_PHY_647_DATA 0x01DDDD90
+#define              DENALI_PHY_648_DATA 0x01030000
+#define              DENALI_PHY_649_DATA 0x01000000
+#define              DENALI_PHY_650_DATA 0x00c00000
+#define              DENALI_PHY_651_DATA 0x00000007
+#define              DENALI_PHY_652_DATA 0x00000000
+#define              DENALI_PHY_653_DATA 0x00000000
+#define              DENALI_PHY_654_DATA 0x04000408
+#define              DENALI_PHY_655_DATA 0x00000408
+#define              DENALI_PHY_656_DATA 0x00e4e400
+#define              DENALI_PHY_657_DATA 0x00000000
+#define              DENALI_PHY_658_DATA 0x00000000
+#define              DENALI_PHY_659_DATA 0x00000000
+#define              DENALI_PHY_660_DATA 0x00000000
+#define              DENALI_PHY_661_DATA 0x00000000
+#define              DENALI_PHY_662_DATA 0x00000000
+#define              DENALI_PHY_663_DATA 0x00000000
+#define              DENALI_PHY_664_DATA 0x00000000
+#define              DENALI_PHY_665_DATA 0x00000000
+#define              DENALI_PHY_666_DATA 0x00000000
+#define              DENALI_PHY_667_DATA 0x00000000
+#define              DENALI_PHY_668_DATA 0x00000000
+#define              DENALI_PHY_669_DATA 0x00000000
+#define              DENALI_PHY_670_DATA 0x00000000
+#define              DENALI_PHY_671_DATA 0x00000000
+#define              DENALI_PHY_672_DATA 0x00000000
+#define              DENALI_PHY_673_DATA 0x00200000
+#define              DENALI_PHY_674_DATA 0x00000000
+#define              DENALI_PHY_675_DATA 0x00000000
+#define              DENALI_PHY_676_DATA 0x00000000
+#define              DENALI_PHY_677_DATA 0x00000000
+#define              DENALI_PHY_678_DATA 0x00000000
+#define              DENALI_PHY_679_DATA 0x00000000
+#define              DENALI_PHY_680_DATA 0x02800280
+#define              DENALI_PHY_681_DATA 0x02800280
+#define              DENALI_PHY_682_DATA 0x02800280
+#define              DENALI_PHY_683_DATA 0x02800280
+#define              DENALI_PHY_684_DATA 0x00000280
+#define              DENALI_PHY_685_DATA 0x00000000
+#define              DENALI_PHY_686_DATA 0x00000000
+#define              DENALI_PHY_687_DATA 0x00000000
+#define              DENALI_PHY_688_DATA 0x00000000
+#define              DENALI_PHY_689_DATA 0x00000000
+#define              DENALI_PHY_690_DATA 0x00800080
+#define              DENALI_PHY_691_DATA 0x00800080
+#define              DENALI_PHY_692_DATA 0x00800080
+#define              DENALI_PHY_693_DATA 0x00800080
+#define              DENALI_PHY_694_DATA 0x00800080
+#define              DENALI_PHY_695_DATA 0x00800080
+#define              DENALI_PHY_696_DATA 0x00800080
+#define              DENALI_PHY_697_DATA 0x00800080
+#define              DENALI_PHY_698_DATA 0x00800080
+#define              DENALI_PHY_699_DATA 0x000100da
+#define              DENALI_PHY_700_DATA 0x00000200
+#define              DENALI_PHY_701_DATA 0x00000000
+#define              DENALI_PHY_702_DATA 0x00000000
+#define              DENALI_PHY_703_DATA 0x00000002
+#define              DENALI_PHY_704_DATA 0x51313152
+#define              DENALI_PHY_705_DATA 0x80013130
+#define              DENALI_PHY_706_DATA 0x02000080
+#define              DENALI_PHY_707_DATA 0x00100001
+#define              DENALI_PHY_708_DATA 0x0c064208
+#define              DENALI_PHY_709_DATA 0x000f0c0f
+#define              DENALI_PHY_710_DATA 0x01000140
+#define              DENALI_PHY_711_DATA 0x0000000c
+#define              DENALI_PHY_712_DATA 0x00000000
+#define              DENALI_PHY_713_DATA 0x00000000
+#define              DENALI_PHY_714_DATA 0x00000000
+#define              DENALI_PHY_715_DATA 0x00000000
+#define              DENALI_PHY_716_DATA 0x00000000
+#define              DENALI_PHY_717_DATA 0x00000000
+#define              DENALI_PHY_718_DATA 0x00000000
+#define              DENALI_PHY_719_DATA 0x00000000
+#define              DENALI_PHY_720_DATA 0x00000000
+#define              DENALI_PHY_721_DATA 0x00000000
+#define              DENALI_PHY_722_DATA 0x00000000
+#define              DENALI_PHY_723_DATA 0x00000000
+#define              DENALI_PHY_724_DATA 0x00000000
+#define              DENALI_PHY_725_DATA 0x00000000
+#define              DENALI_PHY_726_DATA 0x00000000
+#define              DENALI_PHY_727_DATA 0x00000000
+#define              DENALI_PHY_728_DATA 0x00000000
+#define              DENALI_PHY_729_DATA 0x00000000
+#define              DENALI_PHY_730_DATA 0x00000000
+#define              DENALI_PHY_731_DATA 0x00000000
+#define              DENALI_PHY_732_DATA 0x00000000
+#define              DENALI_PHY_733_DATA 0x00000000
+#define              DENALI_PHY_734_DATA 0x00000000
+#define              DENALI_PHY_735_DATA 0x00000000
+#define              DENALI_PHY_736_DATA 0x00000000
+#define              DENALI_PHY_737_DATA 0x00000000
+#define              DENALI_PHY_738_DATA 0x00000000
+#define              DENALI_PHY_739_DATA 0x00000000
+#define              DENALI_PHY_740_DATA 0x00000000
+#define              DENALI_PHY_741_DATA 0x00000000
+#define              DENALI_PHY_742_DATA 0x00000000
+#define              DENALI_PHY_743_DATA 0x00000000
+#define              DENALI_PHY_744_DATA 0x00000000
+#define              DENALI_PHY_745_DATA 0x00000000
+#define              DENALI_PHY_746_DATA 0x00000000
+#define              DENALI_PHY_747_DATA 0x00000000
+#define              DENALI_PHY_748_DATA 0x00000000
+#define              DENALI_PHY_749_DATA 0x00000000
+#define              DENALI_PHY_750_DATA 0x00000000
+#define              DENALI_PHY_751_DATA 0x00000000
+#define              DENALI_PHY_752_DATA 0x00000000
+#define              DENALI_PHY_753_DATA 0x00000000
+#define              DENALI_PHY_754_DATA 0x00000000
+#define              DENALI_PHY_755_DATA 0x00000000
+#define              DENALI_PHY_756_DATA 0x00000000
+#define              DENALI_PHY_757_DATA 0x00000000
+#define              DENALI_PHY_758_DATA 0x00000000
+#define              DENALI_PHY_759_DATA 0x00000000
+#define              DENALI_PHY_760_DATA 0x00000000
+#define              DENALI_PHY_761_DATA 0x00000000
+#define              DENALI_PHY_762_DATA 0x00000000
+#define              DENALI_PHY_763_DATA 0x00000000
+#define              DENALI_PHY_764_DATA 0x00000000
+#define              DENALI_PHY_765_DATA 0x00000000
+#define              DENALI_PHY_766_DATA 0x00000000
+#define              DENALI_PHY_767_DATA 0x00000000
+#define              DENALI_PHY_768_DATA 0x15203476
+#define              DENALI_PHY_769_DATA 0x0004c008
+#define              DENALI_PHY_770_DATA 0x000000da
+#define              DENALI_PHY_771_DATA 0x00000000
+#define              DENALI_PHY_772_DATA 0x00000000
+#define              DENALI_PHY_773_DATA 0x00010000
+#define              DENALI_PHY_774_DATA 0x01DDDD90
+#define              DENALI_PHY_775_DATA 0x01DDDD90
+#define              DENALI_PHY_776_DATA 0x01030000
+#define              DENALI_PHY_777_DATA 0x01000000
+#define              DENALI_PHY_778_DATA 0x00c00000
+#define              DENALI_PHY_779_DATA 0x00000007
+#define              DENALI_PHY_780_DATA 0x00000000
+#define              DENALI_PHY_781_DATA 0x00000000
+#define              DENALI_PHY_782_DATA 0x04000408
+#define              DENALI_PHY_783_DATA 0x00000408
+#define              DENALI_PHY_784_DATA 0x00e4e400
+#define              DENALI_PHY_785_DATA 0x00000000
+#define              DENALI_PHY_786_DATA 0x00000000
+#define              DENALI_PHY_787_DATA 0x00000000
+#define              DENALI_PHY_788_DATA 0x00000000
+#define              DENALI_PHY_789_DATA 0x00000000
+#define              DENALI_PHY_790_DATA 0x00000000
+#define              DENALI_PHY_791_DATA 0x00000000
+#define              DENALI_PHY_792_DATA 0x00000000
+#define              DENALI_PHY_793_DATA 0x00000000
+#define              DENALI_PHY_794_DATA 0x00000000
+#define              DENALI_PHY_795_DATA 0x00000000
+#define              DENALI_PHY_796_DATA 0x00000000
+#define              DENALI_PHY_797_DATA 0x00000000
+#define              DENALI_PHY_798_DATA 0x00000000
+#define              DENALI_PHY_799_DATA 0x00000000
+#define              DENALI_PHY_800_DATA 0x00000000
+#define              DENALI_PHY_801_DATA 0x00200000
+#define              DENALI_PHY_802_DATA 0x00000000
+#define              DENALI_PHY_803_DATA 0x00000000
+#define              DENALI_PHY_804_DATA 0x00000000
+#define              DENALI_PHY_805_DATA 0x00000000
+#define              DENALI_PHY_806_DATA 0x00000000
+#define              DENALI_PHY_807_DATA 0x00000000
+#define              DENALI_PHY_808_DATA 0x02800280
+#define              DENALI_PHY_809_DATA 0x02800280
+#define              DENALI_PHY_810_DATA 0x02800280
+#define              DENALI_PHY_811_DATA 0x02800280
+#define              DENALI_PHY_812_DATA 0x00000280
+#define              DENALI_PHY_813_DATA 0x00000000
+#define              DENALI_PHY_814_DATA 0x00000000
+#define              DENALI_PHY_815_DATA 0x00000000
+#define              DENALI_PHY_816_DATA 0x00000000
+#define              DENALI_PHY_817_DATA 0x00000000
+#define              DENALI_PHY_818_DATA 0x00800080
+#define              DENALI_PHY_819_DATA 0x00800080
+#define              DENALI_PHY_820_DATA 0x00800080
+#define              DENALI_PHY_821_DATA 0x00800080
+#define              DENALI_PHY_822_DATA 0x00800080
+#define              DENALI_PHY_823_DATA 0x00800080
+#define              DENALI_PHY_824_DATA 0x00800080
+#define              DENALI_PHY_825_DATA 0x00800080
+#define              DENALI_PHY_826_DATA 0x00800080
+#define              DENALI_PHY_827_DATA 0x000100da
+#define              DENALI_PHY_828_DATA 0x00000200
+#define              DENALI_PHY_829_DATA 0x00000000
+#define              DENALI_PHY_830_DATA 0x00000000
+#define              DENALI_PHY_831_DATA 0x00000002
+#define              DENALI_PHY_832_DATA 0x51313152
+#define              DENALI_PHY_833_DATA 0x80013130
+#define              DENALI_PHY_834_DATA 0x02000080
+#define              DENALI_PHY_835_DATA 0x00100001
+#define              DENALI_PHY_836_DATA 0x0c064208
+#define              DENALI_PHY_837_DATA 0x000f0c0f
+#define              DENALI_PHY_838_DATA 0x01000140
+#define              DENALI_PHY_839_DATA 0x0000000c
+#define              DENALI_PHY_840_DATA 0x00000000
+#define              DENALI_PHY_841_DATA 0x00000000
+#define              DENALI_PHY_842_DATA 0x00000000
+#define              DENALI_PHY_843_DATA 0x00000000
+#define              DENALI_PHY_844_DATA 0x00000000
+#define              DENALI_PHY_845_DATA 0x00000000
+#define              DENALI_PHY_846_DATA 0x00000000
+#define              DENALI_PHY_847_DATA 0x00000000
+#define              DENALI_PHY_848_DATA 0x00000000
+#define              DENALI_PHY_849_DATA 0x00000000
+#define              DENALI_PHY_850_DATA 0x00000000
+#define              DENALI_PHY_851_DATA 0x00000000
+#define              DENALI_PHY_852_DATA 0x00000000
+#define              DENALI_PHY_853_DATA 0x00000000
+#define              DENALI_PHY_854_DATA 0x00000000
+#define              DENALI_PHY_855_DATA 0x00000000
+#define              DENALI_PHY_856_DATA 0x00000000
+#define              DENALI_PHY_857_DATA 0x00000000
+#define              DENALI_PHY_858_DATA 0x00000000
+#define              DENALI_PHY_859_DATA 0x00000000
+#define              DENALI_PHY_860_DATA 0x00000000
+#define              DENALI_PHY_861_DATA 0x00000000
+#define              DENALI_PHY_862_DATA 0x00000000
+#define              DENALI_PHY_863_DATA 0x00000000
+#define              DENALI_PHY_864_DATA 0x00000000
+#define              DENALI_PHY_865_DATA 0x00000000
+#define              DENALI_PHY_866_DATA 0x00000000
+#define              DENALI_PHY_867_DATA 0x00000000
+#define              DENALI_PHY_868_DATA 0x00000000
+#define              DENALI_PHY_869_DATA 0x00000000
+#define              DENALI_PHY_870_DATA 0x00000000
+#define              DENALI_PHY_871_DATA 0x00000000
+#define              DENALI_PHY_872_DATA 0x00000000
+#define              DENALI_PHY_873_DATA 0x00000000
+#define              DENALI_PHY_874_DATA 0x00000000
+#define              DENALI_PHY_875_DATA 0x00000000
+#define              DENALI_PHY_876_DATA 0x00000000
+#define              DENALI_PHY_877_DATA 0x00000000
+#define              DENALI_PHY_878_DATA 0x00000000
+#define              DENALI_PHY_879_DATA 0x00000000
+#define              DENALI_PHY_880_DATA 0x00000000
+#define              DENALI_PHY_881_DATA 0x00000000
+#define              DENALI_PHY_882_DATA 0x00000000
+#define              DENALI_PHY_883_DATA 0x00000000
+#define              DENALI_PHY_884_DATA 0x00000000
+#define              DENALI_PHY_885_DATA 0x00000000
+#define              DENALI_PHY_886_DATA 0x00000000
+#define              DENALI_PHY_887_DATA 0x00000000
+#define              DENALI_PHY_888_DATA 0x00000000
+#define              DENALI_PHY_889_DATA 0x00000000
+#define              DENALI_PHY_890_DATA 0x00000000
+#define              DENALI_PHY_891_DATA 0x00000000
+#define              DENALI_PHY_892_DATA 0x00000000
+#define              DENALI_PHY_893_DATA 0x00000000
+#define              DENALI_PHY_894_DATA 0x00000000
+#define              DENALI_PHY_895_DATA 0x00000000
+#define              DENALI_PHY_896_DATA 0x41753206
+#define              DENALI_PHY_897_DATA 0x0004c008
+#define              DENALI_PHY_898_DATA 0x000000da
+#define              DENALI_PHY_899_DATA 0x00000000
+#define              DENALI_PHY_900_DATA 0x00000000
+#define              DENALI_PHY_901_DATA 0x00010000
+#define              DENALI_PHY_902_DATA 0x01DDDD90
+#define              DENALI_PHY_903_DATA 0x01DDDD90
+#define              DENALI_PHY_904_DATA 0x01030000
+#define              DENALI_PHY_905_DATA 0x01000000
+#define              DENALI_PHY_906_DATA 0x00c00000
+#define              DENALI_PHY_907_DATA 0x00000007
+#define              DENALI_PHY_908_DATA 0x00000000
+#define              DENALI_PHY_909_DATA 0x00000000
+#define              DENALI_PHY_910_DATA 0x04000408
+#define              DENALI_PHY_911_DATA 0x00000408
+#define              DENALI_PHY_912_DATA 0x00e4e400
+#define              DENALI_PHY_913_DATA 0x00000000
+#define              DENALI_PHY_914_DATA 0x00000000
+#define              DENALI_PHY_915_DATA 0x00000000
+#define              DENALI_PHY_916_DATA 0x00000000
+#define              DENALI_PHY_917_DATA 0x00000000
+#define              DENALI_PHY_918_DATA 0x00000000
+#define              DENALI_PHY_919_DATA 0x00000000
+#define              DENALI_PHY_920_DATA 0x00000000
+#define              DENALI_PHY_921_DATA 0x00000000
+#define              DENALI_PHY_922_DATA 0x00000000
+#define              DENALI_PHY_923_DATA 0x00000000
+#define              DENALI_PHY_924_DATA 0x00000000
+#define              DENALI_PHY_925_DATA 0x00000000
+#define              DENALI_PHY_926_DATA 0x00000000
+#define              DENALI_PHY_927_DATA 0x00000000
+#define              DENALI_PHY_928_DATA 0x00000000
+#define              DENALI_PHY_929_DATA 0x00200000
+#define              DENALI_PHY_930_DATA 0x00000000
+#define              DENALI_PHY_931_DATA 0x00000000
+#define              DENALI_PHY_932_DATA 0x00000000
+#define              DENALI_PHY_933_DATA 0x00000000
+#define              DENALI_PHY_934_DATA 0x00000000
+#define              DENALI_PHY_935_DATA 0x00000000
+#define              DENALI_PHY_936_DATA 0x02800280
+#define              DENALI_PHY_937_DATA 0x02800280
+#define              DENALI_PHY_938_DATA 0x02800280
+#define              DENALI_PHY_939_DATA 0x02800280
+#define              DENALI_PHY_940_DATA 0x00000280
+#define              DENALI_PHY_941_DATA 0x00000000
+#define              DENALI_PHY_942_DATA 0x00000000
+#define              DENALI_PHY_943_DATA 0x00000000
+#define              DENALI_PHY_944_DATA 0x00000000
+#define              DENALI_PHY_945_DATA 0x00000000
+#define              DENALI_PHY_946_DATA 0x00800080
+#define              DENALI_PHY_947_DATA 0x00800080
+#define              DENALI_PHY_948_DATA 0x00800080
+#define              DENALI_PHY_949_DATA 0x00800080
+#define              DENALI_PHY_950_DATA 0x00800080
+#define              DENALI_PHY_951_DATA 0x00800080
+#define              DENALI_PHY_952_DATA 0x00800080
+#define              DENALI_PHY_953_DATA 0x00800080
+#define              DENALI_PHY_954_DATA 0x00800080
+#define              DENALI_PHY_955_DATA 0x000100da
+#define              DENALI_PHY_956_DATA 0x00000200
+#define              DENALI_PHY_957_DATA 0x00000000
+#define              DENALI_PHY_958_DATA 0x00000000
+#define              DENALI_PHY_959_DATA 0x00000002
+#define              DENALI_PHY_960_DATA 0x51313152
+#define              DENALI_PHY_961_DATA 0x80013130
+#define              DENALI_PHY_962_DATA 0x02000080
+#define              DENALI_PHY_963_DATA 0x00100001
+#define              DENALI_PHY_964_DATA 0x0c064208
+#define              DENALI_PHY_965_DATA 0x000f0c0f
+#define              DENALI_PHY_966_DATA 0x01000140
+#define              DENALI_PHY_967_DATA 0x0000000c
+#define              DENALI_PHY_968_DATA 0x00000000
+#define              DENALI_PHY_969_DATA 0x00000000
+#define              DENALI_PHY_970_DATA 0x00000000
+#define              DENALI_PHY_971_DATA 0x00000000
+#define              DENALI_PHY_972_DATA 0x00000000
+#define              DENALI_PHY_973_DATA 0x00000000
+#define              DENALI_PHY_974_DATA 0x00000000
+#define              DENALI_PHY_975_DATA 0x00000000
+#define              DENALI_PHY_976_DATA 0x00000000
+#define              DENALI_PHY_977_DATA 0x00000000
+#define              DENALI_PHY_978_DATA 0x00000000
+#define              DENALI_PHY_979_DATA 0x00000000
+#define              DENALI_PHY_980_DATA 0x00000000
+#define              DENALI_PHY_981_DATA 0x00000000
+#define              DENALI_PHY_982_DATA 0x00000000
+#define              DENALI_PHY_983_DATA 0x00000000
+#define              DENALI_PHY_984_DATA 0x00000000
+#define              DENALI_PHY_985_DATA 0x00000000
+#define              DENALI_PHY_986_DATA 0x00000000
+#define              DENALI_PHY_987_DATA 0x00000000
+#define              DENALI_PHY_988_DATA 0x00000000
+#define              DENALI_PHY_989_DATA 0x00000000
+#define              DENALI_PHY_990_DATA 0x00000000
+#define              DENALI_PHY_991_DATA 0x00000000
+#define              DENALI_PHY_992_DATA 0x00000000
+#define              DENALI_PHY_993_DATA 0x00000000
+#define              DENALI_PHY_994_DATA 0x00000000
+#define              DENALI_PHY_995_DATA 0x00000000
+#define              DENALI_PHY_996_DATA 0x00000000
+#define              DENALI_PHY_997_DATA 0x00000000
+#define              DENALI_PHY_998_DATA 0x00000000
+#define              DENALI_PHY_999_DATA 0x00000000
+#define             DENALI_PHY_1000_DATA 0x00000000
+#define             DENALI_PHY_1001_DATA 0x00000000
+#define             DENALI_PHY_1002_DATA 0x00000000
+#define             DENALI_PHY_1003_DATA 0x00000000
+#define             DENALI_PHY_1004_DATA 0x00000000
+#define             DENALI_PHY_1005_DATA 0x00000000
+#define             DENALI_PHY_1006_DATA 0x00000000
+#define             DENALI_PHY_1007_DATA 0x00000000
+#define             DENALI_PHY_1008_DATA 0x00000000
+#define             DENALI_PHY_1009_DATA 0x00000000
+#define             DENALI_PHY_1010_DATA 0x00000000
+#define             DENALI_PHY_1011_DATA 0x00000000
+#define             DENALI_PHY_1012_DATA 0x00000000
+#define             DENALI_PHY_1013_DATA 0x00000000
+#define             DENALI_PHY_1014_DATA 0x00000000
+#define             DENALI_PHY_1015_DATA 0x00000000
+#define             DENALI_PHY_1016_DATA 0x00000000
+#define             DENALI_PHY_1017_DATA 0x00000000
+#define             DENALI_PHY_1018_DATA 0x00000000
+#define             DENALI_PHY_1019_DATA 0x00000000
+#define             DENALI_PHY_1020_DATA 0x00000000
+#define             DENALI_PHY_1021_DATA 0x00000000
+#define             DENALI_PHY_1022_DATA 0x00000000
+#define             DENALI_PHY_1023_DATA 0x00000000
+#define             DENALI_PHY_1024_DATA 0x36025174
+#define             DENALI_PHY_1025_DATA 0x0004c008
+#define             DENALI_PHY_1026_DATA 0x000000da
+#define             DENALI_PHY_1027_DATA 0x00000000
+#define             DENALI_PHY_1028_DATA 0x00000000
+#define             DENALI_PHY_1029_DATA 0x00010000
+#define             DENALI_PHY_1030_DATA 0x01DDDD90
+#define             DENALI_PHY_1031_DATA 0x01DDDD90
+#define             DENALI_PHY_1032_DATA 0x01030000
+#define             DENALI_PHY_1033_DATA 0x01000000
+#define             DENALI_PHY_1034_DATA 0x00c00000
+#define             DENALI_PHY_1035_DATA 0x00000007
+#define             DENALI_PHY_1036_DATA 0x00000000
+#define             DENALI_PHY_1037_DATA 0x00000000
+#define             DENALI_PHY_1038_DATA 0x04000408
+#define             DENALI_PHY_1039_DATA 0x00000408
+#define             DENALI_PHY_1040_DATA 0x00e4e400
+#define             DENALI_PHY_1041_DATA 0x00000000
+#define             DENALI_PHY_1042_DATA 0x00000000
+#define             DENALI_PHY_1043_DATA 0x00000000
+#define             DENALI_PHY_1044_DATA 0x00000000
+#define             DENALI_PHY_1045_DATA 0x00000000
+#define             DENALI_PHY_1046_DATA 0x00000000
+#define             DENALI_PHY_1047_DATA 0x00000000
+#define             DENALI_PHY_1048_DATA 0x00000000
+#define             DENALI_PHY_1049_DATA 0x00000000
+#define             DENALI_PHY_1050_DATA 0x00000000
+#define             DENALI_PHY_1051_DATA 0x00000000
+#define             DENALI_PHY_1052_DATA 0x00000000
+#define             DENALI_PHY_1053_DATA 0x00000000
+#define             DENALI_PHY_1054_DATA 0x00000000
+#define             DENALI_PHY_1055_DATA 0x00000000
+#define             DENALI_PHY_1056_DATA 0x00000000
+#define             DENALI_PHY_1057_DATA 0x00200000
+#define             DENALI_PHY_1058_DATA 0x00000000
+#define             DENALI_PHY_1059_DATA 0x00000000
+#define             DENALI_PHY_1060_DATA 0x00000000
+#define             DENALI_PHY_1061_DATA 0x00000000
+#define             DENALI_PHY_1062_DATA 0x00000000
+#define             DENALI_PHY_1063_DATA 0x00000000
+#define             DENALI_PHY_1064_DATA 0x02800280
+#define             DENALI_PHY_1065_DATA 0x02800280
+#define             DENALI_PHY_1066_DATA 0x02800280
+#define             DENALI_PHY_1067_DATA 0x02800280
+#define             DENALI_PHY_1068_DATA 0x00000280
+#define             DENALI_PHY_1069_DATA 0x00000000
+#define             DENALI_PHY_1070_DATA 0x00000000
+#define             DENALI_PHY_1071_DATA 0x00000000
+#define             DENALI_PHY_1072_DATA 0x00000000
+#define             DENALI_PHY_1073_DATA 0x00000000
+#define             DENALI_PHY_1074_DATA 0x00800080
+#define             DENALI_PHY_1075_DATA 0x00800080
+#define             DENALI_PHY_1076_DATA 0x00800080
+#define             DENALI_PHY_1077_DATA 0x00800080
+#define             DENALI_PHY_1078_DATA 0x00800080
+#define             DENALI_PHY_1079_DATA 0x00800080
+#define             DENALI_PHY_1080_DATA 0x00800080
+#define             DENALI_PHY_1081_DATA 0x00800080
+#define             DENALI_PHY_1082_DATA 0x00800080
+#define             DENALI_PHY_1083_DATA 0x000100da
+#define             DENALI_PHY_1084_DATA 0x00000200
+#define             DENALI_PHY_1085_DATA 0x00000000
+#define             DENALI_PHY_1086_DATA 0x00000000
+#define             DENALI_PHY_1087_DATA 0x00000002
+#define             DENALI_PHY_1088_DATA 0x51313152
+#define             DENALI_PHY_1089_DATA 0x80013130
+#define             DENALI_PHY_1090_DATA 0x02000080
+#define             DENALI_PHY_1091_DATA 0x00100001
+#define             DENALI_PHY_1092_DATA 0x0c064208
+#define             DENALI_PHY_1093_DATA 0x000f0c0f
+#define             DENALI_PHY_1094_DATA 0x01000140
+#define             DENALI_PHY_1095_DATA 0x0000000c
+#define             DENALI_PHY_1096_DATA 0x00000000
+#define             DENALI_PHY_1097_DATA 0x00000000
+#define             DENALI_PHY_1098_DATA 0x00000000
+#define             DENALI_PHY_1099_DATA 0x00000000
+#define             DENALI_PHY_1100_DATA 0x00000000
+#define             DENALI_PHY_1101_DATA 0x00000000
+#define             DENALI_PHY_1102_DATA 0x00000000
+#define             DENALI_PHY_1103_DATA 0x00000000
+#define             DENALI_PHY_1104_DATA 0x00000000
+#define             DENALI_PHY_1105_DATA 0x00000000
+#define             DENALI_PHY_1106_DATA 0x00000000
+#define             DENALI_PHY_1107_DATA 0x00000000
+#define             DENALI_PHY_1108_DATA 0x00000000
+#define             DENALI_PHY_1109_DATA 0x00000000
+#define             DENALI_PHY_1110_DATA 0x00000000
+#define             DENALI_PHY_1111_DATA 0x00000000
+#define             DENALI_PHY_1112_DATA 0x00000000
+#define             DENALI_PHY_1113_DATA 0x00000000
+#define             DENALI_PHY_1114_DATA 0x00000000
+#define             DENALI_PHY_1115_DATA 0x00000000
+#define             DENALI_PHY_1116_DATA 0x00000000
+#define             DENALI_PHY_1117_DATA 0x00000000
+#define             DENALI_PHY_1118_DATA 0x00000000
+#define             DENALI_PHY_1119_DATA 0x00000000
+#define             DENALI_PHY_1120_DATA 0x00000000
+#define             DENALI_PHY_1121_DATA 0x00000000
+#define             DENALI_PHY_1122_DATA 0x00000000
+#define             DENALI_PHY_1123_DATA 0x00000000
+#define             DENALI_PHY_1124_DATA 0x00000000
+#define             DENALI_PHY_1125_DATA 0x00000000
+#define             DENALI_PHY_1126_DATA 0x00000000
+#define             DENALI_PHY_1127_DATA 0x00000000
+#define             DENALI_PHY_1128_DATA 0x00000000
+#define             DENALI_PHY_1129_DATA 0x00000000
+#define             DENALI_PHY_1130_DATA 0x00000000
+#define             DENALI_PHY_1131_DATA 0x00000000
+#define             DENALI_PHY_1132_DATA 0x00000000
+#define             DENALI_PHY_1133_DATA 0x00000000
+#define             DENALI_PHY_1134_DATA 0x00000000
+#define             DENALI_PHY_1135_DATA 0x00000000
+#define             DENALI_PHY_1136_DATA 0x00000000
+#define             DENALI_PHY_1137_DATA 0x00000000
+#define             DENALI_PHY_1138_DATA 0x00000000
+#define             DENALI_PHY_1139_DATA 0x00000000
+#define             DENALI_PHY_1140_DATA 0x00000000
+#define             DENALI_PHY_1141_DATA 0x00000000
+#define             DENALI_PHY_1142_DATA 0x00000000
+#define             DENALI_PHY_1143_DATA 0x00000000
+#define             DENALI_PHY_1144_DATA 0x00000000
+#define             DENALI_PHY_1145_DATA 0x00000000
+#define             DENALI_PHY_1146_DATA 0x00000000
+#define             DENALI_PHY_1147_DATA 0x00000000
+#define             DENALI_PHY_1148_DATA 0x00000000
+#define             DENALI_PHY_1149_DATA 0x00000000
+#define             DENALI_PHY_1150_DATA 0x00000000
+#define             DENALI_PHY_1151_DATA 0x00000000
+#define             DENALI_PHY_1152_DATA 0x00000000
+#define             DENALI_PHY_1153_DATA 0x00000000
+#define             DENALI_PHY_1154_DATA 0x00050000
+#define             DENALI_PHY_1155_DATA 0x00000000
+#define             DENALI_PHY_1156_DATA 0x00000000
+#define             DENALI_PHY_1157_DATA 0x00000000
+#define             DENALI_PHY_1158_DATA 0x00000100
+#define             DENALI_PHY_1159_DATA 0x00000000
+#define             DENALI_PHY_1160_DATA 0x00000000
+#define             DENALI_PHY_1161_DATA 0x00506401
+#define             DENALI_PHY_1162_DATA 0x01221102
+#define             DENALI_PHY_1163_DATA 0x00000122
+#define             DENALI_PHY_1164_DATA 0x00000000
+#define             DENALI_PHY_1165_DATA 0x000B1F00
+#define             DENALI_PHY_1166_DATA 0x0B1F0B1F
+#define             DENALI_PHY_1167_DATA 0x0B1F0B1B
+#define             DENALI_PHY_1168_DATA 0x0B1F0B1F
+#define             DENALI_PHY_1169_DATA 0x0B1F0B1F
+#define             DENALI_PHY_1170_DATA 0x00000B00
+#define             DENALI_PHY_1171_DATA 0x42080010
+#define             DENALI_PHY_1172_DATA 0x01000100
+#define             DENALI_PHY_1173_DATA 0x01000100
+#define             DENALI_PHY_1174_DATA 0x01000100
+#define             DENALI_PHY_1175_DATA 0x01000100
+#define             DENALI_PHY_1176_DATA 0x00000000
+#define             DENALI_PHY_1177_DATA 0x00000000
+#define             DENALI_PHY_1178_DATA 0x00000000
+#define             DENALI_PHY_1179_DATA 0x00000000
+#define             DENALI_PHY_1180_DATA 0x00000000
+#define             DENALI_PHY_1181_DATA 0x00000803
+#define             DENALI_PHY_1182_DATA 0x223FFF00
+#define             DENALI_PHY_1183_DATA 0x000008FF
+#define             DENALI_PHY_1184_DATA 0x0000057F
+#define             DENALI_PHY_1185_DATA 0x0000057F
+#define             DENALI_PHY_1186_DATA 0x00037FFF
+#define             DENALI_PHY_1187_DATA 0x00037FFF
+#define             DENALI_PHY_1188_DATA 0x00004410
+#define             DENALI_PHY_1189_DATA 0x00004410
+#define             DENALI_PHY_1190_DATA 0x00004410
+#define             DENALI_PHY_1191_DATA 0x00004410
+#define             DENALI_PHY_1192_DATA 0x00004410
+#define             DENALI_PHY_1193_DATA 0x00037FFF
+#define             DENALI_PHY_1194_DATA 0x00037FFF
+#define             DENALI_PHY_1195_DATA 0x00000000
+#define             DENALI_PHY_1196_DATA 0x00000000
+#define             DENALI_PHY_1197_DATA 0x00000000
+#define             DENALI_PHY_1198_DATA 0x04000000
+#define             DENALI_PHY_1199_DATA 0x00000000
+#define             DENALI_PHY_1200_DATA 0x00000000
+#define             DENALI_PHY_1201_DATA 0x00000108
+#define             DENALI_PHY_1202_DATA 0x00000000
+#define             DENALI_PHY_1203_DATA 0x00000000
+#define             DENALI_PHY_1204_DATA 0x00000000
+#define             DENALI_PHY_1205_DATA 0x00000001
+#define             DENALI_PHY_1206_DATA 0x00000000
+#define             DENALI_PHY_1207_DATA 0x00000000
+#define             DENALI_PHY_1208_DATA 0x00000000
+#define             DENALI_PHY_1209_DATA 0x00000000
+#define             DENALI_PHY_1210_DATA 0x00000000
+#define             DENALI_PHY_1211_DATA 0x00000000
+#define             DENALI_PHY_1212_DATA 0x00020100
+#define             DENALI_PHY_1213_DATA 0x00000000
+#define             DENALI_PHY_1214_DATA 0x00000000
diff --git a/board/sifive/fu540/include/spi.h b/board/sifive/fu540/include/spi.h
new file mode 100644
index 0000000000..b2b3260333
--- /dev/null
+++ b/board/sifive/fu540/include/spi.h
@@ -0,0 +1,233 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#ifndef FU540_SPI_H
+#define FU540_SPI_H
+
+#include <asm/arch/spi.h>
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+#include <linux/types.h>
+
+#define _ASSERT_SIZEOF(type, size) _Static_assert(sizeof(type) == (size), # type " must be " # size " bytes wide")
+
+typedef union {
+	struct {
+		u32 pha      : 1;
+		u32 pol      : 1;
+		u32 reserved : 30;
+	};
+	u32 raw_bits;
+} spi_reg_sckmode;
+_ASSERT_SIZEOF(spi_reg_sckmode, 4);
+
+typedef union {
+	struct {
+		u32 mode     : 2;
+		u32 reserved : 30;
+	};
+	u32 raw_bits;
+} spi_reg_csmode;
+_ASSERT_SIZEOF(spi_reg_csmode, 4);
+
+typedef union {
+	struct {
+		u32 cssck     : 8;
+		u32 reserved0 : 8;
+		u32 sckcs     : 8;
+		u32 reserved1 : 8;
+	};
+	u32 raw_bits;
+} spi_reg_delay0;
+_ASSERT_SIZEOF(spi_reg_delay0, 4);
+
+typedef union {
+	struct {
+		u32 intercs   : 8;
+		u32 reserved0 : 8;
+		u32 interxfr  : 8;
+		u32 reserved1 : 8;
+	};
+	u32 raw_bits;
+} spi_reg_delay1;
+_ASSERT_SIZEOF(spi_reg_delay1, 4);
+
+typedef union {
+	struct {
+		u32 proto     : 2;
+		u32 endian    : 1;
+		u32 dir       : 1;
+		u32 reserved0 : 12;
+		u32 len       : 4;
+		u32 reserved1 : 12;
+	};
+	u32 raw_bits;
+} spi_reg_fmt;
+_ASSERT_SIZEOF(spi_reg_fmt, 4);
+
+typedef union {
+	struct {
+		u32 data     : 8;
+		u32 reserved : 23;
+		u32 full     : 1;
+	};
+	u32 raw_bits;
+} spi_reg_txdata;
+_ASSERT_SIZEOF(spi_reg_txdata, 4);
+
+typedef union {
+	struct {
+		u32 data     : 8;
+		u32 reserved : 23;
+		u32 empty    : 1;
+	};
+	u32 raw_bits;
+} spi_reg_rxdata;
+_ASSERT_SIZEOF(spi_reg_rxdata, 4);
+
+typedef union {
+	struct {
+		u32 txmark   : 3;
+		u32 reserved : 29;
+	};
+	u32 raw_bits;
+} spi_reg_txmark;
+_ASSERT_SIZEOF(spi_reg_txmark, 4);
+
+typedef union {
+	struct {
+		u32 rxmark   : 3;
+		u32 reserved : 29;
+	};
+	u32 raw_bits;
+} spi_reg_rxmark;
+_ASSERT_SIZEOF(spi_reg_rxmark, 4);
+
+typedef union {
+	struct {
+		u32 en       : 1;
+		u32 reserved : 31;
+	};
+	u32 raw_bits;
+} spi_reg_fctrl;
+_ASSERT_SIZEOF(spi_reg_fctrl, 4);
+
+typedef union {
+	struct {
+		u32 cmd_en        : 1;
+		u32 addr_len      : 3;
+		u32 pad_cnt       : 4;
+		u32 command_proto : 2;
+		u32 addr_proto    : 2;
+		u32 data_proto    : 2;
+		u32 reserved      : 2;
+		u32 command_code  : 8;
+		u32 pad_code      : 8;
+	};
+	u32 raw_bits;
+} spi_reg_ffmt;
+_ASSERT_SIZEOF(spi_reg_ffmt, 4);
+
+typedef union {
+	struct {
+		u32 txwm     : 1;
+		u32 rxwm     : 1;
+		u32 reserved : 30;
+	};
+	u32 raw_bits;
+} spi_reg_ie;
+typedef spi_reg_ie spi_reg_ip;
+_ASSERT_SIZEOF(spi_reg_ie, 4);
+_ASSERT_SIZEOF(spi_reg_ip, 4);
+
+#undef _ASSERT_SIZEOF
+
+/*
+ * SPI control register memory map.
+ *
+ * All functions take a pointer to a SPI device's control registers.
+ */
+typedef volatile struct
+{
+	u32        sckdiv;
+	spi_reg_sckmode sckmode;
+	u32        reserved08;
+	u32        reserved0c;
+
+	u32        csid;
+	u32        csdef;
+	spi_reg_csmode  csmode;
+	u32        reserved1c;
+
+	u32        reserved20;
+	u32        reserved24;
+	spi_reg_delay0  delay0;
+	spi_reg_delay1  delay1;
+
+	u32        reserved30;
+	u32        reserved34;
+	u32        reserved38;
+	u32        reserved3c;
+
+	spi_reg_fmt     fmt;
+	u32        reserved44;
+	spi_reg_txdata  txdata;
+	spi_reg_rxdata  rxdata;
+
+	spi_reg_txmark  txmark;
+	spi_reg_rxmark  rxmark;
+	u32        reserved58;
+	u32        reserved5c;
+
+	spi_reg_fctrl   fctrl;
+	spi_reg_ffmt    ffmt;
+	u32        reserved68;
+	u32        reserved6c;
+
+	spi_reg_ie      ie;
+	spi_reg_ip      ip;
+} spi_ctrl;
+
+void spi_tx(spi_ctrl *spictrl, uint8_t in);
+uint8_t spi_rx(spi_ctrl *spictrl);
+uint8_t spi_txrx(spi_ctrl *spictrl, uint8_t in);
+int spi_copy(spi_ctrl *spictrl, void *buf, u32 addr, u32 size);
+
+/**
+ * Get smallest clock divisor that divides input_khz to a quotient less than or
+ * equal to max_target_khz;
+ */
+inline unsigned int spi_min_clk_divisor(unsigned int input_khz, unsigned
+		int max_target_khz)
+{
+	// f_sck = f_in / (2 * (div + 1)) => div = (f_in / (2*f_sck)) - 1
+	//
+	// The nearest integer solution for div requires rounding up as to
+	// not exceed max_target_khz.
+	//
+	// div = ceil(f_in / (2*f_sck)) - 1
+	//     = floor((f_in - 1 + 2*f_sck) / (2*f_sck)) - 1
+	//
+	// This should not overflow as long as (f_in - 1 + 2*f_sck) does not
+	// exceed 2^32 - 1, which is unlikely since we represent frequencies
+	// in kHz.
+	unsigned int quotient = (input_khz + 2 * max_target_khz - 1) / (2 *
+			max_target_khz);
+
+	// Avoid underflow
+	if (quotient == 0)
+		return 0;
+	else
+		return quotient - 1;
+}
+
+#endif /* !__ASSEMBLER__ */
+#endif /* FU540_SPI_H */
diff --git a/board/sifive/fu540/include/uart.h b/board/sifive/fu540/include/uart.h
new file mode 100644
index 0000000000..e20dc8a027
--- /dev/null
+++ b/board/sifive/fu540/include/uart.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#ifndef FU540_UART_H
+#define FU540_UART_H
+
+#include <asm/arch/uart.h>
+
+#ifndef __ASSEMBLER__
+
+void uart_putc(void *uartctrl, char c);
+char uart_getc(void *uartctrl);
+void uart_puts(void *uartctrl, const char *s);
+void uart_put_hex(void *uartctrl, uint32_t hex);
+void uart_put_hex64(void *ua64ctrl, u64 hex);
+
+#include <stdint.h>
+#include <linux/types.h>
+
+/*
+ * Get smallest clock divisor that divides input_hz to a quotient less than or
+ * equal to max_target_hz;
+ */
+static inline unsigned int uart_min_clk_divisor(u64 input_hz, u64 max_target_hz)
+{
+	// f_baud = f_in / (div + 1) => div = (f_in / f_baud) - 1
+	// div = (f_in / f_baud) - 1
+	//
+	// The nearest integer solution for div requires rounding up as to not
+	// exceed max_target_hz.
+	//
+	// div = ceil(f_in / f_baud) - 1
+	//     = floor((f_in - 1 + f_baud) / f_baud) - 1
+	//
+	// This should not overflow as long as (f_in - 1 + f_baud) does not
+	// exceed 2^32 - 1, which is unlikely since we represent frequencies
+	// in kHz.
+	u64 quotient = (input_hz + max_target_hz - 1) / (max_target_hz);
+	// Avoid underflow
+	if (quotient == 0)
+		return 0;
+	else
+		return quotient - 1;
+}
+
+#endif /* !__ASSEMBLER__ */
+
+#endif /* FU540_UART_H */
diff --git a/board/sifive/fu540/include/ux00ddr.h b/board/sifive/fu540/include/ux00ddr.h
new file mode 100644
index 0000000000..f3af3be901
--- /dev/null
+++ b/board/sifive/fu540/include/ux00ddr.h
@@ -0,0 +1,268 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#ifndef FU540_UX00DDR_H
+#define FU540_UX00DDR_H
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include "uart.h"
+#include "fu540-memory-map.h"
+
+#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
+
+static inline void phy_reset(volatile u32 *ddrphyreg, const
+		u32 *physettings)
+{
+	unsigned int i;
+
+	for (i = 1152; i <= 1214; i++) {
+		u32 physet = physettings[i];
+		/*if (physet!=0)*/ ddrphyreg[i] = physet;
+	}
+
+	for (i = 0; i <= 1151; i++) {
+		u32 physet = physettings[i];
+		/*if (physet!=0)*/ ddrphyreg[i] = physet;
+	}
+}
+
+static inline void ux00ddr_writeregmap(size_t ahbregaddr, const
+		u32 *ctlsettings, const u32 *physettings)
+{
+	volatile u32 *ddrctlreg = (volatile u32 *)ahbregaddr;
+	volatile u32 *ddrphyreg = ((volatile u32 *)ahbregaddr) +
+		(0x2000 / sizeof(u32));
+
+	unsigned int i;
+
+	for (i = 0; i <= 264; i++) {
+		u32 ctlset = ctlsettings[i];
+		/*if (ctlset!=0)*/ ddrctlreg[i] = ctlset;
+	}
+
+	phy_reset(ddrphyreg, physettings);
+}
+
+static inline void ux00ddr_start(size_t ahbregaddr, size_t filteraddr,
+				 size_t ddrend)
+{
+	// START register@ddrctl register base offset 0
+	u32 regdata = _REG32(0 << 2, ahbregaddr);
+
+	regdata |= 0x1;
+	_REG32(0 << 2, ahbregaddr) = regdata;
+	// WAIT for initialization complete : bit 8 of INT_STATUS
+	// (DENALI_CTL_132) 0x210
+	while ((_REG32(132 << 2, ahbregaddr) & (1 <<
+					MC_INIT_COMPLETE_OFFSET)) == 0) {
+	}
+
+	// Disable the BusBlocker in front of the controller AXI slave ports
+	volatile u64 *filterreg = (volatile u64 *)filteraddr;
+
+	filterreg[0] = 0x0f00000000000000UL | (ddrend >> 2);
+	//                ^^ RWX + TOR
+}
+
+static inline void ux00ddr_mask_mc_init_complete_interrupt(size_t
+		ahbregaddr)
+{
+	// Mask off Bit 8 of Interrupt Status
+	// Bit [8] The MC initialization has been completed
+	_REG32(136 << 2, ahbregaddr) |= (1 << MC_INIT_COMPLETE_OFFSET);
+}
+
+static inline void ux00ddr_mask_outofrange_interrupts(size_t ahbregaddr)
+{
+	// Mask off Bit 8, Bit 2 and Bit 1 of Interrupt Status
+	// Bit [2] Multiple accesses outside the defined PHYSICAL memory
+	// space have occurred
+	// Bit [1] A memory access outside the defined PHYSICAL memory
+	// space has occurred
+	_REG32(136 << 2, ahbregaddr) |= ((1 << OUT_OF_RANGE_OFFSET) | (1 <<
+				MULTIPLE_OUT_OF_RANGE_OFFSET));
+}
+
+static inline void ux00ddr_mask_port_command_error_interrupt(size_t
+		ahbregaddr)
+{
+	// Mask off Bit 7 of Interrupt Status
+	// Bit [7] An error occurred on the port command channel
+	_REG32(136 << 2, ahbregaddr) |= (1 <<
+			PORT_COMMAND_CHANNEL_ERROR_OFFSET);
+}
+
+static inline void ux00ddr_mask_leveling_completed_interrupt(size_t
+		ahbregaddr)
+{
+	// Mask off Bit 22 of Interrupt Status
+	// Bit [22] The leveling operation has completed
+	_REG32(136 << 2, ahbregaddr) |= (1 <<
+			LEVELING_OPERATION_COMPLETED_OFFSET);
+}
+
+static inline void ux00ddr_setuprangeprotection(size_t ahbregaddr, size_t
+		end_addr)
+{
+	_REG32(209 << 2, ahbregaddr) = 0x0;
+	size_t end_addr_16kblocks = ((end_addr >> 14) & 0x7FFFFF) - 1;
+
+	_REG32(210 << 2, ahbregaddr)  = ((u32)end_addr_16kblocks);
+	_REG32(212 << 2, ahbregaddr)  = 0x0;
+	_REG32(214 << 2, ahbregaddr)  = 0x0;
+	_REG32(216 << 2, ahbregaddr)  = 0x0;
+	_REG32(224 << 2, ahbregaddr) |= (0x3 << AXI0_RANGE_PROT_BITS_0_OFFSET);
+	_REG32(225 << 2, ahbregaddr)  = 0xFFFFFFFF;
+	_REG32(208 << 2, ahbregaddr) |= (1 << AXI0_ADDRESS_RANGE_ENABLE);
+	_REG32(208 << 2, ahbregaddr) |= (1 << PORT_ADDR_PROTECTION_EN_OFFSET);
+}
+
+static inline void ux00ddr_disableaxireadinterleave(size_t ahbregaddr)
+{
+	_REG32(120 << 2, ahbregaddr) |= (1 << DISABLE_RD_INTERLEAVE_OFFSET);
+}
+
+static inline void ux00ddr_disableoptimalrmodw(size_t ahbregaddr)
+{
+	_REG32(21 << 2, ahbregaddr) &= (~(1 << OPTIMAL_RMODW_EN_OFFSET));
+}
+
+static inline void ux00ddr_enablewriteleveling(size_t ahbregaddr)
+{
+	_REG32(170 << 2, ahbregaddr) |= ((1 << WRLVL_EN_OFFSET) | (1 <<
+				DFI_PHY_WRLELV_MODE_OFFSET));
+}
+
+static inline void ux00ddr_enablereadleveling(size_t ahbregaddr)
+{
+	_REG32(181 << 2, ahbregaddr) |= (1 << DFI_PHY_RDLVL_MODE_OFFSET);
+	_REG32(260 << 2, ahbregaddr) |= (1 << RDLVL_EN_OFFSET);
+}
+
+static inline void ux00ddr_enablereadlevelinggate(size_t ahbregaddr)
+{
+	_REG32(260 << 2, ahbregaddr) |= (1 << RDLVL_GATE_EN_OFFSET);
+	_REG32(182 << 2, ahbregaddr) |= (1 << DFI_PHY_RDLVL_GATE_MODE_OFFSET);
+}
+
+static inline void ux00ddr_enablevreftraining(size_t ahbregaddr)
+{
+	_REG32(184 << 2, ahbregaddr) |= (1 << VREF_EN_OFFSET);
+}
+
+static inline u32 ux00ddr_getdramclass(size_t ahbregaddr)
+{
+	return((_REG32(0, ahbregaddr) >> DRAM_CLASS_OFFSET) & 0xF);
+}
+
+static inline u64 ux00ddr_phy_fixup(size_t ahbregaddr)
+{
+	// return bitmask of failed lanes
+
+	size_t ddrphyreg = ahbregaddr + 0x2000;
+
+	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 = _REG32((regbase + reg) << 2,
+						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)
+						uart_puts((void *)
+							  UART0_CTRL_ADDR,
+							  "DDR error in fixing up \n");
+
+					fails |= (1 << dq);
+
+					char slicelsc = '0';
+					char slicemsc = '0';
+
+					slicelsc += (dq % 10);
+					slicemsc += (dq / 10);
+					uart_puts((void *)UART0_CTRL_ADDR,
+						  "S ");
+					uart_puts((void *)UART0_CTRL_ADDR,
+						  &slicemsc);
+					uart_puts((void *)UART0_CTRL_ADDR,
+						  &slicelsc);
+					if (failc0)
+						uart_puts((void *)
+							  UART0_CTRL_ADDR,
+							  "U");
+					else
+						uart_puts((void *)
+							  UART0_CTRL_ADDR,
+							  "D");
+
+					uart_puts((void *)UART0_CTRL_ADDR,
+						  "\n");
+				}
+				dq++;
+			}
+		}
+		slicebase += 128;
+	}
+	return(0);
+}
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* FU540_UX00DDR_H */
diff --git a/board/sifive/fu540/include/ux00prci.h b/board/sifive/fu540/include/ux00prci.h
new file mode 100644
index 0000000000..21f4aeb465
--- /dev/null
+++ b/board/sifive/fu540/include/ux00prci.h
@@ -0,0 +1,206 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#ifndef _SIFIVE_UX00PRCI_H
+#define _SIFIVE_UX00PRCI_H
+
+/* Register offsets */
+
+#define UX00PRCI_HFROSCCFG          (0x0000)
+#define UX00PRCI_COREPLLCFG         (0x0004)
+#define UX00PRCI_COREPLLOUT         (0x0008)
+#define UX00PRCI_DDRPLLCFG          (0x000C)
+#define UX00PRCI_DDRPLLOUT          (0x0010)
+#define UX00PRCI_GEMGXLPLLCFG       (0x001C)
+#define UX00PRCI_GEMGXLPLLOUT       (0x0020)
+#define UX00PRCI_CORECLKSELREG      (0x0024)
+#define UX00PRCI_DEVICESRESETREG    (0x0028)
+#define UX00PRCI_CLKMUXSTATUSREG    (0x002C)
+#define UX00PRCI_PROCMONCFG         (0x00F0)
+
+/* Fields */
+#define XOSC_EN(x)            (((x) & 0x1) << 30)
+#define XOSC_RDY(x)           (((x) & 0x1) << 31)
+
+#define PLL_R(x)              (((x) & 0x3F) << 0)
+#define PLL_F(x)              (((x) & 0x1FF) << 6)
+#define PLL_Q(x)              (((x) & 0x7) << 15)
+#define PLL_RANGE(x)          (((x) & 0x7) << 18)
+#define PLL_BYPASS(x)         (((x) & 0x1) << 24)
+#define PLL_FSE(x)            (((x) & 0x1) << 25)
+#define PLL_LOCK(x)           (((x) & 0x1) << 31)
+
+#define PLLOUT_DIV(x)         (((x) & 0x7F) << 0)
+#define PLLOUT_DIV_BY_1(x)    (((x) & 0x1) << 8)
+#define PLLOUT_CLK_EN(x)      (((x) & 0x1) << 31)
+
+#define PLL_R_default              0x1
+#define PLL_F_default              0x1F
+#define PLL_Q_default              0x3
+#define PLL_RANGE_default          0x0
+#define PLL_BYPASS_default         0x1
+#define PLL_FSE_default            0x1
+
+#define PLLOUT_DIV_default         0x0
+#define PLLOUT_DIV_BY_1_default    0x0
+#define PLLOUT_CLK_EN_default      0x0
+
+#define PLL_CORECLKSEL_HFXIN       0x1
+#define PLL_CORECLKSEL_COREPLL     0x0
+
+#define DEVICESRESET_DDR_CTRL_RST_N(x)    (((x) & 0x1) << 0)
+#define DEVICESRESET_DDR_AXI_RST_N(x)     (((x) & 0x1) << 1)
+#define DEVICESRESET_DDR_AHB_RST_N(x)     (((x) & 0x1) << 2)
+#define DEVICESRESET_DDR_PHY_RST_N(x)     (((x) & 0x1) << 3)
+#define DEVICESRESET_GEMGXL_RST_N(x)      (((x) & 0x1) << 5)
+
+#define CLKMUX_STATUS_CORECLKPLLSEL    (0x1 << 0)
+#define CLKMUX_STATUS_TLCLKSEL         (0x1 << 1)
+#define CLKMUX_STATUS_RTCXSEL          (0x1 << 2)
+#define CLKMUX_STATUS_DDRCTRLCLKSEL    (0x1 << 3)
+#define CLKMUX_STATUS_DDRPHYCLKSEL     (0x1 << 4)
+#define CLKMUX_STATUS_GEMGXLCLKSEL     (0x1 << 6)
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+#include <linux/types.h>
+
+static inline int ux00prci_select_corepll(volatile u32 *coreclkselreg,
+					  volatile u32 *corepllcfg,
+					  volatile u32 *corepllout,
+					  u32 pllconfigval)
+{
+	(*corepllcfg) = pllconfigval;
+
+	// Wait for lock
+	while (((*corepllcfg) & (PLL_LOCK(1))) == 0)
+		;
+
+	u32 core_out =
+		(PLLOUT_DIV(PLLOUT_DIV_default)) |
+		(PLLOUT_DIV_BY_1(PLLOUT_DIV_BY_1_default)) |
+		(PLLOUT_CLK_EN(1));
+	(*corepllout) = core_out;
+
+	// Set CORECLKSELREG to select COREPLL
+	(*coreclkselreg) = PLL_CORECLKSEL_COREPLL;
+
+	return 0;
+}
+
+static inline int ux00prci_select_corepll_1_4ghz(volatile u32 *coreclkselreg,
+						 volatile u32 *corepllcfg,
+						 volatile u32 *corepllout)
+{
+	//
+	// CORE pll init
+	// Set corepll 33MHz -> 1GHz
+	//
+
+	u32 core14ghz =
+		(PLL_R(0)) |
+		(PLL_F(41)) |            /*2800MHz VCO*/
+		(PLL_Q(1)) |             /* /2 Output divider */
+		(PLL_RANGE(0x4)) |
+		(PLL_BYPASS(0)) |
+		(PLL_FSE(1));
+
+	return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
+					core14ghz);
+}
+
+static inline int ux00prci_select_corepll_1_5ghz(volatile u32 *coreclkselreg,
+						 volatile u32 *corepllcfg,
+						 volatile u32 *corepllout)
+{
+	//
+	// CORE pll init
+	// Set corepll 33MHz -> 1GHz
+	//
+
+	u32 core15ghz =
+		(PLL_R(0)) |
+		(PLL_F(44)) |            /*3000MHz VCO*/
+		(PLL_Q(1)) |             /* /2 Output divider */
+		(PLL_RANGE(0x4)) |
+		(PLL_BYPASS(0)) |
+		(PLL_FSE(1));
+
+	return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
+					core15ghz);
+}
+
+static inline int ux00prci_select_corepll_1_6ghz(volatile u32 *coreclkselreg,
+						 volatile u32 *corepllcfg,
+						 volatile u32 *corepllout)
+{
+	//
+	// CORE pll init
+	// Set corepll 33MHz -> 1GHz
+	//
+
+	u32 core16ghz =
+		(PLL_R(0)) |
+		(PLL_F(47)) |            /*3200MHz VCO*/
+		(PLL_Q(1)) |             /* /2 Output divider */
+		(PLL_RANGE(0x4)) |
+		(PLL_BYPASS(0)) |
+		(PLL_FSE(1));
+
+	return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
+					core16ghz);
+}
+
+static inline int ux00prci_select_corepll_1ghz(volatile u32 *coreclkselreg,
+					       volatile u32 *corepllcfg,
+					       volatile u32 *corepllout)
+{
+	//
+	// CORE pll init
+	// Set corepll 33MHz -> 1GHz
+	//
+
+	u32 core1ghz =
+		(PLL_R(0)) |
+		(PLL_F(59)) |            /*4000MHz VCO*/
+		(PLL_Q(2)) |             /* /4 Output divider */
+		(PLL_RANGE(0x4)) |
+		(PLL_BYPASS(0)) |
+		(PLL_FSE(1));
+
+	return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
+					core1ghz);
+}
+
+static inline int ux00prci_select_corepll_500mhz(volatile u32 *coreclkselreg,
+						 volatile u32 *corepllcfg,
+						 volatile u32 *corepllout)
+{
+	//
+	// CORE pll init
+	// Set corepll 33MHz -> 1GHz
+	//
+
+	u32 core500mhz =
+		(PLL_R(0)) |
+		(PLL_F(59)) |            /*4000MHz VCO*/
+		(PLL_Q(3)) |             /* /8 Output divider */
+		(PLL_RANGE(0x4)) |
+		(PLL_BYPASS(0)) |
+		(PLL_FSE(1));
+
+	return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
+					core500mhz);
+}
+
+#endif
+
+#endif // _SIFIVE_UX00PRCI_H
diff --git a/board/sifive/fu540/spl.c b/board/sifive/fu540/spl.c
new file mode 100644
index 0000000000..69187066ba
--- /dev/null
+++ b/board/sifive/fu540/spl.c
@@ -0,0 +1,321 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#include <common.h>
+#include <spl.h>
+
+#include "include/regconfig-ctl.h"
+#include "include/regconfig-phy.h"
+#include "include/ux00ddr.h"
+#include "include/ddrregs.h"
+
+#include "include/fu540-memory-map.h"
+#include <stdatomic.h>
+
+#define ddr_phy_settings DENALI_PHY_DATA
+#define ddr_ctl_settings DENALI_CTL_DATA
+
+#define DDR_SIZE  (8UL * 1024UL * 1024UL * 1024UL)
+#define DDRCTLPLL_F 55
+#define DDRCTLPLL_Q 2
+
+#define PHY_NRESET 0x1000
+#define FIRST_SLOT  0xfe
+#define LAST_SLOT   0x80
+
+static const uintptr_t i2c_devices[] = {
+	I2C_CTRL_ADDR,
+};
+
+static spi_ctrl * const spi_devices[] = {
+	(spi_ctrl *)SPI0_CTRL_ADDR,
+	(spi_ctrl *)SPI1_CTRL_ADDR,
+	(spi_ctrl *)SPI2_CTRL_ADDR,
+};
+
+static const uintptr_t uart_devices[] = {
+	UART0_CTRL_ADDR,
+	UART1_CTRL_ADDR,
+};
+
+unsigned int serial_to_burn = ~0;
+
+/**
+ * Scale peripheral clock dividers before changing core PLL.
+ */
+void update_peripheral_clock_dividers(unsigned int peripheral_input_khz)
+{
+	unsigned int i2c_target_khz = 400;
+	u16 prescaler = i2c_min_clk_prescaler(peripheral_input_khz,
+					      i2c_target_khz);
+
+	for (size_t i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
+		_REG32(i2c_devices[i], I2C_PRESCALER_LO) = prescaler & 0xff;
+		_REG32(i2c_devices[i], I2C_PRESCALER_HI) = (prescaler >> 8) &
+							   0xff;
+	}
+
+	unsigned int spi_target_khz = 50000;
+	unsigned int spi_div = spi_min_clk_divisor(peripheral_input_khz,
+						   spi_target_khz);
+
+	for (size_t i = 0; i < ARRAY_SIZE(spi_devices); i++)
+		spi_devices[i]->sckdiv = spi_div;
+
+	unsigned int uart_target_hz = 115200ULL;
+	unsigned int uart_div = uart_min_clk_divisor(peripheral_input_khz *
+						     1000ULL, uart_target_hz);
+
+	for (size_t i = 0; i < ARRAY_SIZE(uart_devices); i++)
+		_REG32(uart_devices[i], UART_REG_DIV) = uart_div;
+}
+
+long nsec_per_cyc = 300; // 33.333MHz
+void nsleep(long nsec)
+{
+	long step = nsec_per_cyc * 2; // 2 instructions per loop iteration
+
+	while (nsec > 0)
+		nsec -= step;
+}
+
+void init_clk_and_ddr(void)
+{
+	// PRCI init
+
+	// Initialize UART divider for 33MHz core clock in case if
+	// trap is taken prior to core clock bump.
+	unsigned long long uart_target_hz = 115200ULL;
+	const u32 initial_core_clk_khz = 33000;
+	unsigned long peripheral_input_khz;
+
+	if (UX00PRCI_REG(UX00PRCI_CLKMUXSTATUSREG) & CLKMUX_STATUS_TLCLKSEL)
+		peripheral_input_khz = initial_core_clk_khz;
+	else
+		peripheral_input_khz = initial_core_clk_khz / 2;
+	UART0_REG(UART_REG_DIV) = uart_min_clk_divisor(peripheral_input_khz *
+						       1000ULL, uart_target_hz);
+
+	// Check Reset Values (lock don't care)
+	u32 pll_default =
+		(PLL_R(PLL_R_default)) |
+		(PLL_F(PLL_F_default)) |
+		(PLL_Q(PLL_Q_default)) |
+		(PLL_RANGE(PLL_RANGE_default)) |
+		(PLL_BYPASS(PLL_BYPASS_default)) |
+		(PLL_FSE(PLL_FSE_default));
+	u32 lockmask = ~PLL_LOCK(1);
+	u32 pllout_default =
+		(PLLOUT_DIV(PLLOUT_DIV_default)) |
+		(PLLOUT_DIV_BY_1(PLLOUT_DIV_BY_1_default)) |
+		(PLLOUT_CLK_EN(PLLOUT_CLK_EN_default));
+
+	if ((UX00PRCI_REG(UX00PRCI_COREPLLCFG)     ^ pll_default) & lockmask)
+		return;
+	if ((UX00PRCI_REG(UX00PRCI_COREPLLOUT)     ^ pllout_default))
+		return;
+	if ((UX00PRCI_REG(UX00PRCI_DDRPLLCFG)      ^ pll_default) & lockmask)
+		return;
+	if ((UX00PRCI_REG(UX00PRCI_DDRPLLOUT)      ^ pllout_default))
+		return;
+	if (((UX00PRCI_REG(UX00PRCI_GEMGXLPLLCFG)) ^ pll_default) & lockmask)
+		return;
+	if (((UX00PRCI_REG(UX00PRCI_GEMGXLPLLOUT)) ^ pllout_default))
+		return;
+
+	//CORE pll init
+	// If tlclksel is set for 2:1 operation,
+	// Set corepll 33Mhz -> 1GHz
+	// Otherwise, set corepll 33MHz -> 500MHz.
+
+	if (UX00PRCI_REG(UX00PRCI_CLKMUXSTATUSREG) & CLKMUX_STATUS_TLCLKSEL) {
+		nsec_per_cyc = 2;
+		peripheral_input_khz = 500000; // peripheral_clk = tlclk
+		update_peripheral_clock_dividers(peripheral_input_khz);
+		ux00prci_select_corepll_500mhz
+			(&UX00PRCI_REG(UX00PRCI_CORECLKSELREG),
+			 &UX00PRCI_REG(UX00PRCI_COREPLLCFG),
+			 &UX00PRCI_REG(UX00PRCI_COREPLLOUT));
+	} else {
+		nsec_per_cyc = 1;
+		peripheral_input_khz = (1000000 / 2); // peripheral_clk = tlclk
+		update_peripheral_clock_dividers(peripheral_input_khz);
+
+		ux00prci_select_corepll_1ghz
+			(&UX00PRCI_REG(UX00PRCI_CORECLKSELREG),
+			 &UX00PRCI_REG(UX00PRCI_COREPLLCFG),
+			 &UX00PRCI_REG(UX00PRCI_COREPLLOUT));
+	}
+
+	//
+	//DDR init
+	//
+
+	u32 ddrctlmhz =
+		(PLL_R(0)) |
+		(PLL_F(DDRCTLPLL_F)) |
+		(PLL_Q(DDRCTLPLL_Q)) |
+		(PLL_RANGE(0x4)) |
+		(PLL_BYPASS(0)) |
+		(PLL_FSE(1));
+	UX00PRCI_REG(UX00PRCI_DDRPLLCFG) = ddrctlmhz;
+
+	// Wait for lock
+	while ((UX00PRCI_REG(UX00PRCI_DDRPLLCFG) & PLL_LOCK(1)) == 0)
+		;
+
+	u32 ddrctl_out =
+		(PLLOUT_DIV(PLLOUT_DIV_default)) |
+		(PLLOUT_DIV_BY_1(PLLOUT_DIV_BY_1_default)) |
+		(PLLOUT_CLK_EN(1));
+	(UX00PRCI_REG(UX00PRCI_DDRPLLOUT)) = ddrctl_out;
+
+	//Release DDR reset.
+	UX00PRCI_REG(UX00PRCI_DEVICESRESETREG) |=
+		DEVICESRESET_DDR_CTRL_RST_N(1);
+
+	// HACK to get the '1 full controller clock cycle'.
+	asm volatile ("fence");
+	UX00PRCI_REG(UX00PRCI_DEVICESRESETREG) |= DEVICESRESET_DDR_AXI_RST_N(1)
+	       | DEVICESRESET_DDR_AHB_RST_N(1) | DEVICESRESET_DDR_PHY_RST_N(1);
+	// 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");
+
+	ux00ddr_writeregmap(UX00DDR_CTRL_ADDR, ddr_ctl_settings,
+			    ddr_phy_settings);
+	ux00ddr_disableaxireadinterleave(UX00DDR_CTRL_ADDR);
+
+	ux00ddr_disableoptimalrmodw(UX00DDR_CTRL_ADDR);
+
+	ux00ddr_enablewriteleveling(UX00DDR_CTRL_ADDR);
+	ux00ddr_enablereadleveling(UX00DDR_CTRL_ADDR);
+	ux00ddr_enablereadlevelinggate(UX00DDR_CTRL_ADDR);
+	if (ux00ddr_getdramclass(UX00DDR_CTRL_ADDR) == DRAM_CLASS_DDR4)
+		ux00ddr_enablevreftraining(UX00DDR_CTRL_ADDR);
+	//mask off interrupts for leveling completion
+	ux00ddr_mask_leveling_completed_interrupt(UX00DDR_CTRL_ADDR);
+
+	ux00ddr_mask_mc_init_complete_interrupt(UX00DDR_CTRL_ADDR);
+	ux00ddr_mask_outofrange_interrupts(UX00DDR_CTRL_ADDR);
+	ux00ddr_setuprangeprotection(UX00DDR_CTRL_ADDR, DDR_SIZE);
+	ux00ddr_mask_port_command_error_interrupt(UX00DDR_CTRL_ADDR);
+
+	const u64 ddr_size = DDR_SIZE;
+	const u64 ddr_end = CONFIG_SYS_SDRAM_BASE + ddr_size;
+
+	ux00ddr_start(UX00DDR_CTRL_ADDR, PHYSICAL_FILTER_CTRL_ADDR, ddr_end);
+	ux00ddr_phy_fixup(UX00DDR_CTRL_ADDR);
+
+	//
+	//GEMGXL init
+	//
+	u32 gemgxl125mhz =
+		(PLL_R(0)) |
+		(PLL_F(59)) |  /*4000Mhz VCO*/
+		(PLL_Q(5)) |   /* /32 */
+		(PLL_RANGE(0x4)) |
+		(PLL_BYPASS(0)) |
+		(PLL_FSE(1));
+	UX00PRCI_REG(UX00PRCI_GEMGXLPLLCFG) = gemgxl125mhz;
+
+	// Wait for lock
+	while ((UX00PRCI_REG(UX00PRCI_GEMGXLPLLCFG) & PLL_LOCK(1)) == 0)
+		;
+
+	u32 gemgxlctl_out =
+		(PLLOUT_DIV(PLLOUT_DIV_default)) |
+		(PLLOUT_DIV_BY_1(PLLOUT_DIV_BY_1_default)) |
+		(PLLOUT_CLK_EN(1));
+	UX00PRCI_REG(UX00PRCI_GEMGXLPLLOUT) = gemgxlctl_out;
+
+	//Release GEMGXL reset (set bit DEVICESRESET_GEMGXL to 1)
+	UX00PRCI_REG(UX00PRCI_DEVICESRESETREG) |= DEVICESRESET_GEMGXL_RST_N(1);
+
+	// VSC8541 PHY reset sequence; leave pull-down active for 2ms
+	nsleep(2000000);
+	// Set GPIO 12 (PHY NRESET) to OE=1 and OVAL=1
+	atomic_fetch_or(&GPIO_REG(GPIO_OUTPUT_VAL), PHY_NRESET);
+	atomic_fetch_or(&GPIO_REG(GPIO_OUTPUT_EN),  PHY_NRESET);
+	nsleep(100);
+
+	// Procmon => core clock
+	UX00PRCI_REG(UX00PRCI_PROCMONCFG) = 0x1 << 24;
+
+	// Post the serial number and build info
+	UART0_REG(UART_REG_TXCTRL) = UART_TXEN;
+	puts("\r\nPRCI Initialized:       ");
+
+	unsigned int serial = ~0;
+	int serial_slot;
+	unsigned int pos;
+	unsigned int neg;
+
+	ememory_otp_power_up_sequence();
+	ememory_otp_begin_read();
+	for (serial_slot = FIRST_SLOT; serial_slot >= LAST_SLOT;
+			serial_slot -= 2) {
+		pos = ememory_otp_read(serial_slot);
+		neg = ememory_otp_read(serial_slot + 1);
+		serial = pos;
+		if (pos == ~neg)
+			break; // legal serial #
+		if (pos == ~0 && neg == ~0)
+			break; // empty slot encountered
+	}
+	ememory_otp_exit_read();
+
+	void *uart = (void *)UART0_CTRL_ADDR;
+
+	uart_puts(uart, "\r\nHiFive-U serial #: ");
+	uart_put_hex(uart, serial);
+
+	// Program the OTP?
+	if (serial_to_burn != ~0 && serial != serial_to_burn &&
+	    serial_slot > LAST_SLOT) {
+		uart_puts(uart, "Programming serial: ");
+		uart_put_hex(uart, serial_to_burn);
+		uart_puts(uart, "\r\n");
+		ememory_otp_pgm_entry();
+		if (serial != ~0) {
+			// erase the current serial
+			uart_puts(uart, "Erasing prior serial\r\n");
+			ememory_otp_pgm_access(serial_slot,   0);
+			ememory_otp_pgm_access(serial_slot + 1, 0);
+			serial_slot -= 2;
+		}
+		ememory_otp_pgm_access(serial_slot,    serial_to_burn);
+		ememory_otp_pgm_access(serial_slot + 1, ~serial_to_burn);
+		ememory_otp_pgm_exit();
+		uart_puts(uart, "Resuming boot\r\n");
+		serial = serial_to_burn;
+	}
+
+	ememory_otp_power_down_sequence();
+	uart_puts(uart, "\r\n");
+}
+
+void board_init_f(ulong dummy)
+{
+	int ret;
+
+	init_clk_and_ddr();
+
+	ret = spl_early_init();
+	if (ret)
+		panic("spl_early_init() failed: %d\n", ret);
+
+	arch_cpu_init_dm();
+
+	preloader_console_init();
+}
diff --git a/board/sifive/fu540/uart.c b/board/sifive/fu540/uart.c
new file mode 100644
index 0000000000..d16f6add47
--- /dev/null
+++ b/board/sifive/fu540/uart.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 SiFive, Inc
+ *
+ * Authors:
+ *   Pragnesh Patel <pragnesh.patel@sifive.com>
+ *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
+ */
+
+#include <stdatomic.h>
+#include "include/fu540-memory-map.h"
+#include "include/uart.h"
+
+void uart_putc(void *uartctrl, char c)
+{
+#if __riscv_atomic
+	s32 r;
+
+	do {
+		asm volatile ("amoor.w %0, %2, %1\n" : "=r" (r),
+			      "+A" (_REG32(uartctrl, UART_REG_TXFIFO))
+			      : "r" (c)
+			     );
+	} while (r < 0);
+#else
+	while ((int)_REG32(uartctrl, UART_REG_TXFIFO) < 0)
+		;
+	_REG32(uartctrl, UART_REG_TXFIFO) = c;
+#endif
+}
+
+char uart_getc(void *uartctrl)
+{
+	s32 val = -1;
+
+	while (val < 0)
+		val = (s32)_REG32(uartctrl, UART_REG_RXFIFO);
+
+	return val & 0xFF;
+}
+
+void uart_puts(void *uartctrl, const char *s)
+{
+	while (*s != '\0')
+		uart_putc(uartctrl, *s++);
+}
+
+void uart_put_hex(void *uartctrl, u32 hex)
+{
+	int num_nibbles = sizeof(hex) * 2;
+
+	for (int nibble_idx = num_nibbles - 1; nibble_idx >= 0; nibble_idx--) {
+		char nibble = (hex >> (nibble_idx * 4)) & 0xf;
+
+		uart_putc(uartctrl, (nibble < 0xa) ? ('0' + nibble) :
+			  ('a' + nibble - 0xa));
+	}
+}
+
+void uart_put_hex64(void *uartctrl, uint64_t hex)
+{
+	uart_put_hex(uartctrl, hex >> 32);
+	uart_put_hex(uartctrl, hex & 0xFFFFFFFF);
+}
diff --git a/configs/sifive_fu540_spl_defconfig b/configs/sifive_fu540_spl_defconfig
new file mode 100644
index 0000000000..6f9a70ee3e
--- /dev/null
+++ b/configs/sifive_fu540_spl_defconfig
@@ -0,0 +1,23 @@
+CONFIG_RISCV=y
+CONFIG_ENV_SIZE=0x20000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_TARGET_SIFIVE_FU540=y
+CONFIG_ARCH_RV64I=y
+CONFIG_RISCV_SMODE=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_FIT=y
+CONFIG_MISC_INIT_R=y
+CONFIG_DEFAULT_DEVICE_TREE="hifive-unleashed-a00"
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DISPLAY_BOARDINFO=y
+CONFIG_OF_SEPARATE=y
+CONFIG_SPL_SEPARATE_BSS=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=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"
diff --git a/include/configs/sifive-fu540.h b/include/configs/sifive-fu540.h
index 2756ed5a77..5afc7ddb66 100644
--- a/include/configs/sifive-fu540.h
+++ b/include/configs/sifive-fu540.h
@@ -11,6 +11,21 @@
 
 #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 +39,7 @@
 
 /* Environment options */
 
+#ifndef CONFIG_SPL_BUILD
 #define BOOT_TARGET_DEVICES(func) \
 	func(MMC, mmc, 0) \
 	func(DHCP, dhcp, na)
@@ -43,5 +59,6 @@
 #define CONFIG_PREBOOT \
 	"setenv fdt_addr ${fdtcontroladdr};" \
 	"fdt addr ${fdtcontroladdr};"
+#endif
 
 #endif /* __CONFIG_H */
diff --git a/lib/Makefile b/lib/Makefile
index 1fb650cd90..2d88c2ab5e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -76,6 +76,7 @@ endif
 
 ifdef CONFIG_SPL_BUILD
 obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o
+obj-$(CONFIG_MMC_SPI) += crc7.o
 obj-$(CONFIG_$(SPL_TPL_)HASH_SUPPORT) += crc16.o
 obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o
 endif
-- 
2.17.1

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

* [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
  2019-12-31  6:30 ` [PATCH 3/3] riscv: sifive: fu540: add SPL configuration Pragnesh Patel
@ 2019-12-31 17:18   ` Amit Tomer
  2020-01-13 13:36     ` Pragnesh Patel
  2020-01-02  4:58   ` Jagan Teki
  2020-01-03 15:34   ` Bin Meng
  2 siblings, 1 reply; 19+ messages in thread
From: Amit Tomer @ 2019-12-31 17:18 UTC (permalink / raw)
  To: u-boot

Hi Pragnesh,

Minor comments regarding coding style, see below.

> +       // Probably don't need to do this, since
> +       // all the other stuff has been happening.
> +       // But it is on the wave form.

U-boot is mostly implemented in C, we should *not* use C++ style comments(//).
is this something picked from BSP code ?

> +#include "include/ccache.h"
> +#include "include/fu540-memory-map.h"

This looks bit strange, I mean the double include above

> +// Inlining header functions in C
> +// https://stackoverflow.com/a/23699777/7433423

This could be conveyed in comments rather then pointing some external
link.

Thanks
-Amit.

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

* [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
  2019-12-31  6:30 ` [PATCH 3/3] riscv: sifive: fu540: add SPL configuration Pragnesh Patel
  2019-12-31 17:18   ` Amit Tomer
@ 2020-01-02  4:58   ` Jagan Teki
  2020-01-06 10:08     ` Pragnesh Patel
  2020-01-03 15:34   ` Bin Meng
  2 siblings, 1 reply; 19+ messages in thread
From: Jagan Teki @ 2020-01-02  4:58 UTC (permalink / raw)
  To: u-boot

+ Rick, Anup

Thanks for the patch, scratching my head to get SPL running on this board.

On Tue, Dec 31, 2019 at 7:30 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> This patch provides sifive_fu540_spl_defconfig which can support
> U-boot SPL to boot from L2 LIM (0x0800_0000) and then boot FIT
> image including OpenSBI FW_DYNAMIC firmware and U-Boot proper
> images from MMC boot devices.
>
> With sifive_fu540_spl_defconfig:
>
> 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 SD card (replace fw_payload.bin with u-boot.itb)
> into RAM.
>
> 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>
> ---
>  arch/riscv/cpu/u-boot-spl.lds                 |    1 +
>  arch/riscv/dts/fu540-c000-u-boot.dtsi         |   65 +
>  .../dts/hifive-unleashed-a00-u-boot.dtsi      |   24 +
>  arch/riscv/include/asm/csr.h                  |    2 +
>  board/sifive/fu540/Kconfig                    |    8 +
>  board/sifive/fu540/MAINTAINERS                |    1 +
>  board/sifive/fu540/Makefile                   |    6 +
>  board/sifive/fu540/ememoryotp.c               |  143 ++
>  board/sifive/fu540/fu540.c                    |   31 +-
>  board/sifive/fu540/include/ccache.h           |   47 +
>  board/sifive/fu540/include/clkutils.h         |   75 +
>  board/sifive/fu540/include/ddrregs.h          |  622 +++++++++
>  board/sifive/fu540/include/ememoryotp.h       |   24 +
>  board/sifive/fu540/include/fu540-memory-map.h |  427 ++++++
>  board/sifive/fu540/include/i2c.h              |   49 +
>  board/sifive/fu540/include/regconfig-ctl.h    |  274 ++++
>  board/sifive/fu540/include/regconfig-phy.h    | 1224 +++++++++++++++++
>  board/sifive/fu540/include/spi.h              |  233 ++++
>  board/sifive/fu540/include/uart.h             |   54 +
>  board/sifive/fu540/include/ux00ddr.h          |  268 ++++
>  board/sifive/fu540/include/ux00prci.h         |  206 +++
>  board/sifive/fu540/spl.c                      |  321 +++++
>  board/sifive/fu540/uart.c                     |   64 +
>  configs/sifive_fu540_spl_defconfig            |   23 +
>  include/configs/sifive-fu540.h                |   17 +
>  lib/Makefile                                  |    1 +

This patch need to divide into multiple patches since it has multiple
functionalities all in one which indeed difficult for review and not
good to go for merging.

>  26 files changed, 4209 insertions(+), 1 deletion(-)
>  create mode 100644 arch/riscv/dts/fu540-c000-u-boot.dtsi
>  create mode 100644 arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>  create mode 100644 board/sifive/fu540/ememoryotp.c
>  create mode 100644 board/sifive/fu540/include/ccache.h
>  create mode 100644 board/sifive/fu540/include/clkutils.h
>  create mode 100644 board/sifive/fu540/include/ddrregs.h
>  create mode 100644 board/sifive/fu540/include/ememoryotp.h
>  create mode 100644 board/sifive/fu540/include/fu540-memory-map.h
>  create mode 100644 board/sifive/fu540/include/i2c.h
>  create mode 100644 board/sifive/fu540/include/regconfig-ctl.h
>  create mode 100644 board/sifive/fu540/include/regconfig-phy.h
>  create mode 100644 board/sifive/fu540/include/spi.h
>  create mode 100644 board/sifive/fu540/include/uart.h
>  create mode 100644 board/sifive/fu540/include/ux00ddr.h
>  create mode 100644 board/sifive/fu540/include/ux00prci.h
>  create mode 100644 board/sifive/fu540/spl.c
>  create mode 100644 board/sifive/fu540/uart.c
>  create mode 100644 configs/sifive_fu540_spl_defconfig
>
> 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 = .;
> 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..b86cdfb38d
> --- /dev/null
> +++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
> @@ -0,0 +1,65 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2019 SiFive, Inc
> + */
> +
> +/ {
> +       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;
> +                       cpu1_intc: interrupt-controller {
> +                               u-boot,dm-spl;
> +                       };
> +               };
> +               cpu2: cpu at 2 {
> +                       u-boot,dm-spl;
> +                       cpu2_intc: interrupt-controller {
> +                               u-boot,dm-spl;
> +                       };
> +               };
> +               cpu3: cpu at 3 {
> +                       u-boot,dm-spl;
> +                       cpu3_intc: interrupt-controller {
> +                               u-boot,dm-spl;
> +                       };
> +               };
> +               cpu4: cpu at 4 {
> +                       u-boot,dm-spl;
> +                       cpu4_intc: interrupt-controller {
> +                               u-boot,dm-spl;
> +                       };
> +               };
> +       };
> +
> +       soc {
> +               u-boot,dm-spl;
> +               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
> new file mode 100644
> index 0000000000..9b59f4ee14
> --- /dev/null
> +++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
> @@ -0,0 +1,24 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2019 SiFive, Inc
> + */
> +
> +#include "fu540-c000-u-boot.dtsi"
> +
> +/ {
> +       hfclk {
> +               u-boot,dm-spl;
> +       };
> +
> +       rtcclk {
> +               u-boot,dm-spl;
> +       };
> +};
> +
> +&qspi2 {
> +
> +       mmc at 0 {
> +               u-boot,dm-spl;
> +       };
> +
> +};
> diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
> index d1520743a2..125c05dd8a 100644
> --- a/arch/riscv/include/asm/csr.h
> +++ b/arch/riscv/include/asm/csr.h
> @@ -103,6 +103,8 @@
>  #define CSR_TIMEH              0xc81
>  #define CSR_INSTRETH           0xc82
>  #define CSR_MHARTID            0xf14
> +#define CSR_MCYCLE             0xb00
> +#define CSR_MCYCLEH            0xb80
>
>  #ifndef __ASSEMBLY__
>
> diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
> index 816a135b21..ac7c6bff37 100644
> --- a/board/sifive/fu540/Kconfig
> +++ b/board/sifive/fu540/Kconfig
> @@ -16,12 +16,20 @@ config SYS_SOC
>         default "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/MAINTAINERS b/board/sifive/fu540/MAINTAINERS
> index 702d803ad8..42c3f3deb0 100644
> --- a/board/sifive/fu540/MAINTAINERS
> +++ b/board/sifive/fu540/MAINTAINERS
> @@ -7,3 +7,4 @@ S:      Maintained
>  F:     board/sifive/fu540/
>  F:     include/configs/sifive-fu540.h
>  F:     configs/sifive_fu540_defconfig
> +F:     configs/sifive_fu540_spl_defconfig
> diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
> index 6e1862c475..e532beb9d5 100644
> --- a/board/sifive/fu540/Makefile
> +++ b/board/sifive/fu540/Makefile
> @@ -3,3 +3,9 @@
>  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
>
>  obj-y  += fu540.o
> +
> +ifdef CONFIG_SPL_BUILD
> +obj-y += spl.o
> +obj-y += ememoryotp.o
> +obj-y += uart.o
> +endif
> diff --git a/board/sifive/fu540/ememoryotp.c b/board/sifive/fu540/ememoryotp.c
> new file mode 100644
> index 0000000000..994724af37
> --- /dev/null
> +++ b/board/sifive/fu540/ememoryotp.c
> @@ -0,0 +1,143 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#include <stdint.h>
> +#include "include/fu540-memory-map.h"
> +#include "include/clkutils.h"
> +#include "include/ememoryotp.h"
> +
> +#define max(x, y) ((x) > (y) ? (x) : (y))
> +
> +extern inline void clkutils_delay_ns(int delay_ns);
> +
> +void ememory_otp_power_up_sequence(void)
> +{
> +       // Probably don't need to do this, since
> +       // all the other stuff has been happening.
> +       // But it is on the wave form.
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TVDS * 1000);
> +
> +       EMEMORYOTP_REG(EMEMORYOTP_PDSTB) = 1;
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TSAS * 1000);
> +
> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 1;
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TTAS * 1000);
> +}
> +
> +void ememory_otp_power_down_sequence(void)
> +{
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TTAH * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 0;
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TASH * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PDSTB) = 0;
> +       // No delay indicated after this
> +}
> +
> +void ememory_otp_begin_read(void)
> +{
> +       // Initialize
> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 0;
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMS * 1000);
> +
> +       // Enable chip select
> +
> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 1;
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TCS * 1000);
> +}
> +
> +void ememory_otp_exit_read(void)
> +{
> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
> +       // Disable chip select
> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 0;
> +       // Wait before changing PTM
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMH * 1000);
> +}
> +
> +unsigned int ememory_otp_read(int address)
> +{
> +       unsigned int read_value;
> +
> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = address;
> +       // Toggle clock
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TAS * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 1;
> +       // Insert delay until data is ready.
> +       // There are lots of delays
> +       // on the chart, but I think this is the most relevant.
> +       int delay = max(EMEMORYOTP_MAX_TCD, EMEMORYOTP_MIN_TKH);
> +
> +       clkutils_delay_ns(delay * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
> +       read_value = EMEMORYOTP_REG(EMEMORYOTP_PDOUT);
> +       // Could check here for things like TCYC < TAH + TCD
> +       return read_value;
> +}
> +
> +void ememory_otp_pgm_entry(void)
> +{
> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PAS) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PAIO) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 2;
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMS * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 1;
> +       clkutils_delay_ns(EMEMORYOTP_TYP_TCSP * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PPROG) = 1;
> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPS * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 1;
> +}
> +
> +void ememory_otp_pgm_exit(void)
> +{
> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPH * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PPROG) = 0;
> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPR * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 0;
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMH * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 0;
> +}
> +
> +void ememory_otp_pgm_access(int address, unsigned int write_data)
> +{
> +       int i;
> +
> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = address;
> +       for (int pas = 0; pas < 2; pas++) {
> +               EMEMORYOTP_REG(EMEMORYOTP_PAS) = pas;
> +               for (i = 0; i < 32; i++) {
> +                       EMEMORYOTP_REG(EMEMORYOTP_PAIO) = i;
> +                       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = ((write_data >> i) &
> +                                                          1);
> +
> +                       int delay = max(EMEMORYOTP_MIN_TASP,
> +                                       EMEMORYOTP_MIN_TDSP);
> +
> +                       clkutils_delay_ns(delay * 1000);
> +                       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 1;
> +                       clkutils_delay_ns(EMEMORYOTP_TYP_TPW * 1000);
> +                       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
> +                       delay = max(EMEMORYOTP_MIN_TAHP, EMEMORYOTP_MIN_TDHP);
> +                       delay = max(delay, EMEMORYOTP_TYP_TPWI);
> +                       clkutils_delay_ns(delay * 1000);
> +               }
> +       }
> +       EMEMORYOTP_REG(EMEMORYOTP_PAS) = 0;
> +}

Please add dm driver for this.

> diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
> index 47a2090251..e91418a88a 100644
> --- a/board/sifive/fu540/fu540.c
> +++ b/board/sifive/fu540/fu540.c
> @@ -10,6 +10,9 @@
>  #include <dm.h>
>  #include <linux/delay.h>
>  #include <linux/io.h>
> +#include <spl.h>
> +#include "include/ccache.h"
> +#include "include/fu540-memory-map.h"
>
>  #ifdef CONFIG_MISC_INIT_R
>
> @@ -143,7 +146,33 @@ int misc_init_r(void)
>
>  int board_init(void)
>  {
> -       /* For now nothing to do here. */
> +       /* enable all cache ways */
> +       ccache_enable_ways(CCACHE_CTRL_ADDR, 15);
> +       return 0;
> +}
> +
> +#ifdef CONFIG_SPL
> +void board_boot_order(u32 *spl_boot_list)
> +{
> +       u8 i;
> +       u32 boot_devices[] = {
> +#ifdef CONFIG_SPL_RAM_SUPPORT
> +               BOOT_DEVICE_RAM,
> +#endif

You may skip if you haven't tested Boot from RAM yet?

> +#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/include/ccache.h b/board/sifive/fu540/include/ccache.h
> new file mode 100644
> index 0000000000..c7978ebdee
> --- /dev/null
> +++ b/board/sifive/fu540/include/ccache.h
> @@ -0,0 +1,47 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef FU540_CCACHE_H
> +#define FU540_CCACHE_H
> +
> +#include <asm/arch/cache.h>
> +
> +#ifndef __ASSEMBLER__
> +
> +#include <stdint.h>
> +#include <stdatomic.h>
> +#include <linux/types.h>
> +
> +// Block memory access until operation completed
> +static inline void ccache_barrier_0(void)
> +{
> +       asm volatile("fence rw, io" : : : "memory");
> +}
> +
> +static inline void ccache_barrier_1(void)
> +{
> +       asm volatile("fence io, rw" : : : "memory");
> +}
> +
> +// Enable ways; allow cache to use these ways
> +static inline u8 ccache_enable_ways(u64 base_addr, u8 value)
> +{
> +       u32 old;
> +
> +       volatile _Atomic(u32) * enable = (_Atomic(u32) *)(base_addr +
> +                                         CCACHE_ENABLE);
> +       ccache_barrier_0();
> +       old = atomic_exchange_explicit(enable, value, memory_order_relaxed);
> +       ccache_barrier_1();
> +       return old;
> +}
> +
> +#endif
> +
> +#endif /* FU540_CCACHE_H */
> diff --git a/board/sifive/fu540/include/clkutils.h b/board/sifive/fu540/include/clkutils.h
> new file mode 100644
> index 0000000000..dbb260a1c3
> --- /dev/null
> +++ b/board/sifive/fu540/include/clkutils.h
> @@ -0,0 +1,75 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef __ASSEMBLER__
> +
> +#include <stdint.h>
> +#include <asm/encoding.h>
> +#include "fu540-memory-map.h"
> +
> +// Inlining header functions in C
> +// https://stackoverflow.com/a/23699777/7433423
> +inline u64 clkutils_read_mtime(void)
> +{
> +#if __riscv_xlen == 32
> +       u32 mtime_hi_0;
> +       u32 mtime_lo;
> +       u32 mtime_hi_1;
> +
> +       do {
> +               mtime_hi_0 = CLINT_REG(CLINT_MTIME + 4);
> +               mtime_lo   = CLINT_REG(CLINT_MTIME + 0);
> +               mtime_hi_1 = CLINT_REG(CLINT_MTIME + 4);
> +       } while (mtime_hi_0 != mtime_hi_1);
> +
> +       return (((u64)mtime_hi_1 << 32) | ((u64)mtime_lo));
> +#else
> +       return CLINT_REG64(CLINT_MTIME);
> +#endif
> +}
> +
> +static inline u64 clkutils_read_mcycle(void)
> +{
> +#if __riscv_xlen == 32
> +       u32 mcycle_hi_0;
> +       u32 mcycle_lo;
> +       u32 mcycle_hi_1;
> +
> +       do {
> +               mcycle_hi_0 = read_csr(mcycleh);
> +               mcycle_lo   = read_csr(mcycle);
> +               mcycle_hi_1 = read_csr(mcycleh);
> +       } while (mcycle_hi_0 != mcycle_hi_1);
> +
> +       return (((u64)mcycle_hi_1 << 32) | ((u64)mcycle_lo));
> +#else
> +       return csr_read(CSR_MCYCLE);
> +#endif
> +}
> +
> +// Note that since this runs off RTC, which is
> +// currently ~1-10MHz, this function is
> +// not acccurate for small delays.
> +// In the future, we may want to determine whether to
> +// use RTC vs mcycle, or create a different function
> +// based off mcycle.
> +// We add 1 to the then value because otherwise, if you wanted
> +// to delay up to RTC_PERIOD_NS-1 (for example), you wouldn't delay
> +// at all. So this function delays AT LEAST delay_ns.

Improper syntax for multiple comments.

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

Can this handle to write separate driver for ram like drivers/ram ?
> diff --git a/board/sifive/fu540/include/ememoryotp.h b/board/sifive/fu540/include/ememoryotp.h
> new file mode 100644
> index 0000000000..274283c4db
> --- /dev/null
> +++ b/board/sifive/fu540/include/ememoryotp.h
> @@ -0,0 +1,24 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef FU540_EMEMORYOTP_H
> +#define FU540_EMEMORYOTP_H
> +
> +#include <asm/arch/otp.h>
> +
> +void ememory_otp_power_up_sequence(void);
> +void ememory_otp_power_down_sequence(void);
> +void ememory_otp_begin_read(void);
> +void ememory_otp_exit_read(void);
> +unsigned int ememory_otp_read(int address);
> +void ememory_otp_pgm_entry(void);
> +void ememory_otp_pgm_exit(void);
> +void ememory_otp_pgm_access(int address, unsigned int write_data);
> +
> +#endif /* FU540_EMEMORYOTP_H */
> diff --git a/board/sifive/fu540/include/fu540-memory-map.h b/board/sifive/fu540/include/fu540-memory-map.h
> new file mode 100644
> index 0000000000..071ee3d1d9
> --- /dev/null
> +++ b/board/sifive/fu540/include/fu540-memory-map.h
> @@ -0,0 +1,427 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef FU540_MEMORY_MAP
> +#define FU540_MEMORY_MAP
> +
> +#include <linux/const.h>
> +#include <asm/arch/clint.h>
> +#include <asm/arch/gpio.h>
> +#include "ememoryotp.h"
> +#include "ccache.h"
> +#include "i2c.h"
> +#include "spi.h"
> +#include "uart.h"
> +#include "ux00prci.h"
> +
> +/****************************************************************************
> + * Platform definitions
> + *****************************************************************************/
> +
> +// CPU info
> +#define NUM_CORES                      5
> +#define MAX_HART_ID                    4
> +#define GLOBAL_INT_SIZE                59
> +#define GLOBAL_INT_MAX_PRIORITY        7
> +#define RTC_FREQUENCY_HZ               _AC(1000000, UL)
> +#define RTC_PERIOD_NS                  _AC(1000, UL)
> +
> +// Memory map
> +#define BUSERROR0_CTRL_ADDR            _AC(0x1700000, UL)
> +#define BUSERROR0_CTRL_SIZE            _AC(0x1000, UL)
> +#define BUSERROR1_CTRL_ADDR            _AC(0x1701000, UL)
> +#define BUSERROR1_CTRL_SIZE            _AC(0x1000, UL)
> +#define BUSERROR2_CTRL_ADDR            _AC(0x1702000, UL)
> +#define BUSERROR2_CTRL_SIZE            _AC(0x1000, UL)
> +#define BUSERROR3_CTRL_ADDR            _AC(0x1703000, UL)
> +#define BUSERROR3_CTRL_SIZE            _AC(0x1000, UL)
> +#define BUSERROR4_CTRL_ADDR            _AC(0x1704000, UL)
> +#define BUSERROR4_CTRL_SIZE            _AC(0x1000, UL)
> +#ifndef BUSERROR_CTRL_ADDR
> +#define BUSERROR_CTRL_ADDR             BUSERROR0_CTRL_ADDR
> +#endif
> +#ifndef BUSERROR_CTRL_SIZE
> +#define BUSERROR_CTRL_SIZE             BUSERROR0_CTRL_SIZE
> +#endif
> +
> +#define CACHEABLE_ZERO_MEM_ADDR        _AC(0xa000000, UL)
> +#define CACHEABLE_ZERO_MEM_SIZE        _AC(0x2000000, UL)
> +#define CADENCEDDRMGMT_CTRL_ADDR       _AC(0x100c0000, UL)
> +#define CADENCEDDRMGMT_CTRL_SIZE       _AC(0x1000, UL)
> +#define CADENCEGEMGXLMGMT_CTRL_ADDR    _AC(0x100a0000, UL)
> +#define CADENCEGEMGXLMGMT_CTRL_SIZE    _AC(0x1000, UL)
> +#define CCACHE_CTRL_ADDR               _AC(0x2010000, UL)
> +#define CCACHE_CTRL_SIZE               _AC(0x1000, UL)
> +#define CCACHE_SIDEBAND_ADDR           _AC(0x8000000, UL)
> +#define CCACHE_SIDEBAND_SIZE           _AC(0x1e0000, UL)
> +
> +#define CHIPLINK_MEM0_ADDR             _AC(0x40000000, UL)
> +#define CHIPLINK_MEM0_SIZE             _AC(0x10000000, UL)
> +#define CHIPLINK_MEM1_ADDR             _AC(0x60000000, UL)
> +#define CHIPLINK_MEM1_SIZE             _AC(0x10000000, UL)
> +#define CHIPLINK_MEM2_ADDR             _AC(0x2000000000, UL)
> +#define CHIPLINK_MEM2_SIZE             _AC(0x20000000, UL)
> +#define CHIPLINK_MEM3_ADDR             _AC(0x2080000000, UL)
> +#define CHIPLINK_MEM3_SIZE             _AC(0x180000000, UL)
> +#define CHIPLINK_MEM4_ADDR             _AC(0x3000000000, UL)
> +#define CHIPLINK_MEM4_SIZE             _AC(0x20000000, UL)
> +
> +#define CLINT_CTRL_ADDR                _AC(0x2000000, UL)
> +#define CLINT_CTRL_SIZE                _AC(0x10000, UL)
> +#define DEBUG_CTRL_ADDR                _AC(0x0, UL)
> +#define DEBUG_CTRL_SIZE                _AC(0x1000, UL)
> +#define DMA_CTRL_ADDR                  _AC(0x3000000, UL)
> +#define DMA_CTRL_SIZE                  _AC(0x100000, UL)
> +#define DTIM_MEM_ADDR                  _AC(0x1000000, UL)
> +#define DTIM_MEM_SIZE                  _AC(0x2000, UL)
> +#define EMEMORYOTP_CTRL_ADDR           _AC(0x10070000, UL)
> +#define EMEMORYOTP_CTRL_SIZE           _AC(0x1000, UL)
> +#define ERROR_MEM_ADDR                 _AC(0x18000000, UL)
> +#define ERROR_MEM_SIZE                 _AC(0x8000000, UL)
> +#define GPIO_CTRL_ADDR                 _AC(0x10060000, UL)
> +#define GPIO_CTRL_SIZE                 _AC(0x1000, UL)
> +#define I2C_CTRL_ADDR                  _AC(0x10030000, UL)
> +#define I2C_CTRL_SIZE                  _AC(0x1000, UL)
> +
> +#define ITIM0_MEM_ADDR                 _AC(0x1800000, UL)
> +#define ITIM0_MEM_SIZE                 _AC(0x2000, UL)
> +#define ITIM1_MEM_ADDR                 _AC(0x1808000, UL)
> +#define ITIM1_MEM_SIZE                 _AC(0x7000, UL)
> +#define ITIM2_MEM_ADDR                 _AC(0x1810000, UL)
> +#define ITIM2_MEM_SIZE                 _AC(0x7000, UL)
> +#define ITIM3_MEM_ADDR                 _AC(0x1818000, UL)
> +#define ITIM3_MEM_SIZE                 _AC(0x7000, UL)
> +#define ITIM4_MEM_ADDR                 _AC(0x1820000, UL)
> +#define ITIM4_MEM_SIZE                 _AC(0x7000, UL)
> +#ifndef ITIM_MEM_ADDR
> +#define ITIM_MEM_ADDR                  ITIM0_MEM_ADDR
> +#endif
> +#ifndef ITIM_MEM_SIZE
> +#define ITIM_MEM_SIZE                  ITIM0_MEM_SIZE
> +#endif
> +
> +#define MAC_CTRL_ADDR                  _AC(0x10090000, UL)
> +#define MAC_CTRL_SIZE                  _AC(0x2000, UL)
> +#define MASKROM_MEM_ADDR               _AC(0x10000, UL)
> +#define MASKROM_MEM_SIZE               _AC(0x8000, UL)
> +#define MEMORY_MEM_ADDR                _AC(0x80000000, UL)
> +#define MEMORY_MEM_SIZE                _AC(0x80000000, UL)
> +#define MODESELECT_MEM_ADDR            _AC(0x1000, UL)
> +#define MODESELECT_MEM_SIZE            _AC(0x1000, UL)
> +#define MSI_CTRL_ADDR                  _AC(0x2020000, UL)
> +#define MSI_CTRL_SIZE                  _AC(0x1000, UL)
> +#define ORDER_OGLER_CTRL_ADDR          _AC(0x10100000, UL)
> +#define ORDER_OGLER_CTRL_SIZE          _AC(0x1000, UL)
> +#define PHYSICAL_FILTER_CTRL_ADDR      _AC(0x100b8000, UL)
> +#define PHYSICAL_FILTER_CTRL_SIZE      _AC(0x1000, UL)
> +#define PINCTRL_CTRL_ADDR              _AC(0x10080000, UL)
> +#define PINCTRL_CTRL_SIZE              _AC(0x1000, UL)
> +#define PLIC_CTRL_ADDR                 _AC(0xc000000, UL)
> +#define PLIC_CTRL_SIZE                 _AC(0x4000000, UL)
> +
> +#define PWM0_CTRL_ADDR                 _AC(0x10020000, UL)
> +#define PWM0_CTRL_SIZE                 _AC(0x1000, UL)
> +#define PWM1_CTRL_ADDR                 _AC(0x10021000, UL)
> +#define PWM1_CTRL_SIZE                 _AC(0x1000, UL)
> +#ifndef PWM_CTRL_ADDR
> +#define PWM_CTRL_ADDR                  PWM0_CTRL_ADDR
> +#endif
> +#ifndef PWM_CTRL_SIZE
> +#define PWM_CTRL_SIZE                  PWM0_CTRL_SIZE
> +#endif
> +
> +#define SPI0_CTRL_ADDR                 _AC(0x10040000, UL)
> +#define SPI0_CTRL_SIZE                 _AC(0x1000, UL)
> +#define SPI0_MEM_ADDR                  _AC(0x20000000, UL)
> +#define SPI0_MEM_SIZE                  _AC(0x10000000, UL)
> +#define SPI1_CTRL_ADDR                 _AC(0x10041000, UL)
> +#define SPI1_CTRL_SIZE                 _AC(0x1000, UL)
> +#define SPI1_MEM_ADDR                  _AC(0x30000000, UL)
> +#define SPI1_MEM_SIZE                  _AC(0x10000000, UL)
> +#define SPI2_CTRL_ADDR                 _AC(0x10050000, UL)
> +#define SPI2_CTRL_SIZE                 _AC(0x1000, UL)
> +#ifndef SPI_CTRL_ADDR
> +#define SPI_CTRL_ADDR                  SPI0_CTRL_ADDR
> +#endif
> +#ifndef SPI_CTRL_SIZE
> +#define SPI_CTRL_SIZE                  SPI0_CTRL_SIZE
> +#endif
> +#ifndef SPI_MEM_ADDR
> +#define SPI_MEM_ADDR                   SPI0_MEM_ADDR
> +#endif
> +#ifndef SPI_MEM_SIZE
> +#define SPI_MEM_SIZE                   SPI0_MEM_SIZE
> +#endif
> +
> +#define TEST_CTRL_ADDR                 _AC(0x4000, UL)
> +#define TEST_CTRL_SIZE                 _AC(0x1000, UL)
> +#define UART0_CTRL_ADDR                _AC(0x10010000, UL)
> +#define UART0_CTRL_SIZE                _AC(0x1000, UL)
> +#define UART1_CTRL_ADDR                _AC(0x10011000, UL)
> +#define UART1_CTRL_SIZE                _AC(0x1000, UL)
> +#ifndef UART_CTRL_ADDR
> +#define UART_CTRL_ADDR                 UART0_CTRL_ADDR
> +#endif
> +#ifndef UART_CTRL_SIZE
> +#define UART_CTRL_SIZE                 UART0_CTRL_SIZE
> +#endif
> +#define UX00DDR_CTRL_ADDR              _AC(0x100b0000, UL)
> +#define UX00DDR_CTRL_SIZE              _AC(0x4000, UL)
> +#define UX00PRCI_CTRL_ADDR             _AC(0x10000000, UL)
> +#define UX00PRCI_CTRL_SIZE             _AC(0x1000, UL)
> +
> +// IOF masks
> +// Interrupt numbers
> +#define CCACHE_INT_BASE       1
> +#define UART0_INT_BASE        5
> +#define UART1_INT_BASE        6
> +#define SPI2_INT_BASE         7
> +#define GPIO_INT_BASE         8
> +#define DMA_INT_BASE          24
> +#define UX00DDR_INT_BASE      32
> +#define MSI_INT_BASE          33
> +#define PWM0_INT_BASE         43
> +#define PWM1_INT_BASE         47
> +#define I2C_INT_BASE          51
> +#define SPI0_INT_BASE         52
> +#define SPI1_INT_BASE         53
> +#define MAC_INT_BASE          54
> +#define BUSERROR0_INT_BASE    55
> +#define BUSERROR1_INT_BASE    56
> +#define BUSERROR2_INT_BASE    57
> +#define BUSERROR3_INT_BASE    58
> +#define BUSERROR4_INT_BASE    59
> +#ifndef BUSERROR_INT_BASE
> +#define BUSERROR_INT_BASE     BUSERROR0_INT_BASE
> +#endif
> +#ifndef PWM_INT_BASE
> +#define PWM_INT_BASE          PWM0_INT_BASE
> +#endif
> +#ifndef SPI_INT_BASE
> +#define SPI_INT_BASE          SPI0_INT_BASE
> +#endif
> +#ifndef UART_INT_BASE
> +#define UART_INT_BASE         UART0_INT_BASE
> +#endif
> +
> +// Helper functions
> +#define _REG64(p, i)    (*(volatile uint64_t *)((p) + (i)))
> +#define _REG32(p, i)    (*(volatile uint32_t *)((p) + (i)))
> +#define _REG16(p, i)    (*(volatile uint16_t *)((p) + (i)))
> +// Bulk set bits in `reg` to either 0 or 1.
> +// E.g. SET_BITS(MY_REG, 0x00000007, 0) would generate MY_REG &= ~0x7
> +// E.g. SET_BITS(MY_REG, 0x00000007, 1) would generate MY_REG |= 0x7
> +#define SET_BITS(reg, mask, value)         \
> +       if ((value) == 0)       \
> +               (reg) &= ~(mask);       \
> +       else    {\
> +               (reg) |= (mask); }
> +
> +#ifndef BUSERROR_REG
> +#define BUSERROR_REG(offset)      BUSERROR0_REG(offset)
> +#endif
> +#ifndef BUSERROR_REG64
> +#define BUSERROR_REG64(offset)    BUSERROR0_REG64(offset)
> +#endif
> +#ifndef ITIM_REG
> +#define ITIM_REG(offset)          ITIM0_REG(offset)
> +#endif
> +#ifndef ITIM_REG64
> +#define ITIM_REG64(offset)        ITIM0_REG64(offset)
> +#endif
> +#ifndef PWM_REG
> +#define PWM_REG(offset)           PWM0_REG(offset)
> +#endif
> +#ifndef PWM_REG64
> +#define PWM_REG64(offset)         PWM0_REG64(offset)
> +#endif
> +#ifndef SPI_REG
> +#define SPI_REG(offset)           SPI0_REG(offset)
> +#endif
> +#ifndef SPI_REG64
> +#define SPI_REG64(offset)         SPI0_REG64(offset)
> +#endif
> +#ifndef UART_REG
> +#define UART_REG(offset)          UART0_REG(offset)
> +#endif
> +#ifndef UART_REG64
> +#define UART_REG64(offset)        UART0_REG64(offset)
> +#endif
> +#define BUSERROR0_REG(offset)  \
> +       _REG32(BUSERROR0_CTRL_ADDR, \
> +                       offset)
> +#define BUSERROR1_REG(offset)  \
> +       _REG32(BUSERROR1_CTRL_ADDR, \
> +                       offset)
> +#define BUSERROR2_REG(offset)  \
> +       _REG32(BUSERROR2_CTRL_ADDR, \
> +                       offset)
> +#define BUSERROR3_REG(offset)  \
> +       _REG32(BUSERROR3_CTRL_ADDR, \
> +                       offset)
> +#define BUSERROR4_REG(offset)  \
> +       _REG32(BUSERROR4_CTRL_ADDR, \
> +                       offset)
> +#define CACHEABLE_ZERO_REG(offset)  \
> +       _REG32(CACHEABLE_ZERO_CTRL_ADDR, \
> +                       offset)
> +#define CADENCEDDRMGMT_REG(offset)  \
> +       _REG32(CADENCEDDRMGMT_CTRL_ADDR, \
> +                       offset)
> +#define CADENCEGEMGXLMGMT_REG(offset) \
> +       _REG32(                            \
> +                       CADENCEGEMGXLMGMT_CTRL_ADDR, offset)
> +#define CCACHE_REG(offset)    _REG32(CCACHE_CTRL_ADDR, offset)
> +#define CHIPLINK_REG(offset)  \
> +       _REG32(CHIPLINK_CTRL_ADDR, \
> +                       offset)
> +#define CLINT_REG(offset)     _REG32(CLINT_CTRL_ADDR, offset)
> +#define DEBUG_REG(offset)     _REG32(DEBUG_CTRL_ADDR, offset)
> +#define DMA_REG(offset)       _REG32(DMA_CTRL_ADDR, offset)
> +#define DTIM_REG(offset)      _REG32(DTIM_CTRL_ADDR, offset)
> +#define EMEMORYOTP_REG(offset)  \
> +       _REG32(EMEMORYOTP_CTRL_ADDR, \
> +                       offset)
> +#define ERROR_REG(offset)     _REG32(ERROR_CTRL_ADDR, offset)
> +#define GPIO_REG(offset)      _REG32(GPIO_CTRL_ADDR, offset)
> +#define I2C_REG(offset)       _REG32(I2C_CTRL_ADDR, offset)
> +#define ITIM0_REG(offset)     _REG32(ITIM0_CTRL_ADDR, offset)
> +#define ITIM1_REG(offset)     _REG32(ITIM1_CTRL_ADDR, offset)
> +#define ITIM2_REG(offset)     _REG32(ITIM2_CTRL_ADDR, offset)
> +#define ITIM3_REG(offset)     _REG32(ITIM3_CTRL_ADDR, offset)
> +#define ITIM4_REG(offset)     _REG32(ITIM4_CTRL_ADDR, offset)
> +#define MAC_REG(offset)       _REG32(MAC_CTRL_ADDR, offset)
> +#define MASKROM_REG(offset)  \
> +       _REG32(MASKROM_CTRL_ADDR, \
> +                       offset)
> +#define MEMORY_REG(offset)    _REG32(MEMORY_CTRL_ADDR, offset)
> +#define MODESELECT_REG(offset)  \
> +       _REG32(MODESELECT_CTRL_ADDR, \
> +                       offset)
> +#define MSI_REG(offset)       _REG32(MSI_CTRL_ADDR, offset)
> +#define ORDER_OGLER_REG(offset)  \
> +       _REG32(ORDER_OGLER_CTRL_ADDR, \
> +                       offset)
> +#define PHYSICAL_FILTER_REG(offset) \
> +       _REG32(                          \
> +                       PHYSICAL_FILTER_CTRL_ADDR, offset)
> +#define PINCTRL_REG(offset)  \
> +       _REG32(PINCTRL_CTRL_ADDR, \
> +                       offset)
> +#define PLIC_REG(offset)     _REG32(PLIC_CTRL_ADDR, offset)
> +#define PWM0_REG(offset)     _REG32(PWM0_CTRL_ADDR, offset)
> +#define PWM1_REG(offset)     _REG32(PWM1_CTRL_ADDR, offset)
> +#define SPI0_REG(offset)     _REG32(SPI0_CTRL_ADDR, offset)
> +#define SPI1_REG(offset)     _REG32(SPI1_CTRL_ADDR, offset)
> +#define SPI2_REG(offset)     _REG32(SPI2_CTRL_ADDR, offset)
> +#define TEST_REG(offset)     _REG32(TEST_CTRL_ADDR, offset)
> +#define UART0_REG(offset)    _REG32(UART0_CTRL_ADDR, offset)
> +#define UART1_REG(offset)    _REG32(UART1_CTRL_ADDR, offset)
> +#define UX00DDR_REG(offset)  \
> +       _REG32(UX00DDR_CTRL_ADDR, \
> +                       offset)
> +#define UX00PRCI_REG(offset)  \
> +       _REG32(UX00PRCI_CTRL_ADDR, \
> +                       offset)
> +#define BUSERROR0_REG64(offset) \
> +       _REG64(BUSERROR0_CTRL_ADDR,  \
> +                       offset)
> +#define BUSERROR1_REG64(offset) \
> +       _REG64(BUSERROR1_CTRL_ADDR,  \
> +                       offset)
> +#define BUSERROR2_REG64(offset) \
> +       _REG64(BUSERROR2_CTRL_ADDR,  \
> +                       offset)
> +#define BUSERROR3_REG64(offset) \
> +       _REG64(BUSERROR3_CTRL_ADDR,  \
> +                       offset)
> +#define BUSERROR4_REG64(offset) \
> +       _REG64(BUSERROR4_CTRL_ADDR,  \
> +                       offset)
> +#define CACHEABLE_ZERO_REG64(offset) \
> +       _REG64(CACHEABLE_ZERO_CTRL_ADDR,  \
> +                       offset)
> +#define CADENCEDDRMGMT_REG64(offset) \
> +       _REG64(CADENCEDDRMGMT_CTRL_ADDR,  \
> +                       offset)
> +#define CADENCEGEMGXLMGMT_REG64(offset) \
> +       _REG64(                              \
> +                       CADENCEGEMGXLMGMT_CTRL_ADDR, offset)
> +#define CCACHE_REG64(offset)    _REG64(CCACHE_CTRL_ADDR, offset)
> +#define CHIPLINK_REG64(offset) \
> +       _REG64(CHIPLINK_CTRL_ADDR,  \
> +                       offset)
> +#define CLINT_REG64(offset)     _REG64(CLINT_CTRL_ADDR, offset)
> +#define DEBUG_REG64(offset)     _REG64(DEBUG_CTRL_ADDR, offset)
> +#define DMA_REG64(offset)       _REG64(DMA_CTRL_ADDR, offset)
> +#define DTIM_REG64(offset)      _REG64(DTIM_CTRL_ADDR, offset)
> +#define EMEMORYOTP_REG64(offset) \
> +       _REG64(EMEMORYOTP_CTRL_ADDR,  \
> +                       offset)
> +#define ERROR_REG64(offset)     _REG64(ERROR_CTRL_ADDR, offset)
> +#define GPIO_REG64(offset)      _REG64(GPIO_CTRL_ADDR, offset)
> +#define I2C_REG64(offset)       _REG64(I2C_CTRL_ADDR, offset)
> +#define ITIM0_REG64(offset)     _REG64(ITIM0_CTRL_ADDR, offset)
> +#define ITIM1_REG64(offset)     _REG64(ITIM1_CTRL_ADDR, offset)
> +#define ITIM2_REG64(offset)     _REG64(ITIM2_CTRL_ADDR, offset)
> +#define ITIM3_REG64(offset)     _REG64(ITIM3_CTRL_ADDR, offset)
> +#define ITIM4_REG64(offset)     _REG64(ITIM4_CTRL_ADDR, offset)
> +#define MAC_REG64(offset)       _REG64(MAC_CTRL_ADDR, offset)
> +#define MASKROM_REG64(offset) \
> +       _REG64(MASKROM_CTRL_ADDR,  \
> +                       offset)
> +#define MEMORY_REG64(offset)    _REG64(MEMORY_CTRL_ADDR, offset)
> +#define MODESELECT_REG64(offset) \
> +       _REG64(MODESELECT_CTRL_ADDR,  \
> +                       offset)
> +#define MSI_REG64(offset)       _REG64(MSI_CTRL_ADDR, offset)
> +#define ORDER_OGLER_REG64(offset) \
> +       _REG64(ORDER_OGLER_CTRL_ADDR,  \
> +                       offset)
> +#define PHYSICAL_FILTER_REG64(offset) \
> +       _REG64(                            \
> +                       PHYSICAL_FILTER_CTRL_ADDR, offset)
> +#define PINCTRL_REG64(offset) \
> +       _REG64(PINCTRL_CTRL_ADDR,  \
> +                       offset)
> +#define PLIC_REG64(offset)     _REG64(PLIC_CTRL_ADDR, offset)
> +#define PWM0_REG64(offset)     _REG64(PWM0_CTRL_ADDR, offset)
> +#define PWM1_REG64(offset)     _REG64(PWM1_CTRL_ADDR, offset)
> +#define SPI0_REG64(offset)     _REG64(SPI0_CTRL_ADDR, offset)
> +#define SPI1_REG64(offset)     _REG64(SPI1_CTRL_ADDR, offset)
> +#define SPI2_REG64(offset)     _REG64(SPI2_CTRL_ADDR, offset)
> +#define TEST_REG64(offset)     _REG64(TEST_CTRL_ADDR, offset)
> +#define UART0_REG64(offset)    _REG64(UART0_CTRL_ADDR, offset)
> +#define UART1_REG64(offset)    _REG64(UART1_CTRL_ADDR, offset)
> +#define UX00DDR_REG64(offset) \
> +       _REG64(UX00DDR_CTRL_ADDR,  \
> +                       offset)
> +#define UX00PRCI_REG64(offset) \
> +       _REG64(UX00PRCI_CTRL_ADDR,  \
> +                       offset)
> +// Helpers for getting and setting individual bit fields, shifting the values
> +// for you.
> +#define GET_FIELD(reg, mask)     \
> +       (((reg) & (mask)) / ((mask) & \
> +               ~((mask) << 1)))
> +#define SET_FIELD(reg, mask, val) \
> +       (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask)))
> +
> +// Misc
> +#define ALOE
> +#define SPI0_CS_WIDTH        1
> +#define SPI0_SCKDIV_WIDTH    16
> +#define SPI1_CS_WIDTH        4
> +#define SPI1_SCKDIV_WIDTH    16
> +#define SPI2_CS_WIDTH        1
> +#define SPI2_SCKDIV_WIDTH    16
> +#define GPIO_WIDTH           16
> +
> +#endif /* FU540_MEMORY_MAP */
> diff --git a/board/sifive/fu540/include/i2c.h b/board/sifive/fu540/include/i2c.h
> new file mode 100644
> index 0000000000..89c81f6b92
> --- /dev/null
> +++ b/board/sifive/fu540/include/i2c.h
> @@ -0,0 +1,49 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef FU540_I2C_H
> +#define FU540_I2C_H
> +
> +#include <asm/arch/i2c.h>
> +
> +#ifndef __ASSEMBLER__
> +
> +#include <stdint.h>
> +
> +/*
> + * Get smallest clock prescaler that divides input_khz to a quotient less
> + * than or equal to max_target_khz;
> + */
> +static inline uint16_t i2c_min_clk_prescaler(unsigned int input_khz,
> +                                            unsigned int max_target_khz)
> +{
> +       // f_sck = f_in / (2 * (div + 1)) => div = (f_in / (2*f_sck)) - 1
> +       // prescale = (f_in / (5*f_scl)) - 1
> +       //
> +       // The nearest integer solution for div requires
> +       // rounding up as to not exceed max_target_khz.
> +       //
> +       // div = ceil(f_in / (5*f_scl)) - 1
> +       //     = floor((f_in - 1 + 5*f_scl) / (5*f_scl)) - 1
> +       //
> +       // This should not overflow as long as (f_in - 1 + 5*f_scl) does not
> +       // exceed 2^32 - 1, which is unlikely since we represent frequencies
> +       // in kHz.
> +       unsigned int quotient = (input_khz + 5 * max_target_khz - 1) / (5 *
> +                                max_target_khz);
> +       // Avoid underflow
> +       if (quotient == 0)
> +               return 0;
> +       else
> +               return quotient - 1;
> +}
> +
> +#endif /* !__ASSEMBLER__ */
> +
> +#endif /* FU540_I2C_H */
> diff --git a/board/sifive/fu540/include/regconfig-ctl.h b/board/sifive/fu540/include/regconfig-ctl.h
> new file mode 100644
> index 0000000000..19a52e7996
> --- /dev/null
> +++ b/board/sifive/fu540/include/regconfig-ctl.h
> @@ -0,0 +1,274 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#define               DENALI_CTL_00_DATA 0x00000a00
> +#define               DENALI_CTL_01_DATA 0x00000000
> +#define               DENALI_CTL_02_DATA 0x00000000
> +#define               DENALI_CTL_03_DATA 0x00000000
> +#define               DENALI_CTL_04_DATA 0x00000000
> +#define               DENALI_CTL_05_DATA 0x00000000
> +#define               DENALI_CTL_06_DATA 0x0000000a
> +#define               DENALI_CTL_07_DATA 0x0002d362
> +#define               DENALI_CTL_08_DATA 0x00071073
> +#define               DENALI_CTL_09_DATA 0x0a1c0255
> +#define               DENALI_CTL_10_DATA 0x1c1c0400
> +#define               DENALI_CTL_11_DATA 0x0404990b
> +#define               DENALI_CTL_12_DATA 0x2b050405
> +#define               DENALI_CTL_13_DATA 0x0e0c081e
> +#define               DENALI_CTL_14_DATA 0x08090914
> +#define               DENALI_CTL_15_DATA 0x00fde718
> +#define               DENALI_CTL_16_DATA 0x00180a05
> +#define               DENALI_CTL_17_DATA 0x008b130e
> +#define               DENALI_CTL_18_DATA 0x01000118
> +#define               DENALI_CTL_19_DATA 0x0e032101
> +#define               DENALI_CTL_20_DATA 0x00000000
> +#define               DENALI_CTL_21_DATA 0x00000101
> +#define               DENALI_CTL_22_DATA 0x00000000
> +#define               DENALI_CTL_23_DATA 0x0a000000
> +#define               DENALI_CTL_24_DATA 0x00000000
> +#define               DENALI_CTL_25_DATA 0x01450100
> +#define               DENALI_CTL_26_DATA 0x00001c36
> +#define               DENALI_CTL_27_DATA 0x00000005
> +#define               DENALI_CTL_28_DATA 0x00170006
> +#define               DENALI_CTL_29_DATA 0x014e0300
> +#define               DENALI_CTL_30_DATA 0x03010000
> +#define               DENALI_CTL_31_DATA 0x000a0e00
> +#define               DENALI_CTL_32_DATA 0x04030200
> +#define               DENALI_CTL_33_DATA 0x0000031f
> +#define               DENALI_CTL_34_DATA 0x00070004
> +#define               DENALI_CTL_35_DATA 0x00000000
> +#define               DENALI_CTL_36_DATA 0x00000000
> +#define               DENALI_CTL_37_DATA 0x00000000
> +#define               DENALI_CTL_38_DATA 0x00000000
> +#define               DENALI_CTL_39_DATA 0x00000000
> +#define               DENALI_CTL_40_DATA 0x00000000
> +#define               DENALI_CTL_41_DATA 0x00000000
> +#define               DENALI_CTL_42_DATA 0x00000000
> +#define               DENALI_CTL_43_DATA 0x00000000
> +#define               DENALI_CTL_44_DATA 0x00000000
> +#define               DENALI_CTL_45_DATA 0x00000000
> +#define               DENALI_CTL_46_DATA 0x00000000
> +#define               DENALI_CTL_47_DATA 0x00000000
> +#define               DENALI_CTL_48_DATA 0x00000000
> +#define               DENALI_CTL_49_DATA 0x00000000
> +#define               DENALI_CTL_50_DATA 0x00000000
> +#define               DENALI_CTL_51_DATA 0x00000000
> +#define               DENALI_CTL_52_DATA 0x00000000
> +#define               DENALI_CTL_53_DATA 0x00000000
> +#define               DENALI_CTL_54_DATA 0x00000000
> +#define               DENALI_CTL_55_DATA 0x00000000
> +#define               DENALI_CTL_56_DATA 0x00000000
> +#define               DENALI_CTL_57_DATA 0x00000000
> +#define               DENALI_CTL_58_DATA 0x00000000
> +#define               DENALI_CTL_59_DATA 0x00000000
> +#define               DENALI_CTL_60_DATA 0x00000424
> +#define               DENALI_CTL_61_DATA 0x00000201
> +#define               DENALI_CTL_62_DATA 0x00001008
> +#define               DENALI_CTL_63_DATA 0x00000000
> +#define               DENALI_CTL_64_DATA 0x00000200
> +#define               DENALI_CTL_65_DATA 0x00000000
> +#define               DENALI_CTL_66_DATA 0x00000481
> +#define               DENALI_CTL_67_DATA 0x00000400
> +#define               DENALI_CTL_68_DATA 0x00000424
> +#define               DENALI_CTL_69_DATA 0x00000201
> +#define               DENALI_CTL_70_DATA 0x00001008
> +#define               DENALI_CTL_71_DATA 0x00000000
> +#define               DENALI_CTL_72_DATA 0x00000200
> +#define               DENALI_CTL_73_DATA 0x00000000
> +#define               DENALI_CTL_74_DATA 0x00000481
> +#define               DENALI_CTL_75_DATA 0x00000400
> +#define               DENALI_CTL_76_DATA 0x01010000
> +#define               DENALI_CTL_77_DATA 0x00000000
> +#define               DENALI_CTL_78_DATA 0x00000000
> +#define               DENALI_CTL_79_DATA 0x00000000
> +#define               DENALI_CTL_80_DATA 0x00000000
> +#define               DENALI_CTL_81_DATA 0x00000000
> +#define               DENALI_CTL_82_DATA 0x00000000
> +#define               DENALI_CTL_83_DATA 0x00000000
> +#define               DENALI_CTL_84_DATA 0x00000000
> +#define               DENALI_CTL_85_DATA 0x00000000
> +#define               DENALI_CTL_86_DATA 0x00000000
> +#define               DENALI_CTL_87_DATA 0x00000000
> +#define               DENALI_CTL_88_DATA 0x00000000
> +#define               DENALI_CTL_89_DATA 0x00000000
> +#define               DENALI_CTL_90_DATA 0x00000000
> +#define               DENALI_CTL_91_DATA 0x00000000
> +#define               DENALI_CTL_92_DATA 0x00000000
> +#define               DENALI_CTL_93_DATA 0x00000000
> +#define               DENALI_CTL_94_DATA 0x00000000
> +#define               DENALI_CTL_95_DATA 0x00000000
> +#define               DENALI_CTL_96_DATA 0x00000000
> +#define               DENALI_CTL_97_DATA 0x00000000
> +#define               DENALI_CTL_98_DATA 0x00000000
> +#define               DENALI_CTL_99_DATA 0x00000000
> +#define              DENALI_CTL_100_DATA 0x00000000
> +#define              DENALI_CTL_101_DATA 0x00000000
> +#define              DENALI_CTL_102_DATA 0x00000000
> +#define              DENALI_CTL_103_DATA 0x00000000
> +#define              DENALI_CTL_104_DATA 0x00000000
> +#define              DENALI_CTL_105_DATA 0x00000003
> +#define              DENALI_CTL_106_DATA 0x00000000
> +#define              DENALI_CTL_107_DATA 0x00000000
> +#define              DENALI_CTL_108_DATA 0x00000000
> +#define              DENALI_CTL_109_DATA 0x00000000
> +#define              DENALI_CTL_110_DATA 0x01000000
> +#define              DENALI_CTL_111_DATA 0x00040000
> +#define              DENALI_CTL_112_DATA 0x00800200
> +#define              DENALI_CTL_113_DATA 0x00000200
> +#define              DENALI_CTL_114_DATA 0x00000040
> +#define              DENALI_CTL_115_DATA 0x01000100
> +#define              DENALI_CTL_116_DATA 0x0a000002
> +#define              DENALI_CTL_117_DATA 0x0101ffff
> +#define              DENALI_CTL_118_DATA 0x01010101
> +#define              DENALI_CTL_119_DATA 0x01010101
> +#define              DENALI_CTL_120_DATA 0x0000010b
> +#define              DENALI_CTL_121_DATA 0x00000c01
> +#define              DENALI_CTL_122_DATA 0x00000000
> +#define              DENALI_CTL_123_DATA 0x00000000
> +#define              DENALI_CTL_124_DATA 0x00000000
> +#define              DENALI_CTL_125_DATA 0x00000000
> +#define              DENALI_CTL_126_DATA 0x00030300
> +#define              DENALI_CTL_127_DATA 0x00000000
> +#define              DENALI_CTL_128_DATA 0x00010001
> +#define              DENALI_CTL_129_DATA 0x00000000
> +#define              DENALI_CTL_130_DATA 0x00000000
> +#define              DENALI_CTL_131_DATA 0x00000000
> +#define              DENALI_CTL_132_DATA 0x00000000
> +#define              DENALI_CTL_133_DATA 0x00000000
> +#define              DENALI_CTL_134_DATA 0x00000000
> +#define              DENALI_CTL_135_DATA 0x00000000
> +#define              DENALI_CTL_136_DATA 0x00000000
> +#define              DENALI_CTL_137_DATA 0x00000000
> +#define              DENALI_CTL_138_DATA 0x00000000
> +#define              DENALI_CTL_139_DATA 0x00000000
> +#define              DENALI_CTL_140_DATA 0x00000000
> +#define              DENALI_CTL_141_DATA 0x00000000
> +#define              DENALI_CTL_142_DATA 0x00000000
> +#define              DENALI_CTL_143_DATA 0x00000000
> +#define              DENALI_CTL_144_DATA 0x00000000
> +#define              DENALI_CTL_145_DATA 0x00000000
> +#define              DENALI_CTL_146_DATA 0x00000000
> +#define              DENALI_CTL_147_DATA 0x00000000
> +#define              DENALI_CTL_148_DATA 0x00000000
> +#define              DENALI_CTL_149_DATA 0x00000000
> +#define              DENALI_CTL_150_DATA 0x00000000
> +#define              DENALI_CTL_151_DATA 0x00000000
> +#define              DENALI_CTL_152_DATA 0x00000000
> +#define              DENALI_CTL_153_DATA 0x00000000
> +#define              DENALI_CTL_154_DATA 0x00000000
> +#define              DENALI_CTL_155_DATA 0x00000000
> +#define              DENALI_CTL_156_DATA 0x00000000
> +#define              DENALI_CTL_157_DATA 0x00000000
> +#define              DENALI_CTL_158_DATA 0x00000000
> +#define              DENALI_CTL_159_DATA 0x00000000
> +#define              DENALI_CTL_160_DATA 0x00000000
> +#define              DENALI_CTL_161_DATA 0x02010102
> +#define              DENALI_CTL_162_DATA 0x0107070d
> +#define              DENALI_CTL_163_DATA 0x04040400
> +#define              DENALI_CTL_164_DATA 0x03000503
> +#define              DENALI_CTL_165_DATA 0x00000000
> +#define              DENALI_CTL_166_DATA 0x00000000
> +#define              DENALI_CTL_167_DATA 0x00000000
> +#define              DENALI_CTL_168_DATA 0x00000000
> +#define              DENALI_CTL_169_DATA 0x280d0000
> +#define              DENALI_CTL_170_DATA 0x01000000
> +#define              DENALI_CTL_171_DATA 0x00000000
> +#define              DENALI_CTL_172_DATA 0x00010001
> +#define              DENALI_CTL_173_DATA 0x00000000
> +#define              DENALI_CTL_174_DATA 0x00000000
> +#define              DENALI_CTL_175_DATA 0x00000000
> +#define              DENALI_CTL_176_DATA 0x00000000
> +#define              DENALI_CTL_177_DATA 0x00000000
> +#define              DENALI_CTL_178_DATA 0x00000000
> +#define              DENALI_CTL_179_DATA 0x00000000
> +#define              DENALI_CTL_180_DATA 0x00000000
> +#define              DENALI_CTL_181_DATA 0x01000000
> +#define              DENALI_CTL_182_DATA 0x00000001
> +#define              DENALI_CTL_183_DATA 0x00000100
> +#define              DENALI_CTL_184_DATA 0x00000101
> +#define              DENALI_CTL_185_DATA 0x67676701
> +#define              DENALI_CTL_186_DATA 0x67676767
> +#define              DENALI_CTL_187_DATA 0x67676767
> +#define              DENALI_CTL_188_DATA 0x67676767
> +#define              DENALI_CTL_189_DATA 0x67676767
> +#define              DENALI_CTL_190_DATA 0x67676767
> +#define              DENALI_CTL_191_DATA 0x67676767
> +#define              DENALI_CTL_192_DATA 0x67676767
> +#define              DENALI_CTL_193_DATA 0x67676767
> +#define              DENALI_CTL_194_DATA 0x01000067
> +#define              DENALI_CTL_195_DATA 0x00000001
> +#define              DENALI_CTL_196_DATA 0x00000101
> +#define              DENALI_CTL_197_DATA 0x00000000
> +#define              DENALI_CTL_198_DATA 0x00000000
> +#define              DENALI_CTL_199_DATA 0x00000000
> +#define              DENALI_CTL_200_DATA 0x00000000
> +#define              DENALI_CTL_201_DATA 0x00000000
> +#define              DENALI_CTL_202_DATA 0x00000000
> +#define              DENALI_CTL_203_DATA 0x00000000
> +#define              DENALI_CTL_204_DATA 0x00000000
> +#define              DENALI_CTL_205_DATA 0x00000000
> +#define              DENALI_CTL_206_DATA 0x00000000
> +#define              DENALI_CTL_207_DATA 0x00000000
> +#define              DENALI_CTL_208_DATA 0x00000001
> +#define              DENALI_CTL_209_DATA 0x00000000
> +#define              DENALI_CTL_210_DATA 0x007fffff
> +#define              DENALI_CTL_211_DATA 0x00000000
> +#define              DENALI_CTL_212_DATA 0x007fffff
> +#define              DENALI_CTL_213_DATA 0x00000000
> +#define              DENALI_CTL_214_DATA 0x007fffff
> +#define              DENALI_CTL_215_DATA 0x00000000
> +#define              DENALI_CTL_216_DATA 0x007fffff
> +#define              DENALI_CTL_217_DATA 0x00000000
> +#define              DENALI_CTL_218_DATA 0x007fffff
> +#define              DENALI_CTL_219_DATA 0x00000000
> +#define              DENALI_CTL_220_DATA 0x007fffff
> +#define              DENALI_CTL_221_DATA 0x00000000
> +#define              DENALI_CTL_222_DATA 0x007fffff
> +#define              DENALI_CTL_223_DATA 0x00000000
> +#define              DENALI_CTL_224_DATA 0x037fffff
> +#define              DENALI_CTL_225_DATA 0xffffffff
> +#define              DENALI_CTL_226_DATA 0x000f000f
> +#define              DENALI_CTL_227_DATA 0x00ffff03
> +#define              DENALI_CTL_228_DATA 0x000fffff
> +#define              DENALI_CTL_229_DATA 0x0003000f
> +#define              DENALI_CTL_230_DATA 0xffffffff
> +#define              DENALI_CTL_231_DATA 0x000f000f
> +#define              DENALI_CTL_232_DATA 0x00ffff03
> +#define              DENALI_CTL_233_DATA 0x000fffff
> +#define              DENALI_CTL_234_DATA 0x0003000f
> +#define              DENALI_CTL_235_DATA 0xffffffff
> +#define              DENALI_CTL_236_DATA 0x000f000f
> +#define              DENALI_CTL_237_DATA 0x00ffff03
> +#define              DENALI_CTL_238_DATA 0x000fffff
> +#define              DENALI_CTL_239_DATA 0x0003000f
> +#define              DENALI_CTL_240_DATA 0xffffffff
> +#define              DENALI_CTL_241_DATA 0x000f000f
> +#define              DENALI_CTL_242_DATA 0x00ffff03
> +#define              DENALI_CTL_243_DATA 0x000fffff
> +#define              DENALI_CTL_244_DATA 0x6407000f
> +#define              DENALI_CTL_245_DATA 0x01640001
> +#define              DENALI_CTL_246_DATA 0x00000000
> +#define              DENALI_CTL_247_DATA 0x00000000
> +#define              DENALI_CTL_248_DATA 0x00001700
> +#define              DENALI_CTL_249_DATA 0x00386c05
> +#define              DENALI_CTL_250_DATA 0x02000200
> +#define              DENALI_CTL_251_DATA 0x02000200
> +#define              DENALI_CTL_252_DATA 0x0000386c
> +#define              DENALI_CTL_253_DATA 0x00023438
> +#define              DENALI_CTL_254_DATA 0x02020d10
> +#define              DENALI_CTL_255_DATA 0x00140303
> +#define              DENALI_CTL_256_DATA 0x00000000
> +#define              DENALI_CTL_257_DATA 0x00000000
> +#define              DENALI_CTL_258_DATA 0x00001403
> +#define              DENALI_CTL_259_DATA 0x00000000
> +#define              DENALI_CTL_260_DATA 0x00000000
> +#define              DENALI_CTL_261_DATA 0x00000000
> +#define              DENALI_CTL_262_DATA 0x00000000
> +#define              DENALI_CTL_263_DATA 0x0d010000
> +#define              DENALI_CTL_264_DATA 0x00000008
> diff --git a/board/sifive/fu540/include/regconfig-phy.h b/board/sifive/fu540/include/regconfig-phy.h
> new file mode 100644
> index 0000000000..3450aecdf1
> --- /dev/null
> +++ b/board/sifive/fu540/include/regconfig-phy.h
> @@ -0,0 +1,1224 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#define               DENALI_PHY_00_DATA 0x31706542
> +#define               DENALI_PHY_01_DATA 0x0004c008
> +#define               DENALI_PHY_02_DATA 0x000000da
> +#define               DENALI_PHY_03_DATA 0x00000000
> +#define               DENALI_PHY_04_DATA 0x00000000
> +#define               DENALI_PHY_05_DATA 0x00010000
> +#define               DENALI_PHY_06_DATA 0x01DDDD90
> +#define               DENALI_PHY_07_DATA 0x01DDDD90
> +#define               DENALI_PHY_08_DATA 0x01030000
> +#define               DENALI_PHY_09_DATA 0x01000000
> +#define               DENALI_PHY_10_DATA 0x00c00000
> +#define               DENALI_PHY_11_DATA 0x00000007
> +#define               DENALI_PHY_12_DATA 0x00000000
> +#define               DENALI_PHY_13_DATA 0x00000000
> +#define               DENALI_PHY_14_DATA 0x04000408
> +#define               DENALI_PHY_15_DATA 0x00000408
> +#define               DENALI_PHY_16_DATA 0x00e4e400
> +#define               DENALI_PHY_17_DATA 0x00000000
> +#define               DENALI_PHY_18_DATA 0x00000000
> +#define               DENALI_PHY_19_DATA 0x00000000
> +#define               DENALI_PHY_20_DATA 0x00000000
> +#define               DENALI_PHY_21_DATA 0x00000000
> +#define               DENALI_PHY_22_DATA 0x00000000
> +#define               DENALI_PHY_23_DATA 0x00000000
> +#define               DENALI_PHY_24_DATA 0x00000000
> +#define               DENALI_PHY_25_DATA 0x00000000
> +#define               DENALI_PHY_26_DATA 0x00000000
> +#define               DENALI_PHY_27_DATA 0x00000000
> +#define               DENALI_PHY_28_DATA 0x00000000
> +#define               DENALI_PHY_29_DATA 0x00000000
> +#define               DENALI_PHY_30_DATA 0x00000000
> +#define               DENALI_PHY_31_DATA 0x00000000
> +#define               DENALI_PHY_32_DATA 0x00000000
> +#define               DENALI_PHY_33_DATA 0x00200000
> +#define               DENALI_PHY_34_DATA 0x00000000
> +#define               DENALI_PHY_35_DATA 0x00000000
> +#define               DENALI_PHY_36_DATA 0x00000000
> +#define               DENALI_PHY_37_DATA 0x00000000
> +#define               DENALI_PHY_38_DATA 0x00000000
> +#define               DENALI_PHY_39_DATA 0x00000000
> +#define               DENALI_PHY_40_DATA 0x02800280
> +#define               DENALI_PHY_41_DATA 0x02800280
> +#define               DENALI_PHY_42_DATA 0x02800280
> +#define               DENALI_PHY_43_DATA 0x02800280
> +#define               DENALI_PHY_44_DATA 0x00000280
> +#define               DENALI_PHY_45_DATA 0x00000000
> +#define               DENALI_PHY_46_DATA 0x00000000
> +#define               DENALI_PHY_47_DATA 0x00000000
> +#define               DENALI_PHY_48_DATA 0x00000000
> +#define               DENALI_PHY_49_DATA 0x00000000
> +#define               DENALI_PHY_50_DATA 0x00800080
> +#define               DENALI_PHY_51_DATA 0x00800080
> +#define               DENALI_PHY_52_DATA 0x00800080
> +#define               DENALI_PHY_53_DATA 0x00800080
> +#define               DENALI_PHY_54_DATA 0x00800080
> +#define               DENALI_PHY_55_DATA 0x00800080
> +#define               DENALI_PHY_56_DATA 0x00800080
> +#define               DENALI_PHY_57_DATA 0x00800080
> +#define               DENALI_PHY_58_DATA 0x00800080
> +#define               DENALI_PHY_59_DATA 0x000100da
> +#define               DENALI_PHY_60_DATA 0x01000200
> +#define               DENALI_PHY_61_DATA 0x00000000
> +#define               DENALI_PHY_62_DATA 0x00000000
> +#define               DENALI_PHY_63_DATA 0x00000002
> +#define               DENALI_PHY_64_DATA 0x51313152
> +#define               DENALI_PHY_65_DATA 0x80013130
> +#define               DENALI_PHY_66_DATA 0x02000080
> +#define               DENALI_PHY_67_DATA 0x00100001
> +#define               DENALI_PHY_68_DATA 0x0c064208
> +#define               DENALI_PHY_69_DATA 0x000f0c0f
> +#define               DENALI_PHY_70_DATA 0x01000140
> +#define               DENALI_PHY_71_DATA 0x0000000c
> +#define               DENALI_PHY_72_DATA 0x00000000
> +#define               DENALI_PHY_73_DATA 0x00000000
> +#define               DENALI_PHY_74_DATA 0x00000000
> +#define               DENALI_PHY_75_DATA 0x00000000
> +#define               DENALI_PHY_76_DATA 0x00000000
> +#define               DENALI_PHY_77_DATA 0x00000000
> +#define               DENALI_PHY_78_DATA 0x00000000
> +#define               DENALI_PHY_79_DATA 0x00000000
> +#define               DENALI_PHY_80_DATA 0x00000000
> +#define               DENALI_PHY_81_DATA 0x00000000
> +#define               DENALI_PHY_82_DATA 0x00000000
> +#define               DENALI_PHY_83_DATA 0x00000000
> +#define               DENALI_PHY_84_DATA 0x00000000
> +#define               DENALI_PHY_85_DATA 0x00000000
> +#define               DENALI_PHY_86_DATA 0x00000000
> +#define               DENALI_PHY_87_DATA 0x00000000
> +#define               DENALI_PHY_88_DATA 0x00000000
> +#define               DENALI_PHY_89_DATA 0x00000000
> +#define               DENALI_PHY_90_DATA 0x00000000
> +#define               DENALI_PHY_91_DATA 0x00000000
> +#define               DENALI_PHY_92_DATA 0x00000000
> +#define               DENALI_PHY_93_DATA 0x00000000
> +#define               DENALI_PHY_94_DATA 0x00000000
> +#define               DENALI_PHY_95_DATA 0x00000000
> +#define               DENALI_PHY_96_DATA 0x00000000
> +#define               DENALI_PHY_97_DATA 0x00000000
> +#define               DENALI_PHY_98_DATA 0x00000000
> +#define               DENALI_PHY_99_DATA 0x00000000
> +#define              DENALI_PHY_100_DATA 0x00000000
> +#define              DENALI_PHY_101_DATA 0x00000000
> +#define              DENALI_PHY_102_DATA 0x00000000
> +#define              DENALI_PHY_103_DATA 0x00000000
> +#define              DENALI_PHY_104_DATA 0x00000000
> +#define              DENALI_PHY_105_DATA 0x00000000
> +#define              DENALI_PHY_106_DATA 0x00000000
> +#define              DENALI_PHY_107_DATA 0x00000000
> +#define              DENALI_PHY_108_DATA 0x00000000
> +#define              DENALI_PHY_109_DATA 0x00000000
> +#define              DENALI_PHY_110_DATA 0x00000000
> +#define              DENALI_PHY_111_DATA 0x00000000
> +#define              DENALI_PHY_112_DATA 0x00000000
> +#define              DENALI_PHY_113_DATA 0x00000000
> +#define              DENALI_PHY_114_DATA 0x00000000
> +#define              DENALI_PHY_115_DATA 0x00000000
> +#define              DENALI_PHY_116_DATA 0x00000000
> +#define              DENALI_PHY_117_DATA 0x00000000
> +#define              DENALI_PHY_118_DATA 0x00000000
> +#define              DENALI_PHY_119_DATA 0x00000000
> +#define              DENALI_PHY_120_DATA 0x00000000
> +#define              DENALI_PHY_121_DATA 0x00000000
> +#define              DENALI_PHY_122_DATA 0x00000000
> +#define              DENALI_PHY_123_DATA 0x00000000
> +#define              DENALI_PHY_124_DATA 0x00000000
> +#define              DENALI_PHY_125_DATA 0x00000000
> +#define              DENALI_PHY_126_DATA 0x00000000
> +#define              DENALI_PHY_127_DATA 0x00000000
> +#define              DENALI_PHY_128_DATA 0x40263571
> +#define              DENALI_PHY_129_DATA 0x0004c008
> +#define              DENALI_PHY_130_DATA 0x000000da
> +#define              DENALI_PHY_131_DATA 0x00000000
> +#define              DENALI_PHY_132_DATA 0x00000000
> +#define              DENALI_PHY_133_DATA 0x00010000
> +#define              DENALI_PHY_134_DATA 0x01DDDD90
> +#define              DENALI_PHY_135_DATA 0x01DDDD90
> +#define              DENALI_PHY_136_DATA 0x01030000
> +#define              DENALI_PHY_137_DATA 0x01000000
> +#define              DENALI_PHY_138_DATA 0x00c00000
> +#define              DENALI_PHY_139_DATA 0x00000007
> +#define              DENALI_PHY_140_DATA 0x00000000
> +#define              DENALI_PHY_141_DATA 0x00000000
> +#define              DENALI_PHY_142_DATA 0x04000408
> +#define              DENALI_PHY_143_DATA 0x00000408
> +#define              DENALI_PHY_144_DATA 0x00e4e400
> +#define              DENALI_PHY_145_DATA 0x00000000
> +#define              DENALI_PHY_146_DATA 0x00000000
> +#define              DENALI_PHY_147_DATA 0x00000000
> +#define              DENALI_PHY_148_DATA 0x00000000
> +#define              DENALI_PHY_149_DATA 0x00000000
> +#define              DENALI_PHY_150_DATA 0x00000000
> +#define              DENALI_PHY_151_DATA 0x00000000
> +#define              DENALI_PHY_152_DATA 0x00000000
> +#define              DENALI_PHY_153_DATA 0x00000000
> +#define              DENALI_PHY_154_DATA 0x00000000
> +#define              DENALI_PHY_155_DATA 0x00000000
> +#define              DENALI_PHY_156_DATA 0x00000000
> +#define              DENALI_PHY_157_DATA 0x00000000
> +#define              DENALI_PHY_158_DATA 0x00000000
> +#define              DENALI_PHY_159_DATA 0x00000000
> +#define              DENALI_PHY_160_DATA 0x00000000
> +#define              DENALI_PHY_161_DATA 0x00200000
> +#define              DENALI_PHY_162_DATA 0x00000000
> +#define              DENALI_PHY_163_DATA 0x00000000
> +#define              DENALI_PHY_164_DATA 0x00000000
> +#define              DENALI_PHY_165_DATA 0x00000000
> +#define              DENALI_PHY_166_DATA 0x00000000
> +#define              DENALI_PHY_167_DATA 0x00000000
> +#define              DENALI_PHY_168_DATA 0x02800280
> +#define              DENALI_PHY_169_DATA 0x02800280
> +#define              DENALI_PHY_170_DATA 0x02800280
> +#define              DENALI_PHY_171_DATA 0x02800280
> +#define              DENALI_PHY_172_DATA 0x00000280
> +#define              DENALI_PHY_173_DATA 0x00000000
> +#define              DENALI_PHY_174_DATA 0x00000000
> +#define              DENALI_PHY_175_DATA 0x00000000
> +#define              DENALI_PHY_176_DATA 0x00000000
> +#define              DENALI_PHY_177_DATA 0x00000000
> +#define              DENALI_PHY_178_DATA 0x00800080
> +#define              DENALI_PHY_179_DATA 0x00800080
> +#define              DENALI_PHY_180_DATA 0x00800080
> +#define              DENALI_PHY_181_DATA 0x00800080
> +#define              DENALI_PHY_182_DATA 0x00800080
> +#define              DENALI_PHY_183_DATA 0x00800080
> +#define              DENALI_PHY_184_DATA 0x00800080
> +#define              DENALI_PHY_185_DATA 0x00800080
> +#define              DENALI_PHY_186_DATA 0x00800080
> +#define              DENALI_PHY_187_DATA 0x000100da
> +#define              DENALI_PHY_188_DATA 0x01000200
> +#define              DENALI_PHY_189_DATA 0x00000000
> +#define              DENALI_PHY_190_DATA 0x00000000
> +#define              DENALI_PHY_191_DATA 0x00000002
> +#define              DENALI_PHY_192_DATA 0x51313152
> +#define              DENALI_PHY_193_DATA 0x80013130
> +#define              DENALI_PHY_194_DATA 0x02000080
> +#define              DENALI_PHY_195_DATA 0x00100001
> +#define              DENALI_PHY_196_DATA 0x0c064208
> +#define              DENALI_PHY_197_DATA 0x000f0c0f
> +#define              DENALI_PHY_198_DATA 0x01000140
> +#define              DENALI_PHY_199_DATA 0x0000000c
> +#define              DENALI_PHY_200_DATA 0x00000000
> +#define              DENALI_PHY_201_DATA 0x00000000
> +#define              DENALI_PHY_202_DATA 0x00000000
> +#define              DENALI_PHY_203_DATA 0x00000000
> +#define              DENALI_PHY_204_DATA 0x00000000
> +#define              DENALI_PHY_205_DATA 0x00000000
> +#define              DENALI_PHY_206_DATA 0x00000000
> +#define              DENALI_PHY_207_DATA 0x00000000
> +#define              DENALI_PHY_208_DATA 0x00000000
> +#define              DENALI_PHY_209_DATA 0x00000000
> +#define              DENALI_PHY_210_DATA 0x00000000
> +#define              DENALI_PHY_211_DATA 0x00000000
> +#define              DENALI_PHY_212_DATA 0x00000000
> +#define              DENALI_PHY_213_DATA 0x00000000
> +#define              DENALI_PHY_214_DATA 0x00000000
> +#define              DENALI_PHY_215_DATA 0x00000000
> +#define              DENALI_PHY_216_DATA 0x00000000
> +#define              DENALI_PHY_217_DATA 0x00000000
> +#define              DENALI_PHY_218_DATA 0x00000000
> +#define              DENALI_PHY_219_DATA 0x00000000
> +#define              DENALI_PHY_220_DATA 0x00000000
> +#define              DENALI_PHY_221_DATA 0x00000000
> +#define              DENALI_PHY_222_DATA 0x00000000
> +#define              DENALI_PHY_223_DATA 0x00000000
> +#define              DENALI_PHY_224_DATA 0x00000000
> +#define              DENALI_PHY_225_DATA 0x00000000
> +#define              DENALI_PHY_226_DATA 0x00000000
> +#define              DENALI_PHY_227_DATA 0x00000000
> +#define              DENALI_PHY_228_DATA 0x00000000
> +#define              DENALI_PHY_229_DATA 0x00000000
> +#define              DENALI_PHY_230_DATA 0x00000000
> +#define              DENALI_PHY_231_DATA 0x00000000
> +#define              DENALI_PHY_232_DATA 0x00000000
> +#define              DENALI_PHY_233_DATA 0x00000000
> +#define              DENALI_PHY_234_DATA 0x00000000
> +#define              DENALI_PHY_235_DATA 0x00000000
> +#define              DENALI_PHY_236_DATA 0x00000000
> +#define              DENALI_PHY_237_DATA 0x00000000
> +#define              DENALI_PHY_238_DATA 0x00000000
> +#define              DENALI_PHY_239_DATA 0x00000000
> +#define              DENALI_PHY_240_DATA 0x00000000
> +#define              DENALI_PHY_241_DATA 0x00000000
> +#define              DENALI_PHY_242_DATA 0x00000000
> +#define              DENALI_PHY_243_DATA 0x00000000
> +#define              DENALI_PHY_244_DATA 0x00000000
> +#define              DENALI_PHY_245_DATA 0x00000000
> +#define              DENALI_PHY_246_DATA 0x00000000
> +#define              DENALI_PHY_247_DATA 0x00000000
> +#define              DENALI_PHY_248_DATA 0x00000000
> +#define              DENALI_PHY_249_DATA 0x00000000
> +#define              DENALI_PHY_250_DATA 0x00000000
> +#define              DENALI_PHY_251_DATA 0x00000000
> +#define              DENALI_PHY_252_DATA 0x00000000
> +#define              DENALI_PHY_253_DATA 0x00000000
> +#define              DENALI_PHY_254_DATA 0x00000000
> +#define              DENALI_PHY_255_DATA 0x00000000
> +#define              DENALI_PHY_256_DATA 0x46052371
> +#define              DENALI_PHY_257_DATA 0x0004c008
> +#define              DENALI_PHY_258_DATA 0x000000da
> +#define              DENALI_PHY_259_DATA 0x00000000
> +#define              DENALI_PHY_260_DATA 0x00000000
> +#define              DENALI_PHY_261_DATA 0x00010000
> +#define              DENALI_PHY_262_DATA 0x01DDDD90
> +#define              DENALI_PHY_263_DATA 0x01DDDD90
> +#define              DENALI_PHY_264_DATA 0x01030000
> +#define              DENALI_PHY_265_DATA 0x01000000
> +#define              DENALI_PHY_266_DATA 0x00c00000
> +#define              DENALI_PHY_267_DATA 0x00000007
> +#define              DENALI_PHY_268_DATA 0x00000000
> +#define              DENALI_PHY_269_DATA 0x00000000
> +#define              DENALI_PHY_270_DATA 0x04000408
> +#define              DENALI_PHY_271_DATA 0x00000408
> +#define              DENALI_PHY_272_DATA 0x00e4e400
> +#define              DENALI_PHY_273_DATA 0x00000000
> +#define              DENALI_PHY_274_DATA 0x00000000
> +#define              DENALI_PHY_275_DATA 0x00000000
> +#define              DENALI_PHY_276_DATA 0x00000000
> +#define              DENALI_PHY_277_DATA 0x00000000
> +#define              DENALI_PHY_278_DATA 0x00000000
> +#define              DENALI_PHY_279_DATA 0x00000000
> +#define              DENALI_PHY_280_DATA 0x00000000
> +#define              DENALI_PHY_281_DATA 0x00000000
> +#define              DENALI_PHY_282_DATA 0x00000000
> +#define              DENALI_PHY_283_DATA 0x00000000
> +#define              DENALI_PHY_284_DATA 0x00000000
> +#define              DENALI_PHY_285_DATA 0x00000000
> +#define              DENALI_PHY_286_DATA 0x00000000
> +#define              DENALI_PHY_287_DATA 0x00000000
> +#define              DENALI_PHY_288_DATA 0x00000000
> +#define              DENALI_PHY_289_DATA 0x00200000
> +#define              DENALI_PHY_290_DATA 0x00000000
> +#define              DENALI_PHY_291_DATA 0x00000000
> +#define              DENALI_PHY_292_DATA 0x00000000
> +#define              DENALI_PHY_293_DATA 0x00000000
> +#define              DENALI_PHY_294_DATA 0x00000000
> +#define              DENALI_PHY_295_DATA 0x00000000
> +#define              DENALI_PHY_296_DATA 0x02800280
> +#define              DENALI_PHY_297_DATA 0x02800280
> +#define              DENALI_PHY_298_DATA 0x02800280
> +#define              DENALI_PHY_299_DATA 0x02800280
> +#define              DENALI_PHY_300_DATA 0x00000280
> +#define              DENALI_PHY_301_DATA 0x00000000
> +#define              DENALI_PHY_302_DATA 0x00000000
> +#define              DENALI_PHY_303_DATA 0x00000000
> +#define              DENALI_PHY_304_DATA 0x00000000
> +#define              DENALI_PHY_305_DATA 0x00000000
> +#define              DENALI_PHY_306_DATA 0x00800080
> +#define              DENALI_PHY_307_DATA 0x00800080
> +#define              DENALI_PHY_308_DATA 0x00800080
> +#define              DENALI_PHY_309_DATA 0x00800080
> +#define              DENALI_PHY_310_DATA 0x00800080
> +#define              DENALI_PHY_311_DATA 0x00800080
> +#define              DENALI_PHY_312_DATA 0x00800080
> +#define              DENALI_PHY_313_DATA 0x00800080
> +#define              DENALI_PHY_314_DATA 0x00800080
> +#define              DENALI_PHY_315_DATA 0x000100da
> +#define              DENALI_PHY_316_DATA 0x00000200
> +#define              DENALI_PHY_317_DATA 0x00000000
> +#define              DENALI_PHY_318_DATA 0x00000000
> +#define              DENALI_PHY_319_DATA 0x00000002
> +#define              DENALI_PHY_320_DATA 0x51313152
> +#define              DENALI_PHY_321_DATA 0x80013130
> +#define              DENALI_PHY_322_DATA 0x02000080
> +#define              DENALI_PHY_323_DATA 0x00100001
> +#define              DENALI_PHY_324_DATA 0x0c064208
> +#define              DENALI_PHY_325_DATA 0x000f0c0f
> +#define              DENALI_PHY_326_DATA 0x01000140
> +#define              DENALI_PHY_327_DATA 0x0000000c
> +#define              DENALI_PHY_328_DATA 0x00000000
> +#define              DENALI_PHY_329_DATA 0x00000000
> +#define              DENALI_PHY_330_DATA 0x00000000
> +#define              DENALI_PHY_331_DATA 0x00000000
> +#define              DENALI_PHY_332_DATA 0x00000000
> +#define              DENALI_PHY_333_DATA 0x00000000
> +#define              DENALI_PHY_334_DATA 0x00000000
> +#define              DENALI_PHY_335_DATA 0x00000000
> +#define              DENALI_PHY_336_DATA 0x00000000
> +#define              DENALI_PHY_337_DATA 0x00000000
> +#define              DENALI_PHY_338_DATA 0x00000000
> +#define              DENALI_PHY_339_DATA 0x00000000
> +#define              DENALI_PHY_340_DATA 0x00000000
> +#define              DENALI_PHY_341_DATA 0x00000000
> +#define              DENALI_PHY_342_DATA 0x00000000
> +#define              DENALI_PHY_343_DATA 0x00000000
> +#define              DENALI_PHY_344_DATA 0x00000000
> +#define              DENALI_PHY_345_DATA 0x00000000
> +#define              DENALI_PHY_346_DATA 0x00000000
> +#define              DENALI_PHY_347_DATA 0x00000000
> +#define              DENALI_PHY_348_DATA 0x00000000
> +#define              DENALI_PHY_349_DATA 0x00000000
> +#define              DENALI_PHY_350_DATA 0x00000000
> +#define              DENALI_PHY_351_DATA 0x00000000
> +#define              DENALI_PHY_352_DATA 0x00000000
> +#define              DENALI_PHY_353_DATA 0x00000000
> +#define              DENALI_PHY_354_DATA 0x00000000
> +#define              DENALI_PHY_355_DATA 0x00000000
> +#define              DENALI_PHY_356_DATA 0x00000000
> +#define              DENALI_PHY_357_DATA 0x00000000
> +#define              DENALI_PHY_358_DATA 0x00000000
> +#define              DENALI_PHY_359_DATA 0x00000000
> +#define              DENALI_PHY_360_DATA 0x00000000
> +#define              DENALI_PHY_361_DATA 0x00000000
> +#define              DENALI_PHY_362_DATA 0x00000000
> +#define              DENALI_PHY_363_DATA 0x00000000
> +#define              DENALI_PHY_364_DATA 0x00000000
> +#define              DENALI_PHY_365_DATA 0x00000000
> +#define              DENALI_PHY_366_DATA 0x00000000
> +#define              DENALI_PHY_367_DATA 0x00000000
> +#define              DENALI_PHY_368_DATA 0x00000000
> +#define              DENALI_PHY_369_DATA 0x00000000
> +#define              DENALI_PHY_370_DATA 0x00000000
> +#define              DENALI_PHY_371_DATA 0x00000000
> +#define              DENALI_PHY_372_DATA 0x00000000
> +#define              DENALI_PHY_373_DATA 0x00000000
> +#define              DENALI_PHY_374_DATA 0x00000000
> +#define              DENALI_PHY_375_DATA 0x00000000
> +#define              DENALI_PHY_376_DATA 0x00000000
> +#define              DENALI_PHY_377_DATA 0x00000000
> +#define              DENALI_PHY_378_DATA 0x00000000
> +#define              DENALI_PHY_379_DATA 0x00000000
> +#define              DENALI_PHY_380_DATA 0x00000000
> +#define              DENALI_PHY_381_DATA 0x00000000
> +#define              DENALI_PHY_382_DATA 0x00000000
> +#define              DENALI_PHY_383_DATA 0x00000000
> +#define              DENALI_PHY_384_DATA 0x37654120
> +#define              DENALI_PHY_385_DATA 0x0004c008
> +#define              DENALI_PHY_386_DATA 0x000000da
> +#define              DENALI_PHY_387_DATA 0x00000000
> +#define              DENALI_PHY_388_DATA 0x00000000
> +#define              DENALI_PHY_389_DATA 0x00010000
> +#define              DENALI_PHY_390_DATA 0x01DDDD90
> +#define              DENALI_PHY_391_DATA 0x01DDDD90
> +#define              DENALI_PHY_392_DATA 0x01030000
> +#define              DENALI_PHY_393_DATA 0x01000000
> +#define              DENALI_PHY_394_DATA 0x00c00000
> +#define              DENALI_PHY_395_DATA 0x00000007
> +#define              DENALI_PHY_396_DATA 0x00000000
> +#define              DENALI_PHY_397_DATA 0x00000000
> +#define              DENALI_PHY_398_DATA 0x04000408
> +#define              DENALI_PHY_399_DATA 0x00000408
> +#define              DENALI_PHY_400_DATA 0x00e4e400
> +#define              DENALI_PHY_401_DATA 0x00000000
> +#define              DENALI_PHY_402_DATA 0x00000000
> +#define              DENALI_PHY_403_DATA 0x00000000
> +#define              DENALI_PHY_404_DATA 0x00000000
> +#define              DENALI_PHY_405_DATA 0x00000000
> +#define              DENALI_PHY_406_DATA 0x00000000
> +#define              DENALI_PHY_407_DATA 0x00000000
> +#define              DENALI_PHY_408_DATA 0x00000000
> +#define              DENALI_PHY_409_DATA 0x00000000
> +#define              DENALI_PHY_410_DATA 0x00000000
> +#define              DENALI_PHY_411_DATA 0x00000000
> +#define              DENALI_PHY_412_DATA 0x00000000
> +#define              DENALI_PHY_413_DATA 0x00000000
> +#define              DENALI_PHY_414_DATA 0x00000000
> +#define              DENALI_PHY_415_DATA 0x00000000
> +#define              DENALI_PHY_416_DATA 0x00000000
> +#define              DENALI_PHY_417_DATA 0x00200000
> +#define              DENALI_PHY_418_DATA 0x00000000
> +#define              DENALI_PHY_419_DATA 0x00000000
> +#define              DENALI_PHY_420_DATA 0x00000000
> +#define              DENALI_PHY_421_DATA 0x00000000
> +#define              DENALI_PHY_422_DATA 0x00000000
> +#define              DENALI_PHY_423_DATA 0x00000000
> +#define              DENALI_PHY_424_DATA 0x02800280
> +#define              DENALI_PHY_425_DATA 0x02800280
> +#define              DENALI_PHY_426_DATA 0x02800280
> +#define              DENALI_PHY_427_DATA 0x02800280
> +#define              DENALI_PHY_428_DATA 0x00000280
> +#define              DENALI_PHY_429_DATA 0x00000000
> +#define              DENALI_PHY_430_DATA 0x00000000
> +#define              DENALI_PHY_431_DATA 0x00000000
> +#define              DENALI_PHY_432_DATA 0x00000000
> +#define              DENALI_PHY_433_DATA 0x00000000
> +#define              DENALI_PHY_434_DATA 0x00800080
> +#define              DENALI_PHY_435_DATA 0x00800080
> +#define              DENALI_PHY_436_DATA 0x00800080
> +#define              DENALI_PHY_437_DATA 0x00800080
> +#define              DENALI_PHY_438_DATA 0x00800080
> +#define              DENALI_PHY_439_DATA 0x00800080
> +#define              DENALI_PHY_440_DATA 0x00800080
> +#define              DENALI_PHY_441_DATA 0x00800080
> +#define              DENALI_PHY_442_DATA 0x00800080
> +#define              DENALI_PHY_443_DATA 0x000100da
> +#define              DENALI_PHY_444_DATA 0x00000200
> +#define              DENALI_PHY_445_DATA 0x00000000
> +#define              DENALI_PHY_446_DATA 0x00000000
> +#define              DENALI_PHY_447_DATA 0x00000002
> +#define              DENALI_PHY_448_DATA 0x51313152
> +#define              DENALI_PHY_449_DATA 0x80013130
> +#define              DENALI_PHY_450_DATA 0x02000080
> +#define              DENALI_PHY_451_DATA 0x00100001
> +#define              DENALI_PHY_452_DATA 0x0c064208
> +#define              DENALI_PHY_453_DATA 0x000f0c0f
> +#define              DENALI_PHY_454_DATA 0x01000140
> +#define              DENALI_PHY_455_DATA 0x0000000c
> +#define              DENALI_PHY_456_DATA 0x00000000
> +#define              DENALI_PHY_457_DATA 0x00000000
> +#define              DENALI_PHY_458_DATA 0x00000000
> +#define              DENALI_PHY_459_DATA 0x00000000
> +#define              DENALI_PHY_460_DATA 0x00000000
> +#define              DENALI_PHY_461_DATA 0x00000000
> +#define              DENALI_PHY_462_DATA 0x00000000
> +#define              DENALI_PHY_463_DATA 0x00000000
> +#define              DENALI_PHY_464_DATA 0x00000000
> +#define              DENALI_PHY_465_DATA 0x00000000
> +#define              DENALI_PHY_466_DATA 0x00000000
> +#define              DENALI_PHY_467_DATA 0x00000000
> +#define              DENALI_PHY_468_DATA 0x00000000
> +#define              DENALI_PHY_469_DATA 0x00000000
> +#define              DENALI_PHY_470_DATA 0x00000000
> +#define              DENALI_PHY_471_DATA 0x00000000
> +#define              DENALI_PHY_472_DATA 0x00000000
> +#define              DENALI_PHY_473_DATA 0x00000000
> +#define              DENALI_PHY_474_DATA 0x00000000
> +#define              DENALI_PHY_475_DATA 0x00000000
> +#define              DENALI_PHY_476_DATA 0x00000000
> +#define              DENALI_PHY_477_DATA 0x00000000
> +#define              DENALI_PHY_478_DATA 0x00000000
> +#define              DENALI_PHY_479_DATA 0x00000000
> +#define              DENALI_PHY_480_DATA 0x00000000
> +#define              DENALI_PHY_481_DATA 0x00000000
> +#define              DENALI_PHY_482_DATA 0x00000000
> +#define              DENALI_PHY_483_DATA 0x00000000
> +#define              DENALI_PHY_484_DATA 0x00000000
> +#define              DENALI_PHY_485_DATA 0x00000000
> +#define              DENALI_PHY_486_DATA 0x00000000
> +#define              DENALI_PHY_487_DATA 0x00000000
> +#define              DENALI_PHY_488_DATA 0x00000000
> +#define              DENALI_PHY_489_DATA 0x00000000
> +#define              DENALI_PHY_490_DATA 0x00000000
> +#define              DENALI_PHY_491_DATA 0x00000000
> +#define              DENALI_PHY_492_DATA 0x00000000
> +#define              DENALI_PHY_493_DATA 0x00000000
> +#define              DENALI_PHY_494_DATA 0x00000000
> +#define              DENALI_PHY_495_DATA 0x00000000
> +#define              DENALI_PHY_496_DATA 0x00000000
> +#define              DENALI_PHY_497_DATA 0x00000000
> +#define              DENALI_PHY_498_DATA 0x00000000
> +#define              DENALI_PHY_499_DATA 0x00000000
> +#define              DENALI_PHY_500_DATA 0x00000000
> +#define              DENALI_PHY_501_DATA 0x00000000
> +#define              DENALI_PHY_502_DATA 0x00000000
> +#define              DENALI_PHY_503_DATA 0x00000000
> +#define              DENALI_PHY_504_DATA 0x00000000
> +#define              DENALI_PHY_505_DATA 0x00000000
> +#define              DENALI_PHY_506_DATA 0x00000000
> +#define              DENALI_PHY_507_DATA 0x00000000
> +#define              DENALI_PHY_508_DATA 0x00000000
> +#define              DENALI_PHY_509_DATA 0x00000000
> +#define              DENALI_PHY_510_DATA 0x00000000
> +#define              DENALI_PHY_511_DATA 0x00000000
> +#define              DENALI_PHY_512_DATA 0x24316750
> +#define              DENALI_PHY_513_DATA 0x0004c008
> +#define              DENALI_PHY_514_DATA 0x000000da
> +#define              DENALI_PHY_515_DATA 0x00000000
> +#define              DENALI_PHY_516_DATA 0x00000000
> +#define              DENALI_PHY_517_DATA 0x00010000
> +#define              DENALI_PHY_518_DATA 0x01DDDD90
> +#define              DENALI_PHY_519_DATA 0x01DDDD90
> +#define              DENALI_PHY_520_DATA 0x01030000
> +#define              DENALI_PHY_521_DATA 0x01000000
> +#define              DENALI_PHY_522_DATA 0x00c00000
> +#define              DENALI_PHY_523_DATA 0x00000007
> +#define              DENALI_PHY_524_DATA 0x00000000
> +#define              DENALI_PHY_525_DATA 0x00000000
> +#define              DENALI_PHY_526_DATA 0x04000408
> +#define              DENALI_PHY_527_DATA 0x00000408
> +#define              DENALI_PHY_528_DATA 0x00e4e400
> +#define              DENALI_PHY_529_DATA 0x00000000
> +#define              DENALI_PHY_530_DATA 0x00000000
> +#define              DENALI_PHY_531_DATA 0x00000000
> +#define              DENALI_PHY_532_DATA 0x00000000
> +#define              DENALI_PHY_533_DATA 0x00000000
> +#define              DENALI_PHY_534_DATA 0x00000000
> +#define              DENALI_PHY_535_DATA 0x00000000
> +#define              DENALI_PHY_536_DATA 0x00000000
> +#define              DENALI_PHY_537_DATA 0x00000000
> +#define              DENALI_PHY_538_DATA 0x00000000
> +#define              DENALI_PHY_539_DATA 0x00000000
> +#define              DENALI_PHY_540_DATA 0x00000000
> +#define              DENALI_PHY_541_DATA 0x00000000
> +#define              DENALI_PHY_542_DATA 0x00000000
> +#define              DENALI_PHY_543_DATA 0x00000000
> +#define              DENALI_PHY_544_DATA 0x00000000
> +#define              DENALI_PHY_545_DATA 0x00200000
> +#define              DENALI_PHY_546_DATA 0x00000000
> +#define              DENALI_PHY_547_DATA 0x00000000
> +#define              DENALI_PHY_548_DATA 0x00000000
> +#define              DENALI_PHY_549_DATA 0x00000000
> +#define              DENALI_PHY_550_DATA 0x00000000
> +#define              DENALI_PHY_551_DATA 0x00000000
> +#define              DENALI_PHY_552_DATA 0x02800280
> +#define              DENALI_PHY_553_DATA 0x02800280
> +#define              DENALI_PHY_554_DATA 0x02800280
> +#define              DENALI_PHY_555_DATA 0x02800280
> +#define              DENALI_PHY_556_DATA 0x00000280
> +#define              DENALI_PHY_557_DATA 0x00000000
> +#define              DENALI_PHY_558_DATA 0x00000000
> +#define              DENALI_PHY_559_DATA 0x00000000
> +#define              DENALI_PHY_560_DATA 0x00000000
> +#define              DENALI_PHY_561_DATA 0x00000000
> +#define              DENALI_PHY_562_DATA 0x00800080
> +#define              DENALI_PHY_563_DATA 0x00800080
> +#define              DENALI_PHY_564_DATA 0x00800080
> +#define              DENALI_PHY_565_DATA 0x00800080
> +#define              DENALI_PHY_566_DATA 0x00800080
> +#define              DENALI_PHY_567_DATA 0x00800080
> +#define              DENALI_PHY_568_DATA 0x00800080
> +#define              DENALI_PHY_569_DATA 0x00800080
> +#define              DENALI_PHY_570_DATA 0x00800080
> +#define              DENALI_PHY_571_DATA 0x000100da
> +#define              DENALI_PHY_572_DATA 0x00000200
> +#define              DENALI_PHY_573_DATA 0x00000000
> +#define              DENALI_PHY_574_DATA 0x00000000
> +#define              DENALI_PHY_575_DATA 0x00000002
> +#define              DENALI_PHY_576_DATA 0x51313152
> +#define              DENALI_PHY_577_DATA 0x80013130
> +#define              DENALI_PHY_578_DATA 0x02000080
> +#define              DENALI_PHY_579_DATA 0x00100001
> +#define              DENALI_PHY_580_DATA 0x0c064208
> +#define              DENALI_PHY_581_DATA 0x000f0c0f
> +#define              DENALI_PHY_582_DATA 0x01000140
> +#define              DENALI_PHY_583_DATA 0x0000000c
> +#define              DENALI_PHY_584_DATA 0x00000000
> +#define              DENALI_PHY_585_DATA 0x00000000
> +#define              DENALI_PHY_586_DATA 0x00000000
> +#define              DENALI_PHY_587_DATA 0x00000000
> +#define              DENALI_PHY_588_DATA 0x00000000
> +#define              DENALI_PHY_589_DATA 0x00000000
> +#define              DENALI_PHY_590_DATA 0x00000000
> +#define              DENALI_PHY_591_DATA 0x00000000
> +#define              DENALI_PHY_592_DATA 0x00000000
> +#define              DENALI_PHY_593_DATA 0x00000000
> +#define              DENALI_PHY_594_DATA 0x00000000
> +#define              DENALI_PHY_595_DATA 0x00000000
> +#define              DENALI_PHY_596_DATA 0x00000000
> +#define              DENALI_PHY_597_DATA 0x00000000
> +#define              DENALI_PHY_598_DATA 0x00000000
> +#define              DENALI_PHY_599_DATA 0x00000000
> +#define              DENALI_PHY_600_DATA 0x00000000
> +#define              DENALI_PHY_601_DATA 0x00000000
> +#define              DENALI_PHY_602_DATA 0x00000000
> +#define              DENALI_PHY_603_DATA 0x00000000
> +#define              DENALI_PHY_604_DATA 0x00000000
> +#define              DENALI_PHY_605_DATA 0x00000000
> +#define              DENALI_PHY_606_DATA 0x00000000
> +#define              DENALI_PHY_607_DATA 0x00000000
> +#define              DENALI_PHY_608_DATA 0x00000000
> +#define              DENALI_PHY_609_DATA 0x00000000
> +#define              DENALI_PHY_610_DATA 0x00000000
> +#define              DENALI_PHY_611_DATA 0x00000000
> +#define              DENALI_PHY_612_DATA 0x00000000
> +#define              DENALI_PHY_613_DATA 0x00000000
> +#define              DENALI_PHY_614_DATA 0x00000000
> +#define              DENALI_PHY_615_DATA 0x00000000
> +#define              DENALI_PHY_616_DATA 0x00000000
> +#define              DENALI_PHY_617_DATA 0x00000000
> +#define              DENALI_PHY_618_DATA 0x00000000
> +#define              DENALI_PHY_619_DATA 0x00000000
> +#define              DENALI_PHY_620_DATA 0x00000000
> +#define              DENALI_PHY_621_DATA 0x00000000
> +#define              DENALI_PHY_622_DATA 0x00000000
> +#define              DENALI_PHY_623_DATA 0x00000000
> +#define              DENALI_PHY_624_DATA 0x00000000
> +#define              DENALI_PHY_625_DATA 0x00000000
> +#define              DENALI_PHY_626_DATA 0x00000000
> +#define              DENALI_PHY_627_DATA 0x00000000
> +#define              DENALI_PHY_628_DATA 0x00000000
> +#define              DENALI_PHY_629_DATA 0x00000000
> +#define              DENALI_PHY_630_DATA 0x00000000
> +#define              DENALI_PHY_631_DATA 0x00000000
> +#define              DENALI_PHY_632_DATA 0x00000000
> +#define              DENALI_PHY_633_DATA 0x00000000
> +#define              DENALI_PHY_634_DATA 0x00000000
> +#define              DENALI_PHY_635_DATA 0x00000000
> +#define              DENALI_PHY_636_DATA 0x00000000
> +#define              DENALI_PHY_637_DATA 0x00000000
> +#define              DENALI_PHY_638_DATA 0x00000000
> +#define              DENALI_PHY_639_DATA 0x00000000
> +#define              DENALI_PHY_640_DATA 0x35174620
> +#define              DENALI_PHY_641_DATA 0x0004c008
> +#define              DENALI_PHY_642_DATA 0x000000da
> +#define              DENALI_PHY_643_DATA 0x00000000
> +#define              DENALI_PHY_644_DATA 0x00000000
> +#define              DENALI_PHY_645_DATA 0x00010000
> +#define              DENALI_PHY_646_DATA 0x01DDDD90
> +#define              DENALI_PHY_647_DATA 0x01DDDD90
> +#define              DENALI_PHY_648_DATA 0x01030000
> +#define              DENALI_PHY_649_DATA 0x01000000
> +#define              DENALI_PHY_650_DATA 0x00c00000
> +#define              DENALI_PHY_651_DATA 0x00000007
> +#define              DENALI_PHY_652_DATA 0x00000000
> +#define              DENALI_PHY_653_DATA 0x00000000
> +#define              DENALI_PHY_654_DATA 0x04000408
> +#define              DENALI_PHY_655_DATA 0x00000408
> +#define              DENALI_PHY_656_DATA 0x00e4e400
> +#define              DENALI_PHY_657_DATA 0x00000000
> +#define              DENALI_PHY_658_DATA 0x00000000
> +#define              DENALI_PHY_659_DATA 0x00000000
> +#define              DENALI_PHY_660_DATA 0x00000000
> +#define              DENALI_PHY_661_DATA 0x00000000
> +#define              DENALI_PHY_662_DATA 0x00000000
> +#define              DENALI_PHY_663_DATA 0x00000000
> +#define              DENALI_PHY_664_DATA 0x00000000
> +#define              DENALI_PHY_665_DATA 0x00000000
> +#define              DENALI_PHY_666_DATA 0x00000000
> +#define              DENALI_PHY_667_DATA 0x00000000
> +#define              DENALI_PHY_668_DATA 0x00000000
> +#define              DENALI_PHY_669_DATA 0x00000000
> +#define              DENALI_PHY_670_DATA 0x00000000
> +#define              DENALI_PHY_671_DATA 0x00000000
> +#define              DENALI_PHY_672_DATA 0x00000000
> +#define              DENALI_PHY_673_DATA 0x00200000
> +#define              DENALI_PHY_674_DATA 0x00000000
> +#define              DENALI_PHY_675_DATA 0x00000000
> +#define              DENALI_PHY_676_DATA 0x00000000
> +#define              DENALI_PHY_677_DATA 0x00000000
> +#define              DENALI_PHY_678_DATA 0x00000000
> +#define              DENALI_PHY_679_DATA 0x00000000
> +#define              DENALI_PHY_680_DATA 0x02800280
> +#define              DENALI_PHY_681_DATA 0x02800280
> +#define              DENALI_PHY_682_DATA 0x02800280
> +#define              DENALI_PHY_683_DATA 0x02800280
> +#define              DENALI_PHY_684_DATA 0x00000280
> +#define              DENALI_PHY_685_DATA 0x00000000
> +#define              DENALI_PHY_686_DATA 0x00000000
> +#define              DENALI_PHY_687_DATA 0x00000000
> +#define              DENALI_PHY_688_DATA 0x00000000
> +#define              DENALI_PHY_689_DATA 0x00000000
> +#define              DENALI_PHY_690_DATA 0x00800080
> +#define              DENALI_PHY_691_DATA 0x00800080
> +#define              DENALI_PHY_692_DATA 0x00800080
> +#define              DENALI_PHY_693_DATA 0x00800080
> +#define              DENALI_PHY_694_DATA 0x00800080
> +#define              DENALI_PHY_695_DATA 0x00800080
> +#define              DENALI_PHY_696_DATA 0x00800080
> +#define              DENALI_PHY_697_DATA 0x00800080
> +#define              DENALI_PHY_698_DATA 0x00800080
> +#define              DENALI_PHY_699_DATA 0x000100da
> +#define              DENALI_PHY_700_DATA 0x00000200
> +#define              DENALI_PHY_701_DATA 0x00000000
> +#define              DENALI_PHY_702_DATA 0x00000000
> +#define              DENALI_PHY_703_DATA 0x00000002
> +#define              DENALI_PHY_704_DATA 0x51313152
> +#define              DENALI_PHY_705_DATA 0x80013130
> +#define              DENALI_PHY_706_DATA 0x02000080
> +#define              DENALI_PHY_707_DATA 0x00100001
> +#define              DENALI_PHY_708_DATA 0x0c064208
> +#define              DENALI_PHY_709_DATA 0x000f0c0f
> +#define              DENALI_PHY_710_DATA 0x01000140
> +#define              DENALI_PHY_711_DATA 0x0000000c
> +#define              DENALI_PHY_712_DATA 0x00000000
> +#define              DENALI_PHY_713_DATA 0x00000000
> +#define              DENALI_PHY_714_DATA 0x00000000
> +#define              DENALI_PHY_715_DATA 0x00000000
> +#define              DENALI_PHY_716_DATA 0x00000000
> +#define              DENALI_PHY_717_DATA 0x00000000
> +#define              DENALI_PHY_718_DATA 0x00000000
> +#define              DENALI_PHY_719_DATA 0x00000000
> +#define              DENALI_PHY_720_DATA 0x00000000
> +#define              DENALI_PHY_721_DATA 0x00000000
> +#define              DENALI_PHY_722_DATA 0x00000000
> +#define              DENALI_PHY_723_DATA 0x00000000
> +#define              DENALI_PHY_724_DATA 0x00000000
> +#define              DENALI_PHY_725_DATA 0x00000000
> +#define              DENALI_PHY_726_DATA 0x00000000
> +#define              DENALI_PHY_727_DATA 0x00000000
> +#define              DENALI_PHY_728_DATA 0x00000000
> +#define              DENALI_PHY_729_DATA 0x00000000
> +#define              DENALI_PHY_730_DATA 0x00000000
> +#define              DENALI_PHY_731_DATA 0x00000000
> +#define              DENALI_PHY_732_DATA 0x00000000
> +#define              DENALI_PHY_733_DATA 0x00000000
> +#define              DENALI_PHY_734_DATA 0x00000000
> +#define              DENALI_PHY_735_DATA 0x00000000
> +#define              DENALI_PHY_736_DATA 0x00000000
> +#define              DENALI_PHY_737_DATA 0x00000000
> +#define              DENALI_PHY_738_DATA 0x00000000
> +#define              DENALI_PHY_739_DATA 0x00000000
> +#define              DENALI_PHY_740_DATA 0x00000000
> +#define              DENALI_PHY_741_DATA 0x00000000
> +#define              DENALI_PHY_742_DATA 0x00000000
> +#define              DENALI_PHY_743_DATA 0x00000000
> +#define              DENALI_PHY_744_DATA 0x00000000
> +#define              DENALI_PHY_745_DATA 0x00000000
> +#define              DENALI_PHY_746_DATA 0x00000000
> +#define              DENALI_PHY_747_DATA 0x00000000
> +#define              DENALI_PHY_748_DATA 0x00000000
> +#define              DENALI_PHY_749_DATA 0x00000000
> +#define              DENALI_PHY_750_DATA 0x00000000
> +#define              DENALI_PHY_751_DATA 0x00000000
> +#define              DENALI_PHY_752_DATA 0x00000000
> +#define              DENALI_PHY_753_DATA 0x00000000
> +#define              DENALI_PHY_754_DATA 0x00000000
> +#define              DENALI_PHY_755_DATA 0x00000000
> +#define              DENALI_PHY_756_DATA 0x00000000
> +#define              DENALI_PHY_757_DATA 0x00000000
> +#define              DENALI_PHY_758_DATA 0x00000000
> +#define              DENALI_PHY_759_DATA 0x00000000
> +#define              DENALI_PHY_760_DATA 0x00000000
> +#define              DENALI_PHY_761_DATA 0x00000000
> +#define              DENALI_PHY_762_DATA 0x00000000
> +#define              DENALI_PHY_763_DATA 0x00000000
> +#define              DENALI_PHY_764_DATA 0x00000000
> +#define              DENALI_PHY_765_DATA 0x00000000
> +#define              DENALI_PHY_766_DATA 0x00000000
> +#define              DENALI_PHY_767_DATA 0x00000000
> +#define              DENALI_PHY_768_DATA 0x15203476
> +#define              DENALI_PHY_769_DATA 0x0004c008
> +#define              DENALI_PHY_770_DATA 0x000000da
> +#define              DENALI_PHY_771_DATA 0x00000000
> +#define              DENALI_PHY_772_DATA 0x00000000
> +#define              DENALI_PHY_773_DATA 0x00010000
> +#define              DENALI_PHY_774_DATA 0x01DDDD90
> +#define              DENALI_PHY_775_DATA 0x01DDDD90
> +#define              DENALI_PHY_776_DATA 0x01030000
> +#define              DENALI_PHY_777_DATA 0x01000000
> +#define              DENALI_PHY_778_DATA 0x00c00000
> +#define              DENALI_PHY_779_DATA 0x00000007
> +#define              DENALI_PHY_780_DATA 0x00000000
> +#define              DENALI_PHY_781_DATA 0x00000000
> +#define              DENALI_PHY_782_DATA 0x04000408
> +#define              DENALI_PHY_783_DATA 0x00000408
> +#define              DENALI_PHY_784_DATA 0x00e4e400
> +#define              DENALI_PHY_785_DATA 0x00000000
> +#define              DENALI_PHY_786_DATA 0x00000000
> +#define              DENALI_PHY_787_DATA 0x00000000
> +#define              DENALI_PHY_788_DATA 0x00000000
> +#define              DENALI_PHY_789_DATA 0x00000000
> +#define              DENALI_PHY_790_DATA 0x00000000
> +#define              DENALI_PHY_791_DATA 0x00000000
> +#define              DENALI_PHY_792_DATA 0x00000000
> +#define              DENALI_PHY_793_DATA 0x00000000
> +#define              DENALI_PHY_794_DATA 0x00000000
> +#define              DENALI_PHY_795_DATA 0x00000000
> +#define              DENALI_PHY_796_DATA 0x00000000
> +#define              DENALI_PHY_797_DATA 0x00000000
> +#define              DENALI_PHY_798_DATA 0x00000000
> +#define              DENALI_PHY_799_DATA 0x00000000
> +#define              DENALI_PHY_800_DATA 0x00000000
> +#define              DENALI_PHY_801_DATA 0x00200000
> +#define              DENALI_PHY_802_DATA 0x00000000
> +#define              DENALI_PHY_803_DATA 0x00000000
> +#define              DENALI_PHY_804_DATA 0x00000000
> +#define              DENALI_PHY_805_DATA 0x00000000
> +#define              DENALI_PHY_806_DATA 0x00000000
> +#define              DENALI_PHY_807_DATA 0x00000000
> +#define              DENALI_PHY_808_DATA 0x02800280
> +#define              DENALI_PHY_809_DATA 0x02800280
> +#define              DENALI_PHY_810_DATA 0x02800280
> +#define              DENALI_PHY_811_DATA 0x02800280
> +#define              DENALI_PHY_812_DATA 0x00000280
> +#define              DENALI_PHY_813_DATA 0x00000000
> +#define              DENALI_PHY_814_DATA 0x00000000
> +#define              DENALI_PHY_815_DATA 0x00000000
> +#define              DENALI_PHY_816_DATA 0x00000000
> +#define              DENALI_PHY_817_DATA 0x00000000
> +#define              DENALI_PHY_818_DATA 0x00800080
> +#define              DENALI_PHY_819_DATA 0x00800080
> +#define              DENALI_PHY_820_DATA 0x00800080
> +#define              DENALI_PHY_821_DATA 0x00800080
> +#define              DENALI_PHY_822_DATA 0x00800080
> +#define              DENALI_PHY_823_DATA 0x00800080
> +#define              DENALI_PHY_824_DATA 0x00800080
> +#define              DENALI_PHY_825_DATA 0x00800080
> +#define              DENALI_PHY_826_DATA 0x00800080
> +#define              DENALI_PHY_827_DATA 0x000100da
> +#define              DENALI_PHY_828_DATA 0x00000200
> +#define              DENALI_PHY_829_DATA 0x00000000
> +#define              DENALI_PHY_830_DATA 0x00000000
> +#define              DENALI_PHY_831_DATA 0x00000002
> +#define              DENALI_PHY_832_DATA 0x51313152
> +#define              DENALI_PHY_833_DATA 0x80013130
> +#define              DENALI_PHY_834_DATA 0x02000080
> +#define              DENALI_PHY_835_DATA 0x00100001
> +#define              DENALI_PHY_836_DATA 0x0c064208
> +#define              DENALI_PHY_837_DATA 0x000f0c0f
> +#define              DENALI_PHY_838_DATA 0x01000140
> +#define              DENALI_PHY_839_DATA 0x0000000c
> +#define              DENALI_PHY_840_DATA 0x00000000
> +#define              DENALI_PHY_841_DATA 0x00000000
> +#define              DENALI_PHY_842_DATA 0x00000000
> +#define              DENALI_PHY_843_DATA 0x00000000
> +#define              DENALI_PHY_844_DATA 0x00000000
> +#define              DENALI_PHY_845_DATA 0x00000000
> +#define              DENALI_PHY_846_DATA 0x00000000
> +#define              DENALI_PHY_847_DATA 0x00000000
> +#define              DENALI_PHY_848_DATA 0x00000000
> +#define              DENALI_PHY_849_DATA 0x00000000
> +#define              DENALI_PHY_850_DATA 0x00000000
> +#define              DENALI_PHY_851_DATA 0x00000000
> +#define              DENALI_PHY_852_DATA 0x00000000
> +#define              DENALI_PHY_853_DATA 0x00000000
> +#define              DENALI_PHY_854_DATA 0x00000000
> +#define              DENALI_PHY_855_DATA 0x00000000
> +#define              DENALI_PHY_856_DATA 0x00000000
> +#define              DENALI_PHY_857_DATA 0x00000000
> +#define              DENALI_PHY_858_DATA 0x00000000
> +#define              DENALI_PHY_859_DATA 0x00000000
> +#define              DENALI_PHY_860_DATA 0x00000000
> +#define              DENALI_PHY_861_DATA 0x00000000
> +#define              DENALI_PHY_862_DATA 0x00000000
> +#define              DENALI_PHY_863_DATA 0x00000000
> +#define              DENALI_PHY_864_DATA 0x00000000
> +#define              DENALI_PHY_865_DATA 0x00000000
> +#define              DENALI_PHY_866_DATA 0x00000000
> +#define              DENALI_PHY_867_DATA 0x00000000
> +#define              DENALI_PHY_868_DATA 0x00000000
> +#define              DENALI_PHY_869_DATA 0x00000000
> +#define              DENALI_PHY_870_DATA 0x00000000
> +#define              DENALI_PHY_871_DATA 0x00000000
> +#define              DENALI_PHY_872_DATA 0x00000000
> +#define              DENALI_PHY_873_DATA 0x00000000
> +#define              DENALI_PHY_874_DATA 0x00000000
> +#define              DENALI_PHY_875_DATA 0x00000000
> +#define              DENALI_PHY_876_DATA 0x00000000
> +#define              DENALI_PHY_877_DATA 0x00000000
> +#define              DENALI_PHY_878_DATA 0x00000000
> +#define              DENALI_PHY_879_DATA 0x00000000
> +#define              DENALI_PHY_880_DATA 0x00000000
> +#define              DENALI_PHY_881_DATA 0x00000000
> +#define              DENALI_PHY_882_DATA 0x00000000
> +#define              DENALI_PHY_883_DATA 0x00000000
> +#define              DENALI_PHY_884_DATA 0x00000000
> +#define              DENALI_PHY_885_DATA 0x00000000
> +#define              DENALI_PHY_886_DATA 0x00000000
> +#define              DENALI_PHY_887_DATA 0x00000000
> +#define              DENALI_PHY_888_DATA 0x00000000
> +#define              DENALI_PHY_889_DATA 0x00000000
> +#define              DENALI_PHY_890_DATA 0x00000000
> +#define              DENALI_PHY_891_DATA 0x00000000
> +#define              DENALI_PHY_892_DATA 0x00000000
> +#define              DENALI_PHY_893_DATA 0x00000000
> +#define              DENALI_PHY_894_DATA 0x00000000
> +#define              DENALI_PHY_895_DATA 0x00000000
> +#define              DENALI_PHY_896_DATA 0x41753206
> +#define              DENALI_PHY_897_DATA 0x0004c008
> +#define              DENALI_PHY_898_DATA 0x000000da
> +#define              DENALI_PHY_899_DATA 0x00000000
> +#define              DENALI_PHY_900_DATA 0x00000000
> +#define              DENALI_PHY_901_DATA 0x00010000
> +#define              DENALI_PHY_902_DATA 0x01DDDD90
> +#define              DENALI_PHY_903_DATA 0x01DDDD90
> +#define              DENALI_PHY_904_DATA 0x01030000
> +#define              DENALI_PHY_905_DATA 0x01000000
> +#define              DENALI_PHY_906_DATA 0x00c00000
> +#define              DENALI_PHY_907_DATA 0x00000007
> +#define              DENALI_PHY_908_DATA 0x00000000
> +#define              DENALI_PHY_909_DATA 0x00000000
> +#define              DENALI_PHY_910_DATA 0x04000408
> +#define              DENALI_PHY_911_DATA 0x00000408
> +#define              DENALI_PHY_912_DATA 0x00e4e400
> +#define              DENALI_PHY_913_DATA 0x00000000
> +#define              DENALI_PHY_914_DATA 0x00000000
> +#define              DENALI_PHY_915_DATA 0x00000000
> +#define              DENALI_PHY_916_DATA 0x00000000
> +#define              DENALI_PHY_917_DATA 0x00000000
> +#define              DENALI_PHY_918_DATA 0x00000000
> +#define              DENALI_PHY_919_DATA 0x00000000
> +#define              DENALI_PHY_920_DATA 0x00000000
> +#define              DENALI_PHY_921_DATA 0x00000000
> +#define              DENALI_PHY_922_DATA 0x00000000
> +#define              DENALI_PHY_923_DATA 0x00000000
> +#define              DENALI_PHY_924_DATA 0x00000000
> +#define              DENALI_PHY_925_DATA 0x00000000
> +#define              DENALI_PHY_926_DATA 0x00000000
> +#define              DENALI_PHY_927_DATA 0x00000000
> +#define              DENALI_PHY_928_DATA 0x00000000
> +#define              DENALI_PHY_929_DATA 0x00200000
> +#define              DENALI_PHY_930_DATA 0x00000000
> +#define              DENALI_PHY_931_DATA 0x00000000
> +#define              DENALI_PHY_932_DATA 0x00000000
> +#define              DENALI_PHY_933_DATA 0x00000000
> +#define              DENALI_PHY_934_DATA 0x00000000
> +#define              DENALI_PHY_935_DATA 0x00000000
> +#define              DENALI_PHY_936_DATA 0x02800280
> +#define              DENALI_PHY_937_DATA 0x02800280
> +#define              DENALI_PHY_938_DATA 0x02800280
> +#define              DENALI_PHY_939_DATA 0x02800280
> +#define              DENALI_PHY_940_DATA 0x00000280
> +#define              DENALI_PHY_941_DATA 0x00000000
> +#define              DENALI_PHY_942_DATA 0x00000000
> +#define              DENALI_PHY_943_DATA 0x00000000
> +#define              DENALI_PHY_944_DATA 0x00000000
> +#define              DENALI_PHY_945_DATA 0x00000000
> +#define              DENALI_PHY_946_DATA 0x00800080
> +#define              DENALI_PHY_947_DATA 0x00800080
> +#define              DENALI_PHY_948_DATA 0x00800080
> +#define              DENALI_PHY_949_DATA 0x00800080
> +#define              DENALI_PHY_950_DATA 0x00800080
> +#define              DENALI_PHY_951_DATA 0x00800080
> +#define              DENALI_PHY_952_DATA 0x00800080
> +#define              DENALI_PHY_953_DATA 0x00800080
> +#define              DENALI_PHY_954_DATA 0x00800080
> +#define              DENALI_PHY_955_DATA 0x000100da
> +#define              DENALI_PHY_956_DATA 0x00000200
> +#define              DENALI_PHY_957_DATA 0x00000000
> +#define              DENALI_PHY_958_DATA 0x00000000
> +#define              DENALI_PHY_959_DATA 0x00000002
> +#define              DENALI_PHY_960_DATA 0x51313152
> +#define              DENALI_PHY_961_DATA 0x80013130
> +#define              DENALI_PHY_962_DATA 0x02000080
> +#define              DENALI_PHY_963_DATA 0x00100001
> +#define              DENALI_PHY_964_DATA 0x0c064208
> +#define              DENALI_PHY_965_DATA 0x000f0c0f
> +#define              DENALI_PHY_966_DATA 0x01000140
> +#define              DENALI_PHY_967_DATA 0x0000000c
> +#define              DENALI_PHY_968_DATA 0x00000000
> +#define              DENALI_PHY_969_DATA 0x00000000
> +#define              DENALI_PHY_970_DATA 0x00000000
> +#define              DENALI_PHY_971_DATA 0x00000000
> +#define              DENALI_PHY_972_DATA 0x00000000
> +#define              DENALI_PHY_973_DATA 0x00000000
> +#define              DENALI_PHY_974_DATA 0x00000000
> +#define              DENALI_PHY_975_DATA 0x00000000
> +#define              DENALI_PHY_976_DATA 0x00000000
> +#define              DENALI_PHY_977_DATA 0x00000000
> +#define              DENALI_PHY_978_DATA 0x00000000
> +#define              DENALI_PHY_979_DATA 0x00000000
> +#define              DENALI_PHY_980_DATA 0x00000000
> +#define              DENALI_PHY_981_DATA 0x00000000
> +#define              DENALI_PHY_982_DATA 0x00000000
> +#define              DENALI_PHY_983_DATA 0x00000000
> +#define              DENALI_PHY_984_DATA 0x00000000
> +#define              DENALI_PHY_985_DATA 0x00000000
> +#define              DENALI_PHY_986_DATA 0x00000000
> +#define              DENALI_PHY_987_DATA 0x00000000
> +#define              DENALI_PHY_988_DATA 0x00000000
> +#define              DENALI_PHY_989_DATA 0x00000000
> +#define              DENALI_PHY_990_DATA 0x00000000
> +#define              DENALI_PHY_991_DATA 0x00000000
> +#define              DENALI_PHY_992_DATA 0x00000000
> +#define              DENALI_PHY_993_DATA 0x00000000
> +#define              DENALI_PHY_994_DATA 0x00000000
> +#define              DENALI_PHY_995_DATA 0x00000000
> +#define              DENALI_PHY_996_DATA 0x00000000
> +#define              DENALI_PHY_997_DATA 0x00000000
> +#define              DENALI_PHY_998_DATA 0x00000000
> +#define              DENALI_PHY_999_DATA 0x00000000
> +#define             DENALI_PHY_1000_DATA 0x00000000
> +#define             DENALI_PHY_1001_DATA 0x00000000
> +#define             DENALI_PHY_1002_DATA 0x00000000
> +#define             DENALI_PHY_1003_DATA 0x00000000
> +#define             DENALI_PHY_1004_DATA 0x00000000
> +#define             DENALI_PHY_1005_DATA 0x00000000
> +#define             DENALI_PHY_1006_DATA 0x00000000
> +#define             DENALI_PHY_1007_DATA 0x00000000
> +#define             DENALI_PHY_1008_DATA 0x00000000
> +#define             DENALI_PHY_1009_DATA 0x00000000
> +#define             DENALI_PHY_1010_DATA 0x00000000
> +#define             DENALI_PHY_1011_DATA 0x00000000
> +#define             DENALI_PHY_1012_DATA 0x00000000
> +#define             DENALI_PHY_1013_DATA 0x00000000
> +#define             DENALI_PHY_1014_DATA 0x00000000
> +#define             DENALI_PHY_1015_DATA 0x00000000
> +#define             DENALI_PHY_1016_DATA 0x00000000
> +#define             DENALI_PHY_1017_DATA 0x00000000
> +#define             DENALI_PHY_1018_DATA 0x00000000
> +#define             DENALI_PHY_1019_DATA 0x00000000
> +#define             DENALI_PHY_1020_DATA 0x00000000
> +#define             DENALI_PHY_1021_DATA 0x00000000
> +#define             DENALI_PHY_1022_DATA 0x00000000
> +#define             DENALI_PHY_1023_DATA 0x00000000
> +#define             DENALI_PHY_1024_DATA 0x36025174
> +#define             DENALI_PHY_1025_DATA 0x0004c008
> +#define             DENALI_PHY_1026_DATA 0x000000da
> +#define             DENALI_PHY_1027_DATA 0x00000000
> +#define             DENALI_PHY_1028_DATA 0x00000000
> +#define             DENALI_PHY_1029_DATA 0x00010000
> +#define             DENALI_PHY_1030_DATA 0x01DDDD90
> +#define             DENALI_PHY_1031_DATA 0x01DDDD90
> +#define             DENALI_PHY_1032_DATA 0x01030000
> +#define             DENALI_PHY_1033_DATA 0x01000000
> +#define             DENALI_PHY_1034_DATA 0x00c00000
> +#define             DENALI_PHY_1035_DATA 0x00000007
> +#define             DENALI_PHY_1036_DATA 0x00000000
> +#define             DENALI_PHY_1037_DATA 0x00000000
> +#define             DENALI_PHY_1038_DATA 0x04000408
> +#define             DENALI_PHY_1039_DATA 0x00000408
> +#define             DENALI_PHY_1040_DATA 0x00e4e400
> +#define             DENALI_PHY_1041_DATA 0x00000000
> +#define             DENALI_PHY_1042_DATA 0x00000000
> +#define             DENALI_PHY_1043_DATA 0x00000000
> +#define             DENALI_PHY_1044_DATA 0x00000000
> +#define             DENALI_PHY_1045_DATA 0x00000000
> +#define             DENALI_PHY_1046_DATA 0x00000000
> +#define             DENALI_PHY_1047_DATA 0x00000000
> +#define             DENALI_PHY_1048_DATA 0x00000000
> +#define             DENALI_PHY_1049_DATA 0x00000000
> +#define             DENALI_PHY_1050_DATA 0x00000000
> +#define             DENALI_PHY_1051_DATA 0x00000000
> +#define             DENALI_PHY_1052_DATA 0x00000000
> +#define             DENALI_PHY_1053_DATA 0x00000000
> +#define             DENALI_PHY_1054_DATA 0x00000000
> +#define             DENALI_PHY_1055_DATA 0x00000000
> +#define             DENALI_PHY_1056_DATA 0x00000000
> +#define             DENALI_PHY_1057_DATA 0x00200000
> +#define             DENALI_PHY_1058_DATA 0x00000000
> +#define             DENALI_PHY_1059_DATA 0x00000000
> +#define             DENALI_PHY_1060_DATA 0x00000000
> +#define             DENALI_PHY_1061_DATA 0x00000000
> +#define             DENALI_PHY_1062_DATA 0x00000000
> +#define             DENALI_PHY_1063_DATA 0x00000000
> +#define             DENALI_PHY_1064_DATA 0x02800280
> +#define             DENALI_PHY_1065_DATA 0x02800280
> +#define             DENALI_PHY_1066_DATA 0x02800280
> +#define             DENALI_PHY_1067_DATA 0x02800280
> +#define             DENALI_PHY_1068_DATA 0x00000280
> +#define             DENALI_PHY_1069_DATA 0x00000000
> +#define             DENALI_PHY_1070_DATA 0x00000000
> +#define             DENALI_PHY_1071_DATA 0x00000000
> +#define             DENALI_PHY_1072_DATA 0x00000000
> +#define             DENALI_PHY_1073_DATA 0x00000000
> +#define             DENALI_PHY_1074_DATA 0x00800080
> +#define             DENALI_PHY_1075_DATA 0x00800080
> +#define             DENALI_PHY_1076_DATA 0x00800080
> +#define             DENALI_PHY_1077_DATA 0x00800080
> +#define             DENALI_PHY_1078_DATA 0x00800080
> +#define             DENALI_PHY_1079_DATA 0x00800080
> +#define             DENALI_PHY_1080_DATA 0x00800080
> +#define             DENALI_PHY_1081_DATA 0x00800080
> +#define             DENALI_PHY_1082_DATA 0x00800080
> +#define             DENALI_PHY_1083_DATA 0x000100da
> +#define             DENALI_PHY_1084_DATA 0x00000200
> +#define             DENALI_PHY_1085_DATA 0x00000000
> +#define             DENALI_PHY_1086_DATA 0x00000000
> +#define             DENALI_PHY_1087_DATA 0x00000002
> +#define             DENALI_PHY_1088_DATA 0x51313152
> +#define             DENALI_PHY_1089_DATA 0x80013130
> +#define             DENALI_PHY_1090_DATA 0x02000080
> +#define             DENALI_PHY_1091_DATA 0x00100001
> +#define             DENALI_PHY_1092_DATA 0x0c064208
> +#define             DENALI_PHY_1093_DATA 0x000f0c0f
> +#define             DENALI_PHY_1094_DATA 0x01000140
> +#define             DENALI_PHY_1095_DATA 0x0000000c
> +#define             DENALI_PHY_1096_DATA 0x00000000
> +#define             DENALI_PHY_1097_DATA 0x00000000
> +#define             DENALI_PHY_1098_DATA 0x00000000
> +#define             DENALI_PHY_1099_DATA 0x00000000
> +#define             DENALI_PHY_1100_DATA 0x00000000
> +#define             DENALI_PHY_1101_DATA 0x00000000
> +#define             DENALI_PHY_1102_DATA 0x00000000
> +#define             DENALI_PHY_1103_DATA 0x00000000
> +#define             DENALI_PHY_1104_DATA 0x00000000
> +#define             DENALI_PHY_1105_DATA 0x00000000
> +#define             DENALI_PHY_1106_DATA 0x00000000
> +#define             DENALI_PHY_1107_DATA 0x00000000
> +#define             DENALI_PHY_1108_DATA 0x00000000
> +#define             DENALI_PHY_1109_DATA 0x00000000
> +#define             DENALI_PHY_1110_DATA 0x00000000
> +#define             DENALI_PHY_1111_DATA 0x00000000
> +#define             DENALI_PHY_1112_DATA 0x00000000
> +#define             DENALI_PHY_1113_DATA 0x00000000
> +#define             DENALI_PHY_1114_DATA 0x00000000
> +#define             DENALI_PHY_1115_DATA 0x00000000
> +#define             DENALI_PHY_1116_DATA 0x00000000
> +#define             DENALI_PHY_1117_DATA 0x00000000
> +#define             DENALI_PHY_1118_DATA 0x00000000
> +#define             DENALI_PHY_1119_DATA 0x00000000
> +#define             DENALI_PHY_1120_DATA 0x00000000
> +#define             DENALI_PHY_1121_DATA 0x00000000
> +#define             DENALI_PHY_1122_DATA 0x00000000
> +#define             DENALI_PHY_1123_DATA 0x00000000
> +#define             DENALI_PHY_1124_DATA 0x00000000
> +#define             DENALI_PHY_1125_DATA 0x00000000
> +#define             DENALI_PHY_1126_DATA 0x00000000
> +#define             DENALI_PHY_1127_DATA 0x00000000
> +#define             DENALI_PHY_1128_DATA 0x00000000
> +#define             DENALI_PHY_1129_DATA 0x00000000
> +#define             DENALI_PHY_1130_DATA 0x00000000
> +#define             DENALI_PHY_1131_DATA 0x00000000
> +#define             DENALI_PHY_1132_DATA 0x00000000
> +#define             DENALI_PHY_1133_DATA 0x00000000
> +#define             DENALI_PHY_1134_DATA 0x00000000
> +#define             DENALI_PHY_1135_DATA 0x00000000
> +#define             DENALI_PHY_1136_DATA 0x00000000
> +#define             DENALI_PHY_1137_DATA 0x00000000
> +#define             DENALI_PHY_1138_DATA 0x00000000
> +#define             DENALI_PHY_1139_DATA 0x00000000
> +#define             DENALI_PHY_1140_DATA 0x00000000
> +#define             DENALI_PHY_1141_DATA 0x00000000
> +#define             DENALI_PHY_1142_DATA 0x00000000
> +#define             DENALI_PHY_1143_DATA 0x00000000
> +#define             DENALI_PHY_1144_DATA 0x00000000
> +#define             DENALI_PHY_1145_DATA 0x00000000
> +#define             DENALI_PHY_1146_DATA 0x00000000
> +#define             DENALI_PHY_1147_DATA 0x00000000
> +#define             DENALI_PHY_1148_DATA 0x00000000
> +#define             DENALI_PHY_1149_DATA 0x00000000
> +#define             DENALI_PHY_1150_DATA 0x00000000
> +#define             DENALI_PHY_1151_DATA 0x00000000
> +#define             DENALI_PHY_1152_DATA 0x00000000
> +#define             DENALI_PHY_1153_DATA 0x00000000
> +#define             DENALI_PHY_1154_DATA 0x00050000
> +#define             DENALI_PHY_1155_DATA 0x00000000
> +#define             DENALI_PHY_1156_DATA 0x00000000
> +#define             DENALI_PHY_1157_DATA 0x00000000
> +#define             DENALI_PHY_1158_DATA 0x00000100
> +#define             DENALI_PHY_1159_DATA 0x00000000
> +#define             DENALI_PHY_1160_DATA 0x00000000
> +#define             DENALI_PHY_1161_DATA 0x00506401
> +#define             DENALI_PHY_1162_DATA 0x01221102
> +#define             DENALI_PHY_1163_DATA 0x00000122
> +#define             DENALI_PHY_1164_DATA 0x00000000
> +#define             DENALI_PHY_1165_DATA 0x000B1F00
> +#define             DENALI_PHY_1166_DATA 0x0B1F0B1F
> +#define             DENALI_PHY_1167_DATA 0x0B1F0B1B
> +#define             DENALI_PHY_1168_DATA 0x0B1F0B1F
> +#define             DENALI_PHY_1169_DATA 0x0B1F0B1F
> +#define             DENALI_PHY_1170_DATA 0x00000B00
> +#define             DENALI_PHY_1171_DATA 0x42080010
> +#define             DENALI_PHY_1172_DATA 0x01000100
> +#define             DENALI_PHY_1173_DATA 0x01000100
> +#define             DENALI_PHY_1174_DATA 0x01000100
> +#define             DENALI_PHY_1175_DATA 0x01000100
> +#define             DENALI_PHY_1176_DATA 0x00000000
> +#define             DENALI_PHY_1177_DATA 0x00000000
> +#define             DENALI_PHY_1178_DATA 0x00000000
> +#define             DENALI_PHY_1179_DATA 0x00000000
> +#define             DENALI_PHY_1180_DATA 0x00000000
> +#define             DENALI_PHY_1181_DATA 0x00000803
> +#define             DENALI_PHY_1182_DATA 0x223FFF00
> +#define             DENALI_PHY_1183_DATA 0x000008FF
> +#define             DENALI_PHY_1184_DATA 0x0000057F
> +#define             DENALI_PHY_1185_DATA 0x0000057F
> +#define             DENALI_PHY_1186_DATA 0x00037FFF
> +#define             DENALI_PHY_1187_DATA 0x00037FFF
> +#define             DENALI_PHY_1188_DATA 0x00004410
> +#define             DENALI_PHY_1189_DATA 0x00004410
> +#define             DENALI_PHY_1190_DATA 0x00004410
> +#define             DENALI_PHY_1191_DATA 0x00004410
> +#define             DENALI_PHY_1192_DATA 0x00004410
> +#define             DENALI_PHY_1193_DATA 0x00037FFF
> +#define             DENALI_PHY_1194_DATA 0x00037FFF
> +#define             DENALI_PHY_1195_DATA 0x00000000
> +#define             DENALI_PHY_1196_DATA 0x00000000
> +#define             DENALI_PHY_1197_DATA 0x00000000
> +#define             DENALI_PHY_1198_DATA 0x04000000
> +#define             DENALI_PHY_1199_DATA 0x00000000
> +#define             DENALI_PHY_1200_DATA 0x00000000
> +#define             DENALI_PHY_1201_DATA 0x00000108
> +#define             DENALI_PHY_1202_DATA 0x00000000
> +#define             DENALI_PHY_1203_DATA 0x00000000
> +#define             DENALI_PHY_1204_DATA 0x00000000
> +#define             DENALI_PHY_1205_DATA 0x00000001
> +#define             DENALI_PHY_1206_DATA 0x00000000
> +#define             DENALI_PHY_1207_DATA 0x00000000
> +#define             DENALI_PHY_1208_DATA 0x00000000
> +#define             DENALI_PHY_1209_DATA 0x00000000
> +#define             DENALI_PHY_1210_DATA 0x00000000
> +#define             DENALI_PHY_1211_DATA 0x00000000
> +#define             DENALI_PHY_1212_DATA 0x00020100
> +#define             DENALI_PHY_1213_DATA 0x00000000
> +#define             DENALI_PHY_1214_DATA 0x00000000
> diff --git a/board/sifive/fu540/include/spi.h b/board/sifive/fu540/include/spi.h
> new file mode 100644
> index 0000000000..b2b3260333
> --- /dev/null
> +++ b/board/sifive/fu540/include/spi.h
> @@ -0,0 +1,233 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef FU540_SPI_H
> +#define FU540_SPI_H
> +
> +#include <asm/arch/spi.h>
> +
> +#ifndef __ASSEMBLER__
> +
> +#include <stdint.h>
> +#include <linux/types.h>
> +
> +#define _ASSERT_SIZEOF(type, size) _Static_assert(sizeof(type) == (size), # type " must be " # size " bytes wide")
> +
> +typedef union {
> +       struct {
> +               u32 pha      : 1;
> +               u32 pol      : 1;
> +               u32 reserved : 30;
> +       };
> +       u32 raw_bits;
> +} spi_reg_sckmode;
> +_ASSERT_SIZEOF(spi_reg_sckmode, 4);
> +
> +typedef union {
> +       struct {
> +               u32 mode     : 2;
> +               u32 reserved : 30;
> +       };
> +       u32 raw_bits;
> +} spi_reg_csmode;
> +_ASSERT_SIZEOF(spi_reg_csmode, 4);
> +
> +typedef union {
> +       struct {
> +               u32 cssck     : 8;
> +               u32 reserved0 : 8;
> +               u32 sckcs     : 8;
> +               u32 reserved1 : 8;
> +       };
> +       u32 raw_bits;
> +} spi_reg_delay0;
> +_ASSERT_SIZEOF(spi_reg_delay0, 4);
> +
> +typedef union {
> +       struct {
> +               u32 intercs   : 8;
> +               u32 reserved0 : 8;
> +               u32 interxfr  : 8;
> +               u32 reserved1 : 8;
> +       };
> +       u32 raw_bits;
> +} spi_reg_delay1;
> +_ASSERT_SIZEOF(spi_reg_delay1, 4);
> +
> +typedef union {
> +       struct {
> +               u32 proto     : 2;
> +               u32 endian    : 1;
> +               u32 dir       : 1;
> +               u32 reserved0 : 12;
> +               u32 len       : 4;
> +               u32 reserved1 : 12;
> +       };
> +       u32 raw_bits;
> +} spi_reg_fmt;
> +_ASSERT_SIZEOF(spi_reg_fmt, 4);
> +
> +typedef union {
> +       struct {
> +               u32 data     : 8;
> +               u32 reserved : 23;
> +               u32 full     : 1;
> +       };
> +       u32 raw_bits;
> +} spi_reg_txdata;
> +_ASSERT_SIZEOF(spi_reg_txdata, 4);
> +
> +typedef union {
> +       struct {
> +               u32 data     : 8;
> +               u32 reserved : 23;
> +               u32 empty    : 1;
> +       };
> +       u32 raw_bits;
> +} spi_reg_rxdata;
> +_ASSERT_SIZEOF(spi_reg_rxdata, 4);
> +
> +typedef union {
> +       struct {
> +               u32 txmark   : 3;
> +               u32 reserved : 29;
> +       };
> +       u32 raw_bits;
> +} spi_reg_txmark;
> +_ASSERT_SIZEOF(spi_reg_txmark, 4);
> +
> +typedef union {
> +       struct {
> +               u32 rxmark   : 3;
> +               u32 reserved : 29;
> +       };
> +       u32 raw_bits;
> +} spi_reg_rxmark;
> +_ASSERT_SIZEOF(spi_reg_rxmark, 4);
> +
> +typedef union {
> +       struct {
> +               u32 en       : 1;
> +               u32 reserved : 31;
> +       };
> +       u32 raw_bits;
> +} spi_reg_fctrl;
> +_ASSERT_SIZEOF(spi_reg_fctrl, 4);
> +
> +typedef union {
> +       struct {
> +               u32 cmd_en        : 1;
> +               u32 addr_len      : 3;
> +               u32 pad_cnt       : 4;
> +               u32 command_proto : 2;
> +               u32 addr_proto    : 2;
> +               u32 data_proto    : 2;
> +               u32 reserved      : 2;
> +               u32 command_code  : 8;
> +               u32 pad_code      : 8;
> +       };
> +       u32 raw_bits;
> +} spi_reg_ffmt;
> +_ASSERT_SIZEOF(spi_reg_ffmt, 4);
> +
> +typedef union {
> +       struct {
> +               u32 txwm     : 1;
> +               u32 rxwm     : 1;
> +               u32 reserved : 30;
> +       };
> +       u32 raw_bits;
> +} spi_reg_ie;
> +typedef spi_reg_ie spi_reg_ip;
> +_ASSERT_SIZEOF(spi_reg_ie, 4);
> +_ASSERT_SIZEOF(spi_reg_ip, 4);
> +
> +#undef _ASSERT_SIZEOF
> +
> +/*
> + * SPI control register memory map.
> + *
> + * All functions take a pointer to a SPI device's control registers.
> + */
> +typedef volatile struct
> +{
> +       u32        sckdiv;
> +       spi_reg_sckmode sckmode;
> +       u32        reserved08;
> +       u32        reserved0c;
> +
> +       u32        csid;
> +       u32        csdef;
> +       spi_reg_csmode  csmode;
> +       u32        reserved1c;
> +
> +       u32        reserved20;
> +       u32        reserved24;
> +       spi_reg_delay0  delay0;
> +       spi_reg_delay1  delay1;
> +
> +       u32        reserved30;
> +       u32        reserved34;
> +       u32        reserved38;
> +       u32        reserved3c;
> +
> +       spi_reg_fmt     fmt;
> +       u32        reserved44;
> +       spi_reg_txdata  txdata;
> +       spi_reg_rxdata  rxdata;
> +
> +       spi_reg_txmark  txmark;
> +       spi_reg_rxmark  rxmark;
> +       u32        reserved58;
> +       u32        reserved5c;
> +
> +       spi_reg_fctrl   fctrl;
> +       spi_reg_ffmt    ffmt;
> +       u32        reserved68;
> +       u32        reserved6c;
> +
> +       spi_reg_ie      ie;
> +       spi_reg_ip      ip;
> +} spi_ctrl;
> +
> +void spi_tx(spi_ctrl *spictrl, uint8_t in);
> +uint8_t spi_rx(spi_ctrl *spictrl);
> +uint8_t spi_txrx(spi_ctrl *spictrl, uint8_t in);
> +int spi_copy(spi_ctrl *spictrl, void *buf, u32 addr, u32 size);
> +
> +/**
> + * Get smallest clock divisor that divides input_khz to a quotient less than or
> + * equal to max_target_khz;
> + */
> +inline unsigned int spi_min_clk_divisor(unsigned int input_khz, unsigned
> +               int max_target_khz)
> +{
> +       // f_sck = f_in / (2 * (div + 1)) => div = (f_in / (2*f_sck)) - 1
> +       //
> +       // The nearest integer solution for div requires rounding up as to
> +       // not exceed max_target_khz.
> +       //
> +       // div = ceil(f_in / (2*f_sck)) - 1
> +       //     = floor((f_in - 1 + 2*f_sck) / (2*f_sck)) - 1
> +       //
> +       // This should not overflow as long as (f_in - 1 + 2*f_sck) does not
> +       // exceed 2^32 - 1, which is unlikely since we represent frequencies
> +       // in kHz.
> +       unsigned int quotient = (input_khz + 2 * max_target_khz - 1) / (2 *
> +                       max_target_khz);
> +
> +       // Avoid underflow
> +       if (quotient == 0)
> +               return 0;
> +       else
> +               return quotient - 1;
> +}
> +
> +#endif /* !__ASSEMBLER__ */
> +#endif /* FU540_SPI_H */
> diff --git a/board/sifive/fu540/include/uart.h b/board/sifive/fu540/include/uart.h
> new file mode 100644
> index 0000000000..e20dc8a027
> --- /dev/null
> +++ b/board/sifive/fu540/include/uart.h
> @@ -0,0 +1,54 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef FU540_UART_H
> +#define FU540_UART_H
> +
> +#include <asm/arch/uart.h>
> +
> +#ifndef __ASSEMBLER__
> +
> +void uart_putc(void *uartctrl, char c);
> +char uart_getc(void *uartctrl);
> +void uart_puts(void *uartctrl, const char *s);
> +void uart_put_hex(void *uartctrl, uint32_t hex);
> +void uart_put_hex64(void *ua64ctrl, u64 hex);
> +
> +#include <stdint.h>
> +#include <linux/types.h>
> +
> +/*
> + * Get smallest clock divisor that divides input_hz to a quotient less than or
> + * equal to max_target_hz;
> + */
> +static inline unsigned int uart_min_clk_divisor(u64 input_hz, u64 max_target_hz)
> +{
> +       // f_baud = f_in / (div + 1) => div = (f_in / f_baud) - 1
> +       // div = (f_in / f_baud) - 1
> +       //
> +       // The nearest integer solution for div requires rounding up as to not
> +       // exceed max_target_hz.
> +       //
> +       // div = ceil(f_in / f_baud) - 1
> +       //     = floor((f_in - 1 + f_baud) / f_baud) - 1
> +       //
> +       // This should not overflow as long as (f_in - 1 + f_baud) does not
> +       // exceed 2^32 - 1, which is unlikely since we represent frequencies
> +       // in kHz.
> +       u64 quotient = (input_hz + max_target_hz - 1) / (max_target_hz);
> +       // Avoid underflow
> +       if (quotient == 0)
> +               return 0;
> +       else
> +               return quotient - 1;
> +}
> +
> +#endif /* !__ASSEMBLER__ */
> +
> +#endif /* FU540_UART_H */
> diff --git a/board/sifive/fu540/include/ux00ddr.h b/board/sifive/fu540/include/ux00ddr.h
> new file mode 100644
> index 0000000000..f3af3be901
> --- /dev/null
> +++ b/board/sifive/fu540/include/ux00ddr.h
> @@ -0,0 +1,268 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef FU540_UX00DDR_H
> +#define FU540_UX00DDR_H
> +
> +#ifndef __ASSEMBLER__
> +
> +#include <stdint.h>
> +#include <stddef.h>
> +#include <stdbool.h>
> +#include "uart.h"
> +#include "fu540-memory-map.h"
> +
> +#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
> +
> +static inline void phy_reset(volatile u32 *ddrphyreg, const
> +               u32 *physettings)
> +{
> +       unsigned int i;
> +
> +       for (i = 1152; i <= 1214; i++) {
> +               u32 physet = physettings[i];
> +               /*if (physet!=0)*/ ddrphyreg[i] = physet;
> +       }
> +
> +       for (i = 0; i <= 1151; i++) {
> +               u32 physet = physettings[i];
> +               /*if (physet!=0)*/ ddrphyreg[i] = physet;
> +       }
> +}
> +
> +static inline void ux00ddr_writeregmap(size_t ahbregaddr, const
> +               u32 *ctlsettings, const u32 *physettings)
> +{
> +       volatile u32 *ddrctlreg = (volatile u32 *)ahbregaddr;
> +       volatile u32 *ddrphyreg = ((volatile u32 *)ahbregaddr) +
> +               (0x2000 / sizeof(u32));
> +
> +       unsigned int i;
> +
> +       for (i = 0; i <= 264; i++) {
> +               u32 ctlset = ctlsettings[i];
> +               /*if (ctlset!=0)*/ ddrctlreg[i] = ctlset;
> +       }
> +
> +       phy_reset(ddrphyreg, physettings);
> +}
> +
> +static inline void ux00ddr_start(size_t ahbregaddr, size_t filteraddr,
> +                                size_t ddrend)
> +{
> +       // START register at ddrctl register base offset 0
> +       u32 regdata = _REG32(0 << 2, ahbregaddr);
> +
> +       regdata |= 0x1;
> +       _REG32(0 << 2, ahbregaddr) = regdata;
> +       // WAIT for initialization complete : bit 8 of INT_STATUS
> +       // (DENALI_CTL_132) 0x210
> +       while ((_REG32(132 << 2, ahbregaddr) & (1 <<
> +                                       MC_INIT_COMPLETE_OFFSET)) == 0) {
> +       }
> +
> +       // Disable the BusBlocker in front of the controller AXI slave ports
> +       volatile u64 *filterreg = (volatile u64 *)filteraddr;
> +
> +       filterreg[0] = 0x0f00000000000000UL | (ddrend >> 2);
> +       //                ^^ RWX + TOR
> +}
> +
> +static inline void ux00ddr_mask_mc_init_complete_interrupt(size_t
> +               ahbregaddr)
> +{
> +       // Mask off Bit 8 of Interrupt Status
> +       // Bit [8] The MC initialization has been completed
> +       _REG32(136 << 2, ahbregaddr) |= (1 << MC_INIT_COMPLETE_OFFSET);
> +}
> +
> +static inline void ux00ddr_mask_outofrange_interrupts(size_t ahbregaddr)
> +{
> +       // Mask off Bit 8, Bit 2 and Bit 1 of Interrupt Status
> +       // Bit [2] Multiple accesses outside the defined PHYSICAL memory
> +       // space have occurred
> +       // Bit [1] A memory access outside the defined PHYSICAL memory
> +       // space has occurred
> +       _REG32(136 << 2, ahbregaddr) |= ((1 << OUT_OF_RANGE_OFFSET) | (1 <<
> +                               MULTIPLE_OUT_OF_RANGE_OFFSET));
> +}
> +
> +static inline void ux00ddr_mask_port_command_error_interrupt(size_t
> +               ahbregaddr)
> +{
> +       // Mask off Bit 7 of Interrupt Status
> +       // Bit [7] An error occurred on the port command channel
> +       _REG32(136 << 2, ahbregaddr) |= (1 <<
> +                       PORT_COMMAND_CHANNEL_ERROR_OFFSET);
> +}
> +
> +static inline void ux00ddr_mask_leveling_completed_interrupt(size_t
> +               ahbregaddr)
> +{
> +       // Mask off Bit 22 of Interrupt Status
> +       // Bit [22] The leveling operation has completed
> +       _REG32(136 << 2, ahbregaddr) |= (1 <<
> +                       LEVELING_OPERATION_COMPLETED_OFFSET);
> +}
> +
> +static inline void ux00ddr_setuprangeprotection(size_t ahbregaddr, size_t
> +               end_addr)
> +{
> +       _REG32(209 << 2, ahbregaddr) = 0x0;
> +       size_t end_addr_16kblocks = ((end_addr >> 14) & 0x7FFFFF) - 1;
> +
> +       _REG32(210 << 2, ahbregaddr)  = ((u32)end_addr_16kblocks);
> +       _REG32(212 << 2, ahbregaddr)  = 0x0;
> +       _REG32(214 << 2, ahbregaddr)  = 0x0;
> +       _REG32(216 << 2, ahbregaddr)  = 0x0;
> +       _REG32(224 << 2, ahbregaddr) |= (0x3 << AXI0_RANGE_PROT_BITS_0_OFFSET);
> +       _REG32(225 << 2, ahbregaddr)  = 0xFFFFFFFF;
> +       _REG32(208 << 2, ahbregaddr) |= (1 << AXI0_ADDRESS_RANGE_ENABLE);
> +       _REG32(208 << 2, ahbregaddr) |= (1 << PORT_ADDR_PROTECTION_EN_OFFSET);
> +}
> +
> +static inline void ux00ddr_disableaxireadinterleave(size_t ahbregaddr)
> +{
> +       _REG32(120 << 2, ahbregaddr) |= (1 << DISABLE_RD_INTERLEAVE_OFFSET);
> +}
> +
> +static inline void ux00ddr_disableoptimalrmodw(size_t ahbregaddr)
> +{
> +       _REG32(21 << 2, ahbregaddr) &= (~(1 << OPTIMAL_RMODW_EN_OFFSET));
> +}
> +
> +static inline void ux00ddr_enablewriteleveling(size_t ahbregaddr)
> +{
> +       _REG32(170 << 2, ahbregaddr) |= ((1 << WRLVL_EN_OFFSET) | (1 <<
> +                               DFI_PHY_WRLELV_MODE_OFFSET));
> +}
> +
> +static inline void ux00ddr_enablereadleveling(size_t ahbregaddr)
> +{
> +       _REG32(181 << 2, ahbregaddr) |= (1 << DFI_PHY_RDLVL_MODE_OFFSET);
> +       _REG32(260 << 2, ahbregaddr) |= (1 << RDLVL_EN_OFFSET);
> +}
> +
> +static inline void ux00ddr_enablereadlevelinggate(size_t ahbregaddr)
> +{
> +       _REG32(260 << 2, ahbregaddr) |= (1 << RDLVL_GATE_EN_OFFSET);
> +       _REG32(182 << 2, ahbregaddr) |= (1 << DFI_PHY_RDLVL_GATE_MODE_OFFSET);
> +}
> +
> +static inline void ux00ddr_enablevreftraining(size_t ahbregaddr)
> +{
> +       _REG32(184 << 2, ahbregaddr) |= (1 << VREF_EN_OFFSET);
> +}
> +
> +static inline u32 ux00ddr_getdramclass(size_t ahbregaddr)
> +{
> +       return((_REG32(0, ahbregaddr) >> DRAM_CLASS_OFFSET) & 0xF);
> +}
> +
> +static inline u64 ux00ddr_phy_fixup(size_t ahbregaddr)
> +{
> +       // return bitmask of failed lanes
> +
> +       size_t ddrphyreg = ahbregaddr + 0x2000;
> +
> +       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 = _REG32((regbase + reg) << 2,
> +                                               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)
> +                                               uart_puts((void *)
> +                                                         UART0_CTRL_ADDR,
> +                                                         "DDR error in fixing up \n");
> +
> +                                       fails |= (1 << dq);
> +
> +                                       char slicelsc = '0';
> +                                       char slicemsc = '0';
> +
> +                                       slicelsc += (dq % 10);
> +                                       slicemsc += (dq / 10);
> +                                       uart_puts((void *)UART0_CTRL_ADDR,
> +                                                 "S ");
> +                                       uart_puts((void *)UART0_CTRL_ADDR,
> +                                                 &slicemsc);
> +                                       uart_puts((void *)UART0_CTRL_ADDR,
> +                                                 &slicelsc);
> +                                       if (failc0)
> +                                               uart_puts((void *)
> +                                                         UART0_CTRL_ADDR,
> +                                                         "U");
> +                                       else
> +                                               uart_puts((void *)
> +                                                         UART0_CTRL_ADDR,
> +                                                         "D");
> +
> +                                       uart_puts((void *)UART0_CTRL_ADDR,
> +                                                 "\n");
> +                               }
> +                               dq++;
> +                       }
> +               }
> +               slicebase += 128;
> +       }
> +       return(0);
> +}
> +
> +#endif /* __ASSEMBLER__ */
> +
> +#endif /* FU540_UX00DDR_H */
> diff --git a/board/sifive/fu540/include/ux00prci.h b/board/sifive/fu540/include/ux00prci.h
> new file mode 100644
> index 0000000000..21f4aeb465
> --- /dev/null
> +++ b/board/sifive/fu540/include/ux00prci.h
> @@ -0,0 +1,206 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef _SIFIVE_UX00PRCI_H
> +#define _SIFIVE_UX00PRCI_H
> +
> +/* Register offsets */
> +
> +#define UX00PRCI_HFROSCCFG          (0x0000)
> +#define UX00PRCI_COREPLLCFG         (0x0004)
> +#define UX00PRCI_COREPLLOUT         (0x0008)
> +#define UX00PRCI_DDRPLLCFG          (0x000C)
> +#define UX00PRCI_DDRPLLOUT          (0x0010)
> +#define UX00PRCI_GEMGXLPLLCFG       (0x001C)
> +#define UX00PRCI_GEMGXLPLLOUT       (0x0020)
> +#define UX00PRCI_CORECLKSELREG      (0x0024)
> +#define UX00PRCI_DEVICESRESETREG    (0x0028)
> +#define UX00PRCI_CLKMUXSTATUSREG    (0x002C)
> +#define UX00PRCI_PROCMONCFG         (0x00F0)
> +
> +/* Fields */
> +#define XOSC_EN(x)            (((x) & 0x1) << 30)
> +#define XOSC_RDY(x)           (((x) & 0x1) << 31)
> +
> +#define PLL_R(x)              (((x) & 0x3F) << 0)
> +#define PLL_F(x)              (((x) & 0x1FF) << 6)
> +#define PLL_Q(x)              (((x) & 0x7) << 15)
> +#define PLL_RANGE(x)          (((x) & 0x7) << 18)
> +#define PLL_BYPASS(x)         (((x) & 0x1) << 24)
> +#define PLL_FSE(x)            (((x) & 0x1) << 25)
> +#define PLL_LOCK(x)           (((x) & 0x1) << 31)
> +
> +#define PLLOUT_DIV(x)         (((x) & 0x7F) << 0)
> +#define PLLOUT_DIV_BY_1(x)    (((x) & 0x1) << 8)
> +#define PLLOUT_CLK_EN(x)      (((x) & 0x1) << 31)
> +
> +#define PLL_R_default              0x1
> +#define PLL_F_default              0x1F
> +#define PLL_Q_default              0x3
> +#define PLL_RANGE_default          0x0
> +#define PLL_BYPASS_default         0x1
> +#define PLL_FSE_default            0x1
> +
> +#define PLLOUT_DIV_default         0x0
> +#define PLLOUT_DIV_BY_1_default    0x0
> +#define PLLOUT_CLK_EN_default      0x0
> +
> +#define PLL_CORECLKSEL_HFXIN       0x1
> +#define PLL_CORECLKSEL_COREPLL     0x0
> +
> +#define DEVICESRESET_DDR_CTRL_RST_N(x)    (((x) & 0x1) << 0)
> +#define DEVICESRESET_DDR_AXI_RST_N(x)     (((x) & 0x1) << 1)
> +#define DEVICESRESET_DDR_AHB_RST_N(x)     (((x) & 0x1) << 2)
> +#define DEVICESRESET_DDR_PHY_RST_N(x)     (((x) & 0x1) << 3)
> +#define DEVICESRESET_GEMGXL_RST_N(x)      (((x) & 0x1) << 5)
> +
> +#define CLKMUX_STATUS_CORECLKPLLSEL    (0x1 << 0)
> +#define CLKMUX_STATUS_TLCLKSEL         (0x1 << 1)
> +#define CLKMUX_STATUS_RTCXSEL          (0x1 << 2)
> +#define CLKMUX_STATUS_DDRCTRLCLKSEL    (0x1 << 3)
> +#define CLKMUX_STATUS_DDRPHYCLKSEL     (0x1 << 4)
> +#define CLKMUX_STATUS_GEMGXLCLKSEL     (0x1 << 6)
> +
> +#ifndef __ASSEMBLER__
> +
> +#include <stdint.h>
> +#include <linux/types.h>
> +
> +static inline int ux00prci_select_corepll(volatile u32 *coreclkselreg,
> +                                         volatile u32 *corepllcfg,
> +                                         volatile u32 *corepllout,
> +                                         u32 pllconfigval)
> +{
> +       (*corepllcfg) = pllconfigval;
> +
> +       // Wait for lock
> +       while (((*corepllcfg) & (PLL_LOCK(1))) == 0)
> +               ;
> +
> +       u32 core_out =
> +               (PLLOUT_DIV(PLLOUT_DIV_default)) |
> +               (PLLOUT_DIV_BY_1(PLLOUT_DIV_BY_1_default)) |
> +               (PLLOUT_CLK_EN(1));
> +       (*corepllout) = core_out;
> +
> +       // Set CORECLKSELREG to select COREPLL
> +       (*coreclkselreg) = PLL_CORECLKSEL_COREPLL;
> +
> +       return 0;
> +}
> +
> +static inline int ux00prci_select_corepll_1_4ghz(volatile u32 *coreclkselreg,
> +                                                volatile u32 *corepllcfg,
> +                                                volatile u32 *corepllout)
> +{
> +       //
> +       // CORE pll init
> +       // Set corepll 33MHz -> 1GHz
> +       //
> +
> +       u32 core14ghz =
> +               (PLL_R(0)) |
> +               (PLL_F(41)) |            /*2800MHz VCO*/
> +               (PLL_Q(1)) |             /* /2 Output divider */
> +               (PLL_RANGE(0x4)) |
> +               (PLL_BYPASS(0)) |
> +               (PLL_FSE(1));
> +
> +       return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
> +                                       core14ghz);
> +}
> +
> +static inline int ux00prci_select_corepll_1_5ghz(volatile u32 *coreclkselreg,
> +                                                volatile u32 *corepllcfg,
> +                                                volatile u32 *corepllout)
> +{
> +       //
> +       // CORE pll init
> +       // Set corepll 33MHz -> 1GHz
> +       //
> +
> +       u32 core15ghz =
> +               (PLL_R(0)) |
> +               (PLL_F(44)) |            /*3000MHz VCO*/
> +               (PLL_Q(1)) |             /* /2 Output divider */
> +               (PLL_RANGE(0x4)) |
> +               (PLL_BYPASS(0)) |
> +               (PLL_FSE(1));
> +
> +       return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
> +                                       core15ghz);
> +}
> +
> +static inline int ux00prci_select_corepll_1_6ghz(volatile u32 *coreclkselreg,
> +                                                volatile u32 *corepllcfg,
> +                                                volatile u32 *corepllout)
> +{
> +       //
> +       // CORE pll init
> +       // Set corepll 33MHz -> 1GHz
> +       //
> +
> +       u32 core16ghz =
> +               (PLL_R(0)) |
> +               (PLL_F(47)) |            /*3200MHz VCO*/
> +               (PLL_Q(1)) |             /* /2 Output divider */
> +               (PLL_RANGE(0x4)) |
> +               (PLL_BYPASS(0)) |
> +               (PLL_FSE(1));
> +
> +       return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
> +                                       core16ghz);
> +}
> +
> +static inline int ux00prci_select_corepll_1ghz(volatile u32 *coreclkselreg,
> +                                              volatile u32 *corepllcfg,
> +                                              volatile u32 *corepllout)
> +{
> +       //
> +       // CORE pll init
> +       // Set corepll 33MHz -> 1GHz
> +       //
> +
> +       u32 core1ghz =
> +               (PLL_R(0)) |
> +               (PLL_F(59)) |            /*4000MHz VCO*/
> +               (PLL_Q(2)) |             /* /4 Output divider */
> +               (PLL_RANGE(0x4)) |
> +               (PLL_BYPASS(0)) |
> +               (PLL_FSE(1));
> +
> +       return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
> +                                       core1ghz);
> +}
> +
> +static inline int ux00prci_select_corepll_500mhz(volatile u32 *coreclkselreg,
> +                                                volatile u32 *corepllcfg,
> +                                                volatile u32 *corepllout)
> +{
> +       //
> +       // CORE pll init
> +       // Set corepll 33MHz -> 1GHz
> +       //
> +
> +       u32 core500mhz =
> +               (PLL_R(0)) |
> +               (PLL_F(59)) |            /*4000MHz VCO*/
> +               (PLL_Q(3)) |             /* /8 Output divider */
> +               (PLL_RANGE(0x4)) |
> +               (PLL_BYPASS(0)) |
> +               (PLL_FSE(1));
> +
> +       return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
> +                                       core500mhz);
> +}
> +
> +#endif
> +
> +#endif // _SIFIVE_UX00PRCI_H
> diff --git a/board/sifive/fu540/spl.c b/board/sifive/fu540/spl.c
> new file mode 100644
> index 0000000000..69187066ba
> --- /dev/null
> +++ b/board/sifive/fu540/spl.c
> @@ -0,0 +1,321 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#include <common.h>
> +#include <spl.h>
> +
> +#include "include/regconfig-ctl.h"
> +#include "include/regconfig-phy.h"
> +#include "include/ux00ddr.h"
> +#include "include/ddrregs.h"
> +
> +#include "include/fu540-memory-map.h"
> +#include <stdatomic.h>
> +
> +#define ddr_phy_settings DENALI_PHY_DATA
> +#define ddr_ctl_settings DENALI_CTL_DATA
> +
> +#define DDR_SIZE  (8UL * 1024UL * 1024UL * 1024UL)
> +#define DDRCTLPLL_F 55
> +#define DDRCTLPLL_Q 2
> +
> +#define PHY_NRESET 0x1000
> +#define FIRST_SLOT  0xfe
> +#define LAST_SLOT   0x80
> +
> +static const uintptr_t i2c_devices[] = {
> +       I2C_CTRL_ADDR,
> +};
> +
> +static spi_ctrl * const spi_devices[] = {
> +       (spi_ctrl *)SPI0_CTRL_ADDR,
> +       (spi_ctrl *)SPI1_CTRL_ADDR,
> +       (spi_ctrl *)SPI2_CTRL_ADDR,
> +};
> +
> +static const uintptr_t uart_devices[] = {
> +       UART0_CTRL_ADDR,
> +       UART1_CTRL_ADDR,
> +};
> +
> +unsigned int serial_to_burn = ~0;
> +
> +/**
> + * Scale peripheral clock dividers before changing core PLL.
> + */
> +void update_peripheral_clock_dividers(unsigned int peripheral_input_khz)
> +{
> +       unsigned int i2c_target_khz = 400;
> +       u16 prescaler = i2c_min_clk_prescaler(peripheral_input_khz,
> +                                             i2c_target_khz);
> +
> +       for (size_t i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
> +               _REG32(i2c_devices[i], I2C_PRESCALER_LO) = prescaler & 0xff;
> +               _REG32(i2c_devices[i], I2C_PRESCALER_HI) = (prescaler >> 8) &
> +                                                          0xff;
> +       }
> +
> +       unsigned int spi_target_khz = 50000;
> +       unsigned int spi_div = spi_min_clk_divisor(peripheral_input_khz,
> +                                                  spi_target_khz);
> +
> +       for (size_t i = 0; i < ARRAY_SIZE(spi_devices); i++)
> +               spi_devices[i]->sckdiv = spi_div;
> +
> +       unsigned int uart_target_hz = 115200ULL;
> +       unsigned int uart_div = uart_min_clk_divisor(peripheral_input_khz *
> +                                                    1000ULL, uart_target_hz);
> +
> +       for (size_t i = 0; i < ARRAY_SIZE(uart_devices); i++)
> +               _REG32(uart_devices[i], UART_REG_DIV) = uart_div;
> +}
> +
> +long nsec_per_cyc = 300; // 33.333MHz
> +void nsleep(long nsec)
> +{
> +       long step = nsec_per_cyc * 2; // 2 instructions per loop iteration
> +
> +       while (nsec > 0)
> +               nsec -= step;
> +}
> +
> +void init_clk_and_ddr(void)
> +{
> +       // PRCI init
> +
> +       // Initialize UART divider for 33MHz core clock in case if
> +       // trap is taken prior to core clock bump.
> +       unsigned long long uart_target_hz = 115200ULL;
> +       const u32 initial_core_clk_khz = 33000;
> +       unsigned long peripheral_input_khz;
> +
> +       if (UX00PRCI_REG(UX00PRCI_CLKMUXSTATUSREG) & CLKMUX_STATUS_TLCLKSEL)
> +               peripheral_input_khz = initial_core_clk_khz;
> +       else
> +               peripheral_input_khz = initial_core_clk_khz / 2;
> +       UART0_REG(UART_REG_DIV) = uart_min_clk_divisor(peripheral_input_khz *
> +                                                      1000ULL, uart_target_hz);
> +
> +       // Check Reset Values (lock don't care)
> +       u32 pll_default =
> +               (PLL_R(PLL_R_default)) |
> +               (PLL_F(PLL_F_default)) |
> +               (PLL_Q(PLL_Q_default)) |
> +               (PLL_RANGE(PLL_RANGE_default)) |
> +               (PLL_BYPASS(PLL_BYPASS_default)) |
> +               (PLL_FSE(PLL_FSE_default));
> +       u32 lockmask = ~PLL_LOCK(1);
> +       u32 pllout_default =
> +               (PLLOUT_DIV(PLLOUT_DIV_default)) |
> +               (PLLOUT_DIV_BY_1(PLLOUT_DIV_BY_1_default)) |
> +               (PLLOUT_CLK_EN(PLLOUT_CLK_EN_default));
> +
> +       if ((UX00PRCI_REG(UX00PRCI_COREPLLCFG)     ^ pll_default) & lockmask)
> +               return;
> +       if ((UX00PRCI_REG(UX00PRCI_COREPLLOUT)     ^ pllout_default))
> +               return;
> +       if ((UX00PRCI_REG(UX00PRCI_DDRPLLCFG)      ^ pll_default) & lockmask)
> +               return;
> +       if ((UX00PRCI_REG(UX00PRCI_DDRPLLOUT)      ^ pllout_default))
> +               return;
> +       if (((UX00PRCI_REG(UX00PRCI_GEMGXLPLLCFG)) ^ pll_default) & lockmask)
> +               return;
> +       if (((UX00PRCI_REG(UX00PRCI_GEMGXLPLLOUT)) ^ pllout_default))
> +               return;
> +
> +       //CORE pll init
> +       // If tlclksel is set for 2:1 operation,
> +       // Set corepll 33Mhz -> 1GHz
> +       // Otherwise, set corepll 33MHz -> 500MHz.
> +
> +       if (UX00PRCI_REG(UX00PRCI_CLKMUXSTATUSREG) & CLKMUX_STATUS_TLCLKSEL) {
> +               nsec_per_cyc = 2;
> +               peripheral_input_khz = 500000; // peripheral_clk = tlclk
> +               update_peripheral_clock_dividers(peripheral_input_khz);
> +               ux00prci_select_corepll_500mhz
> +                       (&UX00PRCI_REG(UX00PRCI_CORECLKSELREG),
> +                        &UX00PRCI_REG(UX00PRCI_COREPLLCFG),
> +                        &UX00PRCI_REG(UX00PRCI_COREPLLOUT));
> +       } else {
> +               nsec_per_cyc = 1;
> +               peripheral_input_khz = (1000000 / 2); // peripheral_clk = tlclk
> +               update_peripheral_clock_dividers(peripheral_input_khz);
> +
> +               ux00prci_select_corepll_1ghz
> +                       (&UX00PRCI_REG(UX00PRCI_CORECLKSELREG),
> +                        &UX00PRCI_REG(UX00PRCI_COREPLLCFG),
> +                        &UX00PRCI_REG(UX00PRCI_COREPLLOUT));
> +       }
> +
> +       //
> +       //DDR init
> +       //
> +
> +       u32 ddrctlmhz =
> +               (PLL_R(0)) |
> +               (PLL_F(DDRCTLPLL_F)) |
> +               (PLL_Q(DDRCTLPLL_Q)) |
> +               (PLL_RANGE(0x4)) |
> +               (PLL_BYPASS(0)) |
> +               (PLL_FSE(1));
> +       UX00PRCI_REG(UX00PRCI_DDRPLLCFG) = ddrctlmhz;
> +
> +       // Wait for lock
> +       while ((UX00PRCI_REG(UX00PRCI_DDRPLLCFG) & PLL_LOCK(1)) == 0)
> +               ;
> +
> +       u32 ddrctl_out =
> +               (PLLOUT_DIV(PLLOUT_DIV_default)) |
> +               (PLLOUT_DIV_BY_1(PLLOUT_DIV_BY_1_default)) |
> +               (PLLOUT_CLK_EN(1));
> +       (UX00PRCI_REG(UX00PRCI_DDRPLLOUT)) = ddrctl_out;
> +
> +       //Release DDR reset.
> +       UX00PRCI_REG(UX00PRCI_DEVICESRESETREG) |=
> +               DEVICESRESET_DDR_CTRL_RST_N(1);
> +
> +       // HACK to get the '1 full controller clock cycle'.
> +       asm volatile ("fence");
> +       UX00PRCI_REG(UX00PRCI_DEVICESRESETREG) |= DEVICESRESET_DDR_AXI_RST_N(1)
> +              | DEVICESRESET_DDR_AHB_RST_N(1) | DEVICESRESET_DDR_PHY_RST_N(1);
> +       // 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");
> +
> +       ux00ddr_writeregmap(UX00DDR_CTRL_ADDR, ddr_ctl_settings,
> +                           ddr_phy_settings);
> +       ux00ddr_disableaxireadinterleave(UX00DDR_CTRL_ADDR);
> +
> +       ux00ddr_disableoptimalrmodw(UX00DDR_CTRL_ADDR);
> +
> +       ux00ddr_enablewriteleveling(UX00DDR_CTRL_ADDR);
> +       ux00ddr_enablereadleveling(UX00DDR_CTRL_ADDR);
> +       ux00ddr_enablereadlevelinggate(UX00DDR_CTRL_ADDR);
> +       if (ux00ddr_getdramclass(UX00DDR_CTRL_ADDR) == DRAM_CLASS_DDR4)
> +               ux00ddr_enablevreftraining(UX00DDR_CTRL_ADDR);
> +       //mask off interrupts for leveling completion
> +       ux00ddr_mask_leveling_completed_interrupt(UX00DDR_CTRL_ADDR);
> +
> +       ux00ddr_mask_mc_init_complete_interrupt(UX00DDR_CTRL_ADDR);
> +       ux00ddr_mask_outofrange_interrupts(UX00DDR_CTRL_ADDR);
> +       ux00ddr_setuprangeprotection(UX00DDR_CTRL_ADDR, DDR_SIZE);
> +       ux00ddr_mask_port_command_error_interrupt(UX00DDR_CTRL_ADDR);
> +
> +       const u64 ddr_size = DDR_SIZE;
> +       const u64 ddr_end = CONFIG_SYS_SDRAM_BASE + ddr_size;
> +
> +       ux00ddr_start(UX00DDR_CTRL_ADDR, PHYSICAL_FILTER_CTRL_ADDR, ddr_end);
> +       ux00ddr_phy_fixup(UX00DDR_CTRL_ADDR);
> +
> +       //
> +       //GEMGXL init
> +       //
> +       u32 gemgxl125mhz =
> +               (PLL_R(0)) |
> +               (PLL_F(59)) |  /*4000Mhz VCO*/
> +               (PLL_Q(5)) |   /* /32 */
> +               (PLL_RANGE(0x4)) |
> +               (PLL_BYPASS(0)) |
> +               (PLL_FSE(1));
> +       UX00PRCI_REG(UX00PRCI_GEMGXLPLLCFG) = gemgxl125mhz;
> +
> +       // Wait for lock
> +       while ((UX00PRCI_REG(UX00PRCI_GEMGXLPLLCFG) & PLL_LOCK(1)) == 0)
> +               ;
> +
> +       u32 gemgxlctl_out =
> +               (PLLOUT_DIV(PLLOUT_DIV_default)) |
> +               (PLLOUT_DIV_BY_1(PLLOUT_DIV_BY_1_default)) |
> +               (PLLOUT_CLK_EN(1));
> +       UX00PRCI_REG(UX00PRCI_GEMGXLPLLOUT) = gemgxlctl_out;
> +
> +       //Release GEMGXL reset (set bit DEVICESRESET_GEMGXL to 1)
> +       UX00PRCI_REG(UX00PRCI_DEVICESRESETREG) |= DEVICESRESET_GEMGXL_RST_N(1);
> +
> +       // VSC8541 PHY reset sequence; leave pull-down active for 2ms
> +       nsleep(2000000);
> +       // Set GPIO 12 (PHY NRESET) to OE=1 and OVAL=1
> +       atomic_fetch_or(&GPIO_REG(GPIO_OUTPUT_VAL), PHY_NRESET);
> +       atomic_fetch_or(&GPIO_REG(GPIO_OUTPUT_EN),  PHY_NRESET);
> +       nsleep(100);
> +
> +       // Procmon => core clock
> +       UX00PRCI_REG(UX00PRCI_PROCMONCFG) = 0x1 << 24;
> +
> +       // Post the serial number and build info
> +       UART0_REG(UART_REG_TXCTRL) = UART_TXEN;
> +       puts("\r\nPRCI Initialized:       ");
> +
> +       unsigned int serial = ~0;
> +       int serial_slot;
> +       unsigned int pos;
> +       unsigned int neg;
> +
> +       ememory_otp_power_up_sequence();
> +       ememory_otp_begin_read();
> +       for (serial_slot = FIRST_SLOT; serial_slot >= LAST_SLOT;
> +                       serial_slot -= 2) {
> +               pos = ememory_otp_read(serial_slot);
> +               neg = ememory_otp_read(serial_slot + 1);
> +               serial = pos;
> +               if (pos == ~neg)
> +                       break; // legal serial #
> +               if (pos == ~0 && neg == ~0)
> +                       break; // empty slot encountered
> +       }
> +       ememory_otp_exit_read();
> +
> +       void *uart = (void *)UART0_CTRL_ADDR;
> +
> +       uart_puts(uart, "\r\nHiFive-U serial #: ");
> +       uart_put_hex(uart, serial);
> +
> +       // Program the OTP?
> +       if (serial_to_burn != ~0 && serial != serial_to_burn &&
> +           serial_slot > LAST_SLOT) {
> +               uart_puts(uart, "Programming serial: ");
> +               uart_put_hex(uart, serial_to_burn);
> +               uart_puts(uart, "\r\n");
> +               ememory_otp_pgm_entry();
> +               if (serial != ~0) {
> +                       // erase the current serial
> +                       uart_puts(uart, "Erasing prior serial\r\n");
> +                       ememory_otp_pgm_access(serial_slot,   0);
> +                       ememory_otp_pgm_access(serial_slot + 1, 0);
> +                       serial_slot -= 2;
> +               }
> +               ememory_otp_pgm_access(serial_slot,    serial_to_burn);
> +               ememory_otp_pgm_access(serial_slot + 1, ~serial_to_burn);
> +               ememory_otp_pgm_exit();
> +               uart_puts(uart, "Resuming boot\r\n");
> +               serial = serial_to_burn;
> +       }
> +
> +       ememory_otp_power_down_sequence();
> +       uart_puts(uart, "\r\n");
> +}
> +
> +void board_init_f(ulong dummy)
> +{
> +       int ret;
> +
> +       init_clk_and_ddr();
> +
> +       ret = spl_early_init();
> +       if (ret)
> +               panic("spl_early_init() failed: %d\n", ret);
> +
> +       arch_cpu_init_dm();
> +
> +       preloader_console_init();
> +}
> diff --git a/board/sifive/fu540/uart.c b/board/sifive/fu540/uart.c
> new file mode 100644
> index 0000000000..d16f6add47
> --- /dev/null
> +++ b/board/sifive/fu540/uart.c
> @@ -0,0 +1,64 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#include <stdatomic.h>
> +#include "include/fu540-memory-map.h"
> +#include "include/uart.h"
> +
> +void uart_putc(void *uartctrl, char c)
> +{
> +#if __riscv_atomic
> +       s32 r;
> +
> +       do {
> +               asm volatile ("amoor.w %0, %2, %1\n" : "=r" (r),
> +                             "+A" (_REG32(uartctrl, UART_REG_TXFIFO))
> +                             : "r" (c)
> +                            );
> +       } while (r < 0);
> +#else
> +       while ((int)_REG32(uartctrl, UART_REG_TXFIFO) < 0)
> +               ;
> +       _REG32(uartctrl, UART_REG_TXFIFO) = c;
> +#endif
> +}
> +
> +char uart_getc(void *uartctrl)
> +{
> +       s32 val = -1;
> +
> +       while (val < 0)
> +               val = (s32)_REG32(uartctrl, UART_REG_RXFIFO);
> +
> +       return val & 0xFF;
> +}
> +
> +void uart_puts(void *uartctrl, const char *s)
> +{
> +       while (*s != '\0')
> +               uart_putc(uartctrl, *s++);
> +}
> +
> +void uart_put_hex(void *uartctrl, u32 hex)
> +{
> +       int num_nibbles = sizeof(hex) * 2;
> +
> +       for (int nibble_idx = num_nibbles - 1; nibble_idx >= 0; nibble_idx--) {
> +               char nibble = (hex >> (nibble_idx * 4)) & 0xf;
> +
> +               uart_putc(uartctrl, (nibble < 0xa) ? ('0' + nibble) :
> +                         ('a' + nibble - 0xa));
> +       }
> +}
> +
> +void uart_put_hex64(void *uartctrl, uint64_t hex)
> +{
> +       uart_put_hex(uartctrl, hex >> 32);
> +       uart_put_hex(uartctrl, hex & 0xFFFFFFFF);
> +}
> diff --git a/configs/sifive_fu540_spl_defconfig b/configs/sifive_fu540_spl_defconfig
> new file mode 100644
> index 0000000000..6f9a70ee3e
> --- /dev/null
> +++ b/configs/sifive_fu540_spl_defconfig
> @@ -0,0 +1,23 @@
> +CONFIG_RISCV=y
> +CONFIG_ENV_SIZE=0x20000
> +CONFIG_NR_DRAM_BANKS=1
> +CONFIG_TARGET_SIFIVE_FU540=y
> +CONFIG_ARCH_RV64I=y
> +CONFIG_RISCV_SMODE=y
> +CONFIG_DISTRO_DEFAULTS=y
> +CONFIG_FIT=y
> +CONFIG_MISC_INIT_R=y
> +CONFIG_DEFAULT_DEVICE_TREE="hifive-unleashed-a00"
> +CONFIG_DISPLAY_CPUINFO=y
> +CONFIG_DISPLAY_BOARDINFO=y
> +CONFIG_OF_SEPARATE=y
> +CONFIG_SPL_SEPARATE_BSS=y
> +CONFIG_SYS_RELOC_GD_ENV_ADDR=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"
> diff --git a/include/configs/sifive-fu540.h b/include/configs/sifive-fu540.h
> index 2756ed5a77..5afc7ddb66 100644
> --- a/include/configs/sifive-fu540.h
> +++ b/include/configs/sifive-fu540.h
> @@ -11,6 +11,21 @@
>
>  #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 +39,7 @@
>
>  /* Environment options */
>
> +#ifndef CONFIG_SPL_BUILD
>  #define BOOT_TARGET_DEVICES(func) \
>         func(MMC, mmc, 0) \
>         func(DHCP, dhcp, na)
> @@ -43,5 +59,6 @@
>  #define CONFIG_PREBOOT \
>         "setenv fdt_addr ${fdtcontroladdr};" \
>         "fdt addr ${fdtcontroladdr};"
> +#endif
>
>  #endif /* __CONFIG_H */
> diff --git a/lib/Makefile b/lib/Makefile
> index 1fb650cd90..2d88c2ab5e 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -76,6 +76,7 @@ endif
>
>  ifdef CONFIG_SPL_BUILD
>  obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o
> +obj-$(CONFIG_MMC_SPI) += crc7.o
>  obj-$(CONFIG_$(SPL_TPL_)HASH_SUPPORT) += crc16.o
>  obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o
>  endif

Sorry, too much stuff in single patch. it is worth require multiple patches.

Jagan.

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

* [PATCH 1/3] riscv: Add place-holder for FU540 clk and gpio
  2019-12-31  6:30 ` [PATCH 1/3] riscv: Add place-holder for FU540 clk and gpio Pragnesh Patel
@ 2020-01-03 14:47   ` Bin Meng
  2020-01-06  9:07     ` Pragnesh Patel
  0 siblings, 1 reply; 19+ messages in thread
From: Bin Meng @ 2020-01-03 14:47 UTC (permalink / raw)
  To: u-boot

Hi Pragnesh,

On Tue, Dec 31, 2019 at 2:31 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> Added FU540 place-holder so that SoC specific values
> will be kept here.

It looks only clk.h is the placer-holder. gpio.h is not.

Can you please split the gpio.h changes to another patch?

>
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> ---
>  arch/riscv/include/asm/arch-fu540/clk.h    | 14 ++++++++
>  arch/riscv/include/asm/arch-fu540/gpio.h   | 42 ++++++++++++++++++++++
>  arch/riscv/include/asm/arch-generic/gpio.h | 32 ++---------------
>  board/sifive/fu540/Kconfig                 |  3 ++
>  4 files changed, 62 insertions(+), 29 deletions(-)
>  create mode 100644 arch/riscv/include/asm/arch-fu540/clk.h
>  create mode 100644 arch/riscv/include/asm/arch-fu540/gpio.h
>
> diff --git a/arch/riscv/include/asm/arch-fu540/clk.h b/arch/riscv/include/asm/arch-fu540/clk.h
> new file mode 100644
> index 0000000000..b39f5b55c9
> --- /dev/null
> +++ b/arch/riscv/include/asm/arch-fu540/clk.h
> @@ -0,0 +1,14 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc.
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + */
> +
> +#ifndef _CLK_FU540_H
> +#define _CLK_FU540_H
> +
> +/* Note: This is a placeholder header for driver compilation. */
> +
> +#endif
> diff --git a/arch/riscv/include/asm/arch-fu540/gpio.h b/arch/riscv/include/asm/arch-fu540/gpio.h

It looks this file is a copy of
arch/riscv/include/asm/arch-generic/gpio.h. Can you explain this a
little bit?

> new file mode 100644
> index 0000000000..f8ddd75852
> --- /dev/null
> +++ b/arch/riscv/include/asm/arch-fu540/gpio.h
> @@ -0,0 +1,42 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2019 SiFive, Inc.
> + *
> + * Authors:
> + *   Sagar Shrikant Kadam <sagar.kadam@sifive.com>
> + */
> +
> +#ifndef _GPIO_FU540_H
> +#define _GPIO_FU540_H
> +
> +#define GPIO_INPUT_VAL  (0x00)
> +#define GPIO_INPUT_EN   (0x04)
> +#define GPIO_OUTPUT_EN  (0x08)
> +#define GPIO_OUTPUT_VAL (0x0C)
> +#define GPIO_PULLUP_EN  (0x10)
> +#define GPIO_DRIVE      (0x14)
> +#define GPIO_RISE_IE    (0x18)
> +#define GPIO_RISE_IP    (0x1C)
> +#define GPIO_FALL_IE    (0x20)
> +#define GPIO_FALL_IP    (0x24)
> +#define GPIO_HIGH_IE    (0x28)
> +#define GPIO_HIGH_IP    (0x2C)
> +#define GPIO_LOW_IE     (0x30)
> +#define GPIO_LOW_IP     (0x34)
> +#define GPIO_IOF_EN     (0x38)
> +#define GPIO_IOF_SEL    (0x3C)
> +#define GPIO_OUTPUT_XOR    (0x40)
> +
> +#define NR_GPIOS       16
> +
> +enum gpio_state {
> +       LOW,
> +       HIGH
> +};
> +
> +/* Details about a GPIO bank */
> +struct sifive_gpio_platdata {
> +       void *base;     /* address of registers in physical memory */
> +};
> +
> +#endif /* _GPIO_FU540_H */
> diff --git a/arch/riscv/include/asm/arch-generic/gpio.h b/arch/riscv/include/asm/arch-generic/gpio.h
> index dfcb753051..5f0dc0a801 100644
> --- a/arch/riscv/include/asm/arch-generic/gpio.h
> +++ b/arch/riscv/include/asm/arch-generic/gpio.h
> @@ -3,33 +3,7 @@
>   * Copyright (C) 2019 SiFive, Inc.
>   */
>
> -#ifndef _GPIO_SIFIVE_H
> -#define _GPIO_SIFIVE_H
> +#ifndef __ASM_RISCV_ARCH_GPIO_H
> +#define __ASM_RISCV_ARCH_GPIO_H
>
> -#define GPIO_INPUT_VAL 0x00
> -#define GPIO_INPUT_EN  0x04
> -#define GPIO_OUTPUT_EN 0x08
> -#define GPIO_OUTPUT_VAL        0x0C
> -#define GPIO_RISE_IE   0x18
> -#define GPIO_RISE_IP   0x1C
> -#define GPIO_FALL_IE   0x20
> -#define GPIO_FALL_IP   0x24
> -#define GPIO_HIGH_IE   0x28
> -#define GPIO_HIGH_IP   0x2C
> -#define GPIO_LOW_IE    0x30
> -#define GPIO_LOW_IP    0x34
> -#define GPIO_OUTPUT_XOR        0x40
> -
> -#define NR_GPIOS       16
> -
> -enum gpio_state {
> -       LOW,
> -       HIGH
> -};
> -
> -/* Details about a GPIO bank */
> -struct sifive_gpio_platdata {
> -       void *base;     /* address of registers in physical memory */
> -};
> -
> -#endif /* _GPIO_SIFIVE_H */
> +#endif /* __ASM_RISCV_ARCH_GPIO_H */
> diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
> index 5ca21474de..816a135b21 100644
> --- a/board/sifive/fu540/Kconfig
> +++ b/board/sifive/fu540/Kconfig
> @@ -12,6 +12,9 @@ config SYS_CPU
>  config SYS_CONFIG_NAME
>         default "sifive-fu540"
>
> +config SYS_SOC
> +       default "fu540"

What about SYS_CPU?

Shouldn't we just rename SYS_CPU to SYS_SOC in this file and assign
"fu540" to it?

> +
>  config SYS_TEXT_BASE
>         default 0x80000000 if !RISCV_SMODE
>         default 0x80200000 if RISCV_SMODE
> --

Regards,
Bin

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

* [PATCH 2/3] riscv: Add FU540 specific includes
  2019-12-31  6:30 ` [PATCH 2/3] riscv: Add FU540 specific includes Pragnesh Patel
@ 2020-01-03 14:51   ` Bin Meng
  2020-01-06  9:41     ` Pragnesh Patel
  0 siblings, 1 reply; 19+ messages in thread
From: Bin Meng @ 2020-01-03 14:51 UTC (permalink / raw)
  To: u-boot

Hi Pragnesh,

On Tue, Dec 31, 2019 at 10:00 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> Added headers needed by upcoming SPL support of FU540.
>
> This headers are leveraged from FSBL
> (https://github.com/sifive/freedom-u540-c000-bootloader.git)
>
> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
> ---
>  arch/riscv/include/asm/arch-fu540/cache.h | 43 ++++++++++++
>  arch/riscv/include/asm/arch-fu540/clint.h | 20 ++++++
>  arch/riscv/include/asm/arch-fu540/i2c.h   | 48 +++++++++++++
>  arch/riscv/include/asm/arch-fu540/otp.h   | 80 +++++++++++++++++++++
>  arch/riscv/include/asm/arch-fu540/spi.h   | 86 +++++++++++++++++++++++
>  arch/riscv/include/asm/arch-fu540/uart.h  | 35 +++++++++
>  6 files changed, 312 insertions(+)
>  create mode 100644 arch/riscv/include/asm/arch-fu540/cache.h
>  create mode 100644 arch/riscv/include/asm/arch-fu540/clint.h
>  create mode 100644 arch/riscv/include/asm/arch-fu540/i2c.h
>  create mode 100644 arch/riscv/include/asm/arch-fu540/otp.h
>  create mode 100644 arch/riscv/include/asm/arch-fu540/spi.h
>  create mode 100644 arch/riscv/include/asm/arch-fu540/uart.h
>
> diff --git a/arch/riscv/include/asm/arch-fu540/cache.h b/arch/riscv/include/asm/arch-fu540/cache.h
> new file mode 100644
> index 0000000000..9043779650
> --- /dev/null
> +++ b/arch/riscv/include/asm/arch-fu540/cache.h
> @@ -0,0 +1,43 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2019 SiFive, Inc.
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef _CACHE_FU540_H
> +#define _CACHE_FU540_H
> +
> +/* Register offsets */
> +#define CCACHE_INFO         0x000
> +#define CCACHE_ENABLE       0x008
> +#define CCACHE_INJECT       0x040
> +#define CCACHE_META_FIX     0x100
> +#define CCACHE_DATA_FIX     0x140
> +#define CCACHE_DATA_FAIL    0x160
> +#define CCACHE_FLUSH64      0x200
> +#define CCACHE_FLUSH32      0x240
> +#define CCACHE_WAYS         0x800
> +
> +/* Bytes inside the INFO field */
> +#define CCACHE_INFO_BANKS           0
> +#define CCACHE_INFO_WAYS            1
> +#define CCACHE_INFO_LG_SETS         2
> +#define CCACHE_INFO_LG_BLOCKBYTES   3
> +
> +/* INJECT types */
> +#define CCACHE_ECC_TOGGLE_DATA  0x00000
> +#define CCACHE_ECC_TOGGLE_META  0x10000
> +
> +/* Offsets per FIX/FAIL */
> +#define CCACHE_ECC_ADDR     0x0
> +#define CCACHE_ECC_COUNT    0x8
> +
> +/* Interrupt Number offsets from Base */
> +#define CCACHE_INT_META_FIX     0
> +#define CCACHE_INT_DATA_FIX     1
> +#define CCACHE_INT_DATA_FAIL    2
> +
> +#endif /* _CACHE_FU540_H */
> diff --git a/arch/riscv/include/asm/arch-fu540/clint.h b/arch/riscv/include/asm/arch-fu540/clint.h
> new file mode 100644
> index 0000000000..f740f30f2d
> --- /dev/null
> +++ b/arch/riscv/include/asm/arch-fu540/clint.h
> @@ -0,0 +1,20 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2019 SiFive, Inc.
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef _CLINT_FU540_H
> +#define _CLINT_FU540_H
> +
> +#define CLINT_MSIP 0x0000
> +#define CLINT_MSIP_size   0x4
> +#define CLINT_MTIMECMP 0x4000
> +#define CLINT_MTIMECMP_size 0x8
> +#define CLINT_MTIME 0xBFF8
> +#define CLINT_MTIME_size 0x8
> +

nits: please have the value indented

> +#endif /* _CLINT_FU540_H */
> diff --git a/arch/riscv/include/asm/arch-fu540/i2c.h b/arch/riscv/include/asm/arch-fu540/i2c.h
> new file mode 100644
> index 0000000000..66cc3edd94
> --- /dev/null
> +++ b/arch/riscv/include/asm/arch-fu540/i2c.h
> @@ -0,0 +1,48 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2019 SiFive, Inc.
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef _I2C_FU540_H
> +#define _I2C_FU540_H
> +
> +// CHECK: word vs byte alignment
> +// OC I2C Linux driver defines registers w/o alignment:
> +// http://lxr.free-electrons.com/source/drivers/i2c/busses/i2c-ocores.c?v=4.6#L46
> +//
> +// However, register accessor functions use reg_shift value
> +// http://lxr.free-electrons.com/source/drivers/i2c/busses/i2c-ocores.c?v=4.6#L80
> +// which is platform specific:
> +// http://lxr.free-electrons.com/source/drivers/i2c/busses/i2c-ocores.c?v=4.6#L346

nits: please use /* */ for the comment format

> +
> +#define I2C_PRESCALER_LO  (0x00)
> +#define I2C_PRESCALER_HI  (0x04)
> +#define I2C_CONTROL       (0x08)
> +#define I2C_DATA          (0x0C)
> +#define I2C_CMD           (0x10) /* write only */
> +#define I2C_STATUS        (0x10) /* read only, same address as I2C_CMD */
> +
> +// I2C_CONTROL register
> +#define I2C_CONTROL_CORE_EN(x)  (((x) & 0x1) << 7)
> +#define I2C_CONTROL_INT_EN(x)   (((x) & 0x1) << 6)
> +
> +// I2C_CMD register
> +#define I2C_CMD_START(x)              (((x) & 0x1) << 7)
> +#define I2C_CMD_STOP(x)               (((x) & 0x1) << 6)
> +#define I2C_CMD_READ(x)               (((x) & 0x1) << 5)
> +#define I2C_CMD_WRITE(x)              (((x) & 0x1) << 4)
> +#define I2C_CMD_NACK(x)               (((x) & 0x1) << 3)
> +#define I2C_CMD_IRQ_ACK(x)            (((x) & 0x1))
> +
> +// I2C_STATUS register
> +#define I2C_STATUS_RECEIVED_NACK(x)   (((x) & 0x80) >> 7)
> +#define I2C_STATUS_BUSY(x)            (((x) & 0x40) >> 6)
> +#define I2C_STATUS_ARB_LOST(x)        (((x) & 0x20) >> 5)
> +#define I2C_STATUS_TRS_INPROGRESS(x)  (((x) & 0x02) >> 1)
> +#define I2C_STATUS_IRQ_FLAG(x)        (((x) & 0x01))
> +
> +#endif /* _I2C_FU540_H */
> diff --git a/arch/riscv/include/asm/arch-fu540/otp.h b/arch/riscv/include/asm/arch-fu540/otp.h
> new file mode 100644
> index 0000000000..588e525765
> --- /dev/null
> +++ b/arch/riscv/include/asm/arch-fu540/otp.h
> @@ -0,0 +1,80 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2019 SiFive, Inc.
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef _OTP_FU540_H
> +#define _OTP_FU540_H
> +
> +/* Register offsets */
> +
> +#define EMEMORYOTP_PA                 0x00
> +#define EMEMORYOTP_PAIO               0x04
> +#define EMEMORYOTP_PAS                0x08
> +#define EMEMORYOTP_PCE                0x0C
> +#define EMEMORYOTP_PCLK               0x10
> +#define EMEMORYOTP_PDIN               0x14
> +#define EMEMORYOTP_PDOUT              0x18
> +#define EMEMORYOTP_PDSTB              0x1C
> +#define EMEMORYOTP_PPROG              0x20
> +#define EMEMORYOTP_PTC                0x24
> +#define EMEMORYOTP_PTM                0x28
> +#define EMEMORYOTP_PTM_REP            0x2C
> +#define EMEMORYOTP_PTR                0x30
> +#define EMEMORYOTP_PTRIM              0x34
> +#define EMEMORYOTP_PWE                0x38
> +
> +/* Timing delays (in us)
> + * MIN indicates that there is no maximum.
> + * TYP indicates that there is a maximum
> + * that should not be exceeded.
> + * When the minimums are < 1us, I just put 1us.
> + */
> +
> +#define EMEMORYOTP_MIN_TVDS      1
> +#define EMEMORYOTP_MIN_TSAS      2
> +#define EMEMORYOTP_MIN_TTAS      50
> +#define EMEMORYOTP_MIN_TTAH      1
> +#define EMEMORYOTP_MIN_TASH      1
> +#define EMEMORYOTP_MIN_TMS       1
> +#define EMEMORYOTP_MIN_TCS       10
> +#define EMEMORYOTP_MIN_TMH       1
> +#define EMEMORYOTP_MIN_TAS       50
> +
> +#define EMEMORYOTP_MAX_TCD       1
> +#define EMEMORYOTP_MIN_TKH       1
> +
> +// Note: This has an upper limit of 100.
> +#define EMEMORYOTP_MIN_TCSP      10
> +#define EMEMORYOTP_TYP_TCSP      11
> +
> +// This has an upper limit of 20.
> +#define EMEMORYOTP_MIN_TPPS      5
> +#define EMEMORYOTP_TYP_TPPS      6
> +
> +// This has an upper limit of 20.
> +#define EMEMORYOTP_MIN_TPPH      1
> +#define EMEMORYOTP_TYP_TPPH      2
> +
> +// This has upper limit of 100.
> +#define EMEMORYOTP_MIN_TPPR      5
> +#define EMEMORYOTP_TYP_TPPR      6
> +
> +// This has upper limit of 20
> +#define EMEMORYOTP_MIN_TPW       10
> +#define EMEMORYOTP_TYP_TPW       11
> +
> +#define EMEMORYOTP_MIN_TASP      1
> +#define EMEMORYOTP_MIN_TDSP      1
> +
> +#define EMEMORYOTP_MIN_TAHP      1
> +#define EMEMORYOTP_MIN_TDHP      1
> +// This has a max of 5!
> +#define EMEMORYOTP_MIN_TPWI      1
> +#define EMEMORYOTP_TYP_TPWI      2
> +
> +#endif /* _OTP_FU540_H */
> diff --git a/arch/riscv/include/asm/arch-fu540/spi.h b/arch/riscv/include/asm/arch-fu540/spi.h
> new file mode 100644
> index 0000000000..ea3f5344b7
> --- /dev/null
> +++ b/arch/riscv/include/asm/arch-fu540/spi.h
> @@ -0,0 +1,86 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2019 SiFive, Inc.
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef _SPI_FU540_H
> +#define _SPI_FU540_H
> +
> +/* Register offsets */
> +
> +#define SPI_REG_SCKDIV          0x00
> +#define SPI_REG_SCKMODE         0x04
> +#define SPI_REG_CSID            0x10
> +#define SPI_REG_CSDEF           0x14
> +#define SPI_REG_CSMODE          0x18
> +
> +#define SPI_REG_DCSSCK          0x28
> +#define SPI_REG_DSCKCS          0x2a
> +#define SPI_REG_DINTERCS        0x2c
> +#define SPI_REG_DINTERXFR       0x2e
> +
> +#define SPI_REG_FMT             0x40
> +#define SPI_REG_TXFIFO          0x48
> +#define SPI_REG_RXFIFO          0x4c
> +#define SPI_REG_TXCTRL          0x50
> +#define SPI_REG_RXCTRL          0x54
> +
> +#define SPI_REG_FCTRL           0x60
> +#define SPI_REG_FFMT            0x64
> +
> +#define SPI_REG_IE              0x70
> +#define SPI_REG_IP              0x74
> +
> +/* Fields */
> +
> +#define SPI_SCK_PHA             0x1
> +#define SPI_SCK_POL             0x2
> +
> +#define SPI_FMT_PROTO(x)        ((x) & 0x3)
> +#define SPI_FMT_ENDIAN(x)       (((x) & 0x1) << 2)
> +#define SPI_FMT_DIR(x)          (((x) & 0x1) << 3)
> +#define SPI_FMT_LEN(x)          (((x) & 0xf) << 16)
> +
> +/* TXCTRL register */
> +#define SPI_TXWM(x)             ((x) & 0xffff)
> +/* RXCTRL register */
> +#define SPI_RXWM(x)             ((x) & 0xffff)
> +
> +#define SPI_IP_TXWM             0x1
> +#define SPI_IP_RXWM             0x2
> +
> +#define SPI_FCTRL_EN            0x1
> +
> +#define SPI_INSN_CMD_EN         0x1
> +#define SPI_INSN_ADDR_LEN(x)    (((x) & 0x7) << 1)
> +#define SPI_INSN_PAD_CNT(x)     (((x) & 0xf) << 4)
> +#define SPI_INSN_CMD_PROTO(x)   (((x) & 0x3) << 8)
> +#define SPI_INSN_ADDR_PROTO(x)  (((x) & 0x3) << 10)
> +#define SPI_INSN_DATA_PROTO(x)  (((x) & 0x3) << 12)
> +#define SPI_INSN_CMD_CODE(x)    (((x) & 0xff) << 16)
> +#define SPI_INSN_PAD_CODE(x)    (((x) & 0xff) << 24)
> +
> +#define SPI_TXFIFO_FULL  BIT(31)
> +#define SPI_RXFIFO_EMPTY BIT(31)
> +
> +/* Values */
> +
> +#define SPI_CSMODE_AUTO         0
> +#define SPI_CSMODE_HOLD         2
> +#define SPI_CSMODE_OFF          3
> +
> +#define SPI_DIR_RX              0
> +#define SPI_DIR_TX              1
> +
> +#define SPI_PROTO_S             0
> +#define SPI_PROTO_D             1
> +#define SPI_PROTO_Q             2
> +
> +#define SPI_ENDIAN_MSB          0
> +#define SPI_ENDIAN_LSB          1
> +
> +#endif /* _SPI_FU540_H */
> diff --git a/arch/riscv/include/asm/arch-fu540/uart.h b/arch/riscv/include/asm/arch-fu540/uart.h
> new file mode 100644
> index 0000000000..31ae079a18
> --- /dev/null
> +++ b/arch/riscv/include/asm/arch-fu540/uart.h
> @@ -0,0 +1,35 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2019 SiFive, Inc.
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef _UART_FU540_H
> +#define _UART_FU540_H
> +
> +/* Register offsets */
> +#define UART_REG_TXFIFO         0x00
> +#define UART_REG_RXFIFO         0x04
> +#define UART_REG_TXCTRL         0x08
> +#define UART_REG_RXCTRL         0x0c
> +#define UART_REG_IE             0x10
> +#define UART_REG_IP             0x14
> +#define UART_REG_DIV            0x18
> +
> +/* TXCTRL register */
> +#define UART_TXEN               0x1
> +#define UART_TXNSTOP            0x2
> +#define UART_TXWM(x)            (((x) & 0xffff) << 16)
> +
> +/* RXCTRL register */
> +#define UART_RXEN               0x1
> +#define UART_RXWM(x)            (((x) & 0xffff) << 16)
> +
> +/* IP register */
> +#define UART_IP_TXWM            0x1
> +#define UART_IP_RXWM            0x2
> +
> +#endif /* _UART_FU540_H */
> --

One generic comment, I think we need add these header files at the
same time when we add something to the FU540 SoC support, and I doubt
all of them are needed.

Regards,
Bin

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

* [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
  2019-12-31  6:30 ` [PATCH 3/3] riscv: sifive: fu540: add SPL configuration Pragnesh Patel
  2019-12-31 17:18   ` Amit Tomer
  2020-01-02  4:58   ` Jagan Teki
@ 2020-01-03 15:34   ` Bin Meng
  2020-01-13 14:54     ` Pragnesh Patel
  2 siblings, 1 reply; 19+ messages in thread
From: Bin Meng @ 2020-01-03 15:34 UTC (permalink / raw)
  To: u-boot

Hi Pragnesh,

On Tue, Dec 31, 2019 at 2:31 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> This patch provides sifive_fu540_spl_defconfig which can support
> U-boot SPL to boot from L2 LIM (0x0800_0000) and then boot FIT

nits: U-Boot

> image including OpenSBI FW_DYNAMIC firmware and U-Boot proper
> images from MMC boot devices.
>
> With sifive_fu540_spl_defconfig:
>
> 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 SD card (replace fw_payload.bin with u-boot.itb)
> into RAM.
>
> 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>
> ---
>  arch/riscv/cpu/u-boot-spl.lds                 |    1 +
>  arch/riscv/dts/fu540-c000-u-boot.dtsi         |   65 +
>  .../dts/hifive-unleashed-a00-u-boot.dtsi      |   24 +
>  arch/riscv/include/asm/csr.h                  |    2 +
>  board/sifive/fu540/Kconfig                    |    8 +
>  board/sifive/fu540/MAINTAINERS                |    1 +
>  board/sifive/fu540/Makefile                   |    6 +
>  board/sifive/fu540/ememoryotp.c               |  143 ++
>  board/sifive/fu540/fu540.c                    |   31 +-
>  board/sifive/fu540/include/ccache.h           |   47 +
>  board/sifive/fu540/include/clkutils.h         |   75 +
>  board/sifive/fu540/include/ddrregs.h          |  622 +++++++++
>  board/sifive/fu540/include/ememoryotp.h       |   24 +
>  board/sifive/fu540/include/fu540-memory-map.h |  427 ++++++
>  board/sifive/fu540/include/i2c.h              |   49 +
>  board/sifive/fu540/include/regconfig-ctl.h    |  274 ++++
>  board/sifive/fu540/include/regconfig-phy.h    | 1224 +++++++++++++++++
>  board/sifive/fu540/include/spi.h              |  233 ++++
>  board/sifive/fu540/include/uart.h             |   54 +
>  board/sifive/fu540/include/ux00ddr.h          |  268 ++++
>  board/sifive/fu540/include/ux00prci.h         |  206 +++
>  board/sifive/fu540/spl.c                      |  321 +++++
>  board/sifive/fu540/uart.c                     |   64 +
>  configs/sifive_fu540_spl_defconfig            |   23 +
>  include/configs/sifive-fu540.h                |   17 +
>  lib/Makefile                                  |    1 +
>  26 files changed, 4209 insertions(+), 1 deletion(-)
>  create mode 100644 arch/riscv/dts/fu540-c000-u-boot.dtsi
>  create mode 100644 arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>  create mode 100644 board/sifive/fu540/ememoryotp.c
>  create mode 100644 board/sifive/fu540/include/ccache.h
>  create mode 100644 board/sifive/fu540/include/clkutils.h
>  create mode 100644 board/sifive/fu540/include/ddrregs.h
>  create mode 100644 board/sifive/fu540/include/ememoryotp.h
>  create mode 100644 board/sifive/fu540/include/fu540-memory-map.h
>  create mode 100644 board/sifive/fu540/include/i2c.h
>  create mode 100644 board/sifive/fu540/include/regconfig-ctl.h
>  create mode 100644 board/sifive/fu540/include/regconfig-phy.h
>  create mode 100644 board/sifive/fu540/include/spi.h
>  create mode 100644 board/sifive/fu540/include/uart.h
>  create mode 100644 board/sifive/fu540/include/ux00ddr.h
>  create mode 100644 board/sifive/fu540/include/ux00prci.h
>  create mode 100644 board/sifive/fu540/spl.c
>  create mode 100644 board/sifive/fu540/uart.c
>  create mode 100644 configs/sifive_fu540_spl_defconfig
>
> 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 = .;

This should be a separate patch.

>
>         .bss : {
>                 __bss_start = .;
> 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..b86cdfb38d
> --- /dev/null
> +++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
> @@ -0,0 +1,65 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2019 SiFive, Inc
> + */
> +
> +/ {
> +       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;
> +                       cpu1_intc: interrupt-controller {
> +                               u-boot,dm-spl;
> +                       };
> +               };
> +               cpu2: cpu at 2 {
> +                       u-boot,dm-spl;
> +                       cpu2_intc: interrupt-controller {
> +                               u-boot,dm-spl;
> +                       };
> +               };
> +               cpu3: cpu at 3 {
> +                       u-boot,dm-spl;
> +                       cpu3_intc: interrupt-controller {
> +                               u-boot,dm-spl;
> +                       };
> +               };
> +               cpu4: cpu at 4 {
> +                       u-boot,dm-spl;
> +                       cpu4_intc: interrupt-controller {
> +                               u-boot,dm-spl;
> +                       };
> +               };
> +       };
> +
> +       soc {
> +               u-boot,dm-spl;
> +               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;
> +};

Are all of these peripherals needed in SPL?

> 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..9b59f4ee14
> --- /dev/null
> +++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
> @@ -0,0 +1,24 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2019 SiFive, Inc
> + */
> +
> +#include "fu540-c000-u-boot.dtsi"
> +
> +/ {
> +       hfclk {
> +               u-boot,dm-spl;
> +       };
> +
> +       rtcclk {
> +               u-boot,dm-spl;
> +       };
> +};
> +
> +&qspi2 {
> +
> +       mmc at 0 {
> +               u-boot,dm-spl;
> +       };
> +
> +};
> diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
> index d1520743a2..125c05dd8a 100644
> --- a/arch/riscv/include/asm/csr.h
> +++ b/arch/riscv/include/asm/csr.h
> @@ -103,6 +103,8 @@
>  #define CSR_TIMEH              0xc81
>  #define CSR_INSTRETH           0xc82
>  #define CSR_MHARTID            0xf14
> +#define CSR_MCYCLE             0xb00
> +#define CSR_MCYCLEH            0xb80
>
>  #ifndef __ASSEMBLY__
>
> diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
> index 816a135b21..ac7c6bff37 100644
> --- a/board/sifive/fu540/Kconfig
> +++ b/board/sifive/fu540/Kconfig
> @@ -16,12 +16,20 @@ config SYS_SOC
>         default "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/MAINTAINERS b/board/sifive/fu540/MAINTAINERS
> index 702d803ad8..42c3f3deb0 100644
> --- a/board/sifive/fu540/MAINTAINERS
> +++ b/board/sifive/fu540/MAINTAINERS
> @@ -7,3 +7,4 @@ S:      Maintained
>  F:     board/sifive/fu540/
>  F:     include/configs/sifive-fu540.h
>  F:     configs/sifive_fu540_defconfig
> +F:     configs/sifive_fu540_spl_defconfig
> diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
> index 6e1862c475..e532beb9d5 100644
> --- a/board/sifive/fu540/Makefile
> +++ b/board/sifive/fu540/Makefile
> @@ -3,3 +3,9 @@
>  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
>
>  obj-y  += fu540.o
> +
> +ifdef CONFIG_SPL_BUILD
> +obj-y += spl.o
> +obj-y += ememoryotp.o
> +obj-y += uart.o
> +endif
> diff --git a/board/sifive/fu540/ememoryotp.c b/board/sifive/fu540/ememoryotp.c
> new file mode 100644
> index 0000000000..994724af37
> --- /dev/null
> +++ b/board/sifive/fu540/ememoryotp.c
> @@ -0,0 +1,143 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#include <stdint.h>
> +#include "include/fu540-memory-map.h"
> +#include "include/clkutils.h"
> +#include "include/ememoryotp.h"
> +
> +#define max(x, y) ((x) > (y) ? (x) : (y))
> +
> +extern inline void clkutils_delay_ns(int delay_ns);
> +
> +void ememory_otp_power_up_sequence(void)
> +{
> +       // Probably don't need to do this, since
> +       // all the other stuff has been happening.
> +       // But it is on the wave form.
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TVDS * 1000);
> +
> +       EMEMORYOTP_REG(EMEMORYOTP_PDSTB) = 1;
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TSAS * 1000);
> +
> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 1;
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TTAS * 1000);
> +}
> +
> +void ememory_otp_power_down_sequence(void)
> +{
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TTAH * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 0;
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TASH * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PDSTB) = 0;
> +       // No delay indicated after this
> +}
> +
> +void ememory_otp_begin_read(void)
> +{
> +       // Initialize
> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 0;
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMS * 1000);
> +
> +       // Enable chip select
> +
> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 1;
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TCS * 1000);
> +}
> +
> +void ememory_otp_exit_read(void)
> +{
> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
> +       // Disable chip select
> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 0;
> +       // Wait before changing PTM
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMH * 1000);
> +}
> +
> +unsigned int ememory_otp_read(int address)
> +{
> +       unsigned int read_value;
> +
> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = address;
> +       // Toggle clock
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TAS * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 1;
> +       // Insert delay until data is ready.
> +       // There are lots of delays
> +       // on the chart, but I think this is the most relevant.
> +       int delay = max(EMEMORYOTP_MAX_TCD, EMEMORYOTP_MIN_TKH);
> +
> +       clkutils_delay_ns(delay * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
> +       read_value = EMEMORYOTP_REG(EMEMORYOTP_PDOUT);
> +       // Could check here for things like TCYC < TAH + TCD
> +       return read_value;
> +}
> +
> +void ememory_otp_pgm_entry(void)
> +{
> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PAS) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PAIO) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 2;
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMS * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 1;
> +       clkutils_delay_ns(EMEMORYOTP_TYP_TCSP * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PPROG) = 1;
> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPS * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 1;
> +}
> +
> +void ememory_otp_pgm_exit(void)
> +{
> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPH * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PPROG) = 0;
> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPR * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 0;
> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMH * 1000);
> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 0;
> +}
> +
> +void ememory_otp_pgm_access(int address, unsigned int write_data)
> +{
> +       int i;
> +
> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = address;
> +       for (int pas = 0; pas < 2; pas++) {
> +               EMEMORYOTP_REG(EMEMORYOTP_PAS) = pas;
> +               for (i = 0; i < 32; i++) {
> +                       EMEMORYOTP_REG(EMEMORYOTP_PAIO) = i;
> +                       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = ((write_data >> i) &
> +                                                          1);
> +
> +                       int delay = max(EMEMORYOTP_MIN_TASP,
> +                                       EMEMORYOTP_MIN_TDSP);
> +
> +                       clkutils_delay_ns(delay * 1000);
> +                       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 1;
> +                       clkutils_delay_ns(EMEMORYOTP_TYP_TPW * 1000);
> +                       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
> +                       delay = max(EMEMORYOTP_MIN_TAHP, EMEMORYOTP_MIN_TDHP);
> +                       delay = max(delay, EMEMORYOTP_TYP_TPWI);
> +                       clkutils_delay_ns(delay * 1000);
> +               }
> +       }
> +       EMEMORYOTP_REG(EMEMORYOTP_PAS) = 0;
> +}
> diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
> index 47a2090251..e91418a88a 100644
> --- a/board/sifive/fu540/fu540.c
> +++ b/board/sifive/fu540/fu540.c
> @@ -10,6 +10,9 @@
>  #include <dm.h>
>  #include <linux/delay.h>
>  #include <linux/io.h>
> +#include <spl.h>
> +#include "include/ccache.h"
> +#include "include/fu540-memory-map.h"
>
>  #ifdef CONFIG_MISC_INIT_R
>
> @@ -143,7 +146,33 @@ int misc_init_r(void)
>
>  int board_init(void)
>  {
> -       /* For now nothing to do here. */
> +       /* enable all cache ways */
> +       ccache_enable_ways(CCACHE_CTRL_ADDR, 15);
> +       return 0;
> +}
> +
> +#ifdef CONFIG_SPL
> +void board_boot_order(u32 *spl_boot_list)
> +{
> +       u8 i;
> +       u32 boot_devices[] = {
> +#ifdef CONFIG_SPL_RAM_SUPPORT
> +               BOOT_DEVICE_RAM,
> +#endif
> +#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/include/ccache.h b/board/sifive/fu540/include/ccache.h
> new file mode 100644
> index 0000000000..c7978ebdee
> --- /dev/null
> +++ b/board/sifive/fu540/include/ccache.h
> @@ -0,0 +1,47 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef FU540_CCACHE_H
> +#define FU540_CCACHE_H
> +
> +#include <asm/arch/cache.h>
> +
> +#ifndef __ASSEMBLER__
> +
> +#include <stdint.h>
> +#include <stdatomic.h>
> +#include <linux/types.h>
> +
> +// Block memory access until operation completed
> +static inline void ccache_barrier_0(void)
> +{
> +       asm volatile("fence rw, io" : : : "memory");
> +}
> +
> +static inline void ccache_barrier_1(void)
> +{
> +       asm volatile("fence io, rw" : : : "memory");
> +}
> +
> +// Enable ways; allow cache to use these ways
> +static inline u8 ccache_enable_ways(u64 base_addr, u8 value)
> +{
> +       u32 old;
> +
> +       volatile _Atomic(u32) * enable = (_Atomic(u32) *)(base_addr +
> +                                         CCACHE_ENABLE);
> +       ccache_barrier_0();
> +       old = atomic_exchange_explicit(enable, value, memory_order_relaxed);

How does this work as we are calling a C11 API?

> +       ccache_barrier_1();
> +       return old;
> +}
> +
> +#endif
> +
> +#endif /* FU540_CCACHE_H */
> diff --git a/board/sifive/fu540/include/clkutils.h b/board/sifive/fu540/include/clkutils.h
> new file mode 100644
> index 0000000000..dbb260a1c3
> --- /dev/null
> +++ b/board/sifive/fu540/include/clkutils.h
> @@ -0,0 +1,75 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef __ASSEMBLER__
> +
> +#include <stdint.h>
> +#include <asm/encoding.h>
> +#include "fu540-memory-map.h"
> +
> +// Inlining header functions in C
> +// https://stackoverflow.com/a/23699777/7433423
> +inline u64 clkutils_read_mtime(void)
> +{
> +#if __riscv_xlen == 32
> +       u32 mtime_hi_0;
> +       u32 mtime_lo;
> +       u32 mtime_hi_1;
> +
> +       do {
> +               mtime_hi_0 = CLINT_REG(CLINT_MTIME + 4);
> +               mtime_lo   = CLINT_REG(CLINT_MTIME + 0);
> +               mtime_hi_1 = CLINT_REG(CLINT_MTIME + 4);
> +       } while (mtime_hi_0 != mtime_hi_1);
> +
> +       return (((u64)mtime_hi_1 << 32) | ((u64)mtime_lo));
> +#else
> +       return CLINT_REG64(CLINT_MTIME);
> +#endif
> +}
> +
> +static inline u64 clkutils_read_mcycle(void)
> +{
> +#if __riscv_xlen == 32
> +       u32 mcycle_hi_0;
> +       u32 mcycle_lo;
> +       u32 mcycle_hi_1;
> +
> +       do {
> +               mcycle_hi_0 = read_csr(mcycleh);
> +               mcycle_lo   = read_csr(mcycle);
> +               mcycle_hi_1 = read_csr(mcycleh);
> +       } while (mcycle_hi_0 != mcycle_hi_1);
> +
> +       return (((u64)mcycle_hi_1 << 32) | ((u64)mcycle_lo));
> +#else
> +       return csr_read(CSR_MCYCLE);
> +#endif
> +}
> +
> +// Note that since this runs off RTC, which is
> +// currently ~1-10MHz, this function is
> +// not acccurate for small delays.
> +// In the future, we may want to determine whether to
> +// use RTC vs mcycle, or create a different function
> +// based off mcycle.
> +// We add 1 to the then value because otherwise, if you wanted
> +// to delay up to RTC_PERIOD_NS-1 (for example), you wouldn't delay
> +// at all. So this function delays AT LEAST delay_ns.
> +inline void clkutils_delay_ns(int delay_ns)
> +{
> +       u64 now = clkutils_read_mtime();
> +       u64 then = now + delay_ns / RTC_PERIOD_NS + 1;
> +
> +       do {
> +               now = clkutils_read_mtime();
> +       } while (now < then);
> +}
> +
> +#endif /* !__ASSEMBLER__ */
> diff --git a/board/sifive/fu540/include/ddrregs.h b/board/sifive/fu540/include/ddrregs.h
> new file mode 100644
> index 0000000000..e436496d87
> --- /dev/null
> +++ b/board/sifive/fu540/include/ddrregs.h
> @@ -0,0 +1,622 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#include <stdint.h>
> +
> +u32 DENALI_PHY_DATA[1215] = {

This is declaring a variable and should not be put in a header file.

> +       DENALI_PHY_00_DATA, DENALI_PHY_01_DATA, DENALI_PHY_02_DATA,
> +       DENALI_PHY_03_DATA, DENALI_PHY_04_DATA, DENALI_PHY_05_DATA,
> +       DENALI_PHY_06_DATA, DENALI_PHY_07_DATA, DENALI_PHY_08_DATA,
> +       DENALI_PHY_09_DATA,
> +       DENALI_PHY_10_DATA, DENALI_PHY_11_DATA, DENALI_PHY_12_DATA,
> +       DENALI_PHY_13_DATA, DENALI_PHY_14_DATA, DENALI_PHY_15_DATA,
> +       DENALI_PHY_16_DATA, DENALI_PHY_17_DATA, DENALI_PHY_18_DATA,
> +       DENALI_PHY_19_DATA,
> +       DENALI_PHY_20_DATA, DENALI_PHY_21_DATA, DENALI_PHY_22_DATA,
> +       DENALI_PHY_23_DATA, DENALI_PHY_24_DATA, DENALI_PHY_25_DATA,
> +       DENALI_PHY_26_DATA, DENALI_PHY_27_DATA, DENALI_PHY_28_DATA,
> +       DENALI_PHY_29_DATA,
> +       DENALI_PHY_30_DATA, DENALI_PHY_31_DATA, DENALI_PHY_32_DATA,
> +       DENALI_PHY_33_DATA, DENALI_PHY_34_DATA, DENALI_PHY_35_DATA,
> +       DENALI_PHY_36_DATA, DENALI_PHY_37_DATA, DENALI_PHY_38_DATA,
> +       DENALI_PHY_39_DATA,
> +       DENALI_PHY_40_DATA, DENALI_PHY_41_DATA, DENALI_PHY_42_DATA,
> +       DENALI_PHY_43_DATA, DENALI_PHY_44_DATA, DENALI_PHY_45_DATA,
> +       DENALI_PHY_46_DATA, DENALI_PHY_47_DATA, DENALI_PHY_48_DATA,
> +       DENALI_PHY_49_DATA,
> +       DENALI_PHY_50_DATA, DENALI_PHY_51_DATA, DENALI_PHY_52_DATA,
> +       DENALI_PHY_53_DATA, DENALI_PHY_54_DATA, DENALI_PHY_55_DATA,
> +       DENALI_PHY_56_DATA, DENALI_PHY_57_DATA, DENALI_PHY_58_DATA,
> +       DENALI_PHY_59_DATA,
> +       DENALI_PHY_60_DATA, DENALI_PHY_61_DATA, DENALI_PHY_62_DATA,
> +       DENALI_PHY_63_DATA, DENALI_PHY_64_DATA, DENALI_PHY_65_DATA,
> +       DENALI_PHY_66_DATA, DENALI_PHY_67_DATA, DENALI_PHY_68_DATA,
> +       DENALI_PHY_69_DATA,
> +       DENALI_PHY_70_DATA, DENALI_PHY_71_DATA, DENALI_PHY_72_DATA,
> +       DENALI_PHY_73_DATA, DENALI_PHY_74_DATA, DENALI_PHY_75_DATA,
> +       DENALI_PHY_76_DATA, DENALI_PHY_77_DATA, DENALI_PHY_78_DATA,
> +       DENALI_PHY_79_DATA,
> +       DENALI_PHY_80_DATA, DENALI_PHY_81_DATA, DENALI_PHY_82_DATA,
> +       DENALI_PHY_83_DATA, DENALI_PHY_84_DATA, DENALI_PHY_85_DATA,
> +       DENALI_PHY_86_DATA, DENALI_PHY_87_DATA, DENALI_PHY_88_DATA,
> +       DENALI_PHY_89_DATA,
> +       DENALI_PHY_90_DATA, DENALI_PHY_91_DATA, DENALI_PHY_92_DATA,
> +       DENALI_PHY_93_DATA, DENALI_PHY_94_DATA, DENALI_PHY_95_DATA,
> +       DENALI_PHY_96_DATA, DENALI_PHY_97_DATA, DENALI_PHY_98_DATA,
> +       DENALI_PHY_99_DATA,
> +
> +       DENALI_PHY_100_DATA, DENALI_PHY_101_DATA, DENALI_PHY_102_DATA,
> +       DENALI_PHY_103_DATA, DENALI_PHY_104_DATA, DENALI_PHY_105_DATA,
> +       DENALI_PHY_106_DATA, DENALI_PHY_107_DATA, DENALI_PHY_108_DATA,
> +       DENALI_PHY_109_DATA,
> +       DENALI_PHY_110_DATA, DENALI_PHY_111_DATA, DENALI_PHY_112_DATA,
> +       DENALI_PHY_113_DATA, DENALI_PHY_114_DATA, DENALI_PHY_115_DATA,
> +       DENALI_PHY_116_DATA, DENALI_PHY_117_DATA, DENALI_PHY_118_DATA,
> +       DENALI_PHY_119_DATA,
> +       DENALI_PHY_120_DATA, DENALI_PHY_121_DATA, DENALI_PHY_122_DATA,
> +       DENALI_PHY_123_DATA, DENALI_PHY_124_DATA, DENALI_PHY_125_DATA,
> +       DENALI_PHY_126_DATA, DENALI_PHY_127_DATA, DENALI_PHY_128_DATA,
> +       DENALI_PHY_129_DATA,
> +       DENALI_PHY_130_DATA, DENALI_PHY_131_DATA, DENALI_PHY_132_DATA,
> +       DENALI_PHY_133_DATA, DENALI_PHY_134_DATA, DENALI_PHY_135_DATA,
> +       DENALI_PHY_136_DATA, DENALI_PHY_137_DATA, DENALI_PHY_138_DATA,
> +       DENALI_PHY_139_DATA,
> +       DENALI_PHY_140_DATA, DENALI_PHY_141_DATA, DENALI_PHY_142_DATA,
> +       DENALI_PHY_143_DATA, DENALI_PHY_144_DATA, DENALI_PHY_145_DATA,
> +       DENALI_PHY_146_DATA, DENALI_PHY_147_DATA, DENALI_PHY_148_DATA,
> +       DENALI_PHY_149_DATA,
> +       DENALI_PHY_150_DATA, DENALI_PHY_151_DATA, DENALI_PHY_152_DATA,
> +       DENALI_PHY_153_DATA, DENALI_PHY_154_DATA, DENALI_PHY_155_DATA,
> +       DENALI_PHY_156_DATA, DENALI_PHY_157_DATA, DENALI_PHY_158_DATA,
> +       DENALI_PHY_159_DATA,
> +       DENALI_PHY_160_DATA, DENALI_PHY_161_DATA, DENALI_PHY_162_DATA,
> +       DENALI_PHY_163_DATA, DENALI_PHY_164_DATA, DENALI_PHY_165_DATA,
> +       DENALI_PHY_166_DATA, DENALI_PHY_167_DATA, DENALI_PHY_168_DATA,
> +       DENALI_PHY_169_DATA,
> +       DENALI_PHY_170_DATA, DENALI_PHY_171_DATA, DENALI_PHY_172_DATA,
> +       DENALI_PHY_173_DATA, DENALI_PHY_174_DATA, DENALI_PHY_175_DATA,
> +       DENALI_PHY_176_DATA, DENALI_PHY_177_DATA, DENALI_PHY_178_DATA,
> +       DENALI_PHY_179_DATA,
> +       DENALI_PHY_180_DATA, DENALI_PHY_181_DATA, DENALI_PHY_182_DATA,
> +       DENALI_PHY_183_DATA, DENALI_PHY_184_DATA, DENALI_PHY_185_DATA,
> +       DENALI_PHY_186_DATA, DENALI_PHY_187_DATA, DENALI_PHY_188_DATA,
> +       DENALI_PHY_189_DATA,
> +       DENALI_PHY_190_DATA, DENALI_PHY_191_DATA, DENALI_PHY_192_DATA,
> +       DENALI_PHY_193_DATA, DENALI_PHY_194_DATA, DENALI_PHY_195_DATA,
> +       DENALI_PHY_196_DATA, DENALI_PHY_197_DATA, DENALI_PHY_198_DATA,
> +       DENALI_PHY_199_DATA,
> +
> +       DENALI_PHY_200_DATA, DENALI_PHY_201_DATA, DENALI_PHY_202_DATA,
> +       DENALI_PHY_203_DATA, DENALI_PHY_204_DATA, DENALI_PHY_205_DATA,
> +       DENALI_PHY_206_DATA, DENALI_PHY_207_DATA, DENALI_PHY_208_DATA,
> +       DENALI_PHY_209_DATA,
> +       DENALI_PHY_210_DATA, DENALI_PHY_211_DATA, DENALI_PHY_212_DATA,
> +       DENALI_PHY_213_DATA, DENALI_PHY_214_DATA, DENALI_PHY_215_DATA,
> +       DENALI_PHY_216_DATA, DENALI_PHY_217_DATA, DENALI_PHY_218_DATA,
> +       DENALI_PHY_219_DATA,
> +       DENALI_PHY_220_DATA, DENALI_PHY_221_DATA, DENALI_PHY_222_DATA,
> +       DENALI_PHY_223_DATA, DENALI_PHY_224_DATA, DENALI_PHY_225_DATA,
> +       DENALI_PHY_226_DATA, DENALI_PHY_227_DATA, DENALI_PHY_228_DATA,
> +       DENALI_PHY_229_DATA,
> +       DENALI_PHY_230_DATA, DENALI_PHY_231_DATA, DENALI_PHY_232_DATA,
> +       DENALI_PHY_233_DATA, DENALI_PHY_234_DATA, DENALI_PHY_235_DATA,
> +       DENALI_PHY_236_DATA, DENALI_PHY_237_DATA, DENALI_PHY_238_DATA,
> +       DENALI_PHY_239_DATA,
> +       DENALI_PHY_240_DATA, DENALI_PHY_241_DATA, DENALI_PHY_242_DATA,
> +       DENALI_PHY_243_DATA, DENALI_PHY_244_DATA, DENALI_PHY_245_DATA,
> +       DENALI_PHY_246_DATA, DENALI_PHY_247_DATA, DENALI_PHY_248_DATA,
> +       DENALI_PHY_249_DATA,
> +       DENALI_PHY_250_DATA, DENALI_PHY_251_DATA, DENALI_PHY_252_DATA,
> +       DENALI_PHY_253_DATA, DENALI_PHY_254_DATA, DENALI_PHY_255_DATA,
> +       DENALI_PHY_256_DATA, DENALI_PHY_257_DATA, DENALI_PHY_258_DATA,
> +       DENALI_PHY_259_DATA,
> +       DENALI_PHY_260_DATA, DENALI_PHY_261_DATA, DENALI_PHY_262_DATA,
> +       DENALI_PHY_263_DATA, DENALI_PHY_264_DATA, DENALI_PHY_265_DATA,
> +       DENALI_PHY_266_DATA, DENALI_PHY_267_DATA, DENALI_PHY_268_DATA,
> +       DENALI_PHY_269_DATA,
> +       DENALI_PHY_270_DATA, DENALI_PHY_271_DATA, DENALI_PHY_272_DATA,
> +       DENALI_PHY_273_DATA, DENALI_PHY_274_DATA, DENALI_PHY_275_DATA,
> +       DENALI_PHY_276_DATA, DENALI_PHY_277_DATA, DENALI_PHY_278_DATA,
> +       DENALI_PHY_279_DATA,
> +       DENALI_PHY_280_DATA, DENALI_PHY_281_DATA, DENALI_PHY_282_DATA,
> +       DENALI_PHY_283_DATA, DENALI_PHY_284_DATA, DENALI_PHY_285_DATA,
> +       DENALI_PHY_286_DATA, DENALI_PHY_287_DATA, DENALI_PHY_288_DATA,
> +       DENALI_PHY_289_DATA,
> +       DENALI_PHY_290_DATA, DENALI_PHY_291_DATA, DENALI_PHY_292_DATA,
> +       DENALI_PHY_293_DATA, DENALI_PHY_294_DATA, DENALI_PHY_295_DATA,
> +       DENALI_PHY_296_DATA, DENALI_PHY_297_DATA, DENALI_PHY_298_DATA,
> +       DENALI_PHY_299_DATA,
> +
> +       DENALI_PHY_300_DATA, DENALI_PHY_301_DATA, DENALI_PHY_302_DATA,
> +       DENALI_PHY_303_DATA, DENALI_PHY_304_DATA, DENALI_PHY_305_DATA,
> +       DENALI_PHY_306_DATA, DENALI_PHY_307_DATA, DENALI_PHY_308_DATA,
> +       DENALI_PHY_309_DATA,
> +       DENALI_PHY_310_DATA, DENALI_PHY_311_DATA, DENALI_PHY_312_DATA,
> +       DENALI_PHY_313_DATA, DENALI_PHY_314_DATA, DENALI_PHY_315_DATA,
> +       DENALI_PHY_316_DATA, DENALI_PHY_317_DATA, DENALI_PHY_318_DATA,
> +       DENALI_PHY_319_DATA,
> +       DENALI_PHY_320_DATA, DENALI_PHY_321_DATA, DENALI_PHY_322_DATA,
> +       DENALI_PHY_323_DATA, DENALI_PHY_324_DATA, DENALI_PHY_325_DATA,
> +       DENALI_PHY_326_DATA, DENALI_PHY_327_DATA, DENALI_PHY_328_DATA,
> +       DENALI_PHY_329_DATA,
> +       DENALI_PHY_330_DATA, DENALI_PHY_331_DATA, DENALI_PHY_332_DATA,
> +       DENALI_PHY_333_DATA, DENALI_PHY_334_DATA, DENALI_PHY_335_DATA,
> +       DENALI_PHY_336_DATA, DENALI_PHY_337_DATA, DENALI_PHY_338_DATA,
> +       DENALI_PHY_339_DATA,
> +       DENALI_PHY_340_DATA, DENALI_PHY_341_DATA, DENALI_PHY_342_DATA,
> +       DENALI_PHY_343_DATA, DENALI_PHY_344_DATA, DENALI_PHY_345_DATA,
> +       DENALI_PHY_346_DATA, DENALI_PHY_347_DATA, DENALI_PHY_348_DATA,
> +       DENALI_PHY_349_DATA,
> +       DENALI_PHY_350_DATA, DENALI_PHY_351_DATA, DENALI_PHY_352_DATA,
> +       DENALI_PHY_353_DATA, DENALI_PHY_354_DATA, DENALI_PHY_355_DATA,
> +       DENALI_PHY_356_DATA, DENALI_PHY_357_DATA, DENALI_PHY_358_DATA,
> +       DENALI_PHY_359_DATA,
> +       DENALI_PHY_360_DATA, DENALI_PHY_361_DATA, DENALI_PHY_362_DATA,
> +       DENALI_PHY_363_DATA, DENALI_PHY_364_DATA, DENALI_PHY_365_DATA,
> +       DENALI_PHY_366_DATA, DENALI_PHY_367_DATA, DENALI_PHY_368_DATA,
> +       DENALI_PHY_369_DATA,
> +       DENALI_PHY_370_DATA, DENALI_PHY_371_DATA, DENALI_PHY_372_DATA,
> +       DENALI_PHY_373_DATA, DENALI_PHY_374_DATA, DENALI_PHY_375_DATA,
> +       DENALI_PHY_376_DATA, DENALI_PHY_377_DATA, DENALI_PHY_378_DATA,
> +       DENALI_PHY_379_DATA,
> +       DENALI_PHY_380_DATA, DENALI_PHY_381_DATA, DENALI_PHY_382_DATA,
> +       DENALI_PHY_383_DATA, DENALI_PHY_384_DATA, DENALI_PHY_385_DATA,
> +       DENALI_PHY_386_DATA, DENALI_PHY_387_DATA, DENALI_PHY_388_DATA,
> +       DENALI_PHY_389_DATA,
> +       DENALI_PHY_390_DATA, DENALI_PHY_391_DATA, DENALI_PHY_392_DATA,
> +       DENALI_PHY_393_DATA, DENALI_PHY_394_DATA, DENALI_PHY_395_DATA,
> +       DENALI_PHY_396_DATA, DENALI_PHY_397_DATA, DENALI_PHY_398_DATA,
> +       DENALI_PHY_399_DATA,
> +
> +       DENALI_PHY_400_DATA, DENALI_PHY_401_DATA, DENALI_PHY_402_DATA,
> +       DENALI_PHY_403_DATA, DENALI_PHY_404_DATA, DENALI_PHY_405_DATA,
> +       DENALI_PHY_406_DATA, DENALI_PHY_407_DATA, DENALI_PHY_408_DATA,
> +       DENALI_PHY_409_DATA,
> +       DENALI_PHY_410_DATA, DENALI_PHY_411_DATA, DENALI_PHY_412_DATA,
> +       DENALI_PHY_413_DATA, DENALI_PHY_414_DATA, DENALI_PHY_415_DATA,
> +       DENALI_PHY_416_DATA, DENALI_PHY_417_DATA, DENALI_PHY_418_DATA,
> +       DENALI_PHY_419_DATA,
> +       DENALI_PHY_420_DATA, DENALI_PHY_421_DATA, DENALI_PHY_422_DATA,
> +       DENALI_PHY_423_DATA, DENALI_PHY_424_DATA, DENALI_PHY_425_DATA,
> +       DENALI_PHY_426_DATA, DENALI_PHY_427_DATA, DENALI_PHY_428_DATA,
> +       DENALI_PHY_429_DATA,
> +       DENALI_PHY_430_DATA, DENALI_PHY_431_DATA, DENALI_PHY_432_DATA,
> +       DENALI_PHY_433_DATA, DENALI_PHY_434_DATA, DENALI_PHY_435_DATA,
> +       DENALI_PHY_436_DATA, DENALI_PHY_437_DATA, DENALI_PHY_438_DATA,
> +       DENALI_PHY_439_DATA,
> +       DENALI_PHY_440_DATA, DENALI_PHY_441_DATA, DENALI_PHY_442_DATA,
> +       DENALI_PHY_443_DATA, DENALI_PHY_444_DATA, DENALI_PHY_445_DATA,
> +       DENALI_PHY_446_DATA, DENALI_PHY_447_DATA, DENALI_PHY_448_DATA,
> +       DENALI_PHY_449_DATA,
> +       DENALI_PHY_450_DATA, DENALI_PHY_451_DATA, DENALI_PHY_452_DATA,
> +       DENALI_PHY_453_DATA, DENALI_PHY_454_DATA, DENALI_PHY_455_DATA,
> +       DENALI_PHY_456_DATA, DENALI_PHY_457_DATA, DENALI_PHY_458_DATA,
> +       DENALI_PHY_459_DATA,
> +       DENALI_PHY_460_DATA, DENALI_PHY_461_DATA, DENALI_PHY_462_DATA,
> +       DENALI_PHY_463_DATA, DENALI_PHY_464_DATA, DENALI_PHY_465_DATA,
> +       DENALI_PHY_466_DATA, DENALI_PHY_467_DATA, DENALI_PHY_468_DATA,
> +       DENALI_PHY_469_DATA,
> +       DENALI_PHY_470_DATA, DENALI_PHY_471_DATA, DENALI_PHY_472_DATA,
> +       DENALI_PHY_473_DATA, DENALI_PHY_474_DATA, DENALI_PHY_475_DATA,
> +       DENALI_PHY_476_DATA, DENALI_PHY_477_DATA, DENALI_PHY_478_DATA,
> +       DENALI_PHY_479_DATA,
> +       DENALI_PHY_480_DATA, DENALI_PHY_481_DATA, DENALI_PHY_482_DATA,
> +       DENALI_PHY_483_DATA, DENALI_PHY_484_DATA, DENALI_PHY_485_DATA,
> +       DENALI_PHY_486_DATA, DENALI_PHY_487_DATA, DENALI_PHY_488_DATA,
> +       DENALI_PHY_489_DATA,
> +       DENALI_PHY_490_DATA, DENALI_PHY_491_DATA, DENALI_PHY_492_DATA,
> +       DENALI_PHY_493_DATA, DENALI_PHY_494_DATA, DENALI_PHY_495_DATA,
> +       DENALI_PHY_496_DATA, DENALI_PHY_497_DATA, DENALI_PHY_498_DATA,
> +       DENALI_PHY_499_DATA,
> +
> +       DENALI_PHY_500_DATA, DENALI_PHY_501_DATA, DENALI_PHY_502_DATA,
> +       DENALI_PHY_503_DATA, DENALI_PHY_504_DATA, DENALI_PHY_505_DATA,
> +       DENALI_PHY_506_DATA, DENALI_PHY_507_DATA, DENALI_PHY_508_DATA,
> +       DENALI_PHY_509_DATA,
> +       DENALI_PHY_510_DATA, DENALI_PHY_511_DATA, DENALI_PHY_512_DATA,
> +       DENALI_PHY_513_DATA, DENALI_PHY_514_DATA, DENALI_PHY_515_DATA,
> +       DENALI_PHY_516_DATA, DENALI_PHY_517_DATA, DENALI_PHY_518_DATA,
> +       DENALI_PHY_519_DATA,
> +       DENALI_PHY_520_DATA, DENALI_PHY_521_DATA, DENALI_PHY_522_DATA,
> +       DENALI_PHY_523_DATA, DENALI_PHY_524_DATA, DENALI_PHY_525_DATA,
> +       DENALI_PHY_526_DATA, DENALI_PHY_527_DATA, DENALI_PHY_528_DATA,
> +       DENALI_PHY_529_DATA,
> +       DENALI_PHY_530_DATA, DENALI_PHY_531_DATA, DENALI_PHY_532_DATA,
> +       DENALI_PHY_533_DATA, DENALI_PHY_534_DATA, DENALI_PHY_535_DATA,
> +       DENALI_PHY_536_DATA, DENALI_PHY_537_DATA, DENALI_PHY_538_DATA,
> +       DENALI_PHY_539_DATA,
> +       DENALI_PHY_540_DATA, DENALI_PHY_541_DATA, DENALI_PHY_542_DATA,
> +       DENALI_PHY_543_DATA, DENALI_PHY_544_DATA, DENALI_PHY_545_DATA,
> +       DENALI_PHY_546_DATA, DENALI_PHY_547_DATA, DENALI_PHY_548_DATA,
> +       DENALI_PHY_549_DATA,
> +       DENALI_PHY_550_DATA, DENALI_PHY_551_DATA, DENALI_PHY_552_DATA,
> +       DENALI_PHY_553_DATA, DENALI_PHY_554_DATA, DENALI_PHY_555_DATA,
> +       DENALI_PHY_556_DATA, DENALI_PHY_557_DATA, DENALI_PHY_558_DATA,
> +       DENALI_PHY_559_DATA,
> +       DENALI_PHY_560_DATA, DENALI_PHY_561_DATA, DENALI_PHY_562_DATA,
> +       DENALI_PHY_563_DATA, DENALI_PHY_564_DATA, DENALI_PHY_565_DATA,
> +       DENALI_PHY_566_DATA, DENALI_PHY_567_DATA, DENALI_PHY_568_DATA,
> +       DENALI_PHY_569_DATA,
> +       DENALI_PHY_570_DATA, DENALI_PHY_571_DATA, DENALI_PHY_572_DATA,
> +       DENALI_PHY_573_DATA, DENALI_PHY_574_DATA, DENALI_PHY_575_DATA,
> +       DENALI_PHY_576_DATA, DENALI_PHY_577_DATA, DENALI_PHY_578_DATA,
> +       DENALI_PHY_579_DATA,
> +       DENALI_PHY_580_DATA, DENALI_PHY_581_DATA, DENALI_PHY_582_DATA,
> +       DENALI_PHY_583_DATA, DENALI_PHY_584_DATA, DENALI_PHY_585_DATA,
> +       DENALI_PHY_586_DATA, DENALI_PHY_587_DATA, DENALI_PHY_588_DATA,
> +       DENALI_PHY_589_DATA,
> +       DENALI_PHY_590_DATA, DENALI_PHY_591_DATA, DENALI_PHY_592_DATA,
> +       DENALI_PHY_593_DATA, DENALI_PHY_594_DATA, DENALI_PHY_595_DATA,
> +       DENALI_PHY_596_DATA, DENALI_PHY_597_DATA, DENALI_PHY_598_DATA,
> +       DENALI_PHY_599_DATA,
> +
> +       DENALI_PHY_600_DATA, DENALI_PHY_601_DATA, DENALI_PHY_602_DATA,
> +       DENALI_PHY_603_DATA, DENALI_PHY_604_DATA, DENALI_PHY_605_DATA,
> +       DENALI_PHY_606_DATA, DENALI_PHY_607_DATA, DENALI_PHY_608_DATA,
> +       DENALI_PHY_609_DATA,
> +       DENALI_PHY_610_DATA, DENALI_PHY_611_DATA, DENALI_PHY_612_DATA,
> +       DENALI_PHY_613_DATA, DENALI_PHY_614_DATA, DENALI_PHY_615_DATA,
> +       DENALI_PHY_616_DATA, DENALI_PHY_617_DATA, DENALI_PHY_618_DATA,
> +       DENALI_PHY_619_DATA,
> +       DENALI_PHY_620_DATA, DENALI_PHY_621_DATA, DENALI_PHY_622_DATA,
> +       DENALI_PHY_623_DATA, DENALI_PHY_624_DATA, DENALI_PHY_625_DATA,
> +       DENALI_PHY_626_DATA, DENALI_PHY_627_DATA, DENALI_PHY_628_DATA,
> +       DENALI_PHY_629_DATA,
> +       DENALI_PHY_630_DATA, DENALI_PHY_631_DATA, DENALI_PHY_632_DATA,
> +       DENALI_PHY_633_DATA, DENALI_PHY_634_DATA, DENALI_PHY_635_DATA,
> +       DENALI_PHY_636_DATA, DENALI_PHY_637_DATA, DENALI_PHY_638_DATA,
> +       DENALI_PHY_639_DATA,
> +       DENALI_PHY_640_DATA, DENALI_PHY_641_DATA, DENALI_PHY_642_DATA,
> +       DENALI_PHY_643_DATA, DENALI_PHY_644_DATA, DENALI_PHY_645_DATA,
> +       DENALI_PHY_646_DATA, DENALI_PHY_647_DATA, DENALI_PHY_648_DATA,
> +       DENALI_PHY_649_DATA,
> +       DENALI_PHY_650_DATA, DENALI_PHY_651_DATA, DENALI_PHY_652_DATA,
> +       DENALI_PHY_653_DATA, DENALI_PHY_654_DATA, DENALI_PHY_655_DATA,
> +       DENALI_PHY_656_DATA, DENALI_PHY_657_DATA, DENALI_PHY_658_DATA,
> +       DENALI_PHY_659_DATA,
> +       DENALI_PHY_660_DATA, DENALI_PHY_661_DATA, DENALI_PHY_662_DATA,
> +       DENALI_PHY_663_DATA, DENALI_PHY_664_DATA, DENALI_PHY_665_DATA,
> +       DENALI_PHY_666_DATA, DENALI_PHY_667_DATA, DENALI_PHY_668_DATA,
> +       DENALI_PHY_669_DATA,
> +       DENALI_PHY_670_DATA, DENALI_PHY_671_DATA, DENALI_PHY_672_DATA,
> +       DENALI_PHY_673_DATA, DENALI_PHY_674_DATA, DENALI_PHY_675_DATA,
> +       DENALI_PHY_676_DATA, DENALI_PHY_677_DATA, DENALI_PHY_678_DATA,
> +       DENALI_PHY_679_DATA,
> +       DENALI_PHY_680_DATA, DENALI_PHY_681_DATA, DENALI_PHY_682_DATA,
> +       DENALI_PHY_683_DATA, DENALI_PHY_684_DATA, DENALI_PHY_685_DATA,
> +       DENALI_PHY_686_DATA, DENALI_PHY_687_DATA, DENALI_PHY_688_DATA,
> +       DENALI_PHY_689_DATA,
> +       DENALI_PHY_690_DATA, DENALI_PHY_691_DATA, DENALI_PHY_692_DATA,
> +       DENALI_PHY_693_DATA, DENALI_PHY_694_DATA, DENALI_PHY_695_DATA,
> +       DENALI_PHY_696_DATA, DENALI_PHY_697_DATA, DENALI_PHY_698_DATA,
> +       DENALI_PHY_699_DATA,
> +
> +       DENALI_PHY_700_DATA, DENALI_PHY_701_DATA, DENALI_PHY_702_DATA,
> +       DENALI_PHY_703_DATA, DENALI_PHY_704_DATA, DENALI_PHY_705_DATA,
> +       DENALI_PHY_706_DATA, DENALI_PHY_707_DATA, DENALI_PHY_708_DATA,
> +       DENALI_PHY_709_DATA,
> +       DENALI_PHY_710_DATA, DENALI_PHY_711_DATA, DENALI_PHY_712_DATA,
> +       DENALI_PHY_713_DATA, DENALI_PHY_714_DATA, DENALI_PHY_715_DATA,
> +       DENALI_PHY_716_DATA, DENALI_PHY_717_DATA, DENALI_PHY_718_DATA,
> +       DENALI_PHY_719_DATA,
> +       DENALI_PHY_720_DATA, DENALI_PHY_721_DATA, DENALI_PHY_722_DATA,
> +       DENALI_PHY_723_DATA, DENALI_PHY_724_DATA, DENALI_PHY_725_DATA,
> +       DENALI_PHY_726_DATA, DENALI_PHY_727_DATA, DENALI_PHY_728_DATA,
> +       DENALI_PHY_729_DATA,
> +       DENALI_PHY_730_DATA, DENALI_PHY_731_DATA, DENALI_PHY_732_DATA,
> +       DENALI_PHY_733_DATA, DENALI_PHY_734_DATA, DENALI_PHY_735_DATA,
> +       DENALI_PHY_736_DATA, DENALI_PHY_737_DATA, DENALI_PHY_738_DATA,
> +       DENALI_PHY_739_DATA,
> +       DENALI_PHY_740_DATA, DENALI_PHY_741_DATA, DENALI_PHY_742_DATA,
> +       DENALI_PHY_743_DATA, DENALI_PHY_744_DATA, DENALI_PHY_745_DATA,
> +       DENALI_PHY_746_DATA, DENALI_PHY_747_DATA, DENALI_PHY_748_DATA,
> +       DENALI_PHY_749_DATA,
> +       DENALI_PHY_750_DATA, DENALI_PHY_751_DATA, DENALI_PHY_752_DATA,
> +       DENALI_PHY_753_DATA, DENALI_PHY_754_DATA, DENALI_PHY_755_DATA,
> +       DENALI_PHY_756_DATA, DENALI_PHY_757_DATA, DENALI_PHY_758_DATA,
> +       DENALI_PHY_759_DATA,
> +       DENALI_PHY_760_DATA, DENALI_PHY_761_DATA, DENALI_PHY_762_DATA,
> +       DENALI_PHY_763_DATA, DENALI_PHY_764_DATA, DENALI_PHY_765_DATA,
> +       DENALI_PHY_766_DATA, DENALI_PHY_767_DATA, DENALI_PHY_768_DATA,
> +       DENALI_PHY_769_DATA,
> +       DENALI_PHY_770_DATA, DENALI_PHY_771_DATA, DENALI_PHY_772_DATA,
> +       DENALI_PHY_773_DATA, DENALI_PHY_774_DATA, DENALI_PHY_775_DATA,
> +       DENALI_PHY_776_DATA, DENALI_PHY_777_DATA, DENALI_PHY_778_DATA,
> +       DENALI_PHY_779_DATA,
> +       DENALI_PHY_780_DATA, DENALI_PHY_781_DATA, DENALI_PHY_782_DATA,
> +       DENALI_PHY_783_DATA, DENALI_PHY_784_DATA, DENALI_PHY_785_DATA,
> +       DENALI_PHY_786_DATA, DENALI_PHY_787_DATA, DENALI_PHY_788_DATA,
> +       DENALI_PHY_789_DATA,
> +       DENALI_PHY_790_DATA, DENALI_PHY_791_DATA, DENALI_PHY_792_DATA,
> +       DENALI_PHY_793_DATA, DENALI_PHY_794_DATA, DENALI_PHY_795_DATA,
> +       DENALI_PHY_796_DATA, DENALI_PHY_797_DATA, DENALI_PHY_798_DATA,
> +       DENALI_PHY_799_DATA,
> +
> +       DENALI_PHY_800_DATA, DENALI_PHY_801_DATA, DENALI_PHY_802_DATA,
> +       DENALI_PHY_803_DATA, DENALI_PHY_804_DATA, DENALI_PHY_805_DATA,
> +       DENALI_PHY_806_DATA, DENALI_PHY_807_DATA, DENALI_PHY_808_DATA,
> +       DENALI_PHY_809_DATA,
> +       DENALI_PHY_810_DATA, DENALI_PHY_811_DATA, DENALI_PHY_812_DATA,
> +       DENALI_PHY_813_DATA, DENALI_PHY_814_DATA, DENALI_PHY_815_DATA,
> +       DENALI_PHY_816_DATA, DENALI_PHY_817_DATA, DENALI_PHY_818_DATA,
> +       DENALI_PHY_819_DATA,
> +       DENALI_PHY_820_DATA, DENALI_PHY_821_DATA, DENALI_PHY_822_DATA,
> +       DENALI_PHY_823_DATA, DENALI_PHY_824_DATA, DENALI_PHY_825_DATA,
> +       DENALI_PHY_826_DATA, DENALI_PHY_827_DATA, DENALI_PHY_828_DATA,
> +       DENALI_PHY_829_DATA,
> +       DENALI_PHY_830_DATA, DENALI_PHY_831_DATA, DENALI_PHY_832_DATA,
> +       DENALI_PHY_833_DATA, DENALI_PHY_834_DATA, DENALI_PHY_835_DATA,
> +       DENALI_PHY_836_DATA, DENALI_PHY_837_DATA, DENALI_PHY_838_DATA,
> +       DENALI_PHY_839_DATA,
> +       DENALI_PHY_840_DATA, DENALI_PHY_841_DATA, DENALI_PHY_842_DATA,
> +       DENALI_PHY_843_DATA, DENALI_PHY_844_DATA, DENALI_PHY_845_DATA,
> +       DENALI_PHY_846_DATA, DENALI_PHY_847_DATA, DENALI_PHY_848_DATA,
> +       DENALI_PHY_849_DATA,
> +       DENALI_PHY_850_DATA, DENALI_PHY_851_DATA, DENALI_PHY_852_DATA,
> +       DENALI_PHY_853_DATA, DENALI_PHY_854_DATA, DENALI_PHY_855_DATA,
> +       DENALI_PHY_856_DATA, DENALI_PHY_857_DATA, DENALI_PHY_858_DATA,
> +       DENALI_PHY_859_DATA,
> +       DENALI_PHY_860_DATA, DENALI_PHY_861_DATA, DENALI_PHY_862_DATA,
> +       DENALI_PHY_863_DATA, DENALI_PHY_864_DATA, DENALI_PHY_865_DATA,
> +       DENALI_PHY_866_DATA, DENALI_PHY_867_DATA, DENALI_PHY_868_DATA,
> +       DENALI_PHY_869_DATA,
> +       DENALI_PHY_870_DATA, DENALI_PHY_871_DATA, DENALI_PHY_872_DATA,
> +       DENALI_PHY_873_DATA, DENALI_PHY_874_DATA, DENALI_PHY_875_DATA,
> +       DENALI_PHY_876_DATA, DENALI_PHY_877_DATA, DENALI_PHY_878_DATA,
> +       DENALI_PHY_879_DATA,
> +       DENALI_PHY_880_DATA, DENALI_PHY_881_DATA, DENALI_PHY_882_DATA,
> +       DENALI_PHY_883_DATA, DENALI_PHY_884_DATA, DENALI_PHY_885_DATA,
> +       DENALI_PHY_886_DATA, DENALI_PHY_887_DATA, DENALI_PHY_888_DATA,
> +       DENALI_PHY_889_DATA,
> +       DENALI_PHY_890_DATA, DENALI_PHY_891_DATA, DENALI_PHY_892_DATA,
> +       DENALI_PHY_893_DATA, DENALI_PHY_894_DATA, DENALI_PHY_895_DATA,
> +       DENALI_PHY_896_DATA, DENALI_PHY_897_DATA, DENALI_PHY_898_DATA,
> +       DENALI_PHY_899_DATA,
> +
> +       DENALI_PHY_900_DATA, DENALI_PHY_901_DATA, DENALI_PHY_902_DATA,
> +       DENALI_PHY_903_DATA, DENALI_PHY_904_DATA, DENALI_PHY_905_DATA,
> +       DENALI_PHY_906_DATA, DENALI_PHY_907_DATA, DENALI_PHY_908_DATA,
> +       DENALI_PHY_909_DATA,
> +       DENALI_PHY_910_DATA, DENALI_PHY_911_DATA, DENALI_PHY_912_DATA,
> +       DENALI_PHY_913_DATA, DENALI_PHY_914_DATA, DENALI_PHY_915_DATA,
> +       DENALI_PHY_916_DATA, DENALI_PHY_917_DATA, DENALI_PHY_918_DATA,
> +       DENALI_PHY_919_DATA,
> +       DENALI_PHY_920_DATA, DENALI_PHY_921_DATA, DENALI_PHY_922_DATA,
> +       DENALI_PHY_923_DATA, DENALI_PHY_924_DATA, DENALI_PHY_925_DATA,
> +       DENALI_PHY_926_DATA, DENALI_PHY_927_DATA, DENALI_PHY_928_DATA,
> +       DENALI_PHY_929_DATA,
> +       DENALI_PHY_930_DATA, DENALI_PHY_931_DATA, DENALI_PHY_932_DATA,
> +       DENALI_PHY_933_DATA, DENALI_PHY_934_DATA, DENALI_PHY_935_DATA,
> +       DENALI_PHY_936_DATA, DENALI_PHY_937_DATA, DENALI_PHY_938_DATA,
> +       DENALI_PHY_939_DATA,
> +       DENALI_PHY_940_DATA, DENALI_PHY_941_DATA, DENALI_PHY_942_DATA,
> +       DENALI_PHY_943_DATA, DENALI_PHY_944_DATA, DENALI_PHY_945_DATA,
> +       DENALI_PHY_946_DATA, DENALI_PHY_947_DATA, DENALI_PHY_948_DATA,
> +       DENALI_PHY_949_DATA,
> +       DENALI_PHY_950_DATA, DENALI_PHY_951_DATA, DENALI_PHY_952_DATA,
> +       DENALI_PHY_953_DATA, DENALI_PHY_954_DATA, DENALI_PHY_955_DATA,
> +       DENALI_PHY_956_DATA, DENALI_PHY_957_DATA, DENALI_PHY_958_DATA,
> +       DENALI_PHY_959_DATA,
> +       DENALI_PHY_960_DATA, DENALI_PHY_961_DATA, DENALI_PHY_962_DATA,
> +       DENALI_PHY_963_DATA, DENALI_PHY_964_DATA, DENALI_PHY_965_DATA,
> +       DENALI_PHY_966_DATA, DENALI_PHY_967_DATA, DENALI_PHY_968_DATA,
> +       DENALI_PHY_969_DATA,
> +       DENALI_PHY_970_DATA, DENALI_PHY_971_DATA, DENALI_PHY_972_DATA,
> +       DENALI_PHY_973_DATA, DENALI_PHY_974_DATA, DENALI_PHY_975_DATA,
> +       DENALI_PHY_976_DATA, DENALI_PHY_977_DATA, DENALI_PHY_978_DATA,
> +       DENALI_PHY_979_DATA,
> +       DENALI_PHY_980_DATA, DENALI_PHY_981_DATA, DENALI_PHY_982_DATA,
> +       DENALI_PHY_983_DATA, DENALI_PHY_984_DATA, DENALI_PHY_985_DATA,
> +       DENALI_PHY_986_DATA, DENALI_PHY_987_DATA, DENALI_PHY_988_DATA,
> +       DENALI_PHY_989_DATA,
> +       DENALI_PHY_990_DATA, DENALI_PHY_991_DATA, DENALI_PHY_992_DATA,
> +       DENALI_PHY_993_DATA, DENALI_PHY_994_DATA, DENALI_PHY_995_DATA,
> +       DENALI_PHY_996_DATA, DENALI_PHY_997_DATA, DENALI_PHY_998_DATA,
> +       DENALI_PHY_999_DATA,
> +
> +       DENALI_PHY_1000_DATA, DENALI_PHY_1001_DATA, DENALI_PHY_1002_DATA,
> +       DENALI_PHY_1003_DATA, DENALI_PHY_1004_DATA, DENALI_PHY_1005_DATA,
> +       DENALI_PHY_1006_DATA, DENALI_PHY_1007_DATA, DENALI_PHY_1008_DATA,
> +       DENALI_PHY_1009_DATA,
> +       DENALI_PHY_1010_DATA, DENALI_PHY_1011_DATA, DENALI_PHY_1012_DATA,
> +       DENALI_PHY_1013_DATA, DENALI_PHY_1014_DATA, DENALI_PHY_1015_DATA,
> +       DENALI_PHY_1016_DATA, DENALI_PHY_1017_DATA, DENALI_PHY_1018_DATA,
> +       DENALI_PHY_1019_DATA,
> +       DENALI_PHY_1020_DATA, DENALI_PHY_1021_DATA, DENALI_PHY_1022_DATA,
> +       DENALI_PHY_1023_DATA, DENALI_PHY_1024_DATA, DENALI_PHY_1025_DATA,
> +       DENALI_PHY_1026_DATA, DENALI_PHY_1027_DATA, DENALI_PHY_1028_DATA,
> +       DENALI_PHY_1029_DATA,
> +       DENALI_PHY_1030_DATA, DENALI_PHY_1031_DATA, DENALI_PHY_1032_DATA,
> +       DENALI_PHY_1033_DATA, DENALI_PHY_1034_DATA, DENALI_PHY_1035_DATA,
> +       DENALI_PHY_1036_DATA, DENALI_PHY_1037_DATA, DENALI_PHY_1038_DATA,
> +       DENALI_PHY_1039_DATA,
> +       DENALI_PHY_1040_DATA, DENALI_PHY_1041_DATA, DENALI_PHY_1042_DATA,
> +       DENALI_PHY_1043_DATA, DENALI_PHY_1044_DATA, DENALI_PHY_1045_DATA,
> +       DENALI_PHY_1046_DATA, DENALI_PHY_1047_DATA, DENALI_PHY_1048_DATA,
> +       DENALI_PHY_1049_DATA,
> +       DENALI_PHY_1050_DATA, DENALI_PHY_1051_DATA, DENALI_PHY_1052_DATA,
> +       DENALI_PHY_1053_DATA, DENALI_PHY_1054_DATA, DENALI_PHY_1055_DATA,
> +       DENALI_PHY_1056_DATA, DENALI_PHY_1057_DATA, DENALI_PHY_1058_DATA,
> +       DENALI_PHY_1059_DATA,
> +       DENALI_PHY_1060_DATA, DENALI_PHY_1061_DATA, DENALI_PHY_1062_DATA,
> +       DENALI_PHY_1063_DATA, DENALI_PHY_1064_DATA, DENALI_PHY_1065_DATA,
> +       DENALI_PHY_1066_DATA, DENALI_PHY_1067_DATA, DENALI_PHY_1068_DATA,
> +       DENALI_PHY_1069_DATA,
> +       DENALI_PHY_1070_DATA, DENALI_PHY_1071_DATA, DENALI_PHY_1072_DATA,
> +       DENALI_PHY_1073_DATA, DENALI_PHY_1074_DATA, DENALI_PHY_1075_DATA,
> +       DENALI_PHY_1076_DATA, DENALI_PHY_1077_DATA, DENALI_PHY_1078_DATA,
> +       DENALI_PHY_1079_DATA,
> +       DENALI_PHY_1080_DATA, DENALI_PHY_1081_DATA, DENALI_PHY_1082_DATA,
> +       DENALI_PHY_1083_DATA, DENALI_PHY_1084_DATA, DENALI_PHY_1085_DATA,
> +       DENALI_PHY_1086_DATA, DENALI_PHY_1087_DATA, DENALI_PHY_1088_DATA,
> +       DENALI_PHY_1089_DATA,
> +       DENALI_PHY_1090_DATA, DENALI_PHY_1091_DATA, DENALI_PHY_1092_DATA,
> +       DENALI_PHY_1093_DATA, DENALI_PHY_1094_DATA, DENALI_PHY_1095_DATA,
> +       DENALI_PHY_1096_DATA, DENALI_PHY_1097_DATA, DENALI_PHY_1098_DATA,
> +       DENALI_PHY_1099_DATA,
> +
> +       DENALI_PHY_1100_DATA, DENALI_PHY_1101_DATA, DENALI_PHY_1102_DATA,
> +       DENALI_PHY_1103_DATA, DENALI_PHY_1104_DATA, DENALI_PHY_1105_DATA,
> +       DENALI_PHY_1106_DATA, DENALI_PHY_1107_DATA, DENALI_PHY_1108_DATA,
> +       DENALI_PHY_1109_DATA,
> +       DENALI_PHY_1110_DATA, DENALI_PHY_1111_DATA, DENALI_PHY_1112_DATA,
> +       DENALI_PHY_1113_DATA, DENALI_PHY_1114_DATA, DENALI_PHY_1115_DATA,
> +       DENALI_PHY_1116_DATA, DENALI_PHY_1117_DATA, DENALI_PHY_1118_DATA,
> +       DENALI_PHY_1119_DATA,
> +       DENALI_PHY_1120_DATA, DENALI_PHY_1121_DATA, DENALI_PHY_1122_DATA,
> +       DENALI_PHY_1123_DATA, DENALI_PHY_1124_DATA, DENALI_PHY_1125_DATA,
> +       DENALI_PHY_1126_DATA, DENALI_PHY_1127_DATA, DENALI_PHY_1128_DATA,
> +       DENALI_PHY_1129_DATA,
> +       DENALI_PHY_1130_DATA, DENALI_PHY_1131_DATA, DENALI_PHY_1132_DATA,
> +       DENALI_PHY_1133_DATA, DENALI_PHY_1134_DATA, DENALI_PHY_1135_DATA,
> +       DENALI_PHY_1136_DATA, DENALI_PHY_1137_DATA, DENALI_PHY_1138_DATA,
> +       DENALI_PHY_1139_DATA,
> +       DENALI_PHY_1140_DATA, DENALI_PHY_1141_DATA, DENALI_PHY_1142_DATA,
> +       DENALI_PHY_1143_DATA, DENALI_PHY_1144_DATA, DENALI_PHY_1145_DATA,
> +       DENALI_PHY_1146_DATA, DENALI_PHY_1147_DATA, DENALI_PHY_1148_DATA,
> +       DENALI_PHY_1149_DATA,
> +       DENALI_PHY_1150_DATA, DENALI_PHY_1151_DATA, DENALI_PHY_1152_DATA,
> +       DENALI_PHY_1153_DATA, DENALI_PHY_1154_DATA, DENALI_PHY_1155_DATA,
> +       DENALI_PHY_1156_DATA, DENALI_PHY_1157_DATA, DENALI_PHY_1158_DATA,
> +       DENALI_PHY_1159_DATA,
> +       DENALI_PHY_1160_DATA, DENALI_PHY_1161_DATA, DENALI_PHY_1162_DATA,
> +       DENALI_PHY_1163_DATA, DENALI_PHY_1164_DATA, DENALI_PHY_1165_DATA,
> +       DENALI_PHY_1166_DATA, DENALI_PHY_1167_DATA, DENALI_PHY_1168_DATA,
> +       DENALI_PHY_1169_DATA,
> +       DENALI_PHY_1170_DATA, DENALI_PHY_1171_DATA, DENALI_PHY_1172_DATA,
> +       DENALI_PHY_1173_DATA, DENALI_PHY_1174_DATA, DENALI_PHY_1175_DATA,
> +       DENALI_PHY_1176_DATA, DENALI_PHY_1177_DATA, DENALI_PHY_1178_DATA,
> +       DENALI_PHY_1179_DATA,
> +       DENALI_PHY_1180_DATA, DENALI_PHY_1181_DATA, DENALI_PHY_1182_DATA,
> +       DENALI_PHY_1183_DATA, DENALI_PHY_1184_DATA, DENALI_PHY_1185_DATA,
> +       DENALI_PHY_1186_DATA, DENALI_PHY_1187_DATA, DENALI_PHY_1188_DATA,
> +       DENALI_PHY_1189_DATA,
> +       DENALI_PHY_1190_DATA, DENALI_PHY_1191_DATA, DENALI_PHY_1192_DATA,
> +       DENALI_PHY_1193_DATA, DENALI_PHY_1194_DATA, DENALI_PHY_1195_DATA,
> +       DENALI_PHY_1196_DATA, DENALI_PHY_1197_DATA, DENALI_PHY_1198_DATA,
> +       DENALI_PHY_1199_DATA,
> +
> +       DENALI_PHY_1200_DATA, DENALI_PHY_1201_DATA, DENALI_PHY_1202_DATA,
> +       DENALI_PHY_1203_DATA, DENALI_PHY_1204_DATA, DENALI_PHY_1205_DATA,
> +       DENALI_PHY_1206_DATA, DENALI_PHY_1207_DATA, DENALI_PHY_1208_DATA,
> +       DENALI_PHY_1209_DATA,
> +       DENALI_PHY_1210_DATA, DENALI_PHY_1211_DATA, DENALI_PHY_1212_DATA,
> +       DENALI_PHY_1213_DATA, DENALI_PHY_1214_DATA
> +};
> +
> +u32 DENALI_CTL_DATA[265] = {
> +       DENALI_CTL_00_DATA, DENALI_CTL_01_DATA, DENALI_CTL_02_DATA,
> +       DENALI_CTL_03_DATA, DENALI_CTL_04_DATA, DENALI_CTL_05_DATA,
> +       DENALI_CTL_06_DATA, DENALI_CTL_07_DATA, DENALI_CTL_08_DATA,
> +       DENALI_CTL_09_DATA,
> +       DENALI_CTL_10_DATA, DENALI_CTL_11_DATA, DENALI_CTL_12_DATA,
> +       DENALI_CTL_13_DATA, DENALI_CTL_14_DATA, DENALI_CTL_15_DATA,
> +       DENALI_CTL_16_DATA, DENALI_CTL_17_DATA, DENALI_CTL_18_DATA,
> +       DENALI_CTL_19_DATA,
> +       DENALI_CTL_20_DATA, DENALI_CTL_21_DATA, DENALI_CTL_22_DATA,
> +       DENALI_CTL_23_DATA, DENALI_CTL_24_DATA, DENALI_CTL_25_DATA,
> +       DENALI_CTL_26_DATA, DENALI_CTL_27_DATA, DENALI_CTL_28_DATA,
> +       DENALI_CTL_29_DATA,
> +       DENALI_CTL_30_DATA, DENALI_CTL_31_DATA, DENALI_CTL_32_DATA,
> +       DENALI_CTL_33_DATA, DENALI_CTL_34_DATA, DENALI_CTL_35_DATA,
> +       DENALI_CTL_36_DATA, DENALI_CTL_37_DATA, DENALI_CTL_38_DATA,
> +       DENALI_CTL_39_DATA,
> +       DENALI_CTL_40_DATA, DENALI_CTL_41_DATA, DENALI_CTL_42_DATA,
> +       DENALI_CTL_43_DATA, DENALI_CTL_44_DATA, DENALI_CTL_45_DATA,
> +       DENALI_CTL_46_DATA, DENALI_CTL_47_DATA, DENALI_CTL_48_DATA,
> +       DENALI_CTL_49_DATA,
> +       DENALI_CTL_50_DATA, DENALI_CTL_51_DATA, DENALI_CTL_52_DATA,
> +       DENALI_CTL_53_DATA, DENALI_CTL_54_DATA, DENALI_CTL_55_DATA,
> +       DENALI_CTL_56_DATA, DENALI_CTL_57_DATA, DENALI_CTL_58_DATA,
> +       DENALI_CTL_59_DATA,
> +       DENALI_CTL_60_DATA, DENALI_CTL_61_DATA, DENALI_CTL_62_DATA,
> +       DENALI_CTL_63_DATA, DENALI_CTL_64_DATA, DENALI_CTL_65_DATA,
> +       DENALI_CTL_66_DATA, DENALI_CTL_67_DATA, DENALI_CTL_68_DATA,
> +       DENALI_CTL_69_DATA,
> +       DENALI_CTL_70_DATA, DENALI_CTL_71_DATA, DENALI_CTL_72_DATA,
> +       DENALI_CTL_73_DATA, DENALI_CTL_74_DATA, DENALI_CTL_75_DATA,
> +       DENALI_CTL_76_DATA, DENALI_CTL_77_DATA, DENALI_CTL_78_DATA,
> +       DENALI_CTL_79_DATA,
> +       DENALI_CTL_80_DATA, DENALI_CTL_81_DATA, DENALI_CTL_82_DATA,
> +       DENALI_CTL_83_DATA, DENALI_CTL_84_DATA, DENALI_CTL_85_DATA,
> +       DENALI_CTL_86_DATA, DENALI_CTL_87_DATA, DENALI_CTL_88_DATA,
> +       DENALI_CTL_89_DATA,
> +       DENALI_CTL_90_DATA, DENALI_CTL_91_DATA, DENALI_CTL_92_DATA,
> +       DENALI_CTL_93_DATA, DENALI_CTL_94_DATA, DENALI_CTL_95_DATA,
> +       DENALI_CTL_96_DATA, DENALI_CTL_97_DATA, DENALI_CTL_98_DATA,
> +       DENALI_CTL_99_DATA,
> +
> +       DENALI_CTL_100_DATA, DENALI_CTL_101_DATA, DENALI_CTL_102_DATA,
> +       DENALI_CTL_103_DATA, DENALI_CTL_104_DATA, DENALI_CTL_105_DATA,
> +       DENALI_CTL_106_DATA, DENALI_CTL_107_DATA, DENALI_CTL_108_DATA,
> +       DENALI_CTL_109_DATA,
> +       DENALI_CTL_110_DATA, DENALI_CTL_111_DATA, DENALI_CTL_112_DATA,
> +       DENALI_CTL_113_DATA, DENALI_CTL_114_DATA, DENALI_CTL_115_DATA,
> +       DENALI_CTL_116_DATA, DENALI_CTL_117_DATA, DENALI_CTL_118_DATA,
> +       DENALI_CTL_119_DATA,
> +       DENALI_CTL_120_DATA, DENALI_CTL_121_DATA, DENALI_CTL_122_DATA,
> +       DENALI_CTL_123_DATA, DENALI_CTL_124_DATA, DENALI_CTL_125_DATA,
> +       DENALI_CTL_126_DATA, DENALI_CTL_127_DATA, DENALI_CTL_128_DATA,
> +       DENALI_CTL_129_DATA,
> +       DENALI_CTL_130_DATA, DENALI_CTL_131_DATA, DENALI_CTL_132_DATA,
> +       DENALI_CTL_133_DATA, DENALI_CTL_134_DATA, DENALI_CTL_135_DATA,
> +       DENALI_CTL_136_DATA, DENALI_CTL_137_DATA, DENALI_CTL_138_DATA,
> +       DENALI_CTL_139_DATA,
> +       DENALI_CTL_140_DATA, DENALI_CTL_141_DATA, DENALI_CTL_142_DATA,
> +       DENALI_CTL_143_DATA, DENALI_CTL_144_DATA, DENALI_CTL_145_DATA,
> +       DENALI_CTL_146_DATA, DENALI_CTL_147_DATA, DENALI_CTL_148_DATA,
> +       DENALI_CTL_149_DATA,
> +       DENALI_CTL_150_DATA, DENALI_CTL_151_DATA, DENALI_CTL_152_DATA,
> +       DENALI_CTL_153_DATA, DENALI_CTL_154_DATA, DENALI_CTL_155_DATA,
> +       DENALI_CTL_156_DATA, DENALI_CTL_157_DATA, DENALI_CTL_158_DATA,
> +       DENALI_CTL_159_DATA,
> +       DENALI_CTL_160_DATA, DENALI_CTL_161_DATA, DENALI_CTL_162_DATA,
> +       DENALI_CTL_163_DATA, DENALI_CTL_164_DATA, DENALI_CTL_165_DATA,
> +       DENALI_CTL_166_DATA, DENALI_CTL_167_DATA, DENALI_CTL_168_DATA,
> +       DENALI_CTL_169_DATA,
> +       DENALI_CTL_170_DATA, DENALI_CTL_171_DATA, DENALI_CTL_172_DATA,
> +       DENALI_CTL_173_DATA, DENALI_CTL_174_DATA, DENALI_CTL_175_DATA,
> +       DENALI_CTL_176_DATA, DENALI_CTL_177_DATA, DENALI_CTL_178_DATA,
> +       DENALI_CTL_179_DATA,
> +       DENALI_CTL_180_DATA, DENALI_CTL_181_DATA, DENALI_CTL_182_DATA,
> +       DENALI_CTL_183_DATA, DENALI_CTL_184_DATA, DENALI_CTL_185_DATA,
> +       DENALI_CTL_186_DATA, DENALI_CTL_187_DATA, DENALI_CTL_188_DATA,
> +       DENALI_CTL_189_DATA,
> +       DENALI_CTL_190_DATA, DENALI_CTL_191_DATA, DENALI_CTL_192_DATA,
> +       DENALI_CTL_193_DATA, DENALI_CTL_194_DATA, DENALI_CTL_195_DATA,
> +       DENALI_CTL_196_DATA, DENALI_CTL_197_DATA, DENALI_CTL_198_DATA,
> +       DENALI_CTL_199_DATA,
> +
> +       DENALI_CTL_200_DATA, DENALI_CTL_201_DATA, DENALI_CTL_202_DATA,
> +       DENALI_CTL_203_DATA, DENALI_CTL_204_DATA, DENALI_CTL_205_DATA,
> +       DENALI_CTL_206_DATA, DENALI_CTL_207_DATA, DENALI_CTL_208_DATA,
> +       DENALI_CTL_209_DATA,
> +       DENALI_CTL_210_DATA, DENALI_CTL_211_DATA, DENALI_CTL_212_DATA,
> +       DENALI_CTL_213_DATA, DENALI_CTL_214_DATA, DENALI_CTL_215_DATA,
> +       DENALI_CTL_216_DATA, DENALI_CTL_217_DATA, DENALI_CTL_218_DATA,
> +       DENALI_CTL_219_DATA,
> +       DENALI_CTL_220_DATA, DENALI_CTL_221_DATA, DENALI_CTL_222_DATA,
> +       DENALI_CTL_223_DATA, DENALI_CTL_224_DATA, DENALI_CTL_225_DATA,
> +       DENALI_CTL_226_DATA, DENALI_CTL_227_DATA, DENALI_CTL_228_DATA,
> +       DENALI_CTL_229_DATA,
> +       DENALI_CTL_230_DATA, DENALI_CTL_231_DATA, DENALI_CTL_232_DATA,
> +       DENALI_CTL_233_DATA, DENALI_CTL_234_DATA, DENALI_CTL_235_DATA,
> +       DENALI_CTL_236_DATA, DENALI_CTL_237_DATA, DENALI_CTL_238_DATA,
> +       DENALI_CTL_239_DATA,
> +       DENALI_CTL_240_DATA, DENALI_CTL_241_DATA, DENALI_CTL_242_DATA,
> +       DENALI_CTL_243_DATA, DENALI_CTL_244_DATA, DENALI_CTL_245_DATA,
> +       DENALI_CTL_246_DATA, DENALI_CTL_247_DATA, DENALI_CTL_248_DATA,
> +       DENALI_CTL_249_DATA,
> +       DENALI_CTL_250_DATA, DENALI_CTL_251_DATA, DENALI_CTL_252_DATA,
> +       DENALI_CTL_253_DATA, DENALI_CTL_254_DATA, DENALI_CTL_255_DATA,
> +       DENALI_CTL_256_DATA, DENALI_CTL_257_DATA, DENALI_CTL_258_DATA,
> +       DENALI_CTL_259_DATA,
> +       DENALI_CTL_260_DATA, DENALI_CTL_261_DATA, DENALI_CTL_262_DATA,
> +       DENALI_CTL_263_DATA, DENALI_CTL_264_DATA
> +};
> diff --git a/board/sifive/fu540/include/ememoryotp.h b/board/sifive/fu540/include/ememoryotp.h
> new file mode 100644
> index 0000000000..274283c4db
> --- /dev/null
> +++ b/board/sifive/fu540/include/ememoryotp.h
> @@ -0,0 +1,24 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef FU540_EMEMORYOTP_H
> +#define FU540_EMEMORYOTP_H
> +
> +#include <asm/arch/otp.h>
> +
> +void ememory_otp_power_up_sequence(void);
> +void ememory_otp_power_down_sequence(void);
> +void ememory_otp_begin_read(void);
> +void ememory_otp_exit_read(void);
> +unsigned int ememory_otp_read(int address);
> +void ememory_otp_pgm_entry(void);
> +void ememory_otp_pgm_exit(void);
> +void ememory_otp_pgm_access(int address, unsigned int write_data);
> +
> +#endif /* FU540_EMEMORYOTP_H */
> diff --git a/board/sifive/fu540/include/fu540-memory-map.h b/board/sifive/fu540/include/fu540-memory-map.h
> new file mode 100644
> index 0000000000..071ee3d1d9
> --- /dev/null
> +++ b/board/sifive/fu540/include/fu540-memory-map.h
> @@ -0,0 +1,427 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef FU540_MEMORY_MAP
> +#define FU540_MEMORY_MAP
> +
> +#include <linux/const.h>
> +#include <asm/arch/clint.h>
> +#include <asm/arch/gpio.h>
> +#include "ememoryotp.h"
> +#include "ccache.h"
> +#include "i2c.h"
> +#include "spi.h"
> +#include "uart.h"
> +#include "ux00prci.h"
> +
> +/****************************************************************************
> + * Platform definitions
> + *****************************************************************************/
> +
> +// CPU info
> +#define NUM_CORES                      5
> +#define MAX_HART_ID                    4
> +#define GLOBAL_INT_SIZE                59
> +#define GLOBAL_INT_MAX_PRIORITY        7
> +#define RTC_FREQUENCY_HZ               _AC(1000000, UL)
> +#define RTC_PERIOD_NS                  _AC(1000, UL)
> +
> +// Memory map
> +#define BUSERROR0_CTRL_ADDR            _AC(0x1700000, UL)
> +#define BUSERROR0_CTRL_SIZE            _AC(0x1000, UL)
> +#define BUSERROR1_CTRL_ADDR            _AC(0x1701000, UL)
> +#define BUSERROR1_CTRL_SIZE            _AC(0x1000, UL)
> +#define BUSERROR2_CTRL_ADDR            _AC(0x1702000, UL)
> +#define BUSERROR2_CTRL_SIZE            _AC(0x1000, UL)
> +#define BUSERROR3_CTRL_ADDR            _AC(0x1703000, UL)
> +#define BUSERROR3_CTRL_SIZE            _AC(0x1000, UL)
> +#define BUSERROR4_CTRL_ADDR            _AC(0x1704000, UL)
> +#define BUSERROR4_CTRL_SIZE            _AC(0x1000, UL)
> +#ifndef BUSERROR_CTRL_ADDR
> +#define BUSERROR_CTRL_ADDR             BUSERROR0_CTRL_ADDR
> +#endif
> +#ifndef BUSERROR_CTRL_SIZE
> +#define BUSERROR_CTRL_SIZE             BUSERROR0_CTRL_SIZE
> +#endif
> +
> +#define CACHEABLE_ZERO_MEM_ADDR        _AC(0xa000000, UL)
> +#define CACHEABLE_ZERO_MEM_SIZE        _AC(0x2000000, UL)
> +#define CADENCEDDRMGMT_CTRL_ADDR       _AC(0x100c0000, UL)
> +#define CADENCEDDRMGMT_CTRL_SIZE       _AC(0x1000, UL)
> +#define CADENCEGEMGXLMGMT_CTRL_ADDR    _AC(0x100a0000, UL)
> +#define CADENCEGEMGXLMGMT_CTRL_SIZE    _AC(0x1000, UL)
> +#define CCACHE_CTRL_ADDR               _AC(0x2010000, UL)
> +#define CCACHE_CTRL_SIZE               _AC(0x1000, UL)
> +#define CCACHE_SIDEBAND_ADDR           _AC(0x8000000, UL)
> +#define CCACHE_SIDEBAND_SIZE           _AC(0x1e0000, UL)
> +
> +#define CHIPLINK_MEM0_ADDR             _AC(0x40000000, UL)
> +#define CHIPLINK_MEM0_SIZE             _AC(0x10000000, UL)
> +#define CHIPLINK_MEM1_ADDR             _AC(0x60000000, UL)
> +#define CHIPLINK_MEM1_SIZE             _AC(0x10000000, UL)
> +#define CHIPLINK_MEM2_ADDR             _AC(0x2000000000, UL)
> +#define CHIPLINK_MEM2_SIZE             _AC(0x20000000, UL)
> +#define CHIPLINK_MEM3_ADDR             _AC(0x2080000000, UL)
> +#define CHIPLINK_MEM3_SIZE             _AC(0x180000000, UL)
> +#define CHIPLINK_MEM4_ADDR             _AC(0x3000000000, UL)
> +#define CHIPLINK_MEM4_SIZE             _AC(0x20000000, UL)
> +
> +#define CLINT_CTRL_ADDR                _AC(0x2000000, UL)
> +#define CLINT_CTRL_SIZE                _AC(0x10000, UL)
> +#define DEBUG_CTRL_ADDR                _AC(0x0, UL)
> +#define DEBUG_CTRL_SIZE                _AC(0x1000, UL)
> +#define DMA_CTRL_ADDR                  _AC(0x3000000, UL)
> +#define DMA_CTRL_SIZE                  _AC(0x100000, UL)
> +#define DTIM_MEM_ADDR                  _AC(0x1000000, UL)
> +#define DTIM_MEM_SIZE                  _AC(0x2000, UL)
> +#define EMEMORYOTP_CTRL_ADDR           _AC(0x10070000, UL)
> +#define EMEMORYOTP_CTRL_SIZE           _AC(0x1000, UL)
> +#define ERROR_MEM_ADDR                 _AC(0x18000000, UL)
> +#define ERROR_MEM_SIZE                 _AC(0x8000000, UL)
> +#define GPIO_CTRL_ADDR                 _AC(0x10060000, UL)
> +#define GPIO_CTRL_SIZE                 _AC(0x1000, UL)
> +#define I2C_CTRL_ADDR                  _AC(0x10030000, UL)
> +#define I2C_CTRL_SIZE                  _AC(0x1000, UL)
> +
> +#define ITIM0_MEM_ADDR                 _AC(0x1800000, UL)
> +#define ITIM0_MEM_SIZE                 _AC(0x2000, UL)
> +#define ITIM1_MEM_ADDR                 _AC(0x1808000, UL)
> +#define ITIM1_MEM_SIZE                 _AC(0x7000, UL)
> +#define ITIM2_MEM_ADDR                 _AC(0x1810000, UL)
> +#define ITIM2_MEM_SIZE                 _AC(0x7000, UL)
> +#define ITIM3_MEM_ADDR                 _AC(0x1818000, UL)
> +#define ITIM3_MEM_SIZE                 _AC(0x7000, UL)
> +#define ITIM4_MEM_ADDR                 _AC(0x1820000, UL)
> +#define ITIM4_MEM_SIZE                 _AC(0x7000, UL)
> +#ifndef ITIM_MEM_ADDR
> +#define ITIM_MEM_ADDR                  ITIM0_MEM_ADDR
> +#endif
> +#ifndef ITIM_MEM_SIZE
> +#define ITIM_MEM_SIZE                  ITIM0_MEM_SIZE
> +#endif
> +
> +#define MAC_CTRL_ADDR                  _AC(0x10090000, UL)
> +#define MAC_CTRL_SIZE                  _AC(0x2000, UL)
> +#define MASKROM_MEM_ADDR               _AC(0x10000, UL)
> +#define MASKROM_MEM_SIZE               _AC(0x8000, UL)
> +#define MEMORY_MEM_ADDR                _AC(0x80000000, UL)
> +#define MEMORY_MEM_SIZE                _AC(0x80000000, UL)
> +#define MODESELECT_MEM_ADDR            _AC(0x1000, UL)
> +#define MODESELECT_MEM_SIZE            _AC(0x1000, UL)
> +#define MSI_CTRL_ADDR                  _AC(0x2020000, UL)
> +#define MSI_CTRL_SIZE                  _AC(0x1000, UL)
> +#define ORDER_OGLER_CTRL_ADDR          _AC(0x10100000, UL)
> +#define ORDER_OGLER_CTRL_SIZE          _AC(0x1000, UL)
> +#define PHYSICAL_FILTER_CTRL_ADDR      _AC(0x100b8000, UL)
> +#define PHYSICAL_FILTER_CTRL_SIZE      _AC(0x1000, UL)
> +#define PINCTRL_CTRL_ADDR              _AC(0x10080000, UL)
> +#define PINCTRL_CTRL_SIZE              _AC(0x1000, UL)
> +#define PLIC_CTRL_ADDR                 _AC(0xc000000, UL)
> +#define PLIC_CTRL_SIZE                 _AC(0x4000000, UL)
> +
> +#define PWM0_CTRL_ADDR                 _AC(0x10020000, UL)
> +#define PWM0_CTRL_SIZE                 _AC(0x1000, UL)
> +#define PWM1_CTRL_ADDR                 _AC(0x10021000, UL)
> +#define PWM1_CTRL_SIZE                 _AC(0x1000, UL)
> +#ifndef PWM_CTRL_ADDR
> +#define PWM_CTRL_ADDR                  PWM0_CTRL_ADDR
> +#endif
> +#ifndef PWM_CTRL_SIZE
> +#define PWM_CTRL_SIZE                  PWM0_CTRL_SIZE
> +#endif
> +
> +#define SPI0_CTRL_ADDR                 _AC(0x10040000, UL)
> +#define SPI0_CTRL_SIZE                 _AC(0x1000, UL)
> +#define SPI0_MEM_ADDR                  _AC(0x20000000, UL)
> +#define SPI0_MEM_SIZE                  _AC(0x10000000, UL)
> +#define SPI1_CTRL_ADDR                 _AC(0x10041000, UL)
> +#define SPI1_CTRL_SIZE                 _AC(0x1000, UL)
> +#define SPI1_MEM_ADDR                  _AC(0x30000000, UL)
> +#define SPI1_MEM_SIZE                  _AC(0x10000000, UL)
> +#define SPI2_CTRL_ADDR                 _AC(0x10050000, UL)
> +#define SPI2_CTRL_SIZE                 _AC(0x1000, UL)
> +#ifndef SPI_CTRL_ADDR
> +#define SPI_CTRL_ADDR                  SPI0_CTRL_ADDR
> +#endif
> +#ifndef SPI_CTRL_SIZE
> +#define SPI_CTRL_SIZE                  SPI0_CTRL_SIZE
> +#endif
> +#ifndef SPI_MEM_ADDR
> +#define SPI_MEM_ADDR                   SPI0_MEM_ADDR
> +#endif
> +#ifndef SPI_MEM_SIZE
> +#define SPI_MEM_SIZE                   SPI0_MEM_SIZE
> +#endif
> +
> +#define TEST_CTRL_ADDR                 _AC(0x4000, UL)
> +#define TEST_CTRL_SIZE                 _AC(0x1000, UL)
> +#define UART0_CTRL_ADDR                _AC(0x10010000, UL)
> +#define UART0_CTRL_SIZE                _AC(0x1000, UL)
> +#define UART1_CTRL_ADDR                _AC(0x10011000, UL)
> +#define UART1_CTRL_SIZE                _AC(0x1000, UL)
> +#ifndef UART_CTRL_ADDR
> +#define UART_CTRL_ADDR                 UART0_CTRL_ADDR
> +#endif
> +#ifndef UART_CTRL_SIZE
> +#define UART_CTRL_SIZE                 UART0_CTRL_SIZE
> +#endif
> +#define UX00DDR_CTRL_ADDR              _AC(0x100b0000, UL)
> +#define UX00DDR_CTRL_SIZE              _AC(0x4000, UL)
> +#define UX00PRCI_CTRL_ADDR             _AC(0x10000000, UL)
> +#define UX00PRCI_CTRL_SIZE             _AC(0x1000, UL)
> +
> +// IOF masks
> +// Interrupt numbers
> +#define CCACHE_INT_BASE       1
> +#define UART0_INT_BASE        5
> +#define UART1_INT_BASE        6
> +#define SPI2_INT_BASE         7
> +#define GPIO_INT_BASE         8
> +#define DMA_INT_BASE          24
> +#define UX00DDR_INT_BASE      32
> +#define MSI_INT_BASE          33
> +#define PWM0_INT_BASE         43
> +#define PWM1_INT_BASE         47
> +#define I2C_INT_BASE          51
> +#define SPI0_INT_BASE         52
> +#define SPI1_INT_BASE         53
> +#define MAC_INT_BASE          54
> +#define BUSERROR0_INT_BASE    55
> +#define BUSERROR1_INT_BASE    56
> +#define BUSERROR2_INT_BASE    57
> +#define BUSERROR3_INT_BASE    58
> +#define BUSERROR4_INT_BASE    59
> +#ifndef BUSERROR_INT_BASE
> +#define BUSERROR_INT_BASE     BUSERROR0_INT_BASE
> +#endif
> +#ifndef PWM_INT_BASE
> +#define PWM_INT_BASE          PWM0_INT_BASE
> +#endif
> +#ifndef SPI_INT_BASE
> +#define SPI_INT_BASE          SPI0_INT_BASE
> +#endif
> +#ifndef UART_INT_BASE
> +#define UART_INT_BASE         UART0_INT_BASE
> +#endif
> +
> +// Helper functions
> +#define _REG64(p, i)    (*(volatile uint64_t *)((p) + (i)))
> +#define _REG32(p, i)    (*(volatile uint32_t *)((p) + (i)))
> +#define _REG16(p, i)    (*(volatile uint16_t *)((p) + (i)))
> +// Bulk set bits in `reg` to either 0 or 1.
> +// E.g. SET_BITS(MY_REG, 0x00000007, 0) would generate MY_REG &= ~0x7
> +// E.g. SET_BITS(MY_REG, 0x00000007, 1) would generate MY_REG |= 0x7
> +#define SET_BITS(reg, mask, value)         \
> +       if ((value) == 0)       \
> +               (reg) &= ~(mask);       \
> +       else    {\
> +               (reg) |= (mask); }
> +
> +#ifndef BUSERROR_REG
> +#define BUSERROR_REG(offset)      BUSERROR0_REG(offset)
> +#endif
> +#ifndef BUSERROR_REG64
> +#define BUSERROR_REG64(offset)    BUSERROR0_REG64(offset)
> +#endif
> +#ifndef ITIM_REG
> +#define ITIM_REG(offset)          ITIM0_REG(offset)
> +#endif
> +#ifndef ITIM_REG64
> +#define ITIM_REG64(offset)        ITIM0_REG64(offset)
> +#endif
> +#ifndef PWM_REG
> +#define PWM_REG(offset)           PWM0_REG(offset)
> +#endif
> +#ifndef PWM_REG64
> +#define PWM_REG64(offset)         PWM0_REG64(offset)
> +#endif
> +#ifndef SPI_REG
> +#define SPI_REG(offset)           SPI0_REG(offset)
> +#endif
> +#ifndef SPI_REG64
> +#define SPI_REG64(offset)         SPI0_REG64(offset)
> +#endif
> +#ifndef UART_REG
> +#define UART_REG(offset)          UART0_REG(offset)
> +#endif
> +#ifndef UART_REG64
> +#define UART_REG64(offset)        UART0_REG64(offset)
> +#endif
> +#define BUSERROR0_REG(offset)  \
> +       _REG32(BUSERROR0_CTRL_ADDR, \
> +                       offset)
> +#define BUSERROR1_REG(offset)  \
> +       _REG32(BUSERROR1_CTRL_ADDR, \
> +                       offset)
> +#define BUSERROR2_REG(offset)  \
> +       _REG32(BUSERROR2_CTRL_ADDR, \
> +                       offset)
> +#define BUSERROR3_REG(offset)  \
> +       _REG32(BUSERROR3_CTRL_ADDR, \
> +                       offset)
> +#define BUSERROR4_REG(offset)  \
> +       _REG32(BUSERROR4_CTRL_ADDR, \
> +                       offset)
> +#define CACHEABLE_ZERO_REG(offset)  \
> +       _REG32(CACHEABLE_ZERO_CTRL_ADDR, \
> +                       offset)
> +#define CADENCEDDRMGMT_REG(offset)  \
> +       _REG32(CADENCEDDRMGMT_CTRL_ADDR, \
> +                       offset)
> +#define CADENCEGEMGXLMGMT_REG(offset) \
> +       _REG32(                            \
> +                       CADENCEGEMGXLMGMT_CTRL_ADDR, offset)
> +#define CCACHE_REG(offset)    _REG32(CCACHE_CTRL_ADDR, offset)
> +#define CHIPLINK_REG(offset)  \
> +       _REG32(CHIPLINK_CTRL_ADDR, \
> +                       offset)
> +#define CLINT_REG(offset)     _REG32(CLINT_CTRL_ADDR, offset)
> +#define DEBUG_REG(offset)     _REG32(DEBUG_CTRL_ADDR, offset)
> +#define DMA_REG(offset)       _REG32(DMA_CTRL_ADDR, offset)
> +#define DTIM_REG(offset)      _REG32(DTIM_CTRL_ADDR, offset)
> +#define EMEMORYOTP_REG(offset)  \
> +       _REG32(EMEMORYOTP_CTRL_ADDR, \
> +                       offset)
> +#define ERROR_REG(offset)     _REG32(ERROR_CTRL_ADDR, offset)
> +#define GPIO_REG(offset)      _REG32(GPIO_CTRL_ADDR, offset)
> +#define I2C_REG(offset)       _REG32(I2C_CTRL_ADDR, offset)
> +#define ITIM0_REG(offset)     _REG32(ITIM0_CTRL_ADDR, offset)
> +#define ITIM1_REG(offset)     _REG32(ITIM1_CTRL_ADDR, offset)
> +#define ITIM2_REG(offset)     _REG32(ITIM2_CTRL_ADDR, offset)
> +#define ITIM3_REG(offset)     _REG32(ITIM3_CTRL_ADDR, offset)
> +#define ITIM4_REG(offset)     _REG32(ITIM4_CTRL_ADDR, offset)
> +#define MAC_REG(offset)       _REG32(MAC_CTRL_ADDR, offset)
> +#define MASKROM_REG(offset)  \
> +       _REG32(MASKROM_CTRL_ADDR, \
> +                       offset)
> +#define MEMORY_REG(offset)    _REG32(MEMORY_CTRL_ADDR, offset)
> +#define MODESELECT_REG(offset)  \
> +       _REG32(MODESELECT_CTRL_ADDR, \
> +                       offset)
> +#define MSI_REG(offset)       _REG32(MSI_CTRL_ADDR, offset)
> +#define ORDER_OGLER_REG(offset)  \
> +       _REG32(ORDER_OGLER_CTRL_ADDR, \
> +                       offset)
> +#define PHYSICAL_FILTER_REG(offset) \
> +       _REG32(                          \
> +                       PHYSICAL_FILTER_CTRL_ADDR, offset)
> +#define PINCTRL_REG(offset)  \
> +       _REG32(PINCTRL_CTRL_ADDR, \
> +                       offset)
> +#define PLIC_REG(offset)     _REG32(PLIC_CTRL_ADDR, offset)
> +#define PWM0_REG(offset)     _REG32(PWM0_CTRL_ADDR, offset)
> +#define PWM1_REG(offset)     _REG32(PWM1_CTRL_ADDR, offset)
> +#define SPI0_REG(offset)     _REG32(SPI0_CTRL_ADDR, offset)
> +#define SPI1_REG(offset)     _REG32(SPI1_CTRL_ADDR, offset)
> +#define SPI2_REG(offset)     _REG32(SPI2_CTRL_ADDR, offset)
> +#define TEST_REG(offset)     _REG32(TEST_CTRL_ADDR, offset)
> +#define UART0_REG(offset)    _REG32(UART0_CTRL_ADDR, offset)
> +#define UART1_REG(offset)    _REG32(UART1_CTRL_ADDR, offset)
> +#define UX00DDR_REG(offset)  \
> +       _REG32(UX00DDR_CTRL_ADDR, \
> +                       offset)
> +#define UX00PRCI_REG(offset)  \
> +       _REG32(UX00PRCI_CTRL_ADDR, \
> +                       offset)
> +#define BUSERROR0_REG64(offset) \
> +       _REG64(BUSERROR0_CTRL_ADDR,  \
> +                       offset)
> +#define BUSERROR1_REG64(offset) \
> +       _REG64(BUSERROR1_CTRL_ADDR,  \
> +                       offset)
> +#define BUSERROR2_REG64(offset) \
> +       _REG64(BUSERROR2_CTRL_ADDR,  \
> +                       offset)
> +#define BUSERROR3_REG64(offset) \
> +       _REG64(BUSERROR3_CTRL_ADDR,  \
> +                       offset)
> +#define BUSERROR4_REG64(offset) \
> +       _REG64(BUSERROR4_CTRL_ADDR,  \
> +                       offset)
> +#define CACHEABLE_ZERO_REG64(offset) \
> +       _REG64(CACHEABLE_ZERO_CTRL_ADDR,  \
> +                       offset)
> +#define CADENCEDDRMGMT_REG64(offset) \
> +       _REG64(CADENCEDDRMGMT_CTRL_ADDR,  \
> +                       offset)
> +#define CADENCEGEMGXLMGMT_REG64(offset) \
> +       _REG64(                              \
> +                       CADENCEGEMGXLMGMT_CTRL_ADDR, offset)
> +#define CCACHE_REG64(offset)    _REG64(CCACHE_CTRL_ADDR, offset)
> +#define CHIPLINK_REG64(offset) \
> +       _REG64(CHIPLINK_CTRL_ADDR,  \
> +                       offset)
> +#define CLINT_REG64(offset)     _REG64(CLINT_CTRL_ADDR, offset)
> +#define DEBUG_REG64(offset)     _REG64(DEBUG_CTRL_ADDR, offset)
> +#define DMA_REG64(offset)       _REG64(DMA_CTRL_ADDR, offset)
> +#define DTIM_REG64(offset)      _REG64(DTIM_CTRL_ADDR, offset)
> +#define EMEMORYOTP_REG64(offset) \
> +       _REG64(EMEMORYOTP_CTRL_ADDR,  \
> +                       offset)
> +#define ERROR_REG64(offset)     _REG64(ERROR_CTRL_ADDR, offset)
> +#define GPIO_REG64(offset)      _REG64(GPIO_CTRL_ADDR, offset)
> +#define I2C_REG64(offset)       _REG64(I2C_CTRL_ADDR, offset)
> +#define ITIM0_REG64(offset)     _REG64(ITIM0_CTRL_ADDR, offset)
> +#define ITIM1_REG64(offset)     _REG64(ITIM1_CTRL_ADDR, offset)
> +#define ITIM2_REG64(offset)     _REG64(ITIM2_CTRL_ADDR, offset)
> +#define ITIM3_REG64(offset)     _REG64(ITIM3_CTRL_ADDR, offset)
> +#define ITIM4_REG64(offset)     _REG64(ITIM4_CTRL_ADDR, offset)
> +#define MAC_REG64(offset)       _REG64(MAC_CTRL_ADDR, offset)
> +#define MASKROM_REG64(offset) \
> +       _REG64(MASKROM_CTRL_ADDR,  \
> +                       offset)
> +#define MEMORY_REG64(offset)    _REG64(MEMORY_CTRL_ADDR, offset)
> +#define MODESELECT_REG64(offset) \
> +       _REG64(MODESELECT_CTRL_ADDR,  \
> +                       offset)
> +#define MSI_REG64(offset)       _REG64(MSI_CTRL_ADDR, offset)
> +#define ORDER_OGLER_REG64(offset) \
> +       _REG64(ORDER_OGLER_CTRL_ADDR,  \
> +                       offset)
> +#define PHYSICAL_FILTER_REG64(offset) \
> +       _REG64(                            \
> +                       PHYSICAL_FILTER_CTRL_ADDR, offset)
> +#define PINCTRL_REG64(offset) \
> +       _REG64(PINCTRL_CTRL_ADDR,  \
> +                       offset)
> +#define PLIC_REG64(offset)     _REG64(PLIC_CTRL_ADDR, offset)
> +#define PWM0_REG64(offset)     _REG64(PWM0_CTRL_ADDR, offset)
> +#define PWM1_REG64(offset)     _REG64(PWM1_CTRL_ADDR, offset)
> +#define SPI0_REG64(offset)     _REG64(SPI0_CTRL_ADDR, offset)
> +#define SPI1_REG64(offset)     _REG64(SPI1_CTRL_ADDR, offset)
> +#define SPI2_REG64(offset)     _REG64(SPI2_CTRL_ADDR, offset)
> +#define TEST_REG64(offset)     _REG64(TEST_CTRL_ADDR, offset)
> +#define UART0_REG64(offset)    _REG64(UART0_CTRL_ADDR, offset)
> +#define UART1_REG64(offset)    _REG64(UART1_CTRL_ADDR, offset)
> +#define UX00DDR_REG64(offset) \
> +       _REG64(UX00DDR_CTRL_ADDR,  \
> +                       offset)
> +#define UX00PRCI_REG64(offset) \
> +       _REG64(UX00PRCI_CTRL_ADDR,  \
> +                       offset)
> +// Helpers for getting and setting individual bit fields, shifting the values
> +// for you.
> +#define GET_FIELD(reg, mask)     \
> +       (((reg) & (mask)) / ((mask) & \
> +               ~((mask) << 1)))
> +#define SET_FIELD(reg, mask, val) \
> +       (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask)))
> +
> +// Misc
> +#define ALOE
> +#define SPI0_CS_WIDTH        1
> +#define SPI0_SCKDIV_WIDTH    16
> +#define SPI1_CS_WIDTH        4
> +#define SPI1_SCKDIV_WIDTH    16
> +#define SPI2_CS_WIDTH        1
> +#define SPI2_SCKDIV_WIDTH    16
> +#define GPIO_WIDTH           16
> +
> +#endif /* FU540_MEMORY_MAP */
> diff --git a/board/sifive/fu540/include/i2c.h b/board/sifive/fu540/include/i2c.h
> new file mode 100644
> index 0000000000..89c81f6b92
> --- /dev/null
> +++ b/board/sifive/fu540/include/i2c.h
> @@ -0,0 +1,49 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef FU540_I2C_H
> +#define FU540_I2C_H
> +
> +#include <asm/arch/i2c.h>
> +
> +#ifndef __ASSEMBLER__
> +
> +#include <stdint.h>
> +
> +/*
> + * Get smallest clock prescaler that divides input_khz to a quotient less
> + * than or equal to max_target_khz;
> + */
> +static inline uint16_t i2c_min_clk_prescaler(unsigned int input_khz,
> +                                            unsigned int max_target_khz)
> +{
> +       // f_sck = f_in / (2 * (div + 1)) => div = (f_in / (2*f_sck)) - 1
> +       // prescale = (f_in / (5*f_scl)) - 1
> +       //
> +       // The nearest integer solution for div requires
> +       // rounding up as to not exceed max_target_khz.
> +       //
> +       // div = ceil(f_in / (5*f_scl)) - 1
> +       //     = floor((f_in - 1 + 5*f_scl) / (5*f_scl)) - 1
> +       //
> +       // This should not overflow as long as (f_in - 1 + 5*f_scl) does not
> +       // exceed 2^32 - 1, which is unlikely since we represent frequencies
> +       // in kHz.
> +       unsigned int quotient = (input_khz + 5 * max_target_khz - 1) / (5 *
> +                                max_target_khz);
> +       // Avoid underflow
> +       if (quotient == 0)
> +               return 0;
> +       else
> +               return quotient - 1;
> +}
> +
> +#endif /* !__ASSEMBLER__ */
> +
> +#endif /* FU540_I2C_H */
> diff --git a/board/sifive/fu540/include/regconfig-ctl.h b/board/sifive/fu540/include/regconfig-ctl.h
> new file mode 100644
> index 0000000000..19a52e7996
> --- /dev/null
> +++ b/board/sifive/fu540/include/regconfig-ctl.h
> @@ -0,0 +1,274 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#define               DENALI_CTL_00_DATA 0x00000a00
> +#define               DENALI_CTL_01_DATA 0x00000000
> +#define               DENALI_CTL_02_DATA 0x00000000
> +#define               DENALI_CTL_03_DATA 0x00000000
> +#define               DENALI_CTL_04_DATA 0x00000000
> +#define               DENALI_CTL_05_DATA 0x00000000
> +#define               DENALI_CTL_06_DATA 0x0000000a
> +#define               DENALI_CTL_07_DATA 0x0002d362
> +#define               DENALI_CTL_08_DATA 0x00071073
> +#define               DENALI_CTL_09_DATA 0x0a1c0255
> +#define               DENALI_CTL_10_DATA 0x1c1c0400
> +#define               DENALI_CTL_11_DATA 0x0404990b
> +#define               DENALI_CTL_12_DATA 0x2b050405
> +#define               DENALI_CTL_13_DATA 0x0e0c081e
> +#define               DENALI_CTL_14_DATA 0x08090914
> +#define               DENALI_CTL_15_DATA 0x00fde718
> +#define               DENALI_CTL_16_DATA 0x00180a05
> +#define               DENALI_CTL_17_DATA 0x008b130e
> +#define               DENALI_CTL_18_DATA 0x01000118
> +#define               DENALI_CTL_19_DATA 0x0e032101
> +#define               DENALI_CTL_20_DATA 0x00000000
> +#define               DENALI_CTL_21_DATA 0x00000101
> +#define               DENALI_CTL_22_DATA 0x00000000
> +#define               DENALI_CTL_23_DATA 0x0a000000
> +#define               DENALI_CTL_24_DATA 0x00000000
> +#define               DENALI_CTL_25_DATA 0x01450100
> +#define               DENALI_CTL_26_DATA 0x00001c36
> +#define               DENALI_CTL_27_DATA 0x00000005
> +#define               DENALI_CTL_28_DATA 0x00170006
> +#define               DENALI_CTL_29_DATA 0x014e0300
> +#define               DENALI_CTL_30_DATA 0x03010000
> +#define               DENALI_CTL_31_DATA 0x000a0e00
> +#define               DENALI_CTL_32_DATA 0x04030200
> +#define               DENALI_CTL_33_DATA 0x0000031f
> +#define               DENALI_CTL_34_DATA 0x00070004
> +#define               DENALI_CTL_35_DATA 0x00000000
> +#define               DENALI_CTL_36_DATA 0x00000000
> +#define               DENALI_CTL_37_DATA 0x00000000
> +#define               DENALI_CTL_38_DATA 0x00000000
> +#define               DENALI_CTL_39_DATA 0x00000000
> +#define               DENALI_CTL_40_DATA 0x00000000
> +#define               DENALI_CTL_41_DATA 0x00000000
> +#define               DENALI_CTL_42_DATA 0x00000000
> +#define               DENALI_CTL_43_DATA 0x00000000
> +#define               DENALI_CTL_44_DATA 0x00000000
> +#define               DENALI_CTL_45_DATA 0x00000000
> +#define               DENALI_CTL_46_DATA 0x00000000
> +#define               DENALI_CTL_47_DATA 0x00000000
> +#define               DENALI_CTL_48_DATA 0x00000000
> +#define               DENALI_CTL_49_DATA 0x00000000
> +#define               DENALI_CTL_50_DATA 0x00000000
> +#define               DENALI_CTL_51_DATA 0x00000000
> +#define               DENALI_CTL_52_DATA 0x00000000
> +#define               DENALI_CTL_53_DATA 0x00000000
> +#define               DENALI_CTL_54_DATA 0x00000000
> +#define               DENALI_CTL_55_DATA 0x00000000
> +#define               DENALI_CTL_56_DATA 0x00000000
> +#define               DENALI_CTL_57_DATA 0x00000000
> +#define               DENALI_CTL_58_DATA 0x00000000
> +#define               DENALI_CTL_59_DATA 0x00000000
> +#define               DENALI_CTL_60_DATA 0x00000424
> +#define               DENALI_CTL_61_DATA 0x00000201
> +#define               DENALI_CTL_62_DATA 0x00001008
> +#define               DENALI_CTL_63_DATA 0x00000000
> +#define               DENALI_CTL_64_DATA 0x00000200
> +#define               DENALI_CTL_65_DATA 0x00000000
> +#define               DENALI_CTL_66_DATA 0x00000481
> +#define               DENALI_CTL_67_DATA 0x00000400
> +#define               DENALI_CTL_68_DATA 0x00000424
> +#define               DENALI_CTL_69_DATA 0x00000201
> +#define               DENALI_CTL_70_DATA 0x00001008
> +#define               DENALI_CTL_71_DATA 0x00000000
> +#define               DENALI_CTL_72_DATA 0x00000200
> +#define               DENALI_CTL_73_DATA 0x00000000
> +#define               DENALI_CTL_74_DATA 0x00000481
> +#define               DENALI_CTL_75_DATA 0x00000400
> +#define               DENALI_CTL_76_DATA 0x01010000
> +#define               DENALI_CTL_77_DATA 0x00000000
> +#define               DENALI_CTL_78_DATA 0x00000000
> +#define               DENALI_CTL_79_DATA 0x00000000
> +#define               DENALI_CTL_80_DATA 0x00000000
> +#define               DENALI_CTL_81_DATA 0x00000000
> +#define               DENALI_CTL_82_DATA 0x00000000
> +#define               DENALI_CTL_83_DATA 0x00000000
> +#define               DENALI_CTL_84_DATA 0x00000000
> +#define               DENALI_CTL_85_DATA 0x00000000
> +#define               DENALI_CTL_86_DATA 0x00000000
> +#define               DENALI_CTL_87_DATA 0x00000000
> +#define               DENALI_CTL_88_DATA 0x00000000
> +#define               DENALI_CTL_89_DATA 0x00000000
> +#define               DENALI_CTL_90_DATA 0x00000000
> +#define               DENALI_CTL_91_DATA 0x00000000
> +#define               DENALI_CTL_92_DATA 0x00000000
> +#define               DENALI_CTL_93_DATA 0x00000000
> +#define               DENALI_CTL_94_DATA 0x00000000
> +#define               DENALI_CTL_95_DATA 0x00000000
> +#define               DENALI_CTL_96_DATA 0x00000000
> +#define               DENALI_CTL_97_DATA 0x00000000
> +#define               DENALI_CTL_98_DATA 0x00000000
> +#define               DENALI_CTL_99_DATA 0x00000000
> +#define              DENALI_CTL_100_DATA 0x00000000
> +#define              DENALI_CTL_101_DATA 0x00000000
> +#define              DENALI_CTL_102_DATA 0x00000000
> +#define              DENALI_CTL_103_DATA 0x00000000
> +#define              DENALI_CTL_104_DATA 0x00000000
> +#define              DENALI_CTL_105_DATA 0x00000003
> +#define              DENALI_CTL_106_DATA 0x00000000
> +#define              DENALI_CTL_107_DATA 0x00000000
> +#define              DENALI_CTL_108_DATA 0x00000000
> +#define              DENALI_CTL_109_DATA 0x00000000
> +#define              DENALI_CTL_110_DATA 0x01000000
> +#define              DENALI_CTL_111_DATA 0x00040000
> +#define              DENALI_CTL_112_DATA 0x00800200
> +#define              DENALI_CTL_113_DATA 0x00000200
> +#define              DENALI_CTL_114_DATA 0x00000040
> +#define              DENALI_CTL_115_DATA 0x01000100
> +#define              DENALI_CTL_116_DATA 0x0a000002
> +#define              DENALI_CTL_117_DATA 0x0101ffff
> +#define              DENALI_CTL_118_DATA 0x01010101
> +#define              DENALI_CTL_119_DATA 0x01010101
> +#define              DENALI_CTL_120_DATA 0x0000010b
> +#define              DENALI_CTL_121_DATA 0x00000c01
> +#define              DENALI_CTL_122_DATA 0x00000000
> +#define              DENALI_CTL_123_DATA 0x00000000
> +#define              DENALI_CTL_124_DATA 0x00000000
> +#define              DENALI_CTL_125_DATA 0x00000000
> +#define              DENALI_CTL_126_DATA 0x00030300
> +#define              DENALI_CTL_127_DATA 0x00000000
> +#define              DENALI_CTL_128_DATA 0x00010001
> +#define              DENALI_CTL_129_DATA 0x00000000
> +#define              DENALI_CTL_130_DATA 0x00000000
> +#define              DENALI_CTL_131_DATA 0x00000000
> +#define              DENALI_CTL_132_DATA 0x00000000
> +#define              DENALI_CTL_133_DATA 0x00000000
> +#define              DENALI_CTL_134_DATA 0x00000000
> +#define              DENALI_CTL_135_DATA 0x00000000
> +#define              DENALI_CTL_136_DATA 0x00000000
> +#define              DENALI_CTL_137_DATA 0x00000000
> +#define              DENALI_CTL_138_DATA 0x00000000
> +#define              DENALI_CTL_139_DATA 0x00000000
> +#define              DENALI_CTL_140_DATA 0x00000000
> +#define              DENALI_CTL_141_DATA 0x00000000
> +#define              DENALI_CTL_142_DATA 0x00000000
> +#define              DENALI_CTL_143_DATA 0x00000000
> +#define              DENALI_CTL_144_DATA 0x00000000
> +#define              DENALI_CTL_145_DATA 0x00000000
> +#define              DENALI_CTL_146_DATA 0x00000000
> +#define              DENALI_CTL_147_DATA 0x00000000
> +#define              DENALI_CTL_148_DATA 0x00000000
> +#define              DENALI_CTL_149_DATA 0x00000000
> +#define              DENALI_CTL_150_DATA 0x00000000
> +#define              DENALI_CTL_151_DATA 0x00000000
> +#define              DENALI_CTL_152_DATA 0x00000000
> +#define              DENALI_CTL_153_DATA 0x00000000
> +#define              DENALI_CTL_154_DATA 0x00000000
> +#define              DENALI_CTL_155_DATA 0x00000000
> +#define              DENALI_CTL_156_DATA 0x00000000
> +#define              DENALI_CTL_157_DATA 0x00000000
> +#define              DENALI_CTL_158_DATA 0x00000000
> +#define              DENALI_CTL_159_DATA 0x00000000
> +#define              DENALI_CTL_160_DATA 0x00000000
> +#define              DENALI_CTL_161_DATA 0x02010102
> +#define              DENALI_CTL_162_DATA 0x0107070d
> +#define              DENALI_CTL_163_DATA 0x04040400
> +#define              DENALI_CTL_164_DATA 0x03000503
> +#define              DENALI_CTL_165_DATA 0x00000000
> +#define              DENALI_CTL_166_DATA 0x00000000
> +#define              DENALI_CTL_167_DATA 0x00000000
> +#define              DENALI_CTL_168_DATA 0x00000000
> +#define              DENALI_CTL_169_DATA 0x280d0000
> +#define              DENALI_CTL_170_DATA 0x01000000
> +#define              DENALI_CTL_171_DATA 0x00000000
> +#define              DENALI_CTL_172_DATA 0x00010001
> +#define              DENALI_CTL_173_DATA 0x00000000
> +#define              DENALI_CTL_174_DATA 0x00000000
> +#define              DENALI_CTL_175_DATA 0x00000000
> +#define              DENALI_CTL_176_DATA 0x00000000
> +#define              DENALI_CTL_177_DATA 0x00000000
> +#define              DENALI_CTL_178_DATA 0x00000000
> +#define              DENALI_CTL_179_DATA 0x00000000
> +#define              DENALI_CTL_180_DATA 0x00000000
> +#define              DENALI_CTL_181_DATA 0x01000000
> +#define              DENALI_CTL_182_DATA 0x00000001
> +#define              DENALI_CTL_183_DATA 0x00000100
> +#define              DENALI_CTL_184_DATA 0x00000101
> +#define              DENALI_CTL_185_DATA 0x67676701
> +#define              DENALI_CTL_186_DATA 0x67676767
> +#define              DENALI_CTL_187_DATA 0x67676767
> +#define              DENALI_CTL_188_DATA 0x67676767
> +#define              DENALI_CTL_189_DATA 0x67676767
> +#define              DENALI_CTL_190_DATA 0x67676767
> +#define              DENALI_CTL_191_DATA 0x67676767
> +#define              DENALI_CTL_192_DATA 0x67676767
> +#define              DENALI_CTL_193_DATA 0x67676767
> +#define              DENALI_CTL_194_DATA 0x01000067
> +#define              DENALI_CTL_195_DATA 0x00000001
> +#define              DENALI_CTL_196_DATA 0x00000101
> +#define              DENALI_CTL_197_DATA 0x00000000
> +#define              DENALI_CTL_198_DATA 0x00000000
> +#define              DENALI_CTL_199_DATA 0x00000000
> +#define              DENALI_CTL_200_DATA 0x00000000
> +#define              DENALI_CTL_201_DATA 0x00000000
> +#define              DENALI_CTL_202_DATA 0x00000000
> +#define              DENALI_CTL_203_DATA 0x00000000
> +#define              DENALI_CTL_204_DATA 0x00000000
> +#define              DENALI_CTL_205_DATA 0x00000000
> +#define              DENALI_CTL_206_DATA 0x00000000
> +#define              DENALI_CTL_207_DATA 0x00000000
> +#define              DENALI_CTL_208_DATA 0x00000001
> +#define              DENALI_CTL_209_DATA 0x00000000
> +#define              DENALI_CTL_210_DATA 0x007fffff
> +#define              DENALI_CTL_211_DATA 0x00000000
> +#define              DENALI_CTL_212_DATA 0x007fffff
> +#define              DENALI_CTL_213_DATA 0x00000000
> +#define              DENALI_CTL_214_DATA 0x007fffff
> +#define              DENALI_CTL_215_DATA 0x00000000
> +#define              DENALI_CTL_216_DATA 0x007fffff
> +#define              DENALI_CTL_217_DATA 0x00000000
> +#define              DENALI_CTL_218_DATA 0x007fffff
> +#define              DENALI_CTL_219_DATA 0x00000000
> +#define              DENALI_CTL_220_DATA 0x007fffff
> +#define              DENALI_CTL_221_DATA 0x00000000
> +#define              DENALI_CTL_222_DATA 0x007fffff
> +#define              DENALI_CTL_223_DATA 0x00000000
> +#define              DENALI_CTL_224_DATA 0x037fffff
> +#define              DENALI_CTL_225_DATA 0xffffffff
> +#define              DENALI_CTL_226_DATA 0x000f000f
> +#define              DENALI_CTL_227_DATA 0x00ffff03
> +#define              DENALI_CTL_228_DATA 0x000fffff
> +#define              DENALI_CTL_229_DATA 0x0003000f
> +#define              DENALI_CTL_230_DATA 0xffffffff
> +#define              DENALI_CTL_231_DATA 0x000f000f
> +#define              DENALI_CTL_232_DATA 0x00ffff03
> +#define              DENALI_CTL_233_DATA 0x000fffff
> +#define              DENALI_CTL_234_DATA 0x0003000f
> +#define              DENALI_CTL_235_DATA 0xffffffff
> +#define              DENALI_CTL_236_DATA 0x000f000f
> +#define              DENALI_CTL_237_DATA 0x00ffff03
> +#define              DENALI_CTL_238_DATA 0x000fffff
> +#define              DENALI_CTL_239_DATA 0x0003000f
> +#define              DENALI_CTL_240_DATA 0xffffffff
> +#define              DENALI_CTL_241_DATA 0x000f000f
> +#define              DENALI_CTL_242_DATA 0x00ffff03
> +#define              DENALI_CTL_243_DATA 0x000fffff
> +#define              DENALI_CTL_244_DATA 0x6407000f
> +#define              DENALI_CTL_245_DATA 0x01640001
> +#define              DENALI_CTL_246_DATA 0x00000000
> +#define              DENALI_CTL_247_DATA 0x00000000
> +#define              DENALI_CTL_248_DATA 0x00001700
> +#define              DENALI_CTL_249_DATA 0x00386c05
> +#define              DENALI_CTL_250_DATA 0x02000200
> +#define              DENALI_CTL_251_DATA 0x02000200
> +#define              DENALI_CTL_252_DATA 0x0000386c
> +#define              DENALI_CTL_253_DATA 0x00023438
> +#define              DENALI_CTL_254_DATA 0x02020d10
> +#define              DENALI_CTL_255_DATA 0x00140303
> +#define              DENALI_CTL_256_DATA 0x00000000
> +#define              DENALI_CTL_257_DATA 0x00000000
> +#define              DENALI_CTL_258_DATA 0x00001403
> +#define              DENALI_CTL_259_DATA 0x00000000
> +#define              DENALI_CTL_260_DATA 0x00000000
> +#define              DENALI_CTL_261_DATA 0x00000000
> +#define              DENALI_CTL_262_DATA 0x00000000
> +#define              DENALI_CTL_263_DATA 0x0d010000
> +#define              DENALI_CTL_264_DATA 0x00000008
> diff --git a/board/sifive/fu540/include/regconfig-phy.h b/board/sifive/fu540/include/regconfig-phy.h
> new file mode 100644
> index 0000000000..3450aecdf1
> --- /dev/null
> +++ b/board/sifive/fu540/include/regconfig-phy.h
> @@ -0,0 +1,1224 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#define               DENALI_PHY_00_DATA 0x31706542
> +#define               DENALI_PHY_01_DATA 0x0004c008
> +#define               DENALI_PHY_02_DATA 0x000000da
> +#define               DENALI_PHY_03_DATA 0x00000000
> +#define               DENALI_PHY_04_DATA 0x00000000
> +#define               DENALI_PHY_05_DATA 0x00010000
> +#define               DENALI_PHY_06_DATA 0x01DDDD90
> +#define               DENALI_PHY_07_DATA 0x01DDDD90
> +#define               DENALI_PHY_08_DATA 0x01030000
> +#define               DENALI_PHY_09_DATA 0x01000000
> +#define               DENALI_PHY_10_DATA 0x00c00000
> +#define               DENALI_PHY_11_DATA 0x00000007
> +#define               DENALI_PHY_12_DATA 0x00000000
> +#define               DENALI_PHY_13_DATA 0x00000000
> +#define               DENALI_PHY_14_DATA 0x04000408
> +#define               DENALI_PHY_15_DATA 0x00000408
> +#define               DENALI_PHY_16_DATA 0x00e4e400
> +#define               DENALI_PHY_17_DATA 0x00000000
> +#define               DENALI_PHY_18_DATA 0x00000000
> +#define               DENALI_PHY_19_DATA 0x00000000
> +#define               DENALI_PHY_20_DATA 0x00000000
> +#define               DENALI_PHY_21_DATA 0x00000000
> +#define               DENALI_PHY_22_DATA 0x00000000
> +#define               DENALI_PHY_23_DATA 0x00000000
> +#define               DENALI_PHY_24_DATA 0x00000000
> +#define               DENALI_PHY_25_DATA 0x00000000
> +#define               DENALI_PHY_26_DATA 0x00000000
> +#define               DENALI_PHY_27_DATA 0x00000000
> +#define               DENALI_PHY_28_DATA 0x00000000
> +#define               DENALI_PHY_29_DATA 0x00000000
> +#define               DENALI_PHY_30_DATA 0x00000000
> +#define               DENALI_PHY_31_DATA 0x00000000
> +#define               DENALI_PHY_32_DATA 0x00000000
> +#define               DENALI_PHY_33_DATA 0x00200000
> +#define               DENALI_PHY_34_DATA 0x00000000
> +#define               DENALI_PHY_35_DATA 0x00000000
> +#define               DENALI_PHY_36_DATA 0x00000000
> +#define               DENALI_PHY_37_DATA 0x00000000
> +#define               DENALI_PHY_38_DATA 0x00000000
> +#define               DENALI_PHY_39_DATA 0x00000000
> +#define               DENALI_PHY_40_DATA 0x02800280
> +#define               DENALI_PHY_41_DATA 0x02800280
> +#define               DENALI_PHY_42_DATA 0x02800280
> +#define               DENALI_PHY_43_DATA 0x02800280
> +#define               DENALI_PHY_44_DATA 0x00000280
> +#define               DENALI_PHY_45_DATA 0x00000000
> +#define               DENALI_PHY_46_DATA 0x00000000
> +#define               DENALI_PHY_47_DATA 0x00000000
> +#define               DENALI_PHY_48_DATA 0x00000000
> +#define               DENALI_PHY_49_DATA 0x00000000
> +#define               DENALI_PHY_50_DATA 0x00800080
> +#define               DENALI_PHY_51_DATA 0x00800080
> +#define               DENALI_PHY_52_DATA 0x00800080
> +#define               DENALI_PHY_53_DATA 0x00800080
> +#define               DENALI_PHY_54_DATA 0x00800080
> +#define               DENALI_PHY_55_DATA 0x00800080
> +#define               DENALI_PHY_56_DATA 0x00800080
> +#define               DENALI_PHY_57_DATA 0x00800080
> +#define               DENALI_PHY_58_DATA 0x00800080
> +#define               DENALI_PHY_59_DATA 0x000100da
> +#define               DENALI_PHY_60_DATA 0x01000200
> +#define               DENALI_PHY_61_DATA 0x00000000
> +#define               DENALI_PHY_62_DATA 0x00000000
> +#define               DENALI_PHY_63_DATA 0x00000002
> +#define               DENALI_PHY_64_DATA 0x51313152
> +#define               DENALI_PHY_65_DATA 0x80013130
> +#define               DENALI_PHY_66_DATA 0x02000080
> +#define               DENALI_PHY_67_DATA 0x00100001
> +#define               DENALI_PHY_68_DATA 0x0c064208
> +#define               DENALI_PHY_69_DATA 0x000f0c0f
> +#define               DENALI_PHY_70_DATA 0x01000140
> +#define               DENALI_PHY_71_DATA 0x0000000c
> +#define               DENALI_PHY_72_DATA 0x00000000
> +#define               DENALI_PHY_73_DATA 0x00000000
> +#define               DENALI_PHY_74_DATA 0x00000000
> +#define               DENALI_PHY_75_DATA 0x00000000
> +#define               DENALI_PHY_76_DATA 0x00000000
> +#define               DENALI_PHY_77_DATA 0x00000000
> +#define               DENALI_PHY_78_DATA 0x00000000
> +#define               DENALI_PHY_79_DATA 0x00000000
> +#define               DENALI_PHY_80_DATA 0x00000000
> +#define               DENALI_PHY_81_DATA 0x00000000
> +#define               DENALI_PHY_82_DATA 0x00000000
> +#define               DENALI_PHY_83_DATA 0x00000000
> +#define               DENALI_PHY_84_DATA 0x00000000
> +#define               DENALI_PHY_85_DATA 0x00000000
> +#define               DENALI_PHY_86_DATA 0x00000000
> +#define               DENALI_PHY_87_DATA 0x00000000
> +#define               DENALI_PHY_88_DATA 0x00000000
> +#define               DENALI_PHY_89_DATA 0x00000000
> +#define               DENALI_PHY_90_DATA 0x00000000
> +#define               DENALI_PHY_91_DATA 0x00000000
> +#define               DENALI_PHY_92_DATA 0x00000000
> +#define               DENALI_PHY_93_DATA 0x00000000
> +#define               DENALI_PHY_94_DATA 0x00000000
> +#define               DENALI_PHY_95_DATA 0x00000000
> +#define               DENALI_PHY_96_DATA 0x00000000
> +#define               DENALI_PHY_97_DATA 0x00000000
> +#define               DENALI_PHY_98_DATA 0x00000000
> +#define               DENALI_PHY_99_DATA 0x00000000
> +#define              DENALI_PHY_100_DATA 0x00000000
> +#define              DENALI_PHY_101_DATA 0x00000000
> +#define              DENALI_PHY_102_DATA 0x00000000
> +#define              DENALI_PHY_103_DATA 0x00000000
> +#define              DENALI_PHY_104_DATA 0x00000000
> +#define              DENALI_PHY_105_DATA 0x00000000
> +#define              DENALI_PHY_106_DATA 0x00000000
> +#define              DENALI_PHY_107_DATA 0x00000000
> +#define              DENALI_PHY_108_DATA 0x00000000
> +#define              DENALI_PHY_109_DATA 0x00000000
> +#define              DENALI_PHY_110_DATA 0x00000000
> +#define              DENALI_PHY_111_DATA 0x00000000
> +#define              DENALI_PHY_112_DATA 0x00000000
> +#define              DENALI_PHY_113_DATA 0x00000000
> +#define              DENALI_PHY_114_DATA 0x00000000
> +#define              DENALI_PHY_115_DATA 0x00000000
> +#define              DENALI_PHY_116_DATA 0x00000000
> +#define              DENALI_PHY_117_DATA 0x00000000
> +#define              DENALI_PHY_118_DATA 0x00000000
> +#define              DENALI_PHY_119_DATA 0x00000000
> +#define              DENALI_PHY_120_DATA 0x00000000
> +#define              DENALI_PHY_121_DATA 0x00000000
> +#define              DENALI_PHY_122_DATA 0x00000000
> +#define              DENALI_PHY_123_DATA 0x00000000
> +#define              DENALI_PHY_124_DATA 0x00000000
> +#define              DENALI_PHY_125_DATA 0x00000000
> +#define              DENALI_PHY_126_DATA 0x00000000
> +#define              DENALI_PHY_127_DATA 0x00000000
> +#define              DENALI_PHY_128_DATA 0x40263571
> +#define              DENALI_PHY_129_DATA 0x0004c008
> +#define              DENALI_PHY_130_DATA 0x000000da
> +#define              DENALI_PHY_131_DATA 0x00000000
> +#define              DENALI_PHY_132_DATA 0x00000000
> +#define              DENALI_PHY_133_DATA 0x00010000
> +#define              DENALI_PHY_134_DATA 0x01DDDD90
> +#define              DENALI_PHY_135_DATA 0x01DDDD90
> +#define              DENALI_PHY_136_DATA 0x01030000
> +#define              DENALI_PHY_137_DATA 0x01000000
> +#define              DENALI_PHY_138_DATA 0x00c00000
> +#define              DENALI_PHY_139_DATA 0x00000007
> +#define              DENALI_PHY_140_DATA 0x00000000
> +#define              DENALI_PHY_141_DATA 0x00000000
> +#define              DENALI_PHY_142_DATA 0x04000408
> +#define              DENALI_PHY_143_DATA 0x00000408
> +#define              DENALI_PHY_144_DATA 0x00e4e400
> +#define              DENALI_PHY_145_DATA 0x00000000
> +#define              DENALI_PHY_146_DATA 0x00000000
> +#define              DENALI_PHY_147_DATA 0x00000000
> +#define              DENALI_PHY_148_DATA 0x00000000
> +#define              DENALI_PHY_149_DATA 0x00000000
> +#define              DENALI_PHY_150_DATA 0x00000000
> +#define              DENALI_PHY_151_DATA 0x00000000
> +#define              DENALI_PHY_152_DATA 0x00000000
> +#define              DENALI_PHY_153_DATA 0x00000000
> +#define              DENALI_PHY_154_DATA 0x00000000
> +#define              DENALI_PHY_155_DATA 0x00000000
> +#define              DENALI_PHY_156_DATA 0x00000000
> +#define              DENALI_PHY_157_DATA 0x00000000
> +#define              DENALI_PHY_158_DATA 0x00000000
> +#define              DENALI_PHY_159_DATA 0x00000000
> +#define              DENALI_PHY_160_DATA 0x00000000
> +#define              DENALI_PHY_161_DATA 0x00200000
> +#define              DENALI_PHY_162_DATA 0x00000000
> +#define              DENALI_PHY_163_DATA 0x00000000
> +#define              DENALI_PHY_164_DATA 0x00000000
> +#define              DENALI_PHY_165_DATA 0x00000000
> +#define              DENALI_PHY_166_DATA 0x00000000
> +#define              DENALI_PHY_167_DATA 0x00000000
> +#define              DENALI_PHY_168_DATA 0x02800280
> +#define              DENALI_PHY_169_DATA 0x02800280
> +#define              DENALI_PHY_170_DATA 0x02800280
> +#define              DENALI_PHY_171_DATA 0x02800280
> +#define              DENALI_PHY_172_DATA 0x00000280
> +#define              DENALI_PHY_173_DATA 0x00000000
> +#define              DENALI_PHY_174_DATA 0x00000000
> +#define              DENALI_PHY_175_DATA 0x00000000
> +#define              DENALI_PHY_176_DATA 0x00000000
> +#define              DENALI_PHY_177_DATA 0x00000000
> +#define              DENALI_PHY_178_DATA 0x00800080
> +#define              DENALI_PHY_179_DATA 0x00800080
> +#define              DENALI_PHY_180_DATA 0x00800080
> +#define              DENALI_PHY_181_DATA 0x00800080
> +#define              DENALI_PHY_182_DATA 0x00800080
> +#define              DENALI_PHY_183_DATA 0x00800080
> +#define              DENALI_PHY_184_DATA 0x00800080
> +#define              DENALI_PHY_185_DATA 0x00800080
> +#define              DENALI_PHY_186_DATA 0x00800080
> +#define              DENALI_PHY_187_DATA 0x000100da
> +#define              DENALI_PHY_188_DATA 0x01000200
> +#define              DENALI_PHY_189_DATA 0x00000000
> +#define              DENALI_PHY_190_DATA 0x00000000
> +#define              DENALI_PHY_191_DATA 0x00000002
> +#define              DENALI_PHY_192_DATA 0x51313152
> +#define              DENALI_PHY_193_DATA 0x80013130
> +#define              DENALI_PHY_194_DATA 0x02000080
> +#define              DENALI_PHY_195_DATA 0x00100001
> +#define              DENALI_PHY_196_DATA 0x0c064208
> +#define              DENALI_PHY_197_DATA 0x000f0c0f
> +#define              DENALI_PHY_198_DATA 0x01000140
> +#define              DENALI_PHY_199_DATA 0x0000000c
> +#define              DENALI_PHY_200_DATA 0x00000000
> +#define              DENALI_PHY_201_DATA 0x00000000
> +#define              DENALI_PHY_202_DATA 0x00000000
> +#define              DENALI_PHY_203_DATA 0x00000000
> +#define              DENALI_PHY_204_DATA 0x00000000
> +#define              DENALI_PHY_205_DATA 0x00000000
> +#define              DENALI_PHY_206_DATA 0x00000000
> +#define              DENALI_PHY_207_DATA 0x00000000
> +#define              DENALI_PHY_208_DATA 0x00000000
> +#define              DENALI_PHY_209_DATA 0x00000000
> +#define              DENALI_PHY_210_DATA 0x00000000
> +#define              DENALI_PHY_211_DATA 0x00000000
> +#define              DENALI_PHY_212_DATA 0x00000000
> +#define              DENALI_PHY_213_DATA 0x00000000
> +#define              DENALI_PHY_214_DATA 0x00000000
> +#define              DENALI_PHY_215_DATA 0x00000000
> +#define              DENALI_PHY_216_DATA 0x00000000
> +#define              DENALI_PHY_217_DATA 0x00000000
> +#define              DENALI_PHY_218_DATA 0x00000000
> +#define              DENALI_PHY_219_DATA 0x00000000
> +#define              DENALI_PHY_220_DATA 0x00000000
> +#define              DENALI_PHY_221_DATA 0x00000000
> +#define              DENALI_PHY_222_DATA 0x00000000
> +#define              DENALI_PHY_223_DATA 0x00000000
> +#define              DENALI_PHY_224_DATA 0x00000000
> +#define              DENALI_PHY_225_DATA 0x00000000
> +#define              DENALI_PHY_226_DATA 0x00000000
> +#define              DENALI_PHY_227_DATA 0x00000000
> +#define              DENALI_PHY_228_DATA 0x00000000
> +#define              DENALI_PHY_229_DATA 0x00000000
> +#define              DENALI_PHY_230_DATA 0x00000000
> +#define              DENALI_PHY_231_DATA 0x00000000
> +#define              DENALI_PHY_232_DATA 0x00000000
> +#define              DENALI_PHY_233_DATA 0x00000000
> +#define              DENALI_PHY_234_DATA 0x00000000
> +#define              DENALI_PHY_235_DATA 0x00000000
> +#define              DENALI_PHY_236_DATA 0x00000000
> +#define              DENALI_PHY_237_DATA 0x00000000
> +#define              DENALI_PHY_238_DATA 0x00000000
> +#define              DENALI_PHY_239_DATA 0x00000000
> +#define              DENALI_PHY_240_DATA 0x00000000
> +#define              DENALI_PHY_241_DATA 0x00000000
> +#define              DENALI_PHY_242_DATA 0x00000000
> +#define              DENALI_PHY_243_DATA 0x00000000
> +#define              DENALI_PHY_244_DATA 0x00000000
> +#define              DENALI_PHY_245_DATA 0x00000000
> +#define              DENALI_PHY_246_DATA 0x00000000
> +#define              DENALI_PHY_247_DATA 0x00000000
> +#define              DENALI_PHY_248_DATA 0x00000000
> +#define              DENALI_PHY_249_DATA 0x00000000
> +#define              DENALI_PHY_250_DATA 0x00000000
> +#define              DENALI_PHY_251_DATA 0x00000000
> +#define              DENALI_PHY_252_DATA 0x00000000
> +#define              DENALI_PHY_253_DATA 0x00000000
> +#define              DENALI_PHY_254_DATA 0x00000000
> +#define              DENALI_PHY_255_DATA 0x00000000
> +#define              DENALI_PHY_256_DATA 0x46052371
> +#define              DENALI_PHY_257_DATA 0x0004c008
> +#define              DENALI_PHY_258_DATA 0x000000da
> +#define              DENALI_PHY_259_DATA 0x00000000
> +#define              DENALI_PHY_260_DATA 0x00000000
> +#define              DENALI_PHY_261_DATA 0x00010000
> +#define              DENALI_PHY_262_DATA 0x01DDDD90
> +#define              DENALI_PHY_263_DATA 0x01DDDD90
> +#define              DENALI_PHY_264_DATA 0x01030000
> +#define              DENALI_PHY_265_DATA 0x01000000
> +#define              DENALI_PHY_266_DATA 0x00c00000
> +#define              DENALI_PHY_267_DATA 0x00000007
> +#define              DENALI_PHY_268_DATA 0x00000000
> +#define              DENALI_PHY_269_DATA 0x00000000
> +#define              DENALI_PHY_270_DATA 0x04000408
> +#define              DENALI_PHY_271_DATA 0x00000408
> +#define              DENALI_PHY_272_DATA 0x00e4e400
> +#define              DENALI_PHY_273_DATA 0x00000000
> +#define              DENALI_PHY_274_DATA 0x00000000
> +#define              DENALI_PHY_275_DATA 0x00000000
> +#define              DENALI_PHY_276_DATA 0x00000000
> +#define              DENALI_PHY_277_DATA 0x00000000
> +#define              DENALI_PHY_278_DATA 0x00000000
> +#define              DENALI_PHY_279_DATA 0x00000000
> +#define              DENALI_PHY_280_DATA 0x00000000
> +#define              DENALI_PHY_281_DATA 0x00000000
> +#define              DENALI_PHY_282_DATA 0x00000000
> +#define              DENALI_PHY_283_DATA 0x00000000
> +#define              DENALI_PHY_284_DATA 0x00000000
> +#define              DENALI_PHY_285_DATA 0x00000000
> +#define              DENALI_PHY_286_DATA 0x00000000
> +#define              DENALI_PHY_287_DATA 0x00000000
> +#define              DENALI_PHY_288_DATA 0x00000000
> +#define              DENALI_PHY_289_DATA 0x00200000
> +#define              DENALI_PHY_290_DATA 0x00000000
> +#define              DENALI_PHY_291_DATA 0x00000000
> +#define              DENALI_PHY_292_DATA 0x00000000
> +#define              DENALI_PHY_293_DATA 0x00000000
> +#define              DENALI_PHY_294_DATA 0x00000000
> +#define              DENALI_PHY_295_DATA 0x00000000
> +#define              DENALI_PHY_296_DATA 0x02800280
> +#define              DENALI_PHY_297_DATA 0x02800280
> +#define              DENALI_PHY_298_DATA 0x02800280
> +#define              DENALI_PHY_299_DATA 0x02800280
> +#define              DENALI_PHY_300_DATA 0x00000280
> +#define              DENALI_PHY_301_DATA 0x00000000
> +#define              DENALI_PHY_302_DATA 0x00000000
> +#define              DENALI_PHY_303_DATA 0x00000000
> +#define              DENALI_PHY_304_DATA 0x00000000
> +#define              DENALI_PHY_305_DATA 0x00000000
> +#define              DENALI_PHY_306_DATA 0x00800080
> +#define              DENALI_PHY_307_DATA 0x00800080
> +#define              DENALI_PHY_308_DATA 0x00800080
> +#define              DENALI_PHY_309_DATA 0x00800080
> +#define              DENALI_PHY_310_DATA 0x00800080
> +#define              DENALI_PHY_311_DATA 0x00800080
> +#define              DENALI_PHY_312_DATA 0x00800080
> +#define              DENALI_PHY_313_DATA 0x00800080
> +#define              DENALI_PHY_314_DATA 0x00800080
> +#define              DENALI_PHY_315_DATA 0x000100da
> +#define              DENALI_PHY_316_DATA 0x00000200
> +#define              DENALI_PHY_317_DATA 0x00000000
> +#define              DENALI_PHY_318_DATA 0x00000000
> +#define              DENALI_PHY_319_DATA 0x00000002
> +#define              DENALI_PHY_320_DATA 0x51313152
> +#define              DENALI_PHY_321_DATA 0x80013130
> +#define              DENALI_PHY_322_DATA 0x02000080
> +#define              DENALI_PHY_323_DATA 0x00100001
> +#define              DENALI_PHY_324_DATA 0x0c064208
> +#define              DENALI_PHY_325_DATA 0x000f0c0f
> +#define              DENALI_PHY_326_DATA 0x01000140
> +#define              DENALI_PHY_327_DATA 0x0000000c
> +#define              DENALI_PHY_328_DATA 0x00000000
> +#define              DENALI_PHY_329_DATA 0x00000000
> +#define              DENALI_PHY_330_DATA 0x00000000
> +#define              DENALI_PHY_331_DATA 0x00000000
> +#define              DENALI_PHY_332_DATA 0x00000000
> +#define              DENALI_PHY_333_DATA 0x00000000
> +#define              DENALI_PHY_334_DATA 0x00000000
> +#define              DENALI_PHY_335_DATA 0x00000000
> +#define              DENALI_PHY_336_DATA 0x00000000
> +#define              DENALI_PHY_337_DATA 0x00000000
> +#define              DENALI_PHY_338_DATA 0x00000000
> +#define              DENALI_PHY_339_DATA 0x00000000
> +#define              DENALI_PHY_340_DATA 0x00000000
> +#define              DENALI_PHY_341_DATA 0x00000000
> +#define              DENALI_PHY_342_DATA 0x00000000
> +#define              DENALI_PHY_343_DATA 0x00000000
> +#define              DENALI_PHY_344_DATA 0x00000000
> +#define              DENALI_PHY_345_DATA 0x00000000
> +#define              DENALI_PHY_346_DATA 0x00000000
> +#define              DENALI_PHY_347_DATA 0x00000000
> +#define              DENALI_PHY_348_DATA 0x00000000
> +#define              DENALI_PHY_349_DATA 0x00000000
> +#define              DENALI_PHY_350_DATA 0x00000000
> +#define              DENALI_PHY_351_DATA 0x00000000
> +#define              DENALI_PHY_352_DATA 0x00000000
> +#define              DENALI_PHY_353_DATA 0x00000000
> +#define              DENALI_PHY_354_DATA 0x00000000
> +#define              DENALI_PHY_355_DATA 0x00000000
> +#define              DENALI_PHY_356_DATA 0x00000000
> +#define              DENALI_PHY_357_DATA 0x00000000
> +#define              DENALI_PHY_358_DATA 0x00000000
> +#define              DENALI_PHY_359_DATA 0x00000000
> +#define              DENALI_PHY_360_DATA 0x00000000
> +#define              DENALI_PHY_361_DATA 0x00000000
> +#define              DENALI_PHY_362_DATA 0x00000000
> +#define              DENALI_PHY_363_DATA 0x00000000
> +#define              DENALI_PHY_364_DATA 0x00000000
> +#define              DENALI_PHY_365_DATA 0x00000000
> +#define              DENALI_PHY_366_DATA 0x00000000
> +#define              DENALI_PHY_367_DATA 0x00000000
> +#define              DENALI_PHY_368_DATA 0x00000000
> +#define              DENALI_PHY_369_DATA 0x00000000
> +#define              DENALI_PHY_370_DATA 0x00000000
> +#define              DENALI_PHY_371_DATA 0x00000000
> +#define              DENALI_PHY_372_DATA 0x00000000
> +#define              DENALI_PHY_373_DATA 0x00000000
> +#define              DENALI_PHY_374_DATA 0x00000000
> +#define              DENALI_PHY_375_DATA 0x00000000
> +#define              DENALI_PHY_376_DATA 0x00000000
> +#define              DENALI_PHY_377_DATA 0x00000000
> +#define              DENALI_PHY_378_DATA 0x00000000
> +#define              DENALI_PHY_379_DATA 0x00000000
> +#define              DENALI_PHY_380_DATA 0x00000000
> +#define              DENALI_PHY_381_DATA 0x00000000
> +#define              DENALI_PHY_382_DATA 0x00000000
> +#define              DENALI_PHY_383_DATA 0x00000000
> +#define              DENALI_PHY_384_DATA 0x37654120
> +#define              DENALI_PHY_385_DATA 0x0004c008
> +#define              DENALI_PHY_386_DATA 0x000000da
> +#define              DENALI_PHY_387_DATA 0x00000000
> +#define              DENALI_PHY_388_DATA 0x00000000
> +#define              DENALI_PHY_389_DATA 0x00010000
> +#define              DENALI_PHY_390_DATA 0x01DDDD90
> +#define              DENALI_PHY_391_DATA 0x01DDDD90
> +#define              DENALI_PHY_392_DATA 0x01030000
> +#define              DENALI_PHY_393_DATA 0x01000000
> +#define              DENALI_PHY_394_DATA 0x00c00000
> +#define              DENALI_PHY_395_DATA 0x00000007
> +#define              DENALI_PHY_396_DATA 0x00000000
> +#define              DENALI_PHY_397_DATA 0x00000000
> +#define              DENALI_PHY_398_DATA 0x04000408
> +#define              DENALI_PHY_399_DATA 0x00000408
> +#define              DENALI_PHY_400_DATA 0x00e4e400
> +#define              DENALI_PHY_401_DATA 0x00000000
> +#define              DENALI_PHY_402_DATA 0x00000000
> +#define              DENALI_PHY_403_DATA 0x00000000
> +#define              DENALI_PHY_404_DATA 0x00000000
> +#define              DENALI_PHY_405_DATA 0x00000000
> +#define              DENALI_PHY_406_DATA 0x00000000
> +#define              DENALI_PHY_407_DATA 0x00000000
> +#define              DENALI_PHY_408_DATA 0x00000000
> +#define              DENALI_PHY_409_DATA 0x00000000
> +#define              DENALI_PHY_410_DATA 0x00000000
> +#define              DENALI_PHY_411_DATA 0x00000000
> +#define              DENALI_PHY_412_DATA 0x00000000
> +#define              DENALI_PHY_413_DATA 0x00000000
> +#define              DENALI_PHY_414_DATA 0x00000000
> +#define              DENALI_PHY_415_DATA 0x00000000
> +#define              DENALI_PHY_416_DATA 0x00000000
> +#define              DENALI_PHY_417_DATA 0x00200000
> +#define              DENALI_PHY_418_DATA 0x00000000
> +#define              DENALI_PHY_419_DATA 0x00000000
> +#define              DENALI_PHY_420_DATA 0x00000000
> +#define              DENALI_PHY_421_DATA 0x00000000
> +#define              DENALI_PHY_422_DATA 0x00000000
> +#define              DENALI_PHY_423_DATA 0x00000000
> +#define              DENALI_PHY_424_DATA 0x02800280
> +#define              DENALI_PHY_425_DATA 0x02800280
> +#define              DENALI_PHY_426_DATA 0x02800280
> +#define              DENALI_PHY_427_DATA 0x02800280
> +#define              DENALI_PHY_428_DATA 0x00000280
> +#define              DENALI_PHY_429_DATA 0x00000000
> +#define              DENALI_PHY_430_DATA 0x00000000
> +#define              DENALI_PHY_431_DATA 0x00000000
> +#define              DENALI_PHY_432_DATA 0x00000000
> +#define              DENALI_PHY_433_DATA 0x00000000
> +#define              DENALI_PHY_434_DATA 0x00800080
> +#define              DENALI_PHY_435_DATA 0x00800080
> +#define              DENALI_PHY_436_DATA 0x00800080
> +#define              DENALI_PHY_437_DATA 0x00800080
> +#define              DENALI_PHY_438_DATA 0x00800080
> +#define              DENALI_PHY_439_DATA 0x00800080
> +#define              DENALI_PHY_440_DATA 0x00800080
> +#define              DENALI_PHY_441_DATA 0x00800080
> +#define              DENALI_PHY_442_DATA 0x00800080
> +#define              DENALI_PHY_443_DATA 0x000100da
> +#define              DENALI_PHY_444_DATA 0x00000200
> +#define              DENALI_PHY_445_DATA 0x00000000
> +#define              DENALI_PHY_446_DATA 0x00000000
> +#define              DENALI_PHY_447_DATA 0x00000002
> +#define              DENALI_PHY_448_DATA 0x51313152
> +#define              DENALI_PHY_449_DATA 0x80013130
> +#define              DENALI_PHY_450_DATA 0x02000080
> +#define              DENALI_PHY_451_DATA 0x00100001
> +#define              DENALI_PHY_452_DATA 0x0c064208
> +#define              DENALI_PHY_453_DATA 0x000f0c0f
> +#define              DENALI_PHY_454_DATA 0x01000140
> +#define              DENALI_PHY_455_DATA 0x0000000c
> +#define              DENALI_PHY_456_DATA 0x00000000
> +#define              DENALI_PHY_457_DATA 0x00000000
> +#define              DENALI_PHY_458_DATA 0x00000000
> +#define              DENALI_PHY_459_DATA 0x00000000
> +#define              DENALI_PHY_460_DATA 0x00000000
> +#define              DENALI_PHY_461_DATA 0x00000000
> +#define              DENALI_PHY_462_DATA 0x00000000
> +#define              DENALI_PHY_463_DATA 0x00000000
> +#define              DENALI_PHY_464_DATA 0x00000000
> +#define              DENALI_PHY_465_DATA 0x00000000
> +#define              DENALI_PHY_466_DATA 0x00000000
> +#define              DENALI_PHY_467_DATA 0x00000000
> +#define              DENALI_PHY_468_DATA 0x00000000
> +#define              DENALI_PHY_469_DATA 0x00000000
> +#define              DENALI_PHY_470_DATA 0x00000000
> +#define              DENALI_PHY_471_DATA 0x00000000
> +#define              DENALI_PHY_472_DATA 0x00000000
> +#define              DENALI_PHY_473_DATA 0x00000000
> +#define              DENALI_PHY_474_DATA 0x00000000
> +#define              DENALI_PHY_475_DATA 0x00000000
> +#define              DENALI_PHY_476_DATA 0x00000000
> +#define              DENALI_PHY_477_DATA 0x00000000
> +#define              DENALI_PHY_478_DATA 0x00000000
> +#define              DENALI_PHY_479_DATA 0x00000000
> +#define              DENALI_PHY_480_DATA 0x00000000
> +#define              DENALI_PHY_481_DATA 0x00000000
> +#define              DENALI_PHY_482_DATA 0x00000000
> +#define              DENALI_PHY_483_DATA 0x00000000
> +#define              DENALI_PHY_484_DATA 0x00000000
> +#define              DENALI_PHY_485_DATA 0x00000000
> +#define              DENALI_PHY_486_DATA 0x00000000
> +#define              DENALI_PHY_487_DATA 0x00000000
> +#define              DENALI_PHY_488_DATA 0x00000000
> +#define              DENALI_PHY_489_DATA 0x00000000
> +#define              DENALI_PHY_490_DATA 0x00000000
> +#define              DENALI_PHY_491_DATA 0x00000000
> +#define              DENALI_PHY_492_DATA 0x00000000
> +#define              DENALI_PHY_493_DATA 0x00000000
> +#define              DENALI_PHY_494_DATA 0x00000000
> +#define              DENALI_PHY_495_DATA 0x00000000
> +#define              DENALI_PHY_496_DATA 0x00000000
> +#define              DENALI_PHY_497_DATA 0x00000000
> +#define              DENALI_PHY_498_DATA 0x00000000
> +#define              DENALI_PHY_499_DATA 0x00000000
> +#define              DENALI_PHY_500_DATA 0x00000000
> +#define              DENALI_PHY_501_DATA 0x00000000
> +#define              DENALI_PHY_502_DATA 0x00000000
> +#define              DENALI_PHY_503_DATA 0x00000000
> +#define              DENALI_PHY_504_DATA 0x00000000
> +#define              DENALI_PHY_505_DATA 0x00000000
> +#define              DENALI_PHY_506_DATA 0x00000000
> +#define              DENALI_PHY_507_DATA 0x00000000
> +#define              DENALI_PHY_508_DATA 0x00000000
> +#define              DENALI_PHY_509_DATA 0x00000000
> +#define              DENALI_PHY_510_DATA 0x00000000
> +#define              DENALI_PHY_511_DATA 0x00000000
> +#define              DENALI_PHY_512_DATA 0x24316750
> +#define              DENALI_PHY_513_DATA 0x0004c008
> +#define              DENALI_PHY_514_DATA 0x000000da
> +#define              DENALI_PHY_515_DATA 0x00000000
> +#define              DENALI_PHY_516_DATA 0x00000000
> +#define              DENALI_PHY_517_DATA 0x00010000
> +#define              DENALI_PHY_518_DATA 0x01DDDD90
> +#define              DENALI_PHY_519_DATA 0x01DDDD90
> +#define              DENALI_PHY_520_DATA 0x01030000
> +#define              DENALI_PHY_521_DATA 0x01000000
> +#define              DENALI_PHY_522_DATA 0x00c00000
> +#define              DENALI_PHY_523_DATA 0x00000007
> +#define              DENALI_PHY_524_DATA 0x00000000
> +#define              DENALI_PHY_525_DATA 0x00000000
> +#define              DENALI_PHY_526_DATA 0x04000408
> +#define              DENALI_PHY_527_DATA 0x00000408
> +#define              DENALI_PHY_528_DATA 0x00e4e400
> +#define              DENALI_PHY_529_DATA 0x00000000
> +#define              DENALI_PHY_530_DATA 0x00000000
> +#define              DENALI_PHY_531_DATA 0x00000000
> +#define              DENALI_PHY_532_DATA 0x00000000
> +#define              DENALI_PHY_533_DATA 0x00000000
> +#define              DENALI_PHY_534_DATA 0x00000000
> +#define              DENALI_PHY_535_DATA 0x00000000
> +#define              DENALI_PHY_536_DATA 0x00000000
> +#define              DENALI_PHY_537_DATA 0x00000000
> +#define              DENALI_PHY_538_DATA 0x00000000
> +#define              DENALI_PHY_539_DATA 0x00000000
> +#define              DENALI_PHY_540_DATA 0x00000000
> +#define              DENALI_PHY_541_DATA 0x00000000
> +#define              DENALI_PHY_542_DATA 0x00000000
> +#define              DENALI_PHY_543_DATA 0x00000000
> +#define              DENALI_PHY_544_DATA 0x00000000
> +#define              DENALI_PHY_545_DATA 0x00200000
> +#define              DENALI_PHY_546_DATA 0x00000000
> +#define              DENALI_PHY_547_DATA 0x00000000
> +#define              DENALI_PHY_548_DATA 0x00000000
> +#define              DENALI_PHY_549_DATA 0x00000000
> +#define              DENALI_PHY_550_DATA 0x00000000
> +#define              DENALI_PHY_551_DATA 0x00000000
> +#define              DENALI_PHY_552_DATA 0x02800280
> +#define              DENALI_PHY_553_DATA 0x02800280
> +#define              DENALI_PHY_554_DATA 0x02800280
> +#define              DENALI_PHY_555_DATA 0x02800280
> +#define              DENALI_PHY_556_DATA 0x00000280
> +#define              DENALI_PHY_557_DATA 0x00000000
> +#define              DENALI_PHY_558_DATA 0x00000000
> +#define              DENALI_PHY_559_DATA 0x00000000
> +#define              DENALI_PHY_560_DATA 0x00000000
> +#define              DENALI_PHY_561_DATA 0x00000000
> +#define              DENALI_PHY_562_DATA 0x00800080
> +#define              DENALI_PHY_563_DATA 0x00800080
> +#define              DENALI_PHY_564_DATA 0x00800080
> +#define              DENALI_PHY_565_DATA 0x00800080
> +#define              DENALI_PHY_566_DATA 0x00800080
> +#define              DENALI_PHY_567_DATA 0x00800080
> +#define              DENALI_PHY_568_DATA 0x00800080
> +#define              DENALI_PHY_569_DATA 0x00800080
> +#define              DENALI_PHY_570_DATA 0x00800080
> +#define              DENALI_PHY_571_DATA 0x000100da
> +#define              DENALI_PHY_572_DATA 0x00000200
> +#define              DENALI_PHY_573_DATA 0x00000000
> +#define              DENALI_PHY_574_DATA 0x00000000
> +#define              DENALI_PHY_575_DATA 0x00000002
> +#define              DENALI_PHY_576_DATA 0x51313152
> +#define              DENALI_PHY_577_DATA 0x80013130
> +#define              DENALI_PHY_578_DATA 0x02000080
> +#define              DENALI_PHY_579_DATA 0x00100001
> +#define              DENALI_PHY_580_DATA 0x0c064208
> +#define              DENALI_PHY_581_DATA 0x000f0c0f
> +#define              DENALI_PHY_582_DATA 0x01000140
> +#define              DENALI_PHY_583_DATA 0x0000000c
> +#define              DENALI_PHY_584_DATA 0x00000000
> +#define              DENALI_PHY_585_DATA 0x00000000
> +#define              DENALI_PHY_586_DATA 0x00000000
> +#define              DENALI_PHY_587_DATA 0x00000000
> +#define              DENALI_PHY_588_DATA 0x00000000
> +#define              DENALI_PHY_589_DATA 0x00000000
> +#define              DENALI_PHY_590_DATA 0x00000000
> +#define              DENALI_PHY_591_DATA 0x00000000
> +#define              DENALI_PHY_592_DATA 0x00000000
> +#define              DENALI_PHY_593_DATA 0x00000000
> +#define              DENALI_PHY_594_DATA 0x00000000
> +#define              DENALI_PHY_595_DATA 0x00000000
> +#define              DENALI_PHY_596_DATA 0x00000000
> +#define              DENALI_PHY_597_DATA 0x00000000
> +#define              DENALI_PHY_598_DATA 0x00000000
> +#define              DENALI_PHY_599_DATA 0x00000000
> +#define              DENALI_PHY_600_DATA 0x00000000
> +#define              DENALI_PHY_601_DATA 0x00000000
> +#define              DENALI_PHY_602_DATA 0x00000000
> +#define              DENALI_PHY_603_DATA 0x00000000
> +#define              DENALI_PHY_604_DATA 0x00000000
> +#define              DENALI_PHY_605_DATA 0x00000000
> +#define              DENALI_PHY_606_DATA 0x00000000
> +#define              DENALI_PHY_607_DATA 0x00000000
> +#define              DENALI_PHY_608_DATA 0x00000000
> +#define              DENALI_PHY_609_DATA 0x00000000
> +#define              DENALI_PHY_610_DATA 0x00000000
> +#define              DENALI_PHY_611_DATA 0x00000000
> +#define              DENALI_PHY_612_DATA 0x00000000
> +#define              DENALI_PHY_613_DATA 0x00000000
> +#define              DENALI_PHY_614_DATA 0x00000000
> +#define              DENALI_PHY_615_DATA 0x00000000
> +#define              DENALI_PHY_616_DATA 0x00000000
> +#define              DENALI_PHY_617_DATA 0x00000000
> +#define              DENALI_PHY_618_DATA 0x00000000
> +#define              DENALI_PHY_619_DATA 0x00000000
> +#define              DENALI_PHY_620_DATA 0x00000000
> +#define              DENALI_PHY_621_DATA 0x00000000
> +#define              DENALI_PHY_622_DATA 0x00000000
> +#define              DENALI_PHY_623_DATA 0x00000000
> +#define              DENALI_PHY_624_DATA 0x00000000
> +#define              DENALI_PHY_625_DATA 0x00000000
> +#define              DENALI_PHY_626_DATA 0x00000000
> +#define              DENALI_PHY_627_DATA 0x00000000
> +#define              DENALI_PHY_628_DATA 0x00000000
> +#define              DENALI_PHY_629_DATA 0x00000000
> +#define              DENALI_PHY_630_DATA 0x00000000
> +#define              DENALI_PHY_631_DATA 0x00000000
> +#define              DENALI_PHY_632_DATA 0x00000000
> +#define              DENALI_PHY_633_DATA 0x00000000
> +#define              DENALI_PHY_634_DATA 0x00000000
> +#define              DENALI_PHY_635_DATA 0x00000000
> +#define              DENALI_PHY_636_DATA 0x00000000
> +#define              DENALI_PHY_637_DATA 0x00000000
> +#define              DENALI_PHY_638_DATA 0x00000000
> +#define              DENALI_PHY_639_DATA 0x00000000
> +#define              DENALI_PHY_640_DATA 0x35174620
> +#define              DENALI_PHY_641_DATA 0x0004c008
> +#define              DENALI_PHY_642_DATA 0x000000da
> +#define              DENALI_PHY_643_DATA 0x00000000
> +#define              DENALI_PHY_644_DATA 0x00000000
> +#define              DENALI_PHY_645_DATA 0x00010000
> +#define              DENALI_PHY_646_DATA 0x01DDDD90
> +#define              DENALI_PHY_647_DATA 0x01DDDD90
> +#define              DENALI_PHY_648_DATA 0x01030000
> +#define              DENALI_PHY_649_DATA 0x01000000
> +#define              DENALI_PHY_650_DATA 0x00c00000
> +#define              DENALI_PHY_651_DATA 0x00000007
> +#define              DENALI_PHY_652_DATA 0x00000000
> +#define              DENALI_PHY_653_DATA 0x00000000
> +#define              DENALI_PHY_654_DATA 0x04000408
> +#define              DENALI_PHY_655_DATA 0x00000408
> +#define              DENALI_PHY_656_DATA 0x00e4e400
> +#define              DENALI_PHY_657_DATA 0x00000000
> +#define              DENALI_PHY_658_DATA 0x00000000
> +#define              DENALI_PHY_659_DATA 0x00000000
> +#define              DENALI_PHY_660_DATA 0x00000000
> +#define              DENALI_PHY_661_DATA 0x00000000
> +#define              DENALI_PHY_662_DATA 0x00000000
> +#define              DENALI_PHY_663_DATA 0x00000000
> +#define              DENALI_PHY_664_DATA 0x00000000
> +#define              DENALI_PHY_665_DATA 0x00000000
> +#define              DENALI_PHY_666_DATA 0x00000000
> +#define              DENALI_PHY_667_DATA 0x00000000
> +#define              DENALI_PHY_668_DATA 0x00000000
> +#define              DENALI_PHY_669_DATA 0x00000000
> +#define              DENALI_PHY_670_DATA 0x00000000
> +#define              DENALI_PHY_671_DATA 0x00000000
> +#define              DENALI_PHY_672_DATA 0x00000000
> +#define              DENALI_PHY_673_DATA 0x00200000
> +#define              DENALI_PHY_674_DATA 0x00000000
> +#define              DENALI_PHY_675_DATA 0x00000000
> +#define              DENALI_PHY_676_DATA 0x00000000
> +#define              DENALI_PHY_677_DATA 0x00000000
> +#define              DENALI_PHY_678_DATA 0x00000000
> +#define              DENALI_PHY_679_DATA 0x00000000
> +#define              DENALI_PHY_680_DATA 0x02800280
> +#define              DENALI_PHY_681_DATA 0x02800280
> +#define              DENALI_PHY_682_DATA 0x02800280
> +#define              DENALI_PHY_683_DATA 0x02800280
> +#define              DENALI_PHY_684_DATA 0x00000280
> +#define              DENALI_PHY_685_DATA 0x00000000
> +#define              DENALI_PHY_686_DATA 0x00000000
> +#define              DENALI_PHY_687_DATA 0x00000000
> +#define              DENALI_PHY_688_DATA 0x00000000
> +#define              DENALI_PHY_689_DATA 0x00000000
> +#define              DENALI_PHY_690_DATA 0x00800080
> +#define              DENALI_PHY_691_DATA 0x00800080
> +#define              DENALI_PHY_692_DATA 0x00800080
> +#define              DENALI_PHY_693_DATA 0x00800080
> +#define              DENALI_PHY_694_DATA 0x00800080
> +#define              DENALI_PHY_695_DATA 0x00800080
> +#define              DENALI_PHY_696_DATA 0x00800080
> +#define              DENALI_PHY_697_DATA 0x00800080
> +#define              DENALI_PHY_698_DATA 0x00800080
> +#define              DENALI_PHY_699_DATA 0x000100da
> +#define              DENALI_PHY_700_DATA 0x00000200
> +#define              DENALI_PHY_701_DATA 0x00000000
> +#define              DENALI_PHY_702_DATA 0x00000000
> +#define              DENALI_PHY_703_DATA 0x00000002
> +#define              DENALI_PHY_704_DATA 0x51313152
> +#define              DENALI_PHY_705_DATA 0x80013130
> +#define              DENALI_PHY_706_DATA 0x02000080
> +#define              DENALI_PHY_707_DATA 0x00100001
> +#define              DENALI_PHY_708_DATA 0x0c064208
> +#define              DENALI_PHY_709_DATA 0x000f0c0f
> +#define              DENALI_PHY_710_DATA 0x01000140
> +#define              DENALI_PHY_711_DATA 0x0000000c
> +#define              DENALI_PHY_712_DATA 0x00000000
> +#define              DENALI_PHY_713_DATA 0x00000000
> +#define              DENALI_PHY_714_DATA 0x00000000
> +#define              DENALI_PHY_715_DATA 0x00000000
> +#define              DENALI_PHY_716_DATA 0x00000000
> +#define              DENALI_PHY_717_DATA 0x00000000
> +#define              DENALI_PHY_718_DATA 0x00000000
> +#define              DENALI_PHY_719_DATA 0x00000000
> +#define              DENALI_PHY_720_DATA 0x00000000
> +#define              DENALI_PHY_721_DATA 0x00000000
> +#define              DENALI_PHY_722_DATA 0x00000000
> +#define              DENALI_PHY_723_DATA 0x00000000
> +#define              DENALI_PHY_724_DATA 0x00000000
> +#define              DENALI_PHY_725_DATA 0x00000000
> +#define              DENALI_PHY_726_DATA 0x00000000
> +#define              DENALI_PHY_727_DATA 0x00000000
> +#define              DENALI_PHY_728_DATA 0x00000000
> +#define              DENALI_PHY_729_DATA 0x00000000
> +#define              DENALI_PHY_730_DATA 0x00000000
> +#define              DENALI_PHY_731_DATA 0x00000000
> +#define              DENALI_PHY_732_DATA 0x00000000
> +#define              DENALI_PHY_733_DATA 0x00000000
> +#define              DENALI_PHY_734_DATA 0x00000000
> +#define              DENALI_PHY_735_DATA 0x00000000
> +#define              DENALI_PHY_736_DATA 0x00000000
> +#define              DENALI_PHY_737_DATA 0x00000000
> +#define              DENALI_PHY_738_DATA 0x00000000
> +#define              DENALI_PHY_739_DATA 0x00000000
> +#define              DENALI_PHY_740_DATA 0x00000000
> +#define              DENALI_PHY_741_DATA 0x00000000
> +#define              DENALI_PHY_742_DATA 0x00000000
> +#define              DENALI_PHY_743_DATA 0x00000000
> +#define              DENALI_PHY_744_DATA 0x00000000
> +#define              DENALI_PHY_745_DATA 0x00000000
> +#define              DENALI_PHY_746_DATA 0x00000000
> +#define              DENALI_PHY_747_DATA 0x00000000
> +#define              DENALI_PHY_748_DATA 0x00000000
> +#define              DENALI_PHY_749_DATA 0x00000000
> +#define              DENALI_PHY_750_DATA 0x00000000
> +#define              DENALI_PHY_751_DATA 0x00000000
> +#define              DENALI_PHY_752_DATA 0x00000000
> +#define              DENALI_PHY_753_DATA 0x00000000
> +#define              DENALI_PHY_754_DATA 0x00000000
> +#define              DENALI_PHY_755_DATA 0x00000000
> +#define              DENALI_PHY_756_DATA 0x00000000
> +#define              DENALI_PHY_757_DATA 0x00000000
> +#define              DENALI_PHY_758_DATA 0x00000000
> +#define              DENALI_PHY_759_DATA 0x00000000
> +#define              DENALI_PHY_760_DATA 0x00000000
> +#define              DENALI_PHY_761_DATA 0x00000000
> +#define              DENALI_PHY_762_DATA 0x00000000
> +#define              DENALI_PHY_763_DATA 0x00000000
> +#define              DENALI_PHY_764_DATA 0x00000000
> +#define              DENALI_PHY_765_DATA 0x00000000
> +#define              DENALI_PHY_766_DATA 0x00000000
> +#define              DENALI_PHY_767_DATA 0x00000000
> +#define              DENALI_PHY_768_DATA 0x15203476
> +#define              DENALI_PHY_769_DATA 0x0004c008
> +#define              DENALI_PHY_770_DATA 0x000000da
> +#define              DENALI_PHY_771_DATA 0x00000000
> +#define              DENALI_PHY_772_DATA 0x00000000
> +#define              DENALI_PHY_773_DATA 0x00010000
> +#define              DENALI_PHY_774_DATA 0x01DDDD90
> +#define              DENALI_PHY_775_DATA 0x01DDDD90
> +#define              DENALI_PHY_776_DATA 0x01030000
> +#define              DENALI_PHY_777_DATA 0x01000000
> +#define              DENALI_PHY_778_DATA 0x00c00000
> +#define              DENALI_PHY_779_DATA 0x00000007
> +#define              DENALI_PHY_780_DATA 0x00000000
> +#define              DENALI_PHY_781_DATA 0x00000000
> +#define              DENALI_PHY_782_DATA 0x04000408
> +#define              DENALI_PHY_783_DATA 0x00000408
> +#define              DENALI_PHY_784_DATA 0x00e4e400
> +#define              DENALI_PHY_785_DATA 0x00000000
> +#define              DENALI_PHY_786_DATA 0x00000000
> +#define              DENALI_PHY_787_DATA 0x00000000
> +#define              DENALI_PHY_788_DATA 0x00000000
> +#define              DENALI_PHY_789_DATA 0x00000000
> +#define              DENALI_PHY_790_DATA 0x00000000
> +#define              DENALI_PHY_791_DATA 0x00000000
> +#define              DENALI_PHY_792_DATA 0x00000000
> +#define              DENALI_PHY_793_DATA 0x00000000
> +#define              DENALI_PHY_794_DATA 0x00000000
> +#define              DENALI_PHY_795_DATA 0x00000000
> +#define              DENALI_PHY_796_DATA 0x00000000
> +#define              DENALI_PHY_797_DATA 0x00000000
> +#define              DENALI_PHY_798_DATA 0x00000000
> +#define              DENALI_PHY_799_DATA 0x00000000
> +#define              DENALI_PHY_800_DATA 0x00000000
> +#define              DENALI_PHY_801_DATA 0x00200000
> +#define              DENALI_PHY_802_DATA 0x00000000
> +#define              DENALI_PHY_803_DATA 0x00000000
> +#define              DENALI_PHY_804_DATA 0x00000000
> +#define              DENALI_PHY_805_DATA 0x00000000
> +#define              DENALI_PHY_806_DATA 0x00000000
> +#define              DENALI_PHY_807_DATA 0x00000000
> +#define              DENALI_PHY_808_DATA 0x02800280
> +#define              DENALI_PHY_809_DATA 0x02800280
> +#define              DENALI_PHY_810_DATA 0x02800280
> +#define              DENALI_PHY_811_DATA 0x02800280
> +#define              DENALI_PHY_812_DATA 0x00000280
> +#define              DENALI_PHY_813_DATA 0x00000000
> +#define              DENALI_PHY_814_DATA 0x00000000
> +#define              DENALI_PHY_815_DATA 0x00000000
> +#define              DENALI_PHY_816_DATA 0x00000000
> +#define              DENALI_PHY_817_DATA 0x00000000
> +#define              DENALI_PHY_818_DATA 0x00800080
> +#define              DENALI_PHY_819_DATA 0x00800080
> +#define              DENALI_PHY_820_DATA 0x00800080
> +#define              DENALI_PHY_821_DATA 0x00800080
> +#define              DENALI_PHY_822_DATA 0x00800080
> +#define              DENALI_PHY_823_DATA 0x00800080
> +#define              DENALI_PHY_824_DATA 0x00800080
> +#define              DENALI_PHY_825_DATA 0x00800080
> +#define              DENALI_PHY_826_DATA 0x00800080
> +#define              DENALI_PHY_827_DATA 0x000100da
> +#define              DENALI_PHY_828_DATA 0x00000200
> +#define              DENALI_PHY_829_DATA 0x00000000
> +#define              DENALI_PHY_830_DATA 0x00000000
> +#define              DENALI_PHY_831_DATA 0x00000002
> +#define              DENALI_PHY_832_DATA 0x51313152
> +#define              DENALI_PHY_833_DATA 0x80013130
> +#define              DENALI_PHY_834_DATA 0x02000080
> +#define              DENALI_PHY_835_DATA 0x00100001
> +#define              DENALI_PHY_836_DATA 0x0c064208
> +#define              DENALI_PHY_837_DATA 0x000f0c0f
> +#define              DENALI_PHY_838_DATA 0x01000140
> +#define              DENALI_PHY_839_DATA 0x0000000c
> +#define              DENALI_PHY_840_DATA 0x00000000
> +#define              DENALI_PHY_841_DATA 0x00000000
> +#define              DENALI_PHY_842_DATA 0x00000000
> +#define              DENALI_PHY_843_DATA 0x00000000
> +#define              DENALI_PHY_844_DATA 0x00000000
> +#define              DENALI_PHY_845_DATA 0x00000000
> +#define              DENALI_PHY_846_DATA 0x00000000
> +#define              DENALI_PHY_847_DATA 0x00000000
> +#define              DENALI_PHY_848_DATA 0x00000000
> +#define              DENALI_PHY_849_DATA 0x00000000
> +#define              DENALI_PHY_850_DATA 0x00000000
> +#define              DENALI_PHY_851_DATA 0x00000000
> +#define              DENALI_PHY_852_DATA 0x00000000
> +#define              DENALI_PHY_853_DATA 0x00000000
> +#define              DENALI_PHY_854_DATA 0x00000000
> +#define              DENALI_PHY_855_DATA 0x00000000
> +#define              DENALI_PHY_856_DATA 0x00000000
> +#define              DENALI_PHY_857_DATA 0x00000000
> +#define              DENALI_PHY_858_DATA 0x00000000
> +#define              DENALI_PHY_859_DATA 0x00000000
> +#define              DENALI_PHY_860_DATA 0x00000000
> +#define              DENALI_PHY_861_DATA 0x00000000
> +#define              DENALI_PHY_862_DATA 0x00000000
> +#define              DENALI_PHY_863_DATA 0x00000000
> +#define              DENALI_PHY_864_DATA 0x00000000
> +#define              DENALI_PHY_865_DATA 0x00000000
> +#define              DENALI_PHY_866_DATA 0x00000000
> +#define              DENALI_PHY_867_DATA 0x00000000
> +#define              DENALI_PHY_868_DATA 0x00000000
> +#define              DENALI_PHY_869_DATA 0x00000000
> +#define              DENALI_PHY_870_DATA 0x00000000
> +#define              DENALI_PHY_871_DATA 0x00000000
> +#define              DENALI_PHY_872_DATA 0x00000000
> +#define              DENALI_PHY_873_DATA 0x00000000
> +#define              DENALI_PHY_874_DATA 0x00000000
> +#define              DENALI_PHY_875_DATA 0x00000000
> +#define              DENALI_PHY_876_DATA 0x00000000
> +#define              DENALI_PHY_877_DATA 0x00000000
> +#define              DENALI_PHY_878_DATA 0x00000000
> +#define              DENALI_PHY_879_DATA 0x00000000
> +#define              DENALI_PHY_880_DATA 0x00000000
> +#define              DENALI_PHY_881_DATA 0x00000000
> +#define              DENALI_PHY_882_DATA 0x00000000
> +#define              DENALI_PHY_883_DATA 0x00000000
> +#define              DENALI_PHY_884_DATA 0x00000000
> +#define              DENALI_PHY_885_DATA 0x00000000
> +#define              DENALI_PHY_886_DATA 0x00000000
> +#define              DENALI_PHY_887_DATA 0x00000000
> +#define              DENALI_PHY_888_DATA 0x00000000
> +#define              DENALI_PHY_889_DATA 0x00000000
> +#define              DENALI_PHY_890_DATA 0x00000000
> +#define              DENALI_PHY_891_DATA 0x00000000
> +#define              DENALI_PHY_892_DATA 0x00000000
> +#define              DENALI_PHY_893_DATA 0x00000000
> +#define              DENALI_PHY_894_DATA 0x00000000
> +#define              DENALI_PHY_895_DATA 0x00000000
> +#define              DENALI_PHY_896_DATA 0x41753206
> +#define              DENALI_PHY_897_DATA 0x0004c008
> +#define              DENALI_PHY_898_DATA 0x000000da
> +#define              DENALI_PHY_899_DATA 0x00000000
> +#define              DENALI_PHY_900_DATA 0x00000000
> +#define              DENALI_PHY_901_DATA 0x00010000
> +#define              DENALI_PHY_902_DATA 0x01DDDD90
> +#define              DENALI_PHY_903_DATA 0x01DDDD90
> +#define              DENALI_PHY_904_DATA 0x01030000
> +#define              DENALI_PHY_905_DATA 0x01000000
> +#define              DENALI_PHY_906_DATA 0x00c00000
> +#define              DENALI_PHY_907_DATA 0x00000007
> +#define              DENALI_PHY_908_DATA 0x00000000
> +#define              DENALI_PHY_909_DATA 0x00000000
> +#define              DENALI_PHY_910_DATA 0x04000408
> +#define              DENALI_PHY_911_DATA 0x00000408
> +#define              DENALI_PHY_912_DATA 0x00e4e400
> +#define              DENALI_PHY_913_DATA 0x00000000
> +#define              DENALI_PHY_914_DATA 0x00000000
> +#define              DENALI_PHY_915_DATA 0x00000000
> +#define              DENALI_PHY_916_DATA 0x00000000
> +#define              DENALI_PHY_917_DATA 0x00000000
> +#define              DENALI_PHY_918_DATA 0x00000000
> +#define              DENALI_PHY_919_DATA 0x00000000
> +#define              DENALI_PHY_920_DATA 0x00000000
> +#define              DENALI_PHY_921_DATA 0x00000000
> +#define              DENALI_PHY_922_DATA 0x00000000
> +#define              DENALI_PHY_923_DATA 0x00000000
> +#define              DENALI_PHY_924_DATA 0x00000000
> +#define              DENALI_PHY_925_DATA 0x00000000
> +#define              DENALI_PHY_926_DATA 0x00000000
> +#define              DENALI_PHY_927_DATA 0x00000000
> +#define              DENALI_PHY_928_DATA 0x00000000
> +#define              DENALI_PHY_929_DATA 0x00200000
> +#define              DENALI_PHY_930_DATA 0x00000000
> +#define              DENALI_PHY_931_DATA 0x00000000
> +#define              DENALI_PHY_932_DATA 0x00000000
> +#define              DENALI_PHY_933_DATA 0x00000000
> +#define              DENALI_PHY_934_DATA 0x00000000
> +#define              DENALI_PHY_935_DATA 0x00000000
> +#define              DENALI_PHY_936_DATA 0x02800280
> +#define              DENALI_PHY_937_DATA 0x02800280
> +#define              DENALI_PHY_938_DATA 0x02800280
> +#define              DENALI_PHY_939_DATA 0x02800280
> +#define              DENALI_PHY_940_DATA 0x00000280
> +#define              DENALI_PHY_941_DATA 0x00000000
> +#define              DENALI_PHY_942_DATA 0x00000000
> +#define              DENALI_PHY_943_DATA 0x00000000
> +#define              DENALI_PHY_944_DATA 0x00000000
> +#define              DENALI_PHY_945_DATA 0x00000000
> +#define              DENALI_PHY_946_DATA 0x00800080
> +#define              DENALI_PHY_947_DATA 0x00800080
> +#define              DENALI_PHY_948_DATA 0x00800080
> +#define              DENALI_PHY_949_DATA 0x00800080
> +#define              DENALI_PHY_950_DATA 0x00800080
> +#define              DENALI_PHY_951_DATA 0x00800080
> +#define              DENALI_PHY_952_DATA 0x00800080
> +#define              DENALI_PHY_953_DATA 0x00800080
> +#define              DENALI_PHY_954_DATA 0x00800080
> +#define              DENALI_PHY_955_DATA 0x000100da
> +#define              DENALI_PHY_956_DATA 0x00000200
> +#define              DENALI_PHY_957_DATA 0x00000000
> +#define              DENALI_PHY_958_DATA 0x00000000
> +#define              DENALI_PHY_959_DATA 0x00000002
> +#define              DENALI_PHY_960_DATA 0x51313152
> +#define              DENALI_PHY_961_DATA 0x80013130
> +#define              DENALI_PHY_962_DATA 0x02000080
> +#define              DENALI_PHY_963_DATA 0x00100001
> +#define              DENALI_PHY_964_DATA 0x0c064208
> +#define              DENALI_PHY_965_DATA 0x000f0c0f
> +#define              DENALI_PHY_966_DATA 0x01000140
> +#define              DENALI_PHY_967_DATA 0x0000000c
> +#define              DENALI_PHY_968_DATA 0x00000000
> +#define              DENALI_PHY_969_DATA 0x00000000
> +#define              DENALI_PHY_970_DATA 0x00000000
> +#define              DENALI_PHY_971_DATA 0x00000000
> +#define              DENALI_PHY_972_DATA 0x00000000
> +#define              DENALI_PHY_973_DATA 0x00000000
> +#define              DENALI_PHY_974_DATA 0x00000000
> +#define              DENALI_PHY_975_DATA 0x00000000
> +#define              DENALI_PHY_976_DATA 0x00000000
> +#define              DENALI_PHY_977_DATA 0x00000000
> +#define              DENALI_PHY_978_DATA 0x00000000
> +#define              DENALI_PHY_979_DATA 0x00000000
> +#define              DENALI_PHY_980_DATA 0x00000000
> +#define              DENALI_PHY_981_DATA 0x00000000
> +#define              DENALI_PHY_982_DATA 0x00000000
> +#define              DENALI_PHY_983_DATA 0x00000000
> +#define              DENALI_PHY_984_DATA 0x00000000
> +#define              DENALI_PHY_985_DATA 0x00000000
> +#define              DENALI_PHY_986_DATA 0x00000000
> +#define              DENALI_PHY_987_DATA 0x00000000
> +#define              DENALI_PHY_988_DATA 0x00000000
> +#define              DENALI_PHY_989_DATA 0x00000000
> +#define              DENALI_PHY_990_DATA 0x00000000
> +#define              DENALI_PHY_991_DATA 0x00000000
> +#define              DENALI_PHY_992_DATA 0x00000000
> +#define              DENALI_PHY_993_DATA 0x00000000
> +#define              DENALI_PHY_994_DATA 0x00000000
> +#define              DENALI_PHY_995_DATA 0x00000000
> +#define              DENALI_PHY_996_DATA 0x00000000
> +#define              DENALI_PHY_997_DATA 0x00000000
> +#define              DENALI_PHY_998_DATA 0x00000000
> +#define              DENALI_PHY_999_DATA 0x00000000
> +#define             DENALI_PHY_1000_DATA 0x00000000
> +#define             DENALI_PHY_1001_DATA 0x00000000
> +#define             DENALI_PHY_1002_DATA 0x00000000
> +#define             DENALI_PHY_1003_DATA 0x00000000
> +#define             DENALI_PHY_1004_DATA 0x00000000
> +#define             DENALI_PHY_1005_DATA 0x00000000
> +#define             DENALI_PHY_1006_DATA 0x00000000
> +#define             DENALI_PHY_1007_DATA 0x00000000
> +#define             DENALI_PHY_1008_DATA 0x00000000
> +#define             DENALI_PHY_1009_DATA 0x00000000
> +#define             DENALI_PHY_1010_DATA 0x00000000
> +#define             DENALI_PHY_1011_DATA 0x00000000
> +#define             DENALI_PHY_1012_DATA 0x00000000
> +#define             DENALI_PHY_1013_DATA 0x00000000
> +#define             DENALI_PHY_1014_DATA 0x00000000
> +#define             DENALI_PHY_1015_DATA 0x00000000
> +#define             DENALI_PHY_1016_DATA 0x00000000
> +#define             DENALI_PHY_1017_DATA 0x00000000
> +#define             DENALI_PHY_1018_DATA 0x00000000
> +#define             DENALI_PHY_1019_DATA 0x00000000
> +#define             DENALI_PHY_1020_DATA 0x00000000
> +#define             DENALI_PHY_1021_DATA 0x00000000
> +#define             DENALI_PHY_1022_DATA 0x00000000
> +#define             DENALI_PHY_1023_DATA 0x00000000
> +#define             DENALI_PHY_1024_DATA 0x36025174
> +#define             DENALI_PHY_1025_DATA 0x0004c008
> +#define             DENALI_PHY_1026_DATA 0x000000da
> +#define             DENALI_PHY_1027_DATA 0x00000000
> +#define             DENALI_PHY_1028_DATA 0x00000000
> +#define             DENALI_PHY_1029_DATA 0x00010000
> +#define             DENALI_PHY_1030_DATA 0x01DDDD90
> +#define             DENALI_PHY_1031_DATA 0x01DDDD90
> +#define             DENALI_PHY_1032_DATA 0x01030000
> +#define             DENALI_PHY_1033_DATA 0x01000000
> +#define             DENALI_PHY_1034_DATA 0x00c00000
> +#define             DENALI_PHY_1035_DATA 0x00000007
> +#define             DENALI_PHY_1036_DATA 0x00000000
> +#define             DENALI_PHY_1037_DATA 0x00000000
> +#define             DENALI_PHY_1038_DATA 0x04000408
> +#define             DENALI_PHY_1039_DATA 0x00000408
> +#define             DENALI_PHY_1040_DATA 0x00e4e400
> +#define             DENALI_PHY_1041_DATA 0x00000000
> +#define             DENALI_PHY_1042_DATA 0x00000000
> +#define             DENALI_PHY_1043_DATA 0x00000000
> +#define             DENALI_PHY_1044_DATA 0x00000000
> +#define             DENALI_PHY_1045_DATA 0x00000000
> +#define             DENALI_PHY_1046_DATA 0x00000000
> +#define             DENALI_PHY_1047_DATA 0x00000000
> +#define             DENALI_PHY_1048_DATA 0x00000000
> +#define             DENALI_PHY_1049_DATA 0x00000000
> +#define             DENALI_PHY_1050_DATA 0x00000000
> +#define             DENALI_PHY_1051_DATA 0x00000000
> +#define             DENALI_PHY_1052_DATA 0x00000000
> +#define             DENALI_PHY_1053_DATA 0x00000000
> +#define             DENALI_PHY_1054_DATA 0x00000000
> +#define             DENALI_PHY_1055_DATA 0x00000000
> +#define             DENALI_PHY_1056_DATA 0x00000000
> +#define             DENALI_PHY_1057_DATA 0x00200000
> +#define             DENALI_PHY_1058_DATA 0x00000000
> +#define             DENALI_PHY_1059_DATA 0x00000000
> +#define             DENALI_PHY_1060_DATA 0x00000000
> +#define             DENALI_PHY_1061_DATA 0x00000000
> +#define             DENALI_PHY_1062_DATA 0x00000000
> +#define             DENALI_PHY_1063_DATA 0x00000000
> +#define             DENALI_PHY_1064_DATA 0x02800280
> +#define             DENALI_PHY_1065_DATA 0x02800280
> +#define             DENALI_PHY_1066_DATA 0x02800280
> +#define             DENALI_PHY_1067_DATA 0x02800280
> +#define             DENALI_PHY_1068_DATA 0x00000280
> +#define             DENALI_PHY_1069_DATA 0x00000000
> +#define             DENALI_PHY_1070_DATA 0x00000000
> +#define             DENALI_PHY_1071_DATA 0x00000000
> +#define             DENALI_PHY_1072_DATA 0x00000000
> +#define             DENALI_PHY_1073_DATA 0x00000000
> +#define             DENALI_PHY_1074_DATA 0x00800080
> +#define             DENALI_PHY_1075_DATA 0x00800080
> +#define             DENALI_PHY_1076_DATA 0x00800080
> +#define             DENALI_PHY_1077_DATA 0x00800080
> +#define             DENALI_PHY_1078_DATA 0x00800080
> +#define             DENALI_PHY_1079_DATA 0x00800080
> +#define             DENALI_PHY_1080_DATA 0x00800080
> +#define             DENALI_PHY_1081_DATA 0x00800080
> +#define             DENALI_PHY_1082_DATA 0x00800080
> +#define             DENALI_PHY_1083_DATA 0x000100da
> +#define             DENALI_PHY_1084_DATA 0x00000200
> +#define             DENALI_PHY_1085_DATA 0x00000000
> +#define             DENALI_PHY_1086_DATA 0x00000000
> +#define             DENALI_PHY_1087_DATA 0x00000002
> +#define             DENALI_PHY_1088_DATA 0x51313152
> +#define             DENALI_PHY_1089_DATA 0x80013130
> +#define             DENALI_PHY_1090_DATA 0x02000080
> +#define             DENALI_PHY_1091_DATA 0x00100001
> +#define             DENALI_PHY_1092_DATA 0x0c064208
> +#define             DENALI_PHY_1093_DATA 0x000f0c0f
> +#define             DENALI_PHY_1094_DATA 0x01000140
> +#define             DENALI_PHY_1095_DATA 0x0000000c
> +#define             DENALI_PHY_1096_DATA 0x00000000
> +#define             DENALI_PHY_1097_DATA 0x00000000
> +#define             DENALI_PHY_1098_DATA 0x00000000
> +#define             DENALI_PHY_1099_DATA 0x00000000
> +#define             DENALI_PHY_1100_DATA 0x00000000
> +#define             DENALI_PHY_1101_DATA 0x00000000
> +#define             DENALI_PHY_1102_DATA 0x00000000
> +#define             DENALI_PHY_1103_DATA 0x00000000
> +#define             DENALI_PHY_1104_DATA 0x00000000
> +#define             DENALI_PHY_1105_DATA 0x00000000
> +#define             DENALI_PHY_1106_DATA 0x00000000
> +#define             DENALI_PHY_1107_DATA 0x00000000
> +#define             DENALI_PHY_1108_DATA 0x00000000
> +#define             DENALI_PHY_1109_DATA 0x00000000
> +#define             DENALI_PHY_1110_DATA 0x00000000
> +#define             DENALI_PHY_1111_DATA 0x00000000
> +#define             DENALI_PHY_1112_DATA 0x00000000
> +#define             DENALI_PHY_1113_DATA 0x00000000
> +#define             DENALI_PHY_1114_DATA 0x00000000
> +#define             DENALI_PHY_1115_DATA 0x00000000
> +#define             DENALI_PHY_1116_DATA 0x00000000
> +#define             DENALI_PHY_1117_DATA 0x00000000
> +#define             DENALI_PHY_1118_DATA 0x00000000
> +#define             DENALI_PHY_1119_DATA 0x00000000
> +#define             DENALI_PHY_1120_DATA 0x00000000
> +#define             DENALI_PHY_1121_DATA 0x00000000
> +#define             DENALI_PHY_1122_DATA 0x00000000
> +#define             DENALI_PHY_1123_DATA 0x00000000
> +#define             DENALI_PHY_1124_DATA 0x00000000
> +#define             DENALI_PHY_1125_DATA 0x00000000
> +#define             DENALI_PHY_1126_DATA 0x00000000
> +#define             DENALI_PHY_1127_DATA 0x00000000
> +#define             DENALI_PHY_1128_DATA 0x00000000
> +#define             DENALI_PHY_1129_DATA 0x00000000
> +#define             DENALI_PHY_1130_DATA 0x00000000
> +#define             DENALI_PHY_1131_DATA 0x00000000
> +#define             DENALI_PHY_1132_DATA 0x00000000
> +#define             DENALI_PHY_1133_DATA 0x00000000
> +#define             DENALI_PHY_1134_DATA 0x00000000
> +#define             DENALI_PHY_1135_DATA 0x00000000
> +#define             DENALI_PHY_1136_DATA 0x00000000
> +#define             DENALI_PHY_1137_DATA 0x00000000
> +#define             DENALI_PHY_1138_DATA 0x00000000
> +#define             DENALI_PHY_1139_DATA 0x00000000
> +#define             DENALI_PHY_1140_DATA 0x00000000
> +#define             DENALI_PHY_1141_DATA 0x00000000
> +#define             DENALI_PHY_1142_DATA 0x00000000
> +#define             DENALI_PHY_1143_DATA 0x00000000
> +#define             DENALI_PHY_1144_DATA 0x00000000
> +#define             DENALI_PHY_1145_DATA 0x00000000
> +#define             DENALI_PHY_1146_DATA 0x00000000
> +#define             DENALI_PHY_1147_DATA 0x00000000
> +#define             DENALI_PHY_1148_DATA 0x00000000
> +#define             DENALI_PHY_1149_DATA 0x00000000
> +#define             DENALI_PHY_1150_DATA 0x00000000
> +#define             DENALI_PHY_1151_DATA 0x00000000
> +#define             DENALI_PHY_1152_DATA 0x00000000
> +#define             DENALI_PHY_1153_DATA 0x00000000
> +#define             DENALI_PHY_1154_DATA 0x00050000
> +#define             DENALI_PHY_1155_DATA 0x00000000
> +#define             DENALI_PHY_1156_DATA 0x00000000
> +#define             DENALI_PHY_1157_DATA 0x00000000
> +#define             DENALI_PHY_1158_DATA 0x00000100
> +#define             DENALI_PHY_1159_DATA 0x00000000
> +#define             DENALI_PHY_1160_DATA 0x00000000
> +#define             DENALI_PHY_1161_DATA 0x00506401
> +#define             DENALI_PHY_1162_DATA 0x01221102
> +#define             DENALI_PHY_1163_DATA 0x00000122
> +#define             DENALI_PHY_1164_DATA 0x00000000
> +#define             DENALI_PHY_1165_DATA 0x000B1F00
> +#define             DENALI_PHY_1166_DATA 0x0B1F0B1F
> +#define             DENALI_PHY_1167_DATA 0x0B1F0B1B
> +#define             DENALI_PHY_1168_DATA 0x0B1F0B1F
> +#define             DENALI_PHY_1169_DATA 0x0B1F0B1F
> +#define             DENALI_PHY_1170_DATA 0x00000B00
> +#define             DENALI_PHY_1171_DATA 0x42080010
> +#define             DENALI_PHY_1172_DATA 0x01000100
> +#define             DENALI_PHY_1173_DATA 0x01000100
> +#define             DENALI_PHY_1174_DATA 0x01000100
> +#define             DENALI_PHY_1175_DATA 0x01000100
> +#define             DENALI_PHY_1176_DATA 0x00000000
> +#define             DENALI_PHY_1177_DATA 0x00000000
> +#define             DENALI_PHY_1178_DATA 0x00000000
> +#define             DENALI_PHY_1179_DATA 0x00000000
> +#define             DENALI_PHY_1180_DATA 0x00000000
> +#define             DENALI_PHY_1181_DATA 0x00000803
> +#define             DENALI_PHY_1182_DATA 0x223FFF00
> +#define             DENALI_PHY_1183_DATA 0x000008FF
> +#define             DENALI_PHY_1184_DATA 0x0000057F
> +#define             DENALI_PHY_1185_DATA 0x0000057F
> +#define             DENALI_PHY_1186_DATA 0x00037FFF
> +#define             DENALI_PHY_1187_DATA 0x00037FFF
> +#define             DENALI_PHY_1188_DATA 0x00004410
> +#define             DENALI_PHY_1189_DATA 0x00004410
> +#define             DENALI_PHY_1190_DATA 0x00004410
> +#define             DENALI_PHY_1191_DATA 0x00004410
> +#define             DENALI_PHY_1192_DATA 0x00004410
> +#define             DENALI_PHY_1193_DATA 0x00037FFF
> +#define             DENALI_PHY_1194_DATA 0x00037FFF
> +#define             DENALI_PHY_1195_DATA 0x00000000
> +#define             DENALI_PHY_1196_DATA 0x00000000
> +#define             DENALI_PHY_1197_DATA 0x00000000
> +#define             DENALI_PHY_1198_DATA 0x04000000
> +#define             DENALI_PHY_1199_DATA 0x00000000
> +#define             DENALI_PHY_1200_DATA 0x00000000
> +#define             DENALI_PHY_1201_DATA 0x00000108
> +#define             DENALI_PHY_1202_DATA 0x00000000
> +#define             DENALI_PHY_1203_DATA 0x00000000
> +#define             DENALI_PHY_1204_DATA 0x00000000
> +#define             DENALI_PHY_1205_DATA 0x00000001
> +#define             DENALI_PHY_1206_DATA 0x00000000
> +#define             DENALI_PHY_1207_DATA 0x00000000
> +#define             DENALI_PHY_1208_DATA 0x00000000
> +#define             DENALI_PHY_1209_DATA 0x00000000
> +#define             DENALI_PHY_1210_DATA 0x00000000
> +#define             DENALI_PHY_1211_DATA 0x00000000
> +#define             DENALI_PHY_1212_DATA 0x00020100
> +#define             DENALI_PHY_1213_DATA 0x00000000
> +#define             DENALI_PHY_1214_DATA 0x00000000
> diff --git a/board/sifive/fu540/include/spi.h b/board/sifive/fu540/include/spi.h
> new file mode 100644
> index 0000000000..b2b3260333
> --- /dev/null
> +++ b/board/sifive/fu540/include/spi.h
> @@ -0,0 +1,233 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef FU540_SPI_H
> +#define FU540_SPI_H
> +
> +#include <asm/arch/spi.h>
> +
> +#ifndef __ASSEMBLER__
> +
> +#include <stdint.h>
> +#include <linux/types.h>
> +
> +#define _ASSERT_SIZEOF(type, size) _Static_assert(sizeof(type) == (size), # type " must be " # size " bytes wide")
> +
> +typedef union {
> +       struct {
> +               u32 pha      : 1;
> +               u32 pol      : 1;
> +               u32 reserved : 30;
> +       };
> +       u32 raw_bits;
> +} spi_reg_sckmode;
> +_ASSERT_SIZEOF(spi_reg_sckmode, 4);
> +
> +typedef union {
> +       struct {
> +               u32 mode     : 2;
> +               u32 reserved : 30;
> +       };
> +       u32 raw_bits;
> +} spi_reg_csmode;
> +_ASSERT_SIZEOF(spi_reg_csmode, 4);
> +
> +typedef union {
> +       struct {
> +               u32 cssck     : 8;
> +               u32 reserved0 : 8;
> +               u32 sckcs     : 8;
> +               u32 reserved1 : 8;
> +       };
> +       u32 raw_bits;
> +} spi_reg_delay0;
> +_ASSERT_SIZEOF(spi_reg_delay0, 4);
> +
> +typedef union {
> +       struct {
> +               u32 intercs   : 8;
> +               u32 reserved0 : 8;
> +               u32 interxfr  : 8;
> +               u32 reserved1 : 8;
> +       };
> +       u32 raw_bits;
> +} spi_reg_delay1;
> +_ASSERT_SIZEOF(spi_reg_delay1, 4);
> +
> +typedef union {
> +       struct {
> +               u32 proto     : 2;
> +               u32 endian    : 1;
> +               u32 dir       : 1;
> +               u32 reserved0 : 12;
> +               u32 len       : 4;
> +               u32 reserved1 : 12;
> +       };
> +       u32 raw_bits;
> +} spi_reg_fmt;
> +_ASSERT_SIZEOF(spi_reg_fmt, 4);
> +
> +typedef union {
> +       struct {
> +               u32 data     : 8;
> +               u32 reserved : 23;
> +               u32 full     : 1;
> +       };
> +       u32 raw_bits;
> +} spi_reg_txdata;
> +_ASSERT_SIZEOF(spi_reg_txdata, 4);
> +
> +typedef union {
> +       struct {
> +               u32 data     : 8;
> +               u32 reserved : 23;
> +               u32 empty    : 1;
> +       };
> +       u32 raw_bits;
> +} spi_reg_rxdata;
> +_ASSERT_SIZEOF(spi_reg_rxdata, 4);
> +
> +typedef union {
> +       struct {
> +               u32 txmark   : 3;
> +               u32 reserved : 29;
> +       };
> +       u32 raw_bits;
> +} spi_reg_txmark;
> +_ASSERT_SIZEOF(spi_reg_txmark, 4);
> +
> +typedef union {
> +       struct {
> +               u32 rxmark   : 3;
> +               u32 reserved : 29;
> +       };
> +       u32 raw_bits;
> +} spi_reg_rxmark;
> +_ASSERT_SIZEOF(spi_reg_rxmark, 4);
> +
> +typedef union {
> +       struct {
> +               u32 en       : 1;
> +               u32 reserved : 31;
> +       };
> +       u32 raw_bits;
> +} spi_reg_fctrl;
> +_ASSERT_SIZEOF(spi_reg_fctrl, 4);
> +
> +typedef union {
> +       struct {
> +               u32 cmd_en        : 1;
> +               u32 addr_len      : 3;
> +               u32 pad_cnt       : 4;
> +               u32 command_proto : 2;
> +               u32 addr_proto    : 2;
> +               u32 data_proto    : 2;
> +               u32 reserved      : 2;
> +               u32 command_code  : 8;
> +               u32 pad_code      : 8;
> +       };
> +       u32 raw_bits;
> +} spi_reg_ffmt;
> +_ASSERT_SIZEOF(spi_reg_ffmt, 4);
> +
> +typedef union {
> +       struct {
> +               u32 txwm     : 1;
> +               u32 rxwm     : 1;
> +               u32 reserved : 30;
> +       };
> +       u32 raw_bits;
> +} spi_reg_ie;
> +typedef spi_reg_ie spi_reg_ip;
> +_ASSERT_SIZEOF(spi_reg_ie, 4);
> +_ASSERT_SIZEOF(spi_reg_ip, 4);
> +
> +#undef _ASSERT_SIZEOF
> +
> +/*
> + * SPI control register memory map.
> + *
> + * All functions take a pointer to a SPI device's control registers.
> + */
> +typedef volatile struct
> +{
> +       u32        sckdiv;
> +       spi_reg_sckmode sckmode;
> +       u32        reserved08;
> +       u32        reserved0c;
> +
> +       u32        csid;
> +       u32        csdef;
> +       spi_reg_csmode  csmode;
> +       u32        reserved1c;
> +
> +       u32        reserved20;
> +       u32        reserved24;
> +       spi_reg_delay0  delay0;
> +       spi_reg_delay1  delay1;
> +
> +       u32        reserved30;
> +       u32        reserved34;
> +       u32        reserved38;
> +       u32        reserved3c;
> +
> +       spi_reg_fmt     fmt;
> +       u32        reserved44;
> +       spi_reg_txdata  txdata;
> +       spi_reg_rxdata  rxdata;
> +
> +       spi_reg_txmark  txmark;
> +       spi_reg_rxmark  rxmark;
> +       u32        reserved58;
> +       u32        reserved5c;
> +
> +       spi_reg_fctrl   fctrl;
> +       spi_reg_ffmt    ffmt;
> +       u32        reserved68;
> +       u32        reserved6c;
> +
> +       spi_reg_ie      ie;
> +       spi_reg_ip      ip;
> +} spi_ctrl;
> +
> +void spi_tx(spi_ctrl *spictrl, uint8_t in);
> +uint8_t spi_rx(spi_ctrl *spictrl);
> +uint8_t spi_txrx(spi_ctrl *spictrl, uint8_t in);
> +int spi_copy(spi_ctrl *spictrl, void *buf, u32 addr, u32 size);
> +
> +/**
> + * Get smallest clock divisor that divides input_khz to a quotient less than or
> + * equal to max_target_khz;
> + */
> +inline unsigned int spi_min_clk_divisor(unsigned int input_khz, unsigned
> +               int max_target_khz)
> +{
> +       // f_sck = f_in / (2 * (div + 1)) => div = (f_in / (2*f_sck)) - 1
> +       //
> +       // The nearest integer solution for div requires rounding up as to
> +       // not exceed max_target_khz.
> +       //
> +       // div = ceil(f_in / (2*f_sck)) - 1
> +       //     = floor((f_in - 1 + 2*f_sck) / (2*f_sck)) - 1
> +       //
> +       // This should not overflow as long as (f_in - 1 + 2*f_sck) does not
> +       // exceed 2^32 - 1, which is unlikely since we represent frequencies
> +       // in kHz.
> +       unsigned int quotient = (input_khz + 2 * max_target_khz - 1) / (2 *
> +                       max_target_khz);
> +
> +       // Avoid underflow
> +       if (quotient == 0)
> +               return 0;
> +       else
> +               return quotient - 1;
> +}
> +
> +#endif /* !__ASSEMBLER__ */
> +#endif /* FU540_SPI_H */
> diff --git a/board/sifive/fu540/include/uart.h b/board/sifive/fu540/include/uart.h
> new file mode 100644
> index 0000000000..e20dc8a027
> --- /dev/null
> +++ b/board/sifive/fu540/include/uart.h
> @@ -0,0 +1,54 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef FU540_UART_H
> +#define FU540_UART_H
> +
> +#include <asm/arch/uart.h>
> +
> +#ifndef __ASSEMBLER__
> +
> +void uart_putc(void *uartctrl, char c);
> +char uart_getc(void *uartctrl);
> +void uart_puts(void *uartctrl, const char *s);
> +void uart_put_hex(void *uartctrl, uint32_t hex);
> +void uart_put_hex64(void *ua64ctrl, u64 hex);
> +
> +#include <stdint.h>
> +#include <linux/types.h>
> +
> +/*
> + * Get smallest clock divisor that divides input_hz to a quotient less than or
> + * equal to max_target_hz;
> + */
> +static inline unsigned int uart_min_clk_divisor(u64 input_hz, u64 max_target_hz)
> +{
> +       // f_baud = f_in / (div + 1) => div = (f_in / f_baud) - 1
> +       // div = (f_in / f_baud) - 1
> +       //
> +       // The nearest integer solution for div requires rounding up as to not
> +       // exceed max_target_hz.
> +       //
> +       // div = ceil(f_in / f_baud) - 1
> +       //     = floor((f_in - 1 + f_baud) / f_baud) - 1
> +       //
> +       // This should not overflow as long as (f_in - 1 + f_baud) does not
> +       // exceed 2^32 - 1, which is unlikely since we represent frequencies
> +       // in kHz.
> +       u64 quotient = (input_hz + max_target_hz - 1) / (max_target_hz);
> +       // Avoid underflow
> +       if (quotient == 0)
> +               return 0;
> +       else
> +               return quotient - 1;
> +}
> +
> +#endif /* !__ASSEMBLER__ */
> +
> +#endif /* FU540_UART_H */
> diff --git a/board/sifive/fu540/include/ux00ddr.h b/board/sifive/fu540/include/ux00ddr.h
> new file mode 100644
> index 0000000000..f3af3be901
> --- /dev/null
> +++ b/board/sifive/fu540/include/ux00ddr.h
> @@ -0,0 +1,268 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef FU540_UX00DDR_H
> +#define FU540_UX00DDR_H
> +
> +#ifndef __ASSEMBLER__
> +
> +#include <stdint.h>
> +#include <stddef.h>
> +#include <stdbool.h>
> +#include "uart.h"
> +#include "fu540-memory-map.h"
> +
> +#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
> +
> +static inline void phy_reset(volatile u32 *ddrphyreg, const
> +               u32 *physettings)
> +{
> +       unsigned int i;
> +
> +       for (i = 1152; i <= 1214; i++) {
> +               u32 physet = physettings[i];
> +               /*if (physet!=0)*/ ddrphyreg[i] = physet;
> +       }
> +
> +       for (i = 0; i <= 1151; i++) {
> +               u32 physet = physettings[i];
> +               /*if (physet!=0)*/ ddrphyreg[i] = physet;
> +       }
> +}
> +
> +static inline void ux00ddr_writeregmap(size_t ahbregaddr, const
> +               u32 *ctlsettings, const u32 *physettings)
> +{
> +       volatile u32 *ddrctlreg = (volatile u32 *)ahbregaddr;
> +       volatile u32 *ddrphyreg = ((volatile u32 *)ahbregaddr) +
> +               (0x2000 / sizeof(u32));
> +
> +       unsigned int i;
> +
> +       for (i = 0; i <= 264; i++) {
> +               u32 ctlset = ctlsettings[i];
> +               /*if (ctlset!=0)*/ ddrctlreg[i] = ctlset;
> +       }
> +
> +       phy_reset(ddrphyreg, physettings);
> +}
> +
> +static inline void ux00ddr_start(size_t ahbregaddr, size_t filteraddr,
> +                                size_t ddrend)
> +{
> +       // START register at ddrctl register base offset 0
> +       u32 regdata = _REG32(0 << 2, ahbregaddr);
> +
> +       regdata |= 0x1;
> +       _REG32(0 << 2, ahbregaddr) = regdata;
> +       // WAIT for initialization complete : bit 8 of INT_STATUS
> +       // (DENALI_CTL_132) 0x210
> +       while ((_REG32(132 << 2, ahbregaddr) & (1 <<
> +                                       MC_INIT_COMPLETE_OFFSET)) == 0) {
> +       }
> +
> +       // Disable the BusBlocker in front of the controller AXI slave ports
> +       volatile u64 *filterreg = (volatile u64 *)filteraddr;
> +
> +       filterreg[0] = 0x0f00000000000000UL | (ddrend >> 2);
> +       //                ^^ RWX + TOR
> +}
> +
> +static inline void ux00ddr_mask_mc_init_complete_interrupt(size_t
> +               ahbregaddr)
> +{
> +       // Mask off Bit 8 of Interrupt Status
> +       // Bit [8] The MC initialization has been completed
> +       _REG32(136 << 2, ahbregaddr) |= (1 << MC_INIT_COMPLETE_OFFSET);
> +}
> +
> +static inline void ux00ddr_mask_outofrange_interrupts(size_t ahbregaddr)
> +{
> +       // Mask off Bit 8, Bit 2 and Bit 1 of Interrupt Status
> +       // Bit [2] Multiple accesses outside the defined PHYSICAL memory
> +       // space have occurred
> +       // Bit [1] A memory access outside the defined PHYSICAL memory
> +       // space has occurred
> +       _REG32(136 << 2, ahbregaddr) |= ((1 << OUT_OF_RANGE_OFFSET) | (1 <<
> +                               MULTIPLE_OUT_OF_RANGE_OFFSET));
> +}
> +
> +static inline void ux00ddr_mask_port_command_error_interrupt(size_t
> +               ahbregaddr)
> +{
> +       // Mask off Bit 7 of Interrupt Status
> +       // Bit [7] An error occurred on the port command channel
> +       _REG32(136 << 2, ahbregaddr) |= (1 <<
> +                       PORT_COMMAND_CHANNEL_ERROR_OFFSET);
> +}
> +
> +static inline void ux00ddr_mask_leveling_completed_interrupt(size_t
> +               ahbregaddr)
> +{
> +       // Mask off Bit 22 of Interrupt Status
> +       // Bit [22] The leveling operation has completed
> +       _REG32(136 << 2, ahbregaddr) |= (1 <<
> +                       LEVELING_OPERATION_COMPLETED_OFFSET);
> +}
> +
> +static inline void ux00ddr_setuprangeprotection(size_t ahbregaddr, size_t
> +               end_addr)
> +{
> +       _REG32(209 << 2, ahbregaddr) = 0x0;
> +       size_t end_addr_16kblocks = ((end_addr >> 14) & 0x7FFFFF) - 1;
> +
> +       _REG32(210 << 2, ahbregaddr)  = ((u32)end_addr_16kblocks);
> +       _REG32(212 << 2, ahbregaddr)  = 0x0;
> +       _REG32(214 << 2, ahbregaddr)  = 0x0;
> +       _REG32(216 << 2, ahbregaddr)  = 0x0;
> +       _REG32(224 << 2, ahbregaddr) |= (0x3 << AXI0_RANGE_PROT_BITS_0_OFFSET);
> +       _REG32(225 << 2, ahbregaddr)  = 0xFFFFFFFF;
> +       _REG32(208 << 2, ahbregaddr) |= (1 << AXI0_ADDRESS_RANGE_ENABLE);
> +       _REG32(208 << 2, ahbregaddr) |= (1 << PORT_ADDR_PROTECTION_EN_OFFSET);
> +}
> +
> +static inline void ux00ddr_disableaxireadinterleave(size_t ahbregaddr)
> +{
> +       _REG32(120 << 2, ahbregaddr) |= (1 << DISABLE_RD_INTERLEAVE_OFFSET);
> +}
> +
> +static inline void ux00ddr_disableoptimalrmodw(size_t ahbregaddr)
> +{
> +       _REG32(21 << 2, ahbregaddr) &= (~(1 << OPTIMAL_RMODW_EN_OFFSET));
> +}
> +
> +static inline void ux00ddr_enablewriteleveling(size_t ahbregaddr)
> +{
> +       _REG32(170 << 2, ahbregaddr) |= ((1 << WRLVL_EN_OFFSET) | (1 <<
> +                               DFI_PHY_WRLELV_MODE_OFFSET));
> +}
> +
> +static inline void ux00ddr_enablereadleveling(size_t ahbregaddr)
> +{
> +       _REG32(181 << 2, ahbregaddr) |= (1 << DFI_PHY_RDLVL_MODE_OFFSET);
> +       _REG32(260 << 2, ahbregaddr) |= (1 << RDLVL_EN_OFFSET);
> +}
> +
> +static inline void ux00ddr_enablereadlevelinggate(size_t ahbregaddr)
> +{
> +       _REG32(260 << 2, ahbregaddr) |= (1 << RDLVL_GATE_EN_OFFSET);
> +       _REG32(182 << 2, ahbregaddr) |= (1 << DFI_PHY_RDLVL_GATE_MODE_OFFSET);
> +}
> +
> +static inline void ux00ddr_enablevreftraining(size_t ahbregaddr)
> +{
> +       _REG32(184 << 2, ahbregaddr) |= (1 << VREF_EN_OFFSET);
> +}
> +
> +static inline u32 ux00ddr_getdramclass(size_t ahbregaddr)
> +{
> +       return((_REG32(0, ahbregaddr) >> DRAM_CLASS_OFFSET) & 0xF);
> +}
> +
> +static inline u64 ux00ddr_phy_fixup(size_t ahbregaddr)
> +{
> +       // return bitmask of failed lanes
> +
> +       size_t ddrphyreg = ahbregaddr + 0x2000;
> +
> +       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 = _REG32((regbase + reg) << 2,
> +                                               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)
> +                                               uart_puts((void *)
> +                                                         UART0_CTRL_ADDR,
> +                                                         "DDR error in fixing up \n");
> +
> +                                       fails |= (1 << dq);
> +
> +                                       char slicelsc = '0';
> +                                       char slicemsc = '0';
> +
> +                                       slicelsc += (dq % 10);
> +                                       slicemsc += (dq / 10);
> +                                       uart_puts((void *)UART0_CTRL_ADDR,
> +                                                 "S ");
> +                                       uart_puts((void *)UART0_CTRL_ADDR,
> +                                                 &slicemsc);
> +                                       uart_puts((void *)UART0_CTRL_ADDR,
> +                                                 &slicelsc);
> +                                       if (failc0)
> +                                               uart_puts((void *)
> +                                                         UART0_CTRL_ADDR,
> +                                                         "U");
> +                                       else
> +                                               uart_puts((void *)
> +                                                         UART0_CTRL_ADDR,
> +                                                         "D");
> +
> +                                       uart_puts((void *)UART0_CTRL_ADDR,
> +                                                 "\n");
> +                               }
> +                               dq++;
> +                       }
> +               }
> +               slicebase += 128;
> +       }
> +       return(0);
> +}
> +
> +#endif /* __ASSEMBLER__ */
> +
> +#endif /* FU540_UX00DDR_H */
> diff --git a/board/sifive/fu540/include/ux00prci.h b/board/sifive/fu540/include/ux00prci.h
> new file mode 100644
> index 0000000000..21f4aeb465
> --- /dev/null
> +++ b/board/sifive/fu540/include/ux00prci.h
> @@ -0,0 +1,206 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#ifndef _SIFIVE_UX00PRCI_H
> +#define _SIFIVE_UX00PRCI_H
> +
> +/* Register offsets */
> +
> +#define UX00PRCI_HFROSCCFG          (0x0000)
> +#define UX00PRCI_COREPLLCFG         (0x0004)
> +#define UX00PRCI_COREPLLOUT         (0x0008)
> +#define UX00PRCI_DDRPLLCFG          (0x000C)
> +#define UX00PRCI_DDRPLLOUT          (0x0010)
> +#define UX00PRCI_GEMGXLPLLCFG       (0x001C)
> +#define UX00PRCI_GEMGXLPLLOUT       (0x0020)
> +#define UX00PRCI_CORECLKSELREG      (0x0024)
> +#define UX00PRCI_DEVICESRESETREG    (0x0028)
> +#define UX00PRCI_CLKMUXSTATUSREG    (0x002C)
> +#define UX00PRCI_PROCMONCFG         (0x00F0)
> +
> +/* Fields */
> +#define XOSC_EN(x)            (((x) & 0x1) << 30)
> +#define XOSC_RDY(x)           (((x) & 0x1) << 31)
> +
> +#define PLL_R(x)              (((x) & 0x3F) << 0)
> +#define PLL_F(x)              (((x) & 0x1FF) << 6)
> +#define PLL_Q(x)              (((x) & 0x7) << 15)
> +#define PLL_RANGE(x)          (((x) & 0x7) << 18)
> +#define PLL_BYPASS(x)         (((x) & 0x1) << 24)
> +#define PLL_FSE(x)            (((x) & 0x1) << 25)
> +#define PLL_LOCK(x)           (((x) & 0x1) << 31)
> +
> +#define PLLOUT_DIV(x)         (((x) & 0x7F) << 0)
> +#define PLLOUT_DIV_BY_1(x)    (((x) & 0x1) << 8)
> +#define PLLOUT_CLK_EN(x)      (((x) & 0x1) << 31)
> +
> +#define PLL_R_default              0x1
> +#define PLL_F_default              0x1F
> +#define PLL_Q_default              0x3
> +#define PLL_RANGE_default          0x0
> +#define PLL_BYPASS_default         0x1
> +#define PLL_FSE_default            0x1
> +
> +#define PLLOUT_DIV_default         0x0
> +#define PLLOUT_DIV_BY_1_default    0x0
> +#define PLLOUT_CLK_EN_default      0x0
> +
> +#define PLL_CORECLKSEL_HFXIN       0x1
> +#define PLL_CORECLKSEL_COREPLL     0x0
> +
> +#define DEVICESRESET_DDR_CTRL_RST_N(x)    (((x) & 0x1) << 0)
> +#define DEVICESRESET_DDR_AXI_RST_N(x)     (((x) & 0x1) << 1)
> +#define DEVICESRESET_DDR_AHB_RST_N(x)     (((x) & 0x1) << 2)
> +#define DEVICESRESET_DDR_PHY_RST_N(x)     (((x) & 0x1) << 3)
> +#define DEVICESRESET_GEMGXL_RST_N(x)      (((x) & 0x1) << 5)
> +
> +#define CLKMUX_STATUS_CORECLKPLLSEL    (0x1 << 0)
> +#define CLKMUX_STATUS_TLCLKSEL         (0x1 << 1)
> +#define CLKMUX_STATUS_RTCXSEL          (0x1 << 2)
> +#define CLKMUX_STATUS_DDRCTRLCLKSEL    (0x1 << 3)
> +#define CLKMUX_STATUS_DDRPHYCLKSEL     (0x1 << 4)
> +#define CLKMUX_STATUS_GEMGXLCLKSEL     (0x1 << 6)
> +
> +#ifndef __ASSEMBLER__
> +
> +#include <stdint.h>
> +#include <linux/types.h>
> +
> +static inline int ux00prci_select_corepll(volatile u32 *coreclkselreg,
> +                                         volatile u32 *corepllcfg,
> +                                         volatile u32 *corepllout,
> +                                         u32 pllconfigval)
> +{
> +       (*corepllcfg) = pllconfigval;
> +
> +       // Wait for lock
> +       while (((*corepllcfg) & (PLL_LOCK(1))) == 0)
> +               ;
> +
> +       u32 core_out =
> +               (PLLOUT_DIV(PLLOUT_DIV_default)) |
> +               (PLLOUT_DIV_BY_1(PLLOUT_DIV_BY_1_default)) |
> +               (PLLOUT_CLK_EN(1));
> +       (*corepllout) = core_out;
> +
> +       // Set CORECLKSELREG to select COREPLL
> +       (*coreclkselreg) = PLL_CORECLKSEL_COREPLL;
> +
> +       return 0;
> +}
> +
> +static inline int ux00prci_select_corepll_1_4ghz(volatile u32 *coreclkselreg,
> +                                                volatile u32 *corepllcfg,
> +                                                volatile u32 *corepllout)
> +{
> +       //
> +       // CORE pll init
> +       // Set corepll 33MHz -> 1GHz
> +       //
> +
> +       u32 core14ghz =
> +               (PLL_R(0)) |
> +               (PLL_F(41)) |            /*2800MHz VCO*/
> +               (PLL_Q(1)) |             /* /2 Output divider */
> +               (PLL_RANGE(0x4)) |
> +               (PLL_BYPASS(0)) |
> +               (PLL_FSE(1));
> +
> +       return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
> +                                       core14ghz);
> +}
> +
> +static inline int ux00prci_select_corepll_1_5ghz(volatile u32 *coreclkselreg,
> +                                                volatile u32 *corepllcfg,
> +                                                volatile u32 *corepllout)
> +{
> +       //
> +       // CORE pll init
> +       // Set corepll 33MHz -> 1GHz
> +       //
> +
> +       u32 core15ghz =
> +               (PLL_R(0)) |
> +               (PLL_F(44)) |            /*3000MHz VCO*/
> +               (PLL_Q(1)) |             /* /2 Output divider */
> +               (PLL_RANGE(0x4)) |
> +               (PLL_BYPASS(0)) |
> +               (PLL_FSE(1));
> +
> +       return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
> +                                       core15ghz);
> +}
> +
> +static inline int ux00prci_select_corepll_1_6ghz(volatile u32 *coreclkselreg,
> +                                                volatile u32 *corepllcfg,
> +                                                volatile u32 *corepllout)
> +{
> +       //
> +       // CORE pll init
> +       // Set corepll 33MHz -> 1GHz
> +       //
> +
> +       u32 core16ghz =
> +               (PLL_R(0)) |
> +               (PLL_F(47)) |            /*3200MHz VCO*/
> +               (PLL_Q(1)) |             /* /2 Output divider */
> +               (PLL_RANGE(0x4)) |
> +               (PLL_BYPASS(0)) |
> +               (PLL_FSE(1));
> +
> +       return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
> +                                       core16ghz);
> +}
> +
> +static inline int ux00prci_select_corepll_1ghz(volatile u32 *coreclkselreg,
> +                                              volatile u32 *corepllcfg,
> +                                              volatile u32 *corepllout)
> +{
> +       //
> +       // CORE pll init
> +       // Set corepll 33MHz -> 1GHz
> +       //
> +
> +       u32 core1ghz =
> +               (PLL_R(0)) |
> +               (PLL_F(59)) |            /*4000MHz VCO*/
> +               (PLL_Q(2)) |             /* /4 Output divider */
> +               (PLL_RANGE(0x4)) |
> +               (PLL_BYPASS(0)) |
> +               (PLL_FSE(1));
> +
> +       return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
> +                                       core1ghz);
> +}
> +
> +static inline int ux00prci_select_corepll_500mhz(volatile u32 *coreclkselreg,
> +                                                volatile u32 *corepllcfg,
> +                                                volatile u32 *corepllout)
> +{
> +       //
> +       // CORE pll init
> +       // Set corepll 33MHz -> 1GHz
> +       //
> +
> +       u32 core500mhz =
> +               (PLL_R(0)) |
> +               (PLL_F(59)) |            /*4000MHz VCO*/
> +               (PLL_Q(3)) |             /* /8 Output divider */
> +               (PLL_RANGE(0x4)) |
> +               (PLL_BYPASS(0)) |
> +               (PLL_FSE(1));
> +
> +       return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
> +                                       core500mhz);
> +}
> +

Can we reuse the U-Boot PRCI driver for SPL? If not, could we update
it instead of creating another ad-hoc driver?

> +#endif
> +
> +#endif // _SIFIVE_UX00PRCI_H
> diff --git a/board/sifive/fu540/spl.c b/board/sifive/fu540/spl.c
> new file mode 100644
> index 0000000000..69187066ba
> --- /dev/null
> +++ b/board/sifive/fu540/spl.c
> @@ -0,0 +1,321 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#include <common.h>
> +#include <spl.h>
> +
> +#include "include/regconfig-ctl.h"
> +#include "include/regconfig-phy.h"
> +#include "include/ux00ddr.h"
> +#include "include/ddrregs.h"
> +
> +#include "include/fu540-memory-map.h"
> +#include <stdatomic.h>
> +
> +#define ddr_phy_settings DENALI_PHY_DATA
> +#define ddr_ctl_settings DENALI_CTL_DATA
> +
> +#define DDR_SIZE  (8UL * 1024UL * 1024UL * 1024UL)
> +#define DDRCTLPLL_F 55
> +#define DDRCTLPLL_Q 2
> +
> +#define PHY_NRESET 0x1000
> +#define FIRST_SLOT  0xfe
> +#define LAST_SLOT   0x80
> +
> +static const uintptr_t i2c_devices[] = {
> +       I2C_CTRL_ADDR,
> +};
> +
> +static spi_ctrl * const spi_devices[] = {
> +       (spi_ctrl *)SPI0_CTRL_ADDR,
> +       (spi_ctrl *)SPI1_CTRL_ADDR,
> +       (spi_ctrl *)SPI2_CTRL_ADDR,
> +};
> +
> +static const uintptr_t uart_devices[] = {
> +       UART0_CTRL_ADDR,
> +       UART1_CTRL_ADDR,
> +};
> +
> +unsigned int serial_to_burn = ~0;
> +
> +/**
> + * Scale peripheral clock dividers before changing core PLL.
> + */
> +void update_peripheral_clock_dividers(unsigned int peripheral_input_khz)

Are these a must-have? ie: can we have individual device driver (ie:
sifive i2c, or sifive spi driver to do such work in their probe()
routine)?

> +{
> +       unsigned int i2c_target_khz = 400;
> +       u16 prescaler = i2c_min_clk_prescaler(peripheral_input_khz,
> +                                             i2c_target_khz);
> +
> +       for (size_t i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
> +               _REG32(i2c_devices[i], I2C_PRESCALER_LO) = prescaler & 0xff;
> +               _REG32(i2c_devices[i], I2C_PRESCALER_HI) = (prescaler >> 8) &
> +                                                          0xff;
> +       }
> +
> +       unsigned int spi_target_khz = 50000;
> +       unsigned int spi_div = spi_min_clk_divisor(peripheral_input_khz,
> +                                                  spi_target_khz);
> +
> +       for (size_t i = 0; i < ARRAY_SIZE(spi_devices); i++)
> +               spi_devices[i]->sckdiv = spi_div;
> +
> +       unsigned int uart_target_hz = 115200ULL;
> +       unsigned int uart_div = uart_min_clk_divisor(peripheral_input_khz *
> +                                                    1000ULL, uart_target_hz);
> +
> +       for (size_t i = 0; i < ARRAY_SIZE(uart_devices); i++)
> +               _REG32(uart_devices[i], UART_REG_DIV) = uart_div;
> +}
> +
> +long nsec_per_cyc = 300; // 33.333MHz
> +void nsleep(long nsec)
> +{
> +       long step = nsec_per_cyc * 2; // 2 instructions per loop iteration
> +
> +       while (nsec > 0)
> +               nsec -= step;
> +}
> +
> +void init_clk_and_ddr(void)
> +{
> +       // PRCI init
> +
> +       // Initialize UART divider for 33MHz core clock in case if
> +       // trap is taken prior to core clock bump.
> +       unsigned long long uart_target_hz = 115200ULL;
> +       const u32 initial_core_clk_khz = 33000;
> +       unsigned long peripheral_input_khz;
> +
> +       if (UX00PRCI_REG(UX00PRCI_CLKMUXSTATUSREG) & CLKMUX_STATUS_TLCLKSEL)
> +               peripheral_input_khz = initial_core_clk_khz;
> +       else
> +               peripheral_input_khz = initial_core_clk_khz / 2;
> +       UART0_REG(UART_REG_DIV) = uart_min_clk_divisor(peripheral_input_khz *
> +                                                      1000ULL, uart_target_hz);
> +
> +       // Check Reset Values (lock don't care)
> +       u32 pll_default =
> +               (PLL_R(PLL_R_default)) |
> +               (PLL_F(PLL_F_default)) |
> +               (PLL_Q(PLL_Q_default)) |
> +               (PLL_RANGE(PLL_RANGE_default)) |
> +               (PLL_BYPASS(PLL_BYPASS_default)) |
> +               (PLL_FSE(PLL_FSE_default));
> +       u32 lockmask = ~PLL_LOCK(1);
> +       u32 pllout_default =
> +               (PLLOUT_DIV(PLLOUT_DIV_default)) |
> +               (PLLOUT_DIV_BY_1(PLLOUT_DIV_BY_1_default)) |
> +               (PLLOUT_CLK_EN(PLLOUT_CLK_EN_default));
> +
> +       if ((UX00PRCI_REG(UX00PRCI_COREPLLCFG)     ^ pll_default) & lockmask)
> +               return;
> +       if ((UX00PRCI_REG(UX00PRCI_COREPLLOUT)     ^ pllout_default))
> +               return;
> +       if ((UX00PRCI_REG(UX00PRCI_DDRPLLCFG)      ^ pll_default) & lockmask)
> +               return;
> +       if ((UX00PRCI_REG(UX00PRCI_DDRPLLOUT)      ^ pllout_default))
> +               return;
> +       if (((UX00PRCI_REG(UX00PRCI_GEMGXLPLLCFG)) ^ pll_default) & lockmask)
> +               return;
> +       if (((UX00PRCI_REG(UX00PRCI_GEMGXLPLLOUT)) ^ pllout_default))
> +               return;
> +
> +       //CORE pll init
> +       // If tlclksel is set for 2:1 operation,
> +       // Set corepll 33Mhz -> 1GHz
> +       // Otherwise, set corepll 33MHz -> 500MHz.
> +
> +       if (UX00PRCI_REG(UX00PRCI_CLKMUXSTATUSREG) & CLKMUX_STATUS_TLCLKSEL) {
> +               nsec_per_cyc = 2;
> +               peripheral_input_khz = 500000; // peripheral_clk = tlclk
> +               update_peripheral_clock_dividers(peripheral_input_khz);
> +               ux00prci_select_corepll_500mhz
> +                       (&UX00PRCI_REG(UX00PRCI_CORECLKSELREG),
> +                        &UX00PRCI_REG(UX00PRCI_COREPLLCFG),
> +                        &UX00PRCI_REG(UX00PRCI_COREPLLOUT));
> +       } else {
> +               nsec_per_cyc = 1;
> +               peripheral_input_khz = (1000000 / 2); // peripheral_clk = tlclk
> +               update_peripheral_clock_dividers(peripheral_input_khz);
> +
> +               ux00prci_select_corepll_1ghz
> +                       (&UX00PRCI_REG(UX00PRCI_CORECLKSELREG),
> +                        &UX00PRCI_REG(UX00PRCI_COREPLLCFG),
> +                        &UX00PRCI_REG(UX00PRCI_COREPLLOUT));
> +       }
> +
> +       //
> +       //DDR init
> +       //
> +
> +       u32 ddrctlmhz =
> +               (PLL_R(0)) |
> +               (PLL_F(DDRCTLPLL_F)) |
> +               (PLL_Q(DDRCTLPLL_Q)) |
> +               (PLL_RANGE(0x4)) |
> +               (PLL_BYPASS(0)) |
> +               (PLL_FSE(1));
> +       UX00PRCI_REG(UX00PRCI_DDRPLLCFG) = ddrctlmhz;
> +
> +       // Wait for lock
> +       while ((UX00PRCI_REG(UX00PRCI_DDRPLLCFG) & PLL_LOCK(1)) == 0)
> +               ;
> +
> +       u32 ddrctl_out =
> +               (PLLOUT_DIV(PLLOUT_DIV_default)) |
> +               (PLLOUT_DIV_BY_1(PLLOUT_DIV_BY_1_default)) |
> +               (PLLOUT_CLK_EN(1));
> +       (UX00PRCI_REG(UX00PRCI_DDRPLLOUT)) = ddrctl_out;
> +
> +       //Release DDR reset.
> +       UX00PRCI_REG(UX00PRCI_DEVICESRESETREG) |=
> +               DEVICESRESET_DDR_CTRL_RST_N(1);
> +
> +       // HACK to get the '1 full controller clock cycle'.
> +       asm volatile ("fence");
> +       UX00PRCI_REG(UX00PRCI_DEVICESRESETREG) |= DEVICESRESET_DDR_AXI_RST_N(1)
> +              | DEVICESRESET_DDR_AHB_RST_N(1) | DEVICESRESET_DDR_PHY_RST_N(1);
> +       // 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");
> +
> +       ux00ddr_writeregmap(UX00DDR_CTRL_ADDR, ddr_ctl_settings,
> +                           ddr_phy_settings);
> +       ux00ddr_disableaxireadinterleave(UX00DDR_CTRL_ADDR);
> +
> +       ux00ddr_disableoptimalrmodw(UX00DDR_CTRL_ADDR);
> +
> +       ux00ddr_enablewriteleveling(UX00DDR_CTRL_ADDR);
> +       ux00ddr_enablereadleveling(UX00DDR_CTRL_ADDR);
> +       ux00ddr_enablereadlevelinggate(UX00DDR_CTRL_ADDR);
> +       if (ux00ddr_getdramclass(UX00DDR_CTRL_ADDR) == DRAM_CLASS_DDR4)
> +               ux00ddr_enablevreftraining(UX00DDR_CTRL_ADDR);
> +       //mask off interrupts for leveling completion
> +       ux00ddr_mask_leveling_completed_interrupt(UX00DDR_CTRL_ADDR);
> +
> +       ux00ddr_mask_mc_init_complete_interrupt(UX00DDR_CTRL_ADDR);
> +       ux00ddr_mask_outofrange_interrupts(UX00DDR_CTRL_ADDR);
> +       ux00ddr_setuprangeprotection(UX00DDR_CTRL_ADDR, DDR_SIZE);
> +       ux00ddr_mask_port_command_error_interrupt(UX00DDR_CTRL_ADDR);
> +
> +       const u64 ddr_size = DDR_SIZE;
> +       const u64 ddr_end = CONFIG_SYS_SDRAM_BASE + ddr_size;
> +
> +       ux00ddr_start(UX00DDR_CTRL_ADDR, PHYSICAL_FILTER_CTRL_ADDR, ddr_end);
> +       ux00ddr_phy_fixup(UX00DDR_CTRL_ADDR);
> +
> +       //
> +       //GEMGXL init
> +       //
> +       u32 gemgxl125mhz =
> +               (PLL_R(0)) |
> +               (PLL_F(59)) |  /*4000Mhz VCO*/
> +               (PLL_Q(5)) |   /* /32 */
> +               (PLL_RANGE(0x4)) |
> +               (PLL_BYPASS(0)) |
> +               (PLL_FSE(1));
> +       UX00PRCI_REG(UX00PRCI_GEMGXLPLLCFG) = gemgxl125mhz;
> +
> +       // Wait for lock
> +       while ((UX00PRCI_REG(UX00PRCI_GEMGXLPLLCFG) & PLL_LOCK(1)) == 0)
> +               ;
> +
> +       u32 gemgxlctl_out =
> +               (PLLOUT_DIV(PLLOUT_DIV_default)) |
> +               (PLLOUT_DIV_BY_1(PLLOUT_DIV_BY_1_default)) |
> +               (PLLOUT_CLK_EN(1));
> +       UX00PRCI_REG(UX00PRCI_GEMGXLPLLOUT) = gemgxlctl_out;
> +
> +       //Release GEMGXL reset (set bit DEVICESRESET_GEMGXL to 1)
> +       UX00PRCI_REG(UX00PRCI_DEVICESRESETREG) |= DEVICESRESET_GEMGXL_RST_N(1);
> +
> +       // VSC8541 PHY reset sequence; leave pull-down active for 2ms
> +       nsleep(2000000);
> +       // Set GPIO 12 (PHY NRESET) to OE=1 and OVAL=1
> +       atomic_fetch_or(&GPIO_REG(GPIO_OUTPUT_VAL), PHY_NRESET);
> +       atomic_fetch_or(&GPIO_REG(GPIO_OUTPUT_EN),  PHY_NRESET);
> +       nsleep(100);
> +
> +       // Procmon => core clock
> +       UX00PRCI_REG(UX00PRCI_PROCMONCFG) = 0x1 << 24;
> +
> +       // Post the serial number and build info
> +       UART0_REG(UART_REG_TXCTRL) = UART_TXEN;
> +       puts("\r\nPRCI Initialized:       ");
> +
> +       unsigned int serial = ~0;
> +       int serial_slot;
> +       unsigned int pos;
> +       unsigned int neg;
> +
> +       ememory_otp_power_up_sequence();
> +       ememory_otp_begin_read();
> +       for (serial_slot = FIRST_SLOT; serial_slot >= LAST_SLOT;
> +                       serial_slot -= 2) {
> +               pos = ememory_otp_read(serial_slot);
> +               neg = ememory_otp_read(serial_slot + 1);
> +               serial = pos;
> +               if (pos == ~neg)
> +                       break; // legal serial #
> +               if (pos == ~0 && neg == ~0)
> +                       break; // empty slot encountered
> +       }
> +       ememory_otp_exit_read();
> +
> +       void *uart = (void *)UART0_CTRL_ADDR;
> +
> +       uart_puts(uart, "\r\nHiFive-U serial #: ");
> +       uart_put_hex(uart, serial);

I don't this we really need this.

> +
> +       // Program the OTP?
> +       if (serial_to_burn != ~0 && serial != serial_to_burn &&
> +           serial_slot > LAST_SLOT) {
> +               uart_puts(uart, "Programming serial: ");
> +               uart_put_hex(uart, serial_to_burn);
> +               uart_puts(uart, "\r\n");
> +               ememory_otp_pgm_entry();
> +               if (serial != ~0) {
> +                       // erase the current serial
> +                       uart_puts(uart, "Erasing prior serial\r\n");
> +                       ememory_otp_pgm_access(serial_slot,   0);
> +                       ememory_otp_pgm_access(serial_slot + 1, 0);
> +                       serial_slot -= 2;
> +               }
> +               ememory_otp_pgm_access(serial_slot,    serial_to_burn);
> +               ememory_otp_pgm_access(serial_slot + 1, ~serial_to_burn);
> +               ememory_otp_pgm_exit();
> +               uart_puts(uart, "Resuming boot\r\n");
> +               serial = serial_to_burn;
> +       }
> +
> +       ememory_otp_power_down_sequence();
> +       uart_puts(uart, "\r\n");
> +}
> +
> +void board_init_f(ulong dummy)
> +{
> +       int ret;
> +
> +       init_clk_and_ddr();
> +
> +       ret = spl_early_init();
> +       if (ret)
> +               panic("spl_early_init() failed: %d\n", ret);
> +
> +       arch_cpu_init_dm();
> +
> +       preloader_console_init();
> +}
> diff --git a/board/sifive/fu540/uart.c b/board/sifive/fu540/uart.c
> new file mode 100644
> index 0000000000..d16f6add47
> --- /dev/null
> +++ b/board/sifive/fu540/uart.c

Can we drop this, instead use the sifive uart driver directory?

> @@ -0,0 +1,64 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2019 SiFive, Inc
> + *
> + * Authors:
> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
> + */
> +
> +#include <stdatomic.h>
> +#include "include/fu540-memory-map.h"
> +#include "include/uart.h"
> +
> +void uart_putc(void *uartctrl, char c)
> +{
> +#if __riscv_atomic
> +       s32 r;
> +
> +       do {
> +               asm volatile ("amoor.w %0, %2, %1\n" : "=r" (r),
> +                             "+A" (_REG32(uartctrl, UART_REG_TXFIFO))
> +                             : "r" (c)
> +                            );
> +       } while (r < 0);
> +#else
> +       while ((int)_REG32(uartctrl, UART_REG_TXFIFO) < 0)
> +               ;
> +       _REG32(uartctrl, UART_REG_TXFIFO) = c;
> +#endif
> +}
> +
> +char uart_getc(void *uartctrl)
> +{
> +       s32 val = -1;
> +
> +       while (val < 0)
> +               val = (s32)_REG32(uartctrl, UART_REG_RXFIFO);
> +
> +       return val & 0xFF;
> +}
> +
> +void uart_puts(void *uartctrl, const char *s)
> +{
> +       while (*s != '\0')
> +               uart_putc(uartctrl, *s++);
> +}
> +
> +void uart_put_hex(void *uartctrl, u32 hex)
> +{
> +       int num_nibbles = sizeof(hex) * 2;
> +
> +       for (int nibble_idx = num_nibbles - 1; nibble_idx >= 0; nibble_idx--) {
> +               char nibble = (hex >> (nibble_idx * 4)) & 0xf;
> +
> +               uart_putc(uartctrl, (nibble < 0xa) ? ('0' + nibble) :
> +                         ('a' + nibble - 0xa));
> +       }
> +}
> +
> +void uart_put_hex64(void *uartctrl, uint64_t hex)
> +{
> +       uart_put_hex(uartctrl, hex >> 32);
> +       uart_put_hex(uartctrl, hex & 0xFFFFFFFF);
> +}
> diff --git a/configs/sifive_fu540_spl_defconfig b/configs/sifive_fu540_spl_defconfig
> new file mode 100644
> index 0000000000..6f9a70ee3e
> --- /dev/null
> +++ b/configs/sifive_fu540_spl_defconfig
> @@ -0,0 +1,23 @@
> +CONFIG_RISCV=y
> +CONFIG_ENV_SIZE=0x20000
> +CONFIG_NR_DRAM_BANKS=1
> +CONFIG_TARGET_SIFIVE_FU540=y
> +CONFIG_ARCH_RV64I=y
> +CONFIG_RISCV_SMODE=y
> +CONFIG_DISTRO_DEFAULTS=y
> +CONFIG_FIT=y
> +CONFIG_MISC_INIT_R=y
> +CONFIG_DEFAULT_DEVICE_TREE="hifive-unleashed-a00"
> +CONFIG_DISPLAY_CPUINFO=y
> +CONFIG_DISPLAY_BOARDINFO=y
> +CONFIG_OF_SEPARATE=y
> +CONFIG_SPL_SEPARATE_BSS=y
> +CONFIG_SYS_RELOC_GD_ENV_ADDR=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"
> diff --git a/include/configs/sifive-fu540.h b/include/configs/sifive-fu540.h
> index 2756ed5a77..5afc7ddb66 100644
> --- a/include/configs/sifive-fu540.h
> +++ b/include/configs/sifive-fu540.h
> @@ -11,6 +11,21 @@
>
>  #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 +39,7 @@
>
>  /* Environment options */
>
> +#ifndef CONFIG_SPL_BUILD
>  #define BOOT_TARGET_DEVICES(func) \
>         func(MMC, mmc, 0) \
>         func(DHCP, dhcp, na)
> @@ -43,5 +59,6 @@
>  #define CONFIG_PREBOOT \
>         "setenv fdt_addr ${fdtcontroladdr};" \
>         "fdt addr ${fdtcontroladdr};"
> +#endif
>
>  #endif /* __CONFIG_H */
> diff --git a/lib/Makefile b/lib/Makefile
> index 1fb650cd90..2d88c2ab5e 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -76,6 +76,7 @@ endif
>
>  ifdef CONFIG_SPL_BUILD
>  obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o
> +obj-$(CONFIG_MMC_SPI) += crc7.o
>  obj-$(CONFIG_$(SPL_TPL_)HASH_SUPPORT) += crc16.o
>  obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o
>  endif

One generic comment, the style in this patch is not aligned with U-Boot's.

Regards,
Bin

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

* [PATCH 1/3] riscv: Add place-holder for FU540 clk and gpio
  2020-01-03 14:47   ` Bin Meng
@ 2020-01-06  9:07     ` Pragnesh Patel
  0 siblings, 0 replies; 19+ messages in thread
From: Pragnesh Patel @ 2020-01-06  9:07 UTC (permalink / raw)
  To: u-boot

>-----Original Message-----
>From: Bin Meng <bmeng.cn@gmail.com>
>Sent: 03 January 2020 20:18
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Rick Chen
><rick@andestech.com>; Paul Walmsley ( Sifive) <paul.walmsley@sifive.com>;
>Palmer Dabbelt ( Sifive) <palmer@sifive.com>; Anup Patel
><anup.patel@wdc.com>; Atish Patra <atish.patra@wdc.com>; Sagar Kadam
><sagar.kadam@sifive.com>
>Subject: Re: [PATCH 1/3] riscv: Add place-holder for FU540 clk and gpio
>
>Hi Pragnesh,
>
>On Tue, Dec 31, 2019 at 2:31 PM Pragnesh Patel <pragnesh.patel@sifive.com>
>wrote:
>>
>> Added FU540 place-holder so that SoC specific values will be kept
>> here.
>
>It looks only clk.h is the placer-holder. gpio.h is not.
>
>Can you please split the gpio.h changes to another patch?

Sure, I will do this in v2 patch.

>
>>
>> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
>> ---
>>  arch/riscv/include/asm/arch-fu540/clk.h    | 14 ++++++++
>>  arch/riscv/include/asm/arch-fu540/gpio.h   | 42 ++++++++++++++++++++++
>>  arch/riscv/include/asm/arch-generic/gpio.h | 32 ++---------------
>>  board/sifive/fu540/Kconfig                 |  3 ++
>>  4 files changed, 62 insertions(+), 29 deletions(-)  create mode
>> 100644 arch/riscv/include/asm/arch-fu540/clk.h
>>  create mode 100644 arch/riscv/include/asm/arch-fu540/gpio.h
>>
>> diff --git a/arch/riscv/include/asm/arch-fu540/clk.h
>> b/arch/riscv/include/asm/arch-fu540/clk.h
>> new file mode 100644
>> index 0000000000..b39f5b55c9
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/arch-fu540/clk.h
>> @@ -0,0 +1,14 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (c) 2019 SiFive, Inc.
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + */
>> +
>> +#ifndef _CLK_FU540_H
>> +#define _CLK_FU540_H
>> +
>> +/* Note: This is a placeholder header for driver compilation. */
>> +
>> +#endif
>> diff --git a/arch/riscv/include/asm/arch-fu540/gpio.h
>> b/arch/riscv/include/asm/arch-fu540/gpio.h
>
>It looks this file is a copy of
>arch/riscv/include/asm/arch-generic/gpio.h. Can you explain this a little bit?

arch-generic/gpio.h contains register information which is specific for FU540, so I moved
the gpio.h from "arch-generic" to "arch-fu540".

I have added arch/riscv/include/asm/arch-fu540/ directory that will contain
FU540 related header files and arch/riscv/include/asm/arch-generic/ will contain
generic riscv header files.

Earlier SYS_SOC for FU540 was not defined, so drivers used  "arch-generic" header files which
I feel can be changed to "arch-fu540".

>
>> new file mode 100644
>> index 0000000000..f8ddd75852
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/arch-fu540/gpio.h
>> @@ -0,0 +1,42 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (C) 2019 SiFive, Inc.
>> + *
>> + * Authors:
>> + *   Sagar Shrikant Kadam <sagar.kadam@sifive.com>
>> + */
>> +
>> +#ifndef _GPIO_FU540_H
>> +#define _GPIO_FU540_H
>> +
>> +#define GPIO_INPUT_VAL  (0x00)
>> +#define GPIO_INPUT_EN   (0x04)
>> +#define GPIO_OUTPUT_EN  (0x08)
>> +#define GPIO_OUTPUT_VAL (0x0C)
>> +#define GPIO_PULLUP_EN  (0x10)
>> +#define GPIO_DRIVE      (0x14)
>> +#define GPIO_RISE_IE    (0x18)
>> +#define GPIO_RISE_IP    (0x1C)
>> +#define GPIO_FALL_IE    (0x20)
>> +#define GPIO_FALL_IP    (0x24)
>> +#define GPIO_HIGH_IE    (0x28)
>> +#define GPIO_HIGH_IP    (0x2C)
>> +#define GPIO_LOW_IE     (0x30)
>> +#define GPIO_LOW_IP     (0x34)
>> +#define GPIO_IOF_EN     (0x38)
>> +#define GPIO_IOF_SEL    (0x3C)
>> +#define GPIO_OUTPUT_XOR    (0x40)
>> +
>> +#define NR_GPIOS       16
>> +
>> +enum gpio_state {
>> +       LOW,
>> +       HIGH
>> +};
>> +
>> +/* Details about a GPIO bank */
>> +struct sifive_gpio_platdata {
>> +       void *base;     /* address of registers in physical memory */
>> +};
>> +
>> +#endif /* _GPIO_FU540_H */
>> diff --git a/arch/riscv/include/asm/arch-generic/gpio.h
>> b/arch/riscv/include/asm/arch-generic/gpio.h
>> index dfcb753051..5f0dc0a801 100644
>> --- a/arch/riscv/include/asm/arch-generic/gpio.h
>> +++ b/arch/riscv/include/asm/arch-generic/gpio.h
>> @@ -3,33 +3,7 @@
>>   * Copyright (C) 2019 SiFive, Inc.
>>   */
>>
>> -#ifndef _GPIO_SIFIVE_H
>> -#define _GPIO_SIFIVE_H
>> +#ifndef __ASM_RISCV_ARCH_GPIO_H
>> +#define __ASM_RISCV_ARCH_GPIO_H
>>
>> -#define GPIO_INPUT_VAL 0x00
>> -#define GPIO_INPUT_EN  0x04
>> -#define GPIO_OUTPUT_EN 0x08
>> -#define GPIO_OUTPUT_VAL        0x0C
>> -#define GPIO_RISE_IE   0x18
>> -#define GPIO_RISE_IP   0x1C
>> -#define GPIO_FALL_IE   0x20
>> -#define GPIO_FALL_IP   0x24
>> -#define GPIO_HIGH_IE   0x28
>> -#define GPIO_HIGH_IP   0x2C
>> -#define GPIO_LOW_IE    0x30
>> -#define GPIO_LOW_IP    0x34
>> -#define GPIO_OUTPUT_XOR        0x40
>> -
>> -#define NR_GPIOS       16
>> -
>> -enum gpio_state {
>> -       LOW,
>> -       HIGH
>> -};
>> -
>> -/* Details about a GPIO bank */
>> -struct sifive_gpio_platdata {
>> -       void *base;     /* address of registers in physical memory */
>> -};
>> -
>> -#endif /* _GPIO_SIFIVE_H */
>> +#endif /* __ASM_RISCV_ARCH_GPIO_H */
>> diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
>> index 5ca21474de..816a135b21 100644
>> --- a/board/sifive/fu540/Kconfig
>> +++ b/board/sifive/fu540/Kconfig
>> @@ -12,6 +12,9 @@ config SYS_CPU
>>  config SYS_CONFIG_NAME
>>         default "sifive-fu540"
>>
>> +config SYS_SOC
>> +       default "fu540"
>
>What about SYS_CPU?
>
>Shouldn't we just rename SYS_CPU to SYS_SOC in this file and assign "fu540"
>to it?

No, I am not planning to change SYS_CPU to "fu540" because Same discussion
happened earlier, you can check here

http://u-boot.10912.n7.nabble.com/PATCH-sifive-riscv-streamline-HiFive-Unleashed-configuration-infrastructure-td379038.html

I have added SYS_SOC to "fu540" because arch-generic should not include
FU540 specific headers.
 
>
>> +
>>  config SYS_TEXT_BASE
>>         default 0x80000000 if !RISCV_SMODE
>>         default 0x80200000 if RISCV_SMODE
>> --
>
>Regards,
>Bin

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

* [PATCH 2/3] riscv: Add FU540 specific includes
  2020-01-03 14:51   ` Bin Meng
@ 2020-01-06  9:41     ` Pragnesh Patel
  0 siblings, 0 replies; 19+ messages in thread
From: Pragnesh Patel @ 2020-01-06  9:41 UTC (permalink / raw)
  To: u-boot

>-----Original Message-----
>From: Bin Meng <bmeng.cn@gmail.com>
>Sent: 03 January 2020 20:22
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot Mailing List <u-boot@lists.denx.de>
>Subject: Re: [PATCH 2/3] riscv: Add FU540 specific includes
>
>Hi Pragnesh,
>
>On Tue, Dec 31, 2019 at 10:00 PM Pragnesh Patel
><pragnesh.patel@sifive.com> wrote:
>>
>> Added headers needed by upcoming SPL support of FU540.
>>
>> This headers are leveraged from FSBL
>> (https://github.com/sifive/freedom-u540-c000-bootloader.git)
>>
>> Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
>> ---
>>  arch/riscv/include/asm/arch-fu540/cache.h | 43 ++++++++++++
>> arch/riscv/include/asm/arch-fu540/clint.h | 20 ++++++
>>  arch/riscv/include/asm/arch-fu540/i2c.h   | 48 +++++++++++++
>>  arch/riscv/include/asm/arch-fu540/otp.h   | 80 +++++++++++++++++++++
>>  arch/riscv/include/asm/arch-fu540/spi.h   | 86 +++++++++++++++++++++++
>>  arch/riscv/include/asm/arch-fu540/uart.h  | 35 +++++++++
>>  6 files changed, 312 insertions(+)
>>  create mode 100644 arch/riscv/include/asm/arch-fu540/cache.h
>>  create mode 100644 arch/riscv/include/asm/arch-fu540/clint.h
>>  create mode 100644 arch/riscv/include/asm/arch-fu540/i2c.h
>>  create mode 100644 arch/riscv/include/asm/arch-fu540/otp.h
>>  create mode 100644 arch/riscv/include/asm/arch-fu540/spi.h
>>  create mode 100644 arch/riscv/include/asm/arch-fu540/uart.h
>>
>> diff --git a/arch/riscv/include/asm/arch-fu540/cache.h
>> b/arch/riscv/include/asm/arch-fu540/cache.h
>> new file mode 100644
>> index 0000000000..9043779650
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/arch-fu540/cache.h
>> @@ -0,0 +1,43 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (C) 2019 SiFive, Inc.
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +
>> +#ifndef _CACHE_FU540_H
>> +#define _CACHE_FU540_H
>> +
>> +/* Register offsets */
>> +#define CCACHE_INFO         0x000
>> +#define CCACHE_ENABLE       0x008
>> +#define CCACHE_INJECT       0x040
>> +#define CCACHE_META_FIX     0x100
>> +#define CCACHE_DATA_FIX     0x140
>> +#define CCACHE_DATA_FAIL    0x160
>> +#define CCACHE_FLUSH64      0x200
>> +#define CCACHE_FLUSH32      0x240
>> +#define CCACHE_WAYS         0x800
>> +
>> +/* Bytes inside the INFO field */
>> +#define CCACHE_INFO_BANKS           0
>> +#define CCACHE_INFO_WAYS            1
>> +#define CCACHE_INFO_LG_SETS         2
>> +#define CCACHE_INFO_LG_BLOCKBYTES   3
>> +
>> +/* INJECT types */
>> +#define CCACHE_ECC_TOGGLE_DATA  0x00000 #define
>> +CCACHE_ECC_TOGGLE_META  0x10000
>> +
>> +/* Offsets per FIX/FAIL */
>> +#define CCACHE_ECC_ADDR     0x0
>> +#define CCACHE_ECC_COUNT    0x8
>> +
>> +/* Interrupt Number offsets from Base */
>> +#define CCACHE_INT_META_FIX     0
>> +#define CCACHE_INT_DATA_FIX     1
>> +#define CCACHE_INT_DATA_FAIL    2
>> +
>> +#endif /* _CACHE_FU540_H */
>> diff --git a/arch/riscv/include/asm/arch-fu540/clint.h
>> b/arch/riscv/include/asm/arch-fu540/clint.h
>> new file mode 100644
>> index 0000000000..f740f30f2d
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/arch-fu540/clint.h
>> @@ -0,0 +1,20 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (C) 2019 SiFive, Inc.
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +
>> +#ifndef _CLINT_FU540_H
>> +#define _CLINT_FU540_H
>> +
>> +#define CLINT_MSIP 0x0000
>> +#define CLINT_MSIP_size   0x4
>> +#define CLINT_MTIMECMP 0x4000
>> +#define CLINT_MTIMECMP_size 0x8
>> +#define CLINT_MTIME 0xBFF8
>> +#define CLINT_MTIME_size 0x8
>> +
>
>nits: please have the value indented

I will update this in v2, thanks for the review.

>
>> +#endif /* _CLINT_FU540_H */
>> diff --git a/arch/riscv/include/asm/arch-fu540/i2c.h
>> b/arch/riscv/include/asm/arch-fu540/i2c.h
>> new file mode 100644
>> index 0000000000..66cc3edd94
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/arch-fu540/i2c.h
>> @@ -0,0 +1,48 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (C) 2019 SiFive, Inc.
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +
>> +#ifndef _I2C_FU540_H
>> +#define _I2C_FU540_H
>> +
>> +// CHECK: word vs byte alignment
>> +// OC I2C Linux driver defines registers w/o alignment:
>> +//
>> +http://lxr.free-electrons.com/source/drivers/i2c/busses/i2c-ocores.c?
>> +v=4.6#L46
>> +//
>> +// However, register accessor functions use reg_shift value //
>> +http://lxr.free-electrons.com/source/drivers/i2c/busses/i2c-ocores.c?
>> +v=4.6#L80
>> +// which is platform specific:
>> +//
>> +http://lxr.free-electrons.com/source/drivers/i2c/busses/i2c-ocores.c?
>> +v=4.6#L346
>
>nits: please use /* */ for the comment format

Update in v2.

>
>> +
>> +#define I2C_PRESCALER_LO  (0x00)
>> +#define I2C_PRESCALER_HI  (0x04)
>> +#define I2C_CONTROL       (0x08)
>> +#define I2C_DATA          (0x0C)
>> +#define I2C_CMD           (0x10) /* write only */
>> +#define I2C_STATUS        (0x10) /* read only, same address as I2C_CMD */
>> +
>> +// I2C_CONTROL register
>> +#define I2C_CONTROL_CORE_EN(x)  (((x) & 0x1) << 7)
>> +#define I2C_CONTROL_INT_EN(x)   (((x) & 0x1) << 6)
>> +
>> +// I2C_CMD register
>> +#define I2C_CMD_START(x)              (((x) & 0x1) << 7)
>> +#define I2C_CMD_STOP(x)               (((x) & 0x1) << 6)
>> +#define I2C_CMD_READ(x)               (((x) & 0x1) << 5)
>> +#define I2C_CMD_WRITE(x)              (((x) & 0x1) << 4)
>> +#define I2C_CMD_NACK(x)               (((x) & 0x1) << 3)
>> +#define I2C_CMD_IRQ_ACK(x)            (((x) & 0x1))
>> +
>> +// I2C_STATUS register
>> +#define I2C_STATUS_RECEIVED_NACK(x)   (((x) & 0x80) >> 7)
>> +#define I2C_STATUS_BUSY(x)            (((x) & 0x40) >> 6)
>> +#define I2C_STATUS_ARB_LOST(x)        (((x) & 0x20) >> 5)
>> +#define I2C_STATUS_TRS_INPROGRESS(x)  (((x) & 0x02) >> 1)
>> +#define I2C_STATUS_IRQ_FLAG(x)        (((x) & 0x01))
>> +
>> +#endif /* _I2C_FU540_H */
>> diff --git a/arch/riscv/include/asm/arch-fu540/otp.h
>> b/arch/riscv/include/asm/arch-fu540/otp.h
>> new file mode 100644
>> index 0000000000..588e525765
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/arch-fu540/otp.h
>> @@ -0,0 +1,80 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (C) 2019 SiFive, Inc.
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +
>> +#ifndef _OTP_FU540_H
>> +#define _OTP_FU540_H
>> +
>> +/* Register offsets */
>> +
>> +#define EMEMORYOTP_PA                 0x00
>> +#define EMEMORYOTP_PAIO               0x04
>> +#define EMEMORYOTP_PAS                0x08
>> +#define EMEMORYOTP_PCE                0x0C
>> +#define EMEMORYOTP_PCLK               0x10
>> +#define EMEMORYOTP_PDIN               0x14
>> +#define EMEMORYOTP_PDOUT              0x18
>> +#define EMEMORYOTP_PDSTB              0x1C
>> +#define EMEMORYOTP_PPROG              0x20
>> +#define EMEMORYOTP_PTC                0x24
>> +#define EMEMORYOTP_PTM                0x28
>> +#define EMEMORYOTP_PTM_REP            0x2C
>> +#define EMEMORYOTP_PTR                0x30
>> +#define EMEMORYOTP_PTRIM              0x34
>> +#define EMEMORYOTP_PWE                0x38
>> +
>> +/* Timing delays (in us)
>> + * MIN indicates that there is no maximum.
>> + * TYP indicates that there is a maximum
>> + * that should not be exceeded.
>> + * When the minimums are < 1us, I just put 1us.
>> + */
>> +
>> +#define EMEMORYOTP_MIN_TVDS      1
>> +#define EMEMORYOTP_MIN_TSAS      2
>> +#define EMEMORYOTP_MIN_TTAS      50
>> +#define EMEMORYOTP_MIN_TTAH      1
>> +#define EMEMORYOTP_MIN_TASH      1
>> +#define EMEMORYOTP_MIN_TMS       1
>> +#define EMEMORYOTP_MIN_TCS       10
>> +#define EMEMORYOTP_MIN_TMH       1
>> +#define EMEMORYOTP_MIN_TAS       50
>> +
>> +#define EMEMORYOTP_MAX_TCD       1
>> +#define EMEMORYOTP_MIN_TKH       1
>> +
>> +// Note: This has an upper limit of 100.
>> +#define EMEMORYOTP_MIN_TCSP      10
>> +#define EMEMORYOTP_TYP_TCSP      11
>> +
>> +// This has an upper limit of 20.
>> +#define EMEMORYOTP_MIN_TPPS      5
>> +#define EMEMORYOTP_TYP_TPPS      6
>> +
>> +// This has an upper limit of 20.
>> +#define EMEMORYOTP_MIN_TPPH      1
>> +#define EMEMORYOTP_TYP_TPPH      2
>> +
>> +// This has upper limit of 100.
>> +#define EMEMORYOTP_MIN_TPPR      5
>> +#define EMEMORYOTP_TYP_TPPR      6
>> +
>> +// This has upper limit of 20
>> +#define EMEMORYOTP_MIN_TPW       10
>> +#define EMEMORYOTP_TYP_TPW       11
>> +
>> +#define EMEMORYOTP_MIN_TASP      1
>> +#define EMEMORYOTP_MIN_TDSP      1
>> +
>> +#define EMEMORYOTP_MIN_TAHP      1
>> +#define EMEMORYOTP_MIN_TDHP      1
>> +// This has a max of 5!
>> +#define EMEMORYOTP_MIN_TPWI      1
>> +#define EMEMORYOTP_TYP_TPWI      2
>> +
>> +#endif /* _OTP_FU540_H */
>> diff --git a/arch/riscv/include/asm/arch-fu540/spi.h
>> b/arch/riscv/include/asm/arch-fu540/spi.h
>> new file mode 100644
>> index 0000000000..ea3f5344b7
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/arch-fu540/spi.h
>> @@ -0,0 +1,86 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (C) 2019 SiFive, Inc.
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +
>> +#ifndef _SPI_FU540_H
>> +#define _SPI_FU540_H
>> +
>> +/* Register offsets */
>> +
>> +#define SPI_REG_SCKDIV          0x00
>> +#define SPI_REG_SCKMODE         0x04
>> +#define SPI_REG_CSID            0x10
>> +#define SPI_REG_CSDEF           0x14
>> +#define SPI_REG_CSMODE          0x18
>> +
>> +#define SPI_REG_DCSSCK          0x28
>> +#define SPI_REG_DSCKCS          0x2a
>> +#define SPI_REG_DINTERCS        0x2c
>> +#define SPI_REG_DINTERXFR       0x2e
>> +
>> +#define SPI_REG_FMT             0x40
>> +#define SPI_REG_TXFIFO          0x48
>> +#define SPI_REG_RXFIFO          0x4c
>> +#define SPI_REG_TXCTRL          0x50
>> +#define SPI_REG_RXCTRL          0x54
>> +
>> +#define SPI_REG_FCTRL           0x60
>> +#define SPI_REG_FFMT            0x64
>> +
>> +#define SPI_REG_IE              0x70
>> +#define SPI_REG_IP              0x74
>> +
>> +/* Fields */
>> +
>> +#define SPI_SCK_PHA             0x1
>> +#define SPI_SCK_POL             0x2
>> +
>> +#define SPI_FMT_PROTO(x)        ((x) & 0x3)
>> +#define SPI_FMT_ENDIAN(x)       (((x) & 0x1) << 2)
>> +#define SPI_FMT_DIR(x)          (((x) & 0x1) << 3)
>> +#define SPI_FMT_LEN(x)          (((x) & 0xf) << 16)
>> +
>> +/* TXCTRL register */
>> +#define SPI_TXWM(x)             ((x) & 0xffff)
>> +/* RXCTRL register */
>> +#define SPI_RXWM(x)             ((x) & 0xffff)
>> +
>> +#define SPI_IP_TXWM             0x1
>> +#define SPI_IP_RXWM             0x2
>> +
>> +#define SPI_FCTRL_EN            0x1
>> +
>> +#define SPI_INSN_CMD_EN         0x1
>> +#define SPI_INSN_ADDR_LEN(x)    (((x) & 0x7) << 1)
>> +#define SPI_INSN_PAD_CNT(x)     (((x) & 0xf) << 4)
>> +#define SPI_INSN_CMD_PROTO(x)   (((x) & 0x3) << 8)
>> +#define SPI_INSN_ADDR_PROTO(x)  (((x) & 0x3) << 10) #define
>> +SPI_INSN_DATA_PROTO(x)  (((x) & 0x3) << 12)
>> +#define SPI_INSN_CMD_CODE(x)    (((x) & 0xff) << 16)
>> +#define SPI_INSN_PAD_CODE(x)    (((x) & 0xff) << 24)
>> +
>> +#define SPI_TXFIFO_FULL  BIT(31)
>> +#define SPI_RXFIFO_EMPTY BIT(31)
>> +
>> +/* Values */
>> +
>> +#define SPI_CSMODE_AUTO         0
>> +#define SPI_CSMODE_HOLD         2
>> +#define SPI_CSMODE_OFF          3
>> +
>> +#define SPI_DIR_RX              0
>> +#define SPI_DIR_TX              1
>> +
>> +#define SPI_PROTO_S             0
>> +#define SPI_PROTO_D             1
>> +#define SPI_PROTO_Q             2
>> +
>> +#define SPI_ENDIAN_MSB          0
>> +#define SPI_ENDIAN_LSB          1
>> +
>> +#endif /* _SPI_FU540_H */
>> diff --git a/arch/riscv/include/asm/arch-fu540/uart.h
>> b/arch/riscv/include/asm/arch-fu540/uart.h
>> new file mode 100644
>> index 0000000000..31ae079a18
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/arch-fu540/uart.h
>> @@ -0,0 +1,35 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (C) 2019 SiFive, Inc.
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +
>> +#ifndef _UART_FU540_H
>> +#define _UART_FU540_H
>> +
>> +/* Register offsets */
>> +#define UART_REG_TXFIFO         0x00
>> +#define UART_REG_RXFIFO         0x04
>> +#define UART_REG_TXCTRL         0x08
>> +#define UART_REG_RXCTRL         0x0c
>> +#define UART_REG_IE             0x10
>> +#define UART_REG_IP             0x14
>> +#define UART_REG_DIV            0x18
>> +
>> +/* TXCTRL register */
>> +#define UART_TXEN               0x1
>> +#define UART_TXNSTOP            0x2
>> +#define UART_TXWM(x)            (((x) & 0xffff) << 16)
>> +
>> +/* RXCTRL register */
>> +#define UART_RXEN               0x1
>> +#define UART_RXWM(x)            (((x) & 0xffff) << 16)
>> +
>> +/* IP register */
>> +#define UART_IP_TXWM            0x1
>> +#define UART_IP_RXWM            0x2
>> +
>> +#endif /* _UART_FU540_H */
>> --
>
>One generic comment, I think we need add these header files at the same
>time when we add something to the FU540 SoC support, and I doubt all of
>them are needed.

I have added this header files for SPL support, I will recheck if not all of them are
needed, thanks for the review.

>
>Regards,
>Bin

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

* [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
  2020-01-02  4:58   ` Jagan Teki
@ 2020-01-06 10:08     ` Pragnesh Patel
  2020-01-13 14:32       ` Pragnesh Patel
  0 siblings, 1 reply; 19+ messages in thread
From: Pragnesh Patel @ 2020-01-06 10:08 UTC (permalink / raw)
  To: u-boot

>-----Original Message-----
>From: Jagan Teki <jagan@amarulasolutions.com>
>Sent: 02 January 2020 10:29
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot-Denx <u-boot@lists.denx.de>; Palmer Dabbelt ( Sifive)
><palmer@sifive.com>; Atish Patra <atish.patra@wdc.com>; Alexander Graf
><agraf@csgraf.de>; Boris Brezillon <bbrezillon@kernel.org>; Rick Chen
><rick@andestech.com>; Anup Patel <Anup.Patel@wdc.com>
>Subject: Re: [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
>
>+ Rick, Anup
>
>Thanks for the patch, scratching my head to get SPL running on this board.
>
>On Tue, Dec 31, 2019 at 7:30 PM Pragnesh Patel
><pragnesh.patel@sifive.com> wrote:
>>
>> This patch provides sifive_fu540_spl_defconfig which can support
>> U-boot SPL to boot from L2 LIM (0x0800_0000) and then boot FIT
>> image including OpenSBI FW_DYNAMIC firmware and U-Boot proper
>> images from MMC boot devices.
>>
>> With sifive_fu540_spl_defconfig:
>>
>> 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 SD card (replace fw_payload.bin with u-boot.itb)
>> into RAM.
>>
>> 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>
>> ---
>>  arch/riscv/cpu/u-boot-spl.lds                 |    1 +
>>  arch/riscv/dts/fu540-c000-u-boot.dtsi         |   65 +
>>  .../dts/hifive-unleashed-a00-u-boot.dtsi      |   24 +
>>  arch/riscv/include/asm/csr.h                  |    2 +
>>  board/sifive/fu540/Kconfig                    |    8 +
>>  board/sifive/fu540/MAINTAINERS                |    1 +
>>  board/sifive/fu540/Makefile                   |    6 +
>>  board/sifive/fu540/ememoryotp.c               |  143 ++
>>  board/sifive/fu540/fu540.c                    |   31 +-
>>  board/sifive/fu540/include/ccache.h           |   47 +
>>  board/sifive/fu540/include/clkutils.h         |   75 +
>>  board/sifive/fu540/include/ddrregs.h          |  622 +++++++++
>>  board/sifive/fu540/include/ememoryotp.h       |   24 +
>>  board/sifive/fu540/include/fu540-memory-map.h |  427 ++++++
>>  board/sifive/fu540/include/i2c.h              |   49 +
>>  board/sifive/fu540/include/regconfig-ctl.h    |  274 ++++
>>  board/sifive/fu540/include/regconfig-phy.h    | 1224 +++++++++++++++++
>>  board/sifive/fu540/include/spi.h              |  233 ++++
>>  board/sifive/fu540/include/uart.h             |   54 +
>>  board/sifive/fu540/include/ux00ddr.h          |  268 ++++
>>  board/sifive/fu540/include/ux00prci.h         |  206 +++
>>  board/sifive/fu540/spl.c                      |  321 +++++
>>  board/sifive/fu540/uart.c                     |   64 +
>>  configs/sifive_fu540_spl_defconfig            |   23 +
>>  include/configs/sifive-fu540.h                |   17 +
>>  lib/Makefile                                  |    1 +
>
>This patch need to divide into multiple patches since it has multiple
>functionalities all in one which indeed difficult for review and not
>good to go for merging.

Will spilt this into multiple patches in v2. Thanks for the suggestion.

>
>>  26 files changed, 4209 insertions(+), 1 deletion(-)
>>  create mode 100644 arch/riscv/dts/fu540-c000-u-boot.dtsi
>>  create mode 100644 arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>>  create mode 100644 board/sifive/fu540/ememoryotp.c
>>  create mode 100644 board/sifive/fu540/include/ccache.h
>>  create mode 100644 board/sifive/fu540/include/clkutils.h
>>  create mode 100644 board/sifive/fu540/include/ddrregs.h
>>  create mode 100644 board/sifive/fu540/include/ememoryotp.h
>>  create mode 100644 board/sifive/fu540/include/fu540-memory-map.h
>>  create mode 100644 board/sifive/fu540/include/i2c.h
>>  create mode 100644 board/sifive/fu540/include/regconfig-ctl.h
>>  create mode 100644 board/sifive/fu540/include/regconfig-phy.h
>>  create mode 100644 board/sifive/fu540/include/spi.h
>>  create mode 100644 board/sifive/fu540/include/uart.h
>>  create mode 100644 board/sifive/fu540/include/ux00ddr.h
>>  create mode 100644 board/sifive/fu540/include/ux00prci.h
>>  create mode 100644 board/sifive/fu540/spl.c
>>  create mode 100644 board/sifive/fu540/uart.c
>>  create mode 100644 configs/sifive_fu540_spl_defconfig
>>
>> 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 = .;
>> 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..b86cdfb38d
>> --- /dev/null
>> +++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
>> @@ -0,0 +1,65 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * (C) Copyright 2019 SiFive, Inc
>> + */
>> +
>> +/ {
>> +       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;
>> +                       cpu1_intc: interrupt-controller {
>> +                               u-boot,dm-spl;
>> +                       };
>> +               };
>> +               cpu2: cpu at 2 {
>> +                       u-boot,dm-spl;
>> +                       cpu2_intc: interrupt-controller {
>> +                               u-boot,dm-spl;
>> +                       };
>> +               };
>> +               cpu3: cpu at 3 {
>> +                       u-boot,dm-spl;
>> +                       cpu3_intc: interrupt-controller {
>> +                               u-boot,dm-spl;
>> +                       };
>> +               };
>> +               cpu4: cpu at 4 {
>> +                       u-boot,dm-spl;
>> +                       cpu4_intc: interrupt-controller {
>> +                               u-boot,dm-spl;
>> +                       };
>> +               };
>> +       };
>> +
>> +       soc {
>> +               u-boot,dm-spl;
>> +               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
>> new file mode 100644
>> index 0000000000..9b59f4ee14
>> --- /dev/null
>> +++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>> @@ -0,0 +1,24 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2019 SiFive, Inc
>> + */
>> +
>> +#include "fu540-c000-u-boot.dtsi"
>> +
>> +/ {
>> +       hfclk {
>> +               u-boot,dm-spl;
>> +       };
>> +
>> +       rtcclk {
>> +               u-boot,dm-spl;
>> +       };
>> +};
>> +
>> +&qspi2 {
>> +
>> +       mmc at 0 {
>> +               u-boot,dm-spl;
>> +       };
>> +
>> +};
>> diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
>> index d1520743a2..125c05dd8a 100644
>> --- a/arch/riscv/include/asm/csr.h
>> +++ b/arch/riscv/include/asm/csr.h
>> @@ -103,6 +103,8 @@
>>  #define CSR_TIMEH              0xc81
>>  #define CSR_INSTRETH           0xc82
>>  #define CSR_MHARTID            0xf14
>> +#define CSR_MCYCLE             0xb00
>> +#define CSR_MCYCLEH            0xb80
>>
>>  #ifndef __ASSEMBLY__
>>
>> diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
>> index 816a135b21..ac7c6bff37 100644
>> --- a/board/sifive/fu540/Kconfig
>> +++ b/board/sifive/fu540/Kconfig
>> @@ -16,12 +16,20 @@ config SYS_SOC
>>         default "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/MAINTAINERS
>b/board/sifive/fu540/MAINTAINERS
>> index 702d803ad8..42c3f3deb0 100644
>> --- a/board/sifive/fu540/MAINTAINERS
>> +++ b/board/sifive/fu540/MAINTAINERS
>> @@ -7,3 +7,4 @@ S:      Maintained
>>  F:     board/sifive/fu540/
>>  F:     include/configs/sifive-fu540.h
>>  F:     configs/sifive_fu540_defconfig
>> +F:     configs/sifive_fu540_spl_defconfig
>> diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
>> index 6e1862c475..e532beb9d5 100644
>> --- a/board/sifive/fu540/Makefile
>> +++ b/board/sifive/fu540/Makefile
>> @@ -3,3 +3,9 @@
>>  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
>>
>>  obj-y  += fu540.o
>> +
>> +ifdef CONFIG_SPL_BUILD
>> +obj-y += spl.o
>> +obj-y += ememoryotp.o
>> +obj-y += uart.o
>> +endif
>> diff --git a/board/sifive/fu540/ememoryotp.c
>b/board/sifive/fu540/ememoryotp.c
>> new file mode 100644
>> index 0000000000..994724af37
>> --- /dev/null
>> +++ b/board/sifive/fu540/ememoryotp.c
>> @@ -0,0 +1,143 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (c) 2019 SiFive, Inc
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +
>> +#include <stdint.h>
>> +#include "include/fu540-memory-map.h"
>> +#include "include/clkutils.h"
>> +#include "include/ememoryotp.h"
>> +
>> +#define max(x, y) ((x) > (y) ? (x) : (y))
>> +
>> +extern inline void clkutils_delay_ns(int delay_ns);
>> +
>> +void ememory_otp_power_up_sequence(void)
>> +{
>> +       // Probably don't need to do this, since
>> +       // all the other stuff has been happening.
>> +       // But it is on the wave form.
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TVDS * 1000);
>> +
>> +       EMEMORYOTP_REG(EMEMORYOTP_PDSTB) = 1;
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TSAS * 1000);
>> +
>> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 1;
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TTAS * 1000);
>> +}
>> +
>> +void ememory_otp_power_down_sequence(void)
>> +{
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TTAH * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 0;
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TASH * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PDSTB) = 0;
>> +       // No delay indicated after this
>> +}
>> +
>> +void ememory_otp_begin_read(void)
>> +{
>> +       // Initialize
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 0;
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMS * 1000);
>> +
>> +       // Enable chip select
>> +
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 1;
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TCS * 1000);
>> +}
>> +
>> +void ememory_otp_exit_read(void)
>> +{
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>> +       // Disable chip select
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 0;
>> +       // Wait before changing PTM
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMH * 1000);
>> +}
>> +
>> +unsigned int ememory_otp_read(int address)
>> +{
>> +       unsigned int read_value;
>> +
>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = address;
>> +       // Toggle clock
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TAS * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 1;
>> +       // Insert delay until data is ready.
>> +       // There are lots of delays
>> +       // on the chart, but I think this is the most relevant.
>> +       int delay = max(EMEMORYOTP_MAX_TCD, EMEMORYOTP_MIN_TKH);
>> +
>> +       clkutils_delay_ns(delay * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
>> +       read_value = EMEMORYOTP_REG(EMEMORYOTP_PDOUT);
>> +       // Could check here for things like TCYC < TAH + TCD
>> +       return read_value;
>> +}
>> +
>> +void ememory_otp_pgm_entry(void)
>> +{
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PAS) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PAIO) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 2;
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMS * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 1;
>> +       clkutils_delay_ns(EMEMORYOTP_TYP_TCSP * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PPROG) = 1;
>> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPS * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 1;
>> +}
>> +
>> +void ememory_otp_pgm_exit(void)
>> +{
>> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPH * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PPROG) = 0;
>> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPR * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 0;
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMH * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 0;
>> +}
>> +
>> +void ememory_otp_pgm_access(int address, unsigned int write_data)
>> +{
>> +       int i;
>> +
>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = address;
>> +       for (int pas = 0; pas < 2; pas++) {
>> +               EMEMORYOTP_REG(EMEMORYOTP_PAS) = pas;
>> +               for (i = 0; i < 32; i++) {
>> +                       EMEMORYOTP_REG(EMEMORYOTP_PAIO) = i;
>> +                       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = ((write_data >> i)
>&
>> +                                                          1);
>> +
>> +                       int delay = max(EMEMORYOTP_MIN_TASP,
>> +                                       EMEMORYOTP_MIN_TDSP);
>> +
>> +                       clkutils_delay_ns(delay * 1000);
>> +                       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 1;
>> +                       clkutils_delay_ns(EMEMORYOTP_TYP_TPW * 1000);
>> +                       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>> +                       delay = max(EMEMORYOTP_MIN_TAHP,
>EMEMORYOTP_MIN_TDHP);
>> +                       delay = max(delay, EMEMORYOTP_TYP_TPWI);
>> +                       clkutils_delay_ns(delay * 1000);
>> +               }
>> +       }
>> +       EMEMORYOTP_REG(EMEMORYOTP_PAS) = 0;
>> +}
>
>Please add dm driver for this.

I will add dm driver in v2.

>
>> diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
>> index 47a2090251..e91418a88a 100644
>> --- a/board/sifive/fu540/fu540.c
>> +++ b/board/sifive/fu540/fu540.c
>> @@ -10,6 +10,9 @@
>>  #include <dm.h>
>>  #include <linux/delay.h>
>>  #include <linux/io.h>
>> +#include <spl.h>
>> +#include "include/ccache.h"
>> +#include "include/fu540-memory-map.h"
>>
>>  #ifdef CONFIG_MISC_INIT_R
>>
>> @@ -143,7 +146,33 @@ int misc_init_r(void)
>>
>>  int board_init(void)
>>  {
>> -       /* For now nothing to do here. */
>> +       /* enable all cache ways */
>> +       ccache_enable_ways(CCACHE_CTRL_ADDR, 15);
>> +       return 0;
>> +}
>> +
>> +#ifdef CONFIG_SPL
>> +void board_boot_order(u32 *spl_boot_list)
>> +{
>> +       u8 i;
>> +       u32 boot_devices[] = {
>> +#ifdef CONFIG_SPL_RAM_SUPPORT
>> +               BOOT_DEVICE_RAM,
>> +#endif
>
>You may skip if you haven't tested Boot from RAM yet?

I have tested the BOOT from RAM.

>
>> +#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/include/ccache.h
>b/board/sifive/fu540/include/ccache.h
>> new file mode 100644
>> index 0000000000..c7978ebdee
>> --- /dev/null
>> +++ b/board/sifive/fu540/include/ccache.h
>> @@ -0,0 +1,47 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (c) 2019 SiFive, Inc
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +
>> +#ifndef FU540_CCACHE_H
>> +#define FU540_CCACHE_H
>> +
>> +#include <asm/arch/cache.h>
>> +
>> +#ifndef __ASSEMBLER__
>> +
>> +#include <stdint.h>
>> +#include <stdatomic.h>
>> +#include <linux/types.h>
>> +
>> +// Block memory access until operation completed
>> +static inline void ccache_barrier_0(void)
>> +{
>> +       asm volatile("fence rw, io" : : : "memory");
>> +}
>> +
>> +static inline void ccache_barrier_1(void)
>> +{
>> +       asm volatile("fence io, rw" : : : "memory");
>> +}
>> +
>> +// Enable ways; allow cache to use these ways
>> +static inline u8 ccache_enable_ways(u64 base_addr, u8 value)
>> +{
>> +       u32 old;
>> +
>> +       volatile _Atomic(u32) * enable = (_Atomic(u32) *)(base_addr +
>> +                                         CCACHE_ENABLE);
>> +       ccache_barrier_0();
>> +       old = atomic_exchange_explicit(enable, value,
>memory_order_relaxed);
>> +       ccache_barrier_1();
>> +       return old;
>> +}
>> +
>> +#endif
>> +
>> +#endif /* FU540_CCACHE_H */
>> diff --git a/board/sifive/fu540/include/clkutils.h
>b/board/sifive/fu540/include/clkutils.h
>> new file mode 100644
>> index 0000000000..dbb260a1c3
>> --- /dev/null
>> +++ b/board/sifive/fu540/include/clkutils.h
>> @@ -0,0 +1,75 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (c) 2019 SiFive, Inc
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +
>> +#ifndef __ASSEMBLER__
>> +
>> +#include <stdint.h>
>> +#include <asm/encoding.h>
>> +#include "fu540-memory-map.h"
>> +
>> +// Inlining header functions in C
>> +// https://stackoverflow.com/a/23699777/7433423
>> +inline u64 clkutils_read_mtime(void)
>> +{
>> +#if __riscv_xlen == 32
>> +       u32 mtime_hi_0;
>> +       u32 mtime_lo;
>> +       u32 mtime_hi_1;
>> +
>> +       do {
>> +               mtime_hi_0 = CLINT_REG(CLINT_MTIME + 4);
>> +               mtime_lo   = CLINT_REG(CLINT_MTIME + 0);
>> +               mtime_hi_1 = CLINT_REG(CLINT_MTIME + 4);
>> +       } while (mtime_hi_0 != mtime_hi_1);
>> +
>> +       return (((u64)mtime_hi_1 << 32) | ((u64)mtime_lo));
>> +#else
>> +       return CLINT_REG64(CLINT_MTIME);
>> +#endif
>> +}
>> +
>> +static inline u64 clkutils_read_mcycle(void)
>> +{
>> +#if __riscv_xlen == 32
>> +       u32 mcycle_hi_0;
>> +       u32 mcycle_lo;
>> +       u32 mcycle_hi_1;
>> +
>> +       do {
>> +               mcycle_hi_0 = read_csr(mcycleh);
>> +               mcycle_lo   = read_csr(mcycle);
>> +               mcycle_hi_1 = read_csr(mcycleh);
>> +       } while (mcycle_hi_0 != mcycle_hi_1);
>> +
>> +       return (((u64)mcycle_hi_1 << 32) | ((u64)mcycle_lo));
>> +#else
>> +       return csr_read(CSR_MCYCLE);
>> +#endif
>> +}
>> +
>> +// Note that since this runs off RTC, which is
>> +// currently ~1-10MHz, this function is
>> +// not acccurate for small delays.
>> +// In the future, we may want to determine whether to
>> +// use RTC vs mcycle, or create a different function
>> +// based off mcycle.
>> +// We add 1 to the then value because otherwise, if you wanted
>> +// to delay up to RTC_PERIOD_NS-1 (for example), you wouldn't delay
>> +// at all. So this function delays AT LEAST delay_ns.
>
>Improper syntax for multiple comments.

I will update this in v2.

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

I didn't get you.

>> diff --git a/board/sifive/fu540/include/ememoryotp.h
>b/board/sifive/fu540/include/ememoryotp.h
>> new file mode 100644
>> index 0000000000..274283c4db
>> --- /dev/null
>> +++ b/board/sifive/fu540/include/ememoryotp.h
>> @@ -0,0 +1,24 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (c) 2019 SiFive, Inc
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +

[...]

>> +
>> +#ifndef __ASSEMBLER__
>> +
>> +#include <stdint.h>
>> +#include <stddef.h>
>> +#include <stdbool.h>
>> +#include "uart.h"
>> +#include "fu540-memory-map.h"
>> +
>> +#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
>> +#
>
>Sorry, too much stuff in single patch. it is worth require multiple patches.

Sure, will split this into multiple patches.

>
>Jagan.

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

* [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
  2019-12-31 17:18   ` Amit Tomer
@ 2020-01-13 13:36     ` Pragnesh Patel
  0 siblings, 0 replies; 19+ messages in thread
From: Pragnesh Patel @ 2020-01-13 13:36 UTC (permalink / raw)
  To: u-boot


>-----Original Message-----
>From: Amit Tomer <amittomer25@gmail.com>
>Sent: 31 December 2019 22:49
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot <u-boot@lists.denx.de>; Palmer Dabbelt ( Sifive)
><palmer@sifive.com>; Atish Patra <atish.patra@wdc.com>; Alexander Graf
><agraf@csgraf.de>; Boris Brezillon <bbrezillon@kernel.org>
>Subject: Re: [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
>
>Hi Pragnesh,
>
>Minor comments regarding coding style, see below.
>
>> +       // Probably don't need to do this, since
>> +       // all the other stuff has been happening.
>> +       // But it is on the wave form.
>
>U-boot is mostly implemented in C, we should *not* use C++ style
>comments(//).
>is this something picked from BSP code ?

Yes that is copied from BSP, I will update this in v2, thanks for highlighting this.

>
>> +#include "include/ccache.h"
>> +#include "include/fu540-memory-map.h"
>
>This looks bit strange, I mean the double include above

This "fu540/include" directory is specifically for SPL, I will rename it in v2 patch.

>
>> +// Inlining header functions in C
>> +// https://stackoverflow.com/a/23699777/7433423
>
>This could be conveyed in comments rather then pointing some external link.

Will remove the external link and add inline comments for that, thanks for the review.

>
>Thanks
>-Amit.

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

* [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
  2020-01-06 10:08     ` Pragnesh Patel
@ 2020-01-13 14:32       ` Pragnesh Patel
  2020-01-13 22:31         ` Lukas Auer
  0 siblings, 1 reply; 19+ messages in thread
From: Pragnesh Patel @ 2020-01-13 14:32 UTC (permalink / raw)
  To: u-boot

>-----Original Message-----
>From: Pragnesh Patel
>Sent: 06 January 2020 15:39
>To: Jagan Teki <jagan@amarulasolutions.com>
>Cc: U-Boot-Denx <u-boot@lists.denx.de>; Atish Patra
><atish.patra@wdc.com>; Alexander Graf <agraf@csgraf.de>; Boris Brezillon
><bbrezillon@kernel.org>; Rick Chen <rick@andestech.com>; Anup Patel
><Anup.Patel@wdc.com>; palmerdabbelt at google.com
>Subject: RE: [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
>
>>-----Original Message-----
>>From: Jagan Teki <jagan@amarulasolutions.com>
>>Sent: 02 January 2020 10:29
>>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>>Cc: U-Boot-Denx <u-boot@lists.denx.de>; Palmer Dabbelt ( Sifive)
>><palmer@sifive.com>; Atish Patra <atish.patra@wdc.com>; Alexander Graf
>><agraf@csgraf.de>; Boris Brezillon <bbrezillon@kernel.org>; Rick Chen
>><rick@andestech.com>; Anup Patel <Anup.Patel@wdc.com>
>>Subject: Re: [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
>>
>>+ Rick, Anup
>>
>>Thanks for the patch, scratching my head to get SPL running on this board.
>>
>>On Tue, Dec 31, 2019 at 7:30 PM Pragnesh Patel
>><pragnesh.patel@sifive.com> wrote:
>>>
>>> This patch provides sifive_fu540_spl_defconfig which can support
>>> U-boot SPL to boot from L2 LIM (0x0800_0000) and then boot FIT
>>> image including OpenSBI FW_DYNAMIC firmware and U-Boot proper
>>> images from MMC boot devices.
>>>
>>> With sifive_fu540_spl_defconfig:
>>>
>>> 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 SD card (replace fw_payload.bin with u-boot.itb)
>>> into RAM.
>>>
>>> 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>
>>> ---
>>>  arch/riscv/cpu/u-boot-spl.lds                 |    1 +
>>>  arch/riscv/dts/fu540-c000-u-boot.dtsi         |   65 +
>>>  .../dts/hifive-unleashed-a00-u-boot.dtsi      |   24 +
>>>  arch/riscv/include/asm/csr.h                  |    2 +
>>>  board/sifive/fu540/Kconfig                    |    8 +
>>>  board/sifive/fu540/MAINTAINERS                |    1 +
>>>  board/sifive/fu540/Makefile                   |    6 +
>>>  board/sifive/fu540/ememoryotp.c               |  143 ++
>>>  board/sifive/fu540/fu540.c                    |   31 +-
>>>  board/sifive/fu540/include/ccache.h           |   47 +
>>>  board/sifive/fu540/include/clkutils.h         |   75 +
>>>  board/sifive/fu540/include/ddrregs.h          |  622 +++++++++
>>>  board/sifive/fu540/include/ememoryotp.h       |   24 +
>>>  board/sifive/fu540/include/fu540-memory-map.h |  427 ++++++
>>>  board/sifive/fu540/include/i2c.h              |   49 +
>>>  board/sifive/fu540/include/regconfig-ctl.h    |  274 ++++
>>>  board/sifive/fu540/include/regconfig-phy.h    | 1224 +++++++++++++++++
>>>  board/sifive/fu540/include/spi.h              |  233 ++++
>>>  board/sifive/fu540/include/uart.h             |   54 +
>>>  board/sifive/fu540/include/ux00ddr.h          |  268 ++++
>>>  board/sifive/fu540/include/ux00prci.h         |  206 +++
>>>  board/sifive/fu540/spl.c                      |  321 +++++
>>>  board/sifive/fu540/uart.c                     |   64 +
>>>  configs/sifive_fu540_spl_defconfig            |   23 +
>>>  include/configs/sifive-fu540.h                |   17 +
>>>  lib/Makefile                                  |    1 +
>>
>>This patch need to divide into multiple patches since it has multiple
>>functionalities all in one which indeed difficult for review and not
>>good to go for merging.
>
>Will spilt this into multiple patches in v2. Thanks for the suggestion.
>
>>
>>>  26 files changed, 4209 insertions(+), 1 deletion(-)
>>>  create mode 100644 arch/riscv/dts/fu540-c000-u-boot.dtsi
>>>  create mode 100644 arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>>>  create mode 100644 board/sifive/fu540/ememoryotp.c
>>>  create mode 100644 board/sifive/fu540/include/ccache.h
>>>  create mode 100644 board/sifive/fu540/include/clkutils.h
>>>  create mode 100644 board/sifive/fu540/include/ddrregs.h
>>>  create mode 100644 board/sifive/fu540/include/ememoryotp.h
>>>  create mode 100644 board/sifive/fu540/include/fu540-memory-map.h
>>>  create mode 100644 board/sifive/fu540/include/i2c.h
>>>  create mode 100644 board/sifive/fu540/include/regconfig-ctl.h
>>>  create mode 100644 board/sifive/fu540/include/regconfig-phy.h
>>>  create mode 100644 board/sifive/fu540/include/spi.h
>>>  create mode 100644 board/sifive/fu540/include/uart.h
>>>  create mode 100644 board/sifive/fu540/include/ux00ddr.h
>>>  create mode 100644 board/sifive/fu540/include/ux00prci.h
>>>  create mode 100644 board/sifive/fu540/spl.c
>>>  create mode 100644 board/sifive/fu540/uart.c
>>>  create mode 100644 configs/sifive_fu540_spl_defconfig
>>>
>>> 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 = .;
>>> 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..b86cdfb38d
>>> --- /dev/null
>>> +++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
>>> @@ -0,0 +1,65 @@
>>> +// SPDX-License-Identifier: GPL-2.0+
>>> +/*
>>> + * (C) Copyright 2019 SiFive, Inc
>>> + */
>>> +
>>> +/ {
>>> +       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;
>>> +                       cpu1_intc: interrupt-controller {
>>> +                               u-boot,dm-spl;
>>> +                       };
>>> +               };
>>> +               cpu2: cpu at 2 {
>>> +                       u-boot,dm-spl;
>>> +                       cpu2_intc: interrupt-controller {
>>> +                               u-boot,dm-spl;
>>> +                       };
>>> +               };
>>> +               cpu3: cpu at 3 {
>>> +                       u-boot,dm-spl;
>>> +                       cpu3_intc: interrupt-controller {
>>> +                               u-boot,dm-spl;
>>> +                       };
>>> +               };
>>> +               cpu4: cpu at 4 {
>>> +                       u-boot,dm-spl;
>>> +                       cpu4_intc: interrupt-controller {
>>> +                               u-boot,dm-spl;
>>> +                       };
>>> +               };
>>> +       };
>>> +
>>> +       soc {
>>> +               u-boot,dm-spl;
>>> +               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
>>> new file mode 100644
>>> index 0000000000..9b59f4ee14
>>> --- /dev/null
>>> +++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>>> @@ -0,0 +1,24 @@
>>> +// SPDX-License-Identifier: GPL-2.0+
>>> +/*
>>> + * Copyright (C) 2019 SiFive, Inc
>>> + */
>>> +
>>> +#include "fu540-c000-u-boot.dtsi"
>>> +
>>> +/ {
>>> +       hfclk {
>>> +               u-boot,dm-spl;
>>> +       };
>>> +
>>> +       rtcclk {
>>> +               u-boot,dm-spl;
>>> +       };
>>> +};
>>> +
>>> +&qspi2 {
>>> +
>>> +       mmc at 0 {
>>> +               u-boot,dm-spl;
>>> +       };
>>> +
>>> +};
>>> diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
>>> index d1520743a2..125c05dd8a 100644
>>> --- a/arch/riscv/include/asm/csr.h
>>> +++ b/arch/riscv/include/asm/csr.h
>>> @@ -103,6 +103,8 @@
>>>  #define CSR_TIMEH              0xc81
>>>  #define CSR_INSTRETH           0xc82
>>>  #define CSR_MHARTID            0xf14
>>> +#define CSR_MCYCLE             0xb00
>>> +#define CSR_MCYCLEH            0xb80
>>>
>>>  #ifndef __ASSEMBLY__
>>>
>>> diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
>>> index 816a135b21..ac7c6bff37 100644
>>> --- a/board/sifive/fu540/Kconfig
>>> +++ b/board/sifive/fu540/Kconfig
>>> @@ -16,12 +16,20 @@ config SYS_SOC
>>>         default "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/MAINTAINERS
>>b/board/sifive/fu540/MAINTAINERS
>>> index 702d803ad8..42c3f3deb0 100644
>>> --- a/board/sifive/fu540/MAINTAINERS
>>> +++ b/board/sifive/fu540/MAINTAINERS
>>> @@ -7,3 +7,4 @@ S:      Maintained
>>>  F:     board/sifive/fu540/
>>>  F:     include/configs/sifive-fu540.h
>>>  F:     configs/sifive_fu540_defconfig
>>> +F:     configs/sifive_fu540_spl_defconfig
>>> diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
>>> index 6e1862c475..e532beb9d5 100644
>>> --- a/board/sifive/fu540/Makefile
>>> +++ b/board/sifive/fu540/Makefile
>>> @@ -3,3 +3,9 @@
>>>  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
>>>
>>>  obj-y  += fu540.o
>>> +
>>> +ifdef CONFIG_SPL_BUILD
>>> +obj-y += spl.o
>>> +obj-y += ememoryotp.o
>>> +obj-y += uart.o
>>> +endif
>>> diff --git a/board/sifive/fu540/ememoryotp.c
>>b/board/sifive/fu540/ememoryotp.c
>>> new file mode 100644
>>> index 0000000000..994724af37
>>> --- /dev/null
>>> +++ b/board/sifive/fu540/ememoryotp.c
>>> @@ -0,0 +1,143 @@
>>> +// SPDX-License-Identifier: GPL-2.0+
>>> +/*
>>> + * Copyright (c) 2019 SiFive, Inc
>>> + *
>>> + * Authors:
>>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>>> + */
>>> +
>>> +#include <stdint.h>
>>> +#include "include/fu540-memory-map.h"
>>> +#include "include/clkutils.h"
>>> +#include "include/ememoryotp.h"
>>> +
>>> +#define max(x, y) ((x) > (y) ? (x) : (y))
>>> +
>>> +extern inline void clkutils_delay_ns(int delay_ns);
>>> +
>>> +void ememory_otp_power_up_sequence(void)
>>> +{
>>> +       // Probably don't need to do this, since
>>> +       // all the other stuff has been happening.
>>> +       // But it is on the wave form.
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TVDS * 1000);
>>> +
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PDSTB) = 1;
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TSAS * 1000);
>>> +
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 1;
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TTAS * 1000);
>>> +}
>>> +
>>> +void ememory_otp_power_down_sequence(void)
>>> +{
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TTAH * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 0;
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TASH * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PDSTB) = 0;
>>> +       // No delay indicated after this
>>> +}
>>> +
>>> +void ememory_otp_begin_read(void)
>>> +{
>>> +       // Initialize
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 0;
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMS * 1000);
>>> +
>>> +       // Enable chip select
>>> +
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 1;
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TCS * 1000);
>>> +}
>>> +
>>> +void ememory_otp_exit_read(void)
>>> +{
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>>> +       // Disable chip select
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 0;
>>> +       // Wait before changing PTM
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMH * 1000);
>>> +}
>>> +
>>> +unsigned int ememory_otp_read(int address)
>>> +{
>>> +       unsigned int read_value;
>>> +
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = address;
>>> +       // Toggle clock
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TAS * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 1;
>>> +       // Insert delay until data is ready.
>>> +       // There are lots of delays
>>> +       // on the chart, but I think this is the most relevant.
>>> +       int delay = max(EMEMORYOTP_MAX_TCD, EMEMORYOTP_MIN_TKH);
>>> +
>>> +       clkutils_delay_ns(delay * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
>>> +       read_value = EMEMORYOTP_REG(EMEMORYOTP_PDOUT);
>>> +       // Could check here for things like TCYC < TAH + TCD
>>> +       return read_value;
>>> +}
>>> +
>>> +void ememory_otp_pgm_entry(void)
>>> +{
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PAS) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PAIO) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 2;
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMS * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 1;
>>> +       clkutils_delay_ns(EMEMORYOTP_TYP_TCSP * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PPROG) = 1;
>>> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPS * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 1;
>>> +}
>>> +
>>> +void ememory_otp_pgm_exit(void)
>>> +{
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>>> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPH * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PPROG) = 0;
>>> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPR * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 0;
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMH * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 0;
>>> +}
>>> +
>>> +void ememory_otp_pgm_access(int address, unsigned int write_data)
>>> +{
>>> +       int i;
>>> +
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = address;
>>> +       for (int pas = 0; pas < 2; pas++) {
>>> +               EMEMORYOTP_REG(EMEMORYOTP_PAS) = pas;
>>> +               for (i = 0; i < 32; i++) {
>>> +                       EMEMORYOTP_REG(EMEMORYOTP_PAIO) = i;
>>> +                       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = ((write_data >>
>i)
>>&
>>> +                                                          1);
>>> +
>>> +                       int delay = max(EMEMORYOTP_MIN_TASP,
>>> +                                       EMEMORYOTP_MIN_TDSP);
>>> +
>>> +                       clkutils_delay_ns(delay * 1000);
>>> +                       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 1;
>>> +                       clkutils_delay_ns(EMEMORYOTP_TYP_TPW * 1000);
>>> +                       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>>> +                       delay = max(EMEMORYOTP_MIN_TAHP,
>>EMEMORYOTP_MIN_TDHP);
>>> +                       delay = max(delay, EMEMORYOTP_TYP_TPWI);
>>> +                       clkutils_delay_ns(delay * 1000);
>>> +               }
>>> +       }
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PAS) = 0;
>>> +}
>>
>>Please add dm driver for this.
>
>I will add dm driver in v2.
>
>>
>>> diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
>>> index 47a2090251..e91418a88a 100644
>>> --- a/board/sifive/fu540/fu540.c
>>> +++ b/board/sifive/fu540/fu540.c
>>> @@ -10,6 +10,9 @@
>>>  #include <dm.h>
>>>  #include <linux/delay.h>
>>>  #include <linux/io.h>
>>> +#include <spl.h>
>>> +#include "include/ccache.h"
>>> +#include "include/fu540-memory-map.h"
>>>
>>>  #ifdef CONFIG_MISC_INIT_R
>>>
>>> @@ -143,7 +146,33 @@ int misc_init_r(void)
>>>
>>>  int board_init(void)
>>>  {
>>> -       /* For now nothing to do here. */
>>> +       /* enable all cache ways */
>>> +       ccache_enable_ways(CCACHE_CTRL_ADDR, 15);
>>> +       return 0;
>>> +}
>>> +
>>> +#ifdef CONFIG_SPL
>>> +void board_boot_order(u32 *spl_boot_list)
>>> +{
>>> +       u8 i;
>>> +       u32 boot_devices[] = {
>>> +#ifdef CONFIG_SPL_RAM_SUPPORT
>>> +               BOOT_DEVICE_RAM,
>>> +#endif
>>
>>You may skip if you haven't tested Boot from RAM yet?
>
>I have tested the BOOT from RAM.
>
>>
>>> +#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/include/ccache.h
>>b/board/sifive/fu540/include/ccache.h
>>> new file mode 100644
>>> index 0000000000..c7978ebdee
>>> --- /dev/null
>>> +++ b/board/sifive/fu540/include/ccache.h
>>> @@ -0,0 +1,47 @@
>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>> +/*
>>> + * Copyright (c) 2019 SiFive, Inc
>>> + *
>>> + * Authors:
>>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>>> + */
>>> +
>>> +#ifndef FU540_CCACHE_H
>>> +#define FU540_CCACHE_H
>>> +
>>> +#include <asm/arch/cache.h>
>>> +
>>> +#ifndef __ASSEMBLER__
>>> +
>>> +#include <stdint.h>
>>> +#include <stdatomic.h>
>>> +#include <linux/types.h>
>>> +
>>> +// Block memory access until operation completed
>>> +static inline void ccache_barrier_0(void)
>>> +{
>>> +       asm volatile("fence rw, io" : : : "memory");
>>> +}
>>> +
>>> +static inline void ccache_barrier_1(void)
>>> +{
>>> +       asm volatile("fence io, rw" : : : "memory");
>>> +}
>>> +
>>> +// Enable ways; allow cache to use these ways
>>> +static inline u8 ccache_enable_ways(u64 base_addr, u8 value)
>>> +{
>>> +       u32 old;
>>> +
>>> +       volatile _Atomic(u32) * enable = (_Atomic(u32) *)(base_addr +
>>> +                                         CCACHE_ENABLE);
>>> +       ccache_barrier_0();
>>> +       old = atomic_exchange_explicit(enable, value,
>>memory_order_relaxed);
>>> +       ccache_barrier_1();
>>> +       return old;
>>> +}
>>> +
>>> +#endif
>>> +
>>> +#endif /* FU540_CCACHE_H */
>>> diff --git a/board/sifive/fu540/include/clkutils.h
>>b/board/sifive/fu540/include/clkutils.h
>>> new file mode 100644
>>> index 0000000000..dbb260a1c3
>>> --- /dev/null
>>> +++ b/board/sifive/fu540/include/clkutils.h
>>> @@ -0,0 +1,75 @@
>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>> +/*
>>> + * Copyright (c) 2019 SiFive, Inc
>>> + *
>>> + * Authors:
>>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>>> + */
>>> +
>>> +#ifndef __ASSEMBLER__
>>> +
>>> +#include <stdint.h>
>>> +#include <asm/encoding.h>
>>> +#include "fu540-memory-map.h"
>>> +
>>> +// Inlining header functions in C
>>> +// https://stackoverflow.com/a/23699777/7433423
>>> +inline u64 clkutils_read_mtime(void)
>>> +{
>>> +#if __riscv_xlen == 32
>>> +       u32 mtime_hi_0;
>>> +       u32 mtime_lo;
>>> +       u32 mtime_hi_1;
>>> +
>>> +       do {
>>> +               mtime_hi_0 = CLINT_REG(CLINT_MTIME + 4);
>>> +               mtime_lo   = CLINT_REG(CLINT_MTIME + 0);
>>> +               mtime_hi_1 = CLINT_REG(CLINT_MTIME + 4);
>>> +       } while (mtime_hi_0 != mtime_hi_1);
>>> +
>>> +       return (((u64)mtime_hi_1 << 32) | ((u64)mtime_lo));
>>> +#else
>>> +       return CLINT_REG64(CLINT_MTIME);
>>> +#endif
>>> +}
>>> +
>>> +static inline u64 clkutils_read_mcycle(void)
>>> +{
>>> +#if __riscv_xlen == 32
>>> +       u32 mcycle_hi_0;
>>> +       u32 mcycle_lo;
>>> +       u32 mcycle_hi_1;
>>> +
>>> +       do {
>>> +               mcycle_hi_0 = read_csr(mcycleh);
>>> +               mcycle_lo   = read_csr(mcycle);
>>> +               mcycle_hi_1 = read_csr(mcycleh);
>>> +       } while (mcycle_hi_0 != mcycle_hi_1);
>>> +
>>> +       return (((u64)mcycle_hi_1 << 32) | ((u64)mcycle_lo));
>>> +#else
>>> +       return csr_read(CSR_MCYCLE);
>>> +#endif
>>> +}
>>> +
>>> +// Note that since this runs off RTC, which is
>>> +// currently ~1-10MHz, this function is
>>> +// not acccurate for small delays.
>>> +// In the future, we may want to determine whether to
>>> +// use RTC vs mcycle, or create a different function
>>> +// based off mcycle.
>>> +// We add 1 to the then value because otherwise, if you wanted
>>> +// to delay up to RTC_PERIOD_NS-1 (for example), you wouldn't delay
>>> +// at all. So this function delays AT LEAST delay_ns.
>>
>>Improper syntax for multiple comments.
>
>I will update this in v2.
>
>>
>>> +inline void clkutils_delay_ns(int delay_ns)
>>> +{
>>> +       u64 now = clkutils_read_mtime();
>>> +       u64 then = now + delay_ns / RTC_PERIOD_NS + 1;
>>> +
>>> +       do {
>>> +               now = clkutils_read_mtime();
>>> +       } while (now < then);
>>> +}
>>> +
>>> +#endif /* !__ASSEMBLER__ */
>>> diff --git a/board/sifive/fu540/include/ddrregs.h
>>b/board/sifive/fu540/include/ddrregs.h
>>> new file mode 100644
>>> index 0000000000..e436496d87
>>> --- /dev/null
>>> +++ b/board/sifive/fu540/include/ddrregs.h
>>> @@ -0,0 +1,622 @@
>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>> +/*
>>> + * Copyright (c) 2019 SiFive, Inc
>>> + *
>>> + * Authors:
>>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>>> + */
>>> +
>>> +#include <stdint.h>
>>> +
>>> +u32 DENALI_PHY_DATA[1215] = {
>>> +       DENALI_PHY_00_DATA, DENALI_PHY_01_DATA,
>>DENALI_PHY_02_DATA,
>>> +       DENALI_PHY_03_DATA, DENALI_PHY_04_DATA,
>>DENALI_PHY_05_DATA,
>>> +       DENALI_PHY_06_DATA, DENALI_PHY_07_DATA,
>>DENALI_PHY_08_DATA,
>>
>>Can this handle to write separate driver for ram like drivers/ram ?

We can add DM driver for RAM later. Right now, I want to get U-boot SPL running for FU540.

>
>I didn't get you.
>
>>> diff --git a/board/sifive/fu540/include/ememoryotp.h
>>b/board/sifive/fu540/include/ememoryotp.h
>>> new file mode 100644
>>> index 0000000000..274283c4db
>>> --- /dev/null
>>> +++ b/board/sifive/fu540/include/ememoryotp.h
>>> @@ -0,0 +1,24 @@
>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>> +/*
>>> + * Copyright (c) 2019 SiFive, Inc
>>> + *
>>> + * Authors:
>>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>>> + */
>>> +
>
>[...]
>
>>> +
>>> +#ifndef __ASSEMBLER__
>>> +
>>> +#include <stdint.h>
>>> +#include <stddef.h>
>>> +#include <stdbool.h>
>>> +#include "uart.h"
>>> +#include "fu540-memory-map.h"
>>> +
>>> +#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
>>> +#
>>
>>Sorry, too much stuff in single patch. it is worth require multiple patches.
>
>Sure, will split this into multiple patches.
>
>>
>>Jagan.

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

* [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
  2020-01-03 15:34   ` Bin Meng
@ 2020-01-13 14:54     ` Pragnesh Patel
  0 siblings, 0 replies; 19+ messages in thread
From: Pragnesh Patel @ 2020-01-13 14:54 UTC (permalink / raw)
  To: u-boot

>-----Original Message-----
>From: Bin Meng <bmeng.cn@gmail.com>
>Sent: 03 January 2020 21:05
>To: Pragnesh Patel <pragnesh.patel@sifive.com>
>Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Rick Chen
><rick@andestech.com>; Paul Walmsley ( Sifive) <paul.walmsley@sifive.com>;
>Palmer Dabbelt ( Sifive) <palmer@sifive.com>; Anup Patel
><anup.patel@wdc.com>; Atish Patra <atish.patra@wdc.com>; Lukas Auer
><lukas.auer@aisec.fraunhofer.de>; AKASHI Takahiro
><takahiro.akashi@linaro.org>; Simon Glass <sjg@chromium.org>; Marek
>Behún <marek.behun@nic.cz>; Simon Goldschmidt
><simon.k.r.goldschmidt@gmail.com>; Peng Fan <peng.fan@nxp.com>; Boris
>Brezillon <bbrezillon@kernel.org>; Alexander Graf <agraf@csgraf.de>
>Subject: Re: [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
>
>Hi Pragnesh,
>
>On Tue, Dec 31, 2019 at 2:31 PM Pragnesh Patel
><pragnesh.patel@sifive.com> wrote:
>>
>> This patch provides sifive_fu540_spl_defconfig which can support
>> U-boot SPL to boot from L2 LIM (0x0800_0000) and then boot FIT
>
>nits: U-Boot
>
>> image including OpenSBI FW_DYNAMIC firmware and U-Boot proper
>> images from MMC boot devices.
>>
>> With sifive_fu540_spl_defconfig:
>>
>> 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 SD card (replace fw_payload.bin with u-boot.itb)
>> into RAM.
>>
>> 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>
>> ---
>>  arch/riscv/cpu/u-boot-spl.lds                 |    1 +
>>  arch/riscv/dts/fu540-c000-u-boot.dtsi         |   65 +
>>  .../dts/hifive-unleashed-a00-u-boot.dtsi      |   24 +
>>  arch/riscv/include/asm/csr.h                  |    2 +
>>  board/sifive/fu540/Kconfig                    |    8 +
>>  board/sifive/fu540/MAINTAINERS                |    1 +
>>  board/sifive/fu540/Makefile                   |    6 +
>>  board/sifive/fu540/ememoryotp.c               |  143 ++
>>  board/sifive/fu540/fu540.c                    |   31 +-
>>  board/sifive/fu540/include/ccache.h           |   47 +
>>  board/sifive/fu540/include/clkutils.h         |   75 +
>>  board/sifive/fu540/include/ddrregs.h          |  622 +++++++++
>>  board/sifive/fu540/include/ememoryotp.h       |   24 +
>>  board/sifive/fu540/include/fu540-memory-map.h |  427 ++++++
>>  board/sifive/fu540/include/i2c.h              |   49 +
>>  board/sifive/fu540/include/regconfig-ctl.h    |  274 ++++
>>  board/sifive/fu540/include/regconfig-phy.h    | 1224 +++++++++++++++++
>>  board/sifive/fu540/include/spi.h              |  233 ++++
>>  board/sifive/fu540/include/uart.h             |   54 +
>>  board/sifive/fu540/include/ux00ddr.h          |  268 ++++
>>  board/sifive/fu540/include/ux00prci.h         |  206 +++
>>  board/sifive/fu540/spl.c                      |  321 +++++
>>  board/sifive/fu540/uart.c                     |   64 +
>>  configs/sifive_fu540_spl_defconfig            |   23 +
>>  include/configs/sifive-fu540.h                |   17 +
>>  lib/Makefile                                  |    1 +
>>  26 files changed, 4209 insertions(+), 1 deletion(-)
>>  create mode 100644 arch/riscv/dts/fu540-c000-u-boot.dtsi
>>  create mode 100644 arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>>  create mode 100644 board/sifive/fu540/ememoryotp.c
>>  create mode 100644 board/sifive/fu540/include/ccache.h
>>  create mode 100644 board/sifive/fu540/include/clkutils.h
>>  create mode 100644 board/sifive/fu540/include/ddrregs.h
>>  create mode 100644 board/sifive/fu540/include/ememoryotp.h
>>  create mode 100644 board/sifive/fu540/include/fu540-memory-map.h
>>  create mode 100644 board/sifive/fu540/include/i2c.h
>>  create mode 100644 board/sifive/fu540/include/regconfig-ctl.h
>>  create mode 100644 board/sifive/fu540/include/regconfig-phy.h
>>  create mode 100644 board/sifive/fu540/include/spi.h
>>  create mode 100644 board/sifive/fu540/include/uart.h
>>  create mode 100644 board/sifive/fu540/include/ux00ddr.h
>>  create mode 100644 board/sifive/fu540/include/ux00prci.h
>>  create mode 100644 board/sifive/fu540/spl.c
>>  create mode 100644 board/sifive/fu540/uart.c
>>  create mode 100644 configs/sifive_fu540_spl_defconfig
>>
>> 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 = .;
>
>This should be a separate patch.

Sure.

>
>>
>>         .bss : {
>>                 __bss_start = .;
>> 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..b86cdfb38d
>> --- /dev/null
>> +++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
>> @@ -0,0 +1,65 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * (C) Copyright 2019 SiFive, Inc
>> + */
>> +
>> +/ {
>> +       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;
>> +                       cpu1_intc: interrupt-controller {
>> +                               u-boot,dm-spl;
>> +                       };
>> +               };
>> +               cpu2: cpu at 2 {
>> +                       u-boot,dm-spl;
>> +                       cpu2_intc: interrupt-controller {
>> +                               u-boot,dm-spl;
>> +                       };
>> +               };
>> +               cpu3: cpu at 3 {
>> +                       u-boot,dm-spl;
>> +                       cpu3_intc: interrupt-controller {
>> +                               u-boot,dm-spl;
>> +                       };
>> +               };
>> +               cpu4: cpu at 4 {
>> +                       u-boot,dm-spl;
>> +                       cpu4_intc: interrupt-controller {
>> +                               u-boot,dm-spl;
>> +                       };
>> +               };
>> +       };
>> +
>> +       soc {
>> +               u-boot,dm-spl;
>> +               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;
>> +};
>
>Are all of these peripherals needed in SPL?

As far as I know they are all needed, I will recheck and remove any not needed peripherals in v2. 

>
>> 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..9b59f4ee14
>> --- /dev/null
>> +++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>> @@ -0,0 +1,24 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2019 SiFive, Inc
>> + */
>> +
>> +#include "fu540-c000-u-boot.dtsi"
>> +
>> +/ {
>> +       hfclk {
>> +               u-boot,dm-spl;
>> +       };
>> +
>> +       rtcclk {
>> +               u-boot,dm-spl;
>> +       };
>> +};
>> +
>> +&qspi2 {
>> +
>> +       mmc at 0 {
>> +               u-boot,dm-spl;
>> +       };
>> +
>> +};
>> diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
>> index d1520743a2..125c05dd8a 100644
>> --- a/arch/riscv/include/asm/csr.h
>> +++ b/arch/riscv/include/asm/csr.h
>> @@ -103,6 +103,8 @@
>>  #define CSR_TIMEH              0xc81
>>  #define CSR_INSTRETH           0xc82
>>  #define CSR_MHARTID            0xf14
>> +#define CSR_MCYCLE             0xb00
>> +#define CSR_MCYCLEH            0xb80
>>
>>  #ifndef __ASSEMBLY__
>>
>> diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
>> index 816a135b21..ac7c6bff37 100644
>> --- a/board/sifive/fu540/Kconfig
>> +++ b/board/sifive/fu540/Kconfig
>> @@ -16,12 +16,20 @@ config SYS_SOC
>>         default "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/MAINTAINERS
>b/board/sifive/fu540/MAINTAINERS
>> index 702d803ad8..42c3f3deb0 100644
>> --- a/board/sifive/fu540/MAINTAINERS
>> +++ b/board/sifive/fu540/MAINTAINERS
>> @@ -7,3 +7,4 @@ S:      Maintained
>>  F:     board/sifive/fu540/
>>  F:     include/configs/sifive-fu540.h
>>  F:     configs/sifive_fu540_defconfig
>> +F:     configs/sifive_fu540_spl_defconfig
>> diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
>> index 6e1862c475..e532beb9d5 100644
>> --- a/board/sifive/fu540/Makefile
>> +++ b/board/sifive/fu540/Makefile
>> @@ -3,3 +3,9 @@
>>  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
>>
>>  obj-y  += fu540.o
>> +
>> +ifdef CONFIG_SPL_BUILD
>> +obj-y += spl.o
>> +obj-y += ememoryotp.o
>> +obj-y += uart.o
>> +endif
>> diff --git a/board/sifive/fu540/ememoryotp.c
>b/board/sifive/fu540/ememoryotp.c
>> new file mode 100644
>> index 0000000000..994724af37
>> --- /dev/null
>> +++ b/board/sifive/fu540/ememoryotp.c
>> @@ -0,0 +1,143 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (c) 2019 SiFive, Inc
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +
>> +#include <stdint.h>
>> +#include "include/fu540-memory-map.h"
>> +#include "include/clkutils.h"
>> +#include "include/ememoryotp.h"
>> +
>> +#define max(x, y) ((x) > (y) ? (x) : (y))
>> +
>> +extern inline void clkutils_delay_ns(int delay_ns);
>> +
>> +void ememory_otp_power_up_sequence(void)
>> +{
>> +       // Probably don't need to do this, since
>> +       // all the other stuff has been happening.
>> +       // But it is on the wave form.
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TVDS * 1000);
>> +
>> +       EMEMORYOTP_REG(EMEMORYOTP_PDSTB) = 1;
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TSAS * 1000);
>> +
>> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 1;
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TTAS * 1000);
>> +}
>> +
>> +void ememory_otp_power_down_sequence(void)
>> +{
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TTAH * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 0;
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TASH * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PDSTB) = 0;
>> +       // No delay indicated after this
>> +}
>> +
>> +void ememory_otp_begin_read(void)
>> +{
>> +       // Initialize
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 0;
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMS * 1000);
>> +
>> +       // Enable chip select
>> +
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 1;
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TCS * 1000);
>> +}
>> +
>> +void ememory_otp_exit_read(void)
>> +{
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>> +       // Disable chip select
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 0;
>> +       // Wait before changing PTM
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMH * 1000);
>> +}
>> +
>> +unsigned int ememory_otp_read(int address)
>> +{
>> +       unsigned int read_value;
>> +
>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = address;
>> +       // Toggle clock
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TAS * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 1;
>> +       // Insert delay until data is ready.
>> +       // There are lots of delays
>> +       // on the chart, but I think this is the most relevant.
>> +       int delay = max(EMEMORYOTP_MAX_TCD, EMEMORYOTP_MIN_TKH);
>> +
>> +       clkutils_delay_ns(delay * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
>> +       read_value = EMEMORYOTP_REG(EMEMORYOTP_PDOUT);
>> +       // Could check here for things like TCYC < TAH + TCD
>> +       return read_value;
>> +}
>> +
>> +void ememory_otp_pgm_entry(void)
>> +{
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PAS) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PAIO) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 2;
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMS * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 1;
>> +       clkutils_delay_ns(EMEMORYOTP_TYP_TCSP * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PPROG) = 1;
>> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPS * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 1;
>> +}
>> +
>> +void ememory_otp_pgm_exit(void)
>> +{
>> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPH * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PPROG) = 0;
>> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPR * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 0;
>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMH * 1000);
>> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 0;
>> +}
>> +
>> +void ememory_otp_pgm_access(int address, unsigned int write_data)
>> +{
>> +       int i;
>> +
>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = address;
>> +       for (int pas = 0; pas < 2; pas++) {
>> +               EMEMORYOTP_REG(EMEMORYOTP_PAS) = pas;
>> +               for (i = 0; i < 32; i++) {
>> +                       EMEMORYOTP_REG(EMEMORYOTP_PAIO) = i;
>> +                       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = ((write_data >> i)
>&
>> +                                                          1);
>> +
>> +                       int delay = max(EMEMORYOTP_MIN_TASP,
>> +                                       EMEMORYOTP_MIN_TDSP);
>> +
>> +                       clkutils_delay_ns(delay * 1000);
>> +                       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 1;
>> +                       clkutils_delay_ns(EMEMORYOTP_TYP_TPW * 1000);
>> +                       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>> +                       delay = max(EMEMORYOTP_MIN_TAHP,
>EMEMORYOTP_MIN_TDHP);
>> +                       delay = max(delay, EMEMORYOTP_TYP_TPWI);
>> +                       clkutils_delay_ns(delay * 1000);
>> +               }
>> +       }
>> +       EMEMORYOTP_REG(EMEMORYOTP_PAS) = 0;
>> +}
>> diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
>> index 47a2090251..e91418a88a 100644
>> --- a/board/sifive/fu540/fu540.c
>> +++ b/board/sifive/fu540/fu540.c
>> @@ -10,6 +10,9 @@
>>  #include <dm.h>
>>  #include <linux/delay.h>
>>  #include <linux/io.h>
>> +#include <spl.h>
>> +#include "include/ccache.h"
>> +#include "include/fu540-memory-map.h"
>>
>>  #ifdef CONFIG_MISC_INIT_R
>>
>> @@ -143,7 +146,33 @@ int misc_init_r(void)
>>
>>  int board_init(void)
>>  {
>> -       /* For now nothing to do here. */
>> +       /* enable all cache ways */
>> +       ccache_enable_ways(CCACHE_CTRL_ADDR, 15);
>> +       return 0;
>> +}
>> +
>> +#ifdef CONFIG_SPL
>> +void board_boot_order(u32 *spl_boot_list)
>> +{
>> +       u8 i;
>> +       u32 boot_devices[] = {
>> +#ifdef CONFIG_SPL_RAM_SUPPORT
>> +               BOOT_DEVICE_RAM,
>> +#endif
>> +#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/include/ccache.h
>b/board/sifive/fu540/include/ccache.h
>> new file mode 100644
>> index 0000000000..c7978ebdee
>> --- /dev/null
>> +++ b/board/sifive/fu540/include/ccache.h
>> @@ -0,0 +1,47 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (c) 2019 SiFive, Inc
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +
>> +#ifndef FU540_CCACHE_H
>> +#define FU540_CCACHE_H
>> +
>> +#include <asm/arch/cache.h>
>> +
>> +#ifndef __ASSEMBLER__
>> +
>> +#include <stdint.h>
>> +#include <stdatomic.h>
>> +#include <linux/types.h>
>> +
>> +// Block memory access until operation completed
>> +static inline void ccache_barrier_0(void)
>> +{
>> +       asm volatile("fence rw, io" : : : "memory");
>> +}
>> +
>> +static inline void ccache_barrier_1(void)
>> +{
>> +       asm volatile("fence io, rw" : : : "memory");
>> +}
>> +
>> +// Enable ways; allow cache to use these ways
>> +static inline u8 ccache_enable_ways(u64 base_addr, u8 value)
>> +{
>> +       u32 old;
>> +
>> +       volatile _Atomic(u32) * enable = (_Atomic(u32) *)(base_addr +
>> +                                         CCACHE_ENABLE);
>> +       ccache_barrier_0();
>> +       old = atomic_exchange_explicit(enable, value,
>memory_order_relaxed);
>
>How does this work as we are calling a C11 API?

I will check this and update in v2.

>
>> +       ccache_barrier_1();
>> +       return old;
>> +}
>> +
>> +#endif
>> +
>> +#endif /* FU540_CCACHE_H */
>> diff --git a/board/sifive/fu540/include/clkutils.h
>b/board/sifive/fu540/include/clkutils.h
>> new file mode 100644
>> index 0000000000..dbb260a1c3
>> --- /dev/null
>> +++ b/board/sifive/fu540/include/clkutils.h
>> @@ -0,0 +1,75 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (c) 2019 SiFive, Inc
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +
>> +#ifndef __ASSEMBLER__
>> +
>> +#include <stdint.h>
>> +#include <asm/encoding.h>
>> +#include "fu540-memory-map.h"
>> +
>> +// Inlining header functions in C
>> +// https://stackoverflow.com/a/23699777/7433423
>> +inline u64 clkutils_read_mtime(void)
>> +{
>> +#if __riscv_xlen == 32
>> +       u32 mtime_hi_0;
>> +       u32 mtime_lo;
>> +       u32 mtime_hi_1;
>> +
>> +       do {
>> +               mtime_hi_0 = CLINT_REG(CLINT_MTIME + 4);
>> +               mtime_lo   = CLINT_REG(CLINT_MTIME + 0);
>> +               mtime_hi_1 = CLINT_REG(CLINT_MTIME + 4);
>> +       } while (mtime_hi_0 != mtime_hi_1);
>> +
>> +       return (((u64)mtime_hi_1 << 32) | ((u64)mtime_lo));
>> +#else
>> +       return CLINT_REG64(CLINT_MTIME);
>> +#endif
>> +}
>> +
>> +static inline u64 clkutils_read_mcycle(void)
>> +{
>> +#if __riscv_xlen == 32
>> +       u32 mcycle_hi_0;
>> +       u32 mcycle_lo;
>> +       u32 mcycle_hi_1;
>> +
>> +       do {
>> +               mcycle_hi_0 = read_csr(mcycleh);
>> +               mcycle_lo   = read_csr(mcycle);
>> +               mcycle_hi_1 = read_csr(mcycleh);
>> +       } while (mcycle_hi_0 != mcycle_hi_1);
>> +
>> +       return (((u64)mcycle_hi_1 << 32) | ((u64)mcycle_lo));
>> +#else
>> +       return csr_read(CSR_MCYCLE);
>> +#endif
>> +}
>> +
>> +// Note that since this runs off RTC, which is
>> +// currently ~1-10MHz, this function is
>> +// not acccurate for small delays.
>> +// In the future, we may want to determine whether to
>> +// use RTC vs mcycle, or create a different function
>> +// based off mcycle.
>> +// We add 1 to the then value because otherwise, if you wanted
>> +// to delay up to RTC_PERIOD_NS-1 (for example), you wouldn't delay
>> +// at all. So this function delays AT LEAST delay_ns.
>> +inline void clkutils_delay_ns(int delay_ns)
>> +{
>> +       u64 now = clkutils_read_mtime();
>> +       u64 then = now + delay_ns / RTC_PERIOD_NS + 1;
>> +
>> +       do {
>> +               now = clkutils_read_mtime();
>> +       } while (now < then);
>> +}
>> +
>> +#endif /* !__ASSEMBLER__ */
>> diff --git a/board/sifive/fu540/include/ddrregs.h
>b/board/sifive/fu540/include/ddrregs.h
>> new file mode 100644
>> index 0000000000..e436496d87
>> --- /dev/null
>> +++ b/board/sifive/fu540/include/ddrregs.h
>> @@ -0,0 +1,622 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (c) 2019 SiFive, Inc
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +
>> +#include <stdint.h>
>> +
>> +u32 DENALI_PHY_DATA[1215] = {
>
>This is declaring a variable and should not be put in a header file.

I will update in v2, thanks for the review.

>
>> +       DENALI_PHY_00_DATA, DENALI_PHY_01_DATA,
> [......]
>> diff --git a/board/sifive/fu540/include/ememoryotp.h
>b/board/sifive/fu540/include/ememoryotp.h
>> new file mode 100644
>> index 0000000000..274283c4db
>> --- /dev/null
>> +++ b/board/sifive/fu540/include/ememoryotp.h
>> @@ -0,0 +1,24 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (c) 2019 SiFive, Inc
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +
>> +#ifndef FU540_EMEMORYOTP_H
>> +#define FU540_EMEMORYOTP_H
>> +
>> +#include <asm/arch/otp.h>
>> +
>> +void ememory_otp_power_up_sequence(void);
>> +void ememory_otp_power_down_sequence(void);
>> +}
>> +
>> +#endif /* __ASSEMBLER__ */
>> +
>> +#endif /* FU540_UX00DDR_H */
> [....]
>> diff --git a/board/sifive/fu540/include/ux00prci.h
>b/board/sifive/fu540/include/ux00prci.h
>> new file mode 100644
>> index 0000000000..21f4aeb465
>> --- /dev/null
>> +++ b/board/sifive/fu540/include/ux00prci.h
>> @@ -0,0 +1,206 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +
>> +/*
>> + * Copyright (c) 2019 SiFive, Inc
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +
>> +#ifndef _SIFIVE_UX00PRCI_H
>> +#define _SIFIVE_UX00PRCI_H
>> +
>> +/* Register offsets */
>> +
>> +#define UX00PRCI_HFROSCCFG          (0x0000)
>> +#define UX00PRCI_COREPLLCFG         (0x0004)
>> +#define UX00PRCI_COREPLLOUT         (0x0008)
>> +#define UX00PRCI_DDRPLLCFG          (0x000C)
>> +#define UX00PRCI_DDRPLLOUT          (0x0010)
>> +#define UX00PRCI_GEMGXLPLLCFG       (0x001C)
>> +#define UX00PRCI_GEMGXLPLLOUT       (0x0020)
>> +#define UX00PRCI_CORECLKSELREG      (0x0024)
>> +#define UX00PRCI_DEVICESRESETREG    (0x0028)
>> +#define UX00PRCI_CLKMUXSTATUSREG    (0x002C)
>> +#define UX00PRCI_PROCMONCFG         (0x00F0)
>> +
>> +/* Fields */
>> +#define XOSC_EN(x)            (((x) & 0x1) << 30)
>> +#define XOSC_RDY(x)           (((x) & 0x1) << 31)
>> +
>> +#define PLL_R(x)              (((x) & 0x3F) << 0)
>> +#define PLL_F(x)              (((x) & 0x1FF) << 6)
>> +#define PLL_Q(x)              (((x) & 0x7) << 15)
>> +#define PLL_RANGE(x)          (((x) & 0x7) << 18)
>> +#define PLL_BYPASS(x)         (((x) & 0x1) << 24)
>> +#define PLL_FSE(x)            (((x) & 0x1) << 25)
>> +#define PLL_LOCK(x)           (((x) & 0x1) << 31)
>> +
>> +#define PLLOUT_DIV(x)         (((x) & 0x7F) << 0)
>> +#define PLLOUT_DIV_BY_1(x)    (((x) & 0x1) << 8)
>> +#define PLLOUT_CLK_EN(x)      (((x) & 0x1) << 31)
>> +
>> +#define PLL_R_default              0x1
>> +#define PLL_F_default              0x1F
>> +#define PLL_Q_default              0x3
>> +#define PLL_RANGE_default          0x0
>> +#define PLL_BYPASS_default         0x1
>> +#define PLL_FSE_default            0x1
>> +
>> +#define PLLOUT_DIV_default         0x0
>> +#define PLLOUT_DIV_BY_1_default    0x0
>> +#define PLLOUT_CLK_EN_default      0x0
>> +
>> +#define PLL_CORECLKSEL_HFXIN       0x1
>> +#define PLL_CORECLKSEL_COREPLL     0x0
>> +
>> +#define DEVICESRESET_DDR_CTRL_RST_N(x)    (((x) & 0x1) << 0)
>> +#define DEVICESRESET_DDR_AXI_RST_N(x)     (((x) & 0x1) << 1)
>> +#define DEVICESRESET_DDR_AHB_RST_N(x)     (((x) & 0x1) << 2)
>> +#define DEVICESRESET_DDR_PHY_RST_N(x)     (((x) & 0x1) << 3)
>> +#define DEVICESRESET_GEMGXL_RST_N(x)      (((x) & 0x1) << 5)
>> +
>> +#define CLKMUX_STATUS_CORECLKPLLSEL    (0x1 << 0)
>> +#define CLKMUX_STATUS_TLCLKSEL         (0x1 << 1)
>> +#define CLKMUX_STATUS_RTCXSEL          (0x1 << 2)
>> +#define CLKMUX_STATUS_DDRCTRLCLKSEL    (0x1 << 3)
>> +#define CLKMUX_STATUS_DDRPHYCLKSEL     (0x1 << 4)
>> +#define CLKMUX_STATUS_GEMGXLCLKSEL     (0x1 << 6)
>> +
>> +#ifndef __ASSEMBLER__
>> +
>> +#include <stdint.h>
>> +#include <linux/types.h>
>> +
>> +static inline int ux00prci_select_corepll(volatile u32 *coreclkselreg,
>> +                                         volatile u32 *corepllcfg,
>> +                                         volatile u32 *corepllout,
>> +                                         u32 pllconfigval)
>> +{
>> +       (*corepllcfg) = pllconfigval;
>> +
>> +       // Wait for lock
>> +       while (((*corepllcfg) & (PLL_LOCK(1))) == 0)
>> +               ;
>> +
>> +       u32 core_out =
>> +               (PLLOUT_DIV(PLLOUT_DIV_default)) |
>> +               (PLLOUT_DIV_BY_1(PLLOUT_DIV_BY_1_default)) |
>> +               (PLLOUT_CLK_EN(1));
>> +       (*corepllout) = core_out;
>> +
>> +       // Set CORECLKSELREG to select COREPLL
>> +       (*coreclkselreg) = PLL_CORECLKSEL_COREPLL;
>> +
>> +       return 0;
>> +}
>> +
>> +static inline int ux00prci_select_corepll_1_4ghz(volatile u32 *coreclkselreg,
>> +                                                volatile u32 *corepllcfg,
>> +                                                volatile u32 *corepllout)
>> +{
>> +       //
>> +       // CORE pll init
>> +       // Set corepll 33MHz -> 1GHz
>> +       //
>> +
>> +       u32 core14ghz =
>> +               (PLL_R(0)) |
>> +               (PLL_F(41)) |            /*2800MHz VCO*/
>> +               (PLL_Q(1)) |             /* /2 Output divider */
>> +               (PLL_RANGE(0x4)) |
>> +               (PLL_BYPASS(0)) |
>> +               (PLL_FSE(1));
>> +
>> +       return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
>> +                                       core14ghz);
>> +}
>> +
>> +static inline int ux00prci_select_corepll_1_5ghz(volatile u32 *coreclkselreg,
>> +                                                volatile u32 *corepllcfg,
>> +                                                volatile u32 *corepllout)
>> +{
>> +       //
>> +       // CORE pll init
>> +       // Set corepll 33MHz -> 1GHz
>> +       //
>> +
>> +       u32 core15ghz =
>> +               (PLL_R(0)) |
>> +               (PLL_F(44)) |            /*3000MHz VCO*/
>> +               (PLL_Q(1)) |             /* /2 Output divider */
>> +               (PLL_RANGE(0x4)) |
>> +               (PLL_BYPASS(0)) |
>> +               (PLL_FSE(1));
>> +
>> +       return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
>> +                                       core15ghz);
>> +}
>> +
>> +static inline int ux00prci_select_corepll_1_6ghz(volatile u32 *coreclkselreg,
>> +                                                volatile u32 *corepllcfg,
>> +                                                volatile u32 *corepllout)
>> +{
>> +       //
>> +       // CORE pll init
>> +       // Set corepll 33MHz -> 1GHz
>> +       //
>> +
>> +       u32 core16ghz =
>> +               (PLL_R(0)) |
>> +               (PLL_F(47)) |            /*3200MHz VCO*/
>> +               (PLL_Q(1)) |             /* /2 Output divider */
>> +               (PLL_RANGE(0x4)) |
>> +               (PLL_BYPASS(0)) |
>> +               (PLL_FSE(1));
>> +
>> +       return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
>> +                                       core16ghz);
>> +}
>> +
>> +static inline int ux00prci_select_corepll_1ghz(volatile u32 *coreclkselreg,
>> +                                              volatile u32 *corepllcfg,
>> +                                              volatile u32 *corepllout)
>> +{
>> +       //
>> +       // CORE pll init
>> +       // Set corepll 33MHz -> 1GHz
>> +       //
>> +
>> +       u32 core1ghz =
>> +               (PLL_R(0)) |
>> +               (PLL_F(59)) |            /*4000MHz VCO*/
>> +               (PLL_Q(2)) |             /* /4 Output divider */
>> +               (PLL_RANGE(0x4)) |
>> +               (PLL_BYPASS(0)) |
>> +               (PLL_FSE(1));
>> +
>> +       return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
>> +                                       core1ghz);
>> +}
>> +
>> +static inline int ux00prci_select_corepll_500mhz(volatile u32 *coreclkselreg,
>> +                                                volatile u32 *corepllcfg,
>> +                                                volatile u32 *corepllout)
>> +{
>> +       //
>> +       // CORE pll init
>> +       // Set corepll 33MHz -> 1GHz
>> +       //
>> +
>> +       u32 core500mhz =
>> +               (PLL_R(0)) |
>> +               (PLL_F(59)) |            /*4000MHz VCO*/
>> +               (PLL_Q(3)) |             /* /8 Output divider */
>> +               (PLL_RANGE(0x4)) |
>> +               (PLL_BYPASS(0)) |
>> +               (PLL_FSE(1));
>> +
>> +       return ux00prci_select_corepll(coreclkselreg, corepllcfg, corepllout,
>> +                                       core500mhz);
>> +}
>> +
>
>Can we reuse the U-Boot PRCI driver for SPL? If not, could we update
>it instead of creating another ad-hoc driver?

I agreed with you but for preload_console_init(), UART clock needs to be enabled and that is
provided by tlclk (corepll).

This clock initialization is necessary for SPL but I will move this code to spl.c from header file.
Let me know if you have any other suggestion.
 
>
>> +#endif
>> +
>> +#endif // _SIFIVE_UX00PRCI_H
>> diff --git a/board/sifive/fu540/spl.c b/board/sifive/fu540/spl.c
>> new file mode 100644
>> index 0000000000..69187066ba
>> --- /dev/null
>> +++ b/board/sifive/fu540/spl.c
>> @@ -0,0 +1,321 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (c) 2019 SiFive, Inc
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +
>> +#include <common.h>
>> +#include <spl.h>
>> +
>> +#include "include/regconfig-ctl.h"
>> +#include "include/regconfig-phy.h"
>> +#include "include/ux00ddr.h"
>> +#include "include/ddrregs.h"
>> +
>> +#include "include/fu540-memory-map.h"
>> +#include <stdatomic.h>
>> +
>> +#define ddr_phy_settings DENALI_PHY_DATA
>> +#define ddr_ctl_settings DENALI_CTL_DATA
>> +
>> +#define DDR_SIZE  (8UL * 1024UL * 1024UL * 1024UL)
>> +#define DDRCTLPLL_F 55
>> +#define DDRCTLPLL_Q 2
>> +
>> +#define PHY_NRESET 0x1000
>> +#define FIRST_SLOT  0xfe
>> +#define LAST_SLOT   0x80
>> +
>> +static const uintptr_t i2c_devices[] = {
>> +       I2C_CTRL_ADDR,
>> +};
>> +
>> +static spi_ctrl * const spi_devices[] = {
>> +       (spi_ctrl *)SPI0_CTRL_ADDR,
>> +       (spi_ctrl *)SPI1_CTRL_ADDR,
>> +       (spi_ctrl *)SPI2_CTRL_ADDR,
>> +};
>> +
>> +static const uintptr_t uart_devices[] = {
>> +       UART0_CTRL_ADDR,
>> +       UART1_CTRL_ADDR,
>> +};
>> +
>> +unsigned int serial_to_burn = ~0;
>> +
>> +/**
>> + * Scale peripheral clock dividers before changing core PLL.
>> + */
>> +void update_peripheral_clock_dividers(unsigned int peripheral_input_khz)
>
>Are these a must-have? ie: can we have individual device driver (ie:
>sifive i2c, or sifive spi driver to do such work in their probe()
>routine)?

Yes, you are right. Only UART clock divider needs to be updated.
Will update in v2.

>
>> +{
>> +       unsigned int i2c_target_khz = 400;
>> +       u16 prescaler = i2c_min_clk_prescaler(peripheral_input_khz,
>> +                                             i2c_target_khz);
>> +
>> +       for (size_t i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
>> +               _REG32(i2c_devices[i], I2C_PRESCALER_LO) = prescaler & 0xff;
>> +               _REG32(i2c_devices[i], I2C_PRESCALER_HI) = (prescaler >> 8) &
>> +                                                          0xff;
>> +       }
>> +
>> +       unsigned int spi_target_khz = 50000;
>> +       unsigned int spi_div = spi_min_clk_divisor(peripheral_input_khz,
>> +                                                  spi_target_khz);
>> +
>> +       for (size_t i = 0; i < ARRAY_SIZE(spi_devices); i++)
>> +               spi_devices[i]->sckdiv = spi_div;
>> +
>> +       unsigned int uart_target_hz = 115200ULL;
>> +       unsigned int uart_div = uart_min_clk_divisor(peripheral_input_khz *
>> +                                                    1000ULL, uart_target_hz);
>> +
>> +       for (size_t i = 0; i < ARRAY_SIZE(uart_devices); i++)
>> +               _REG32(uart_devices[i], UART_REG_DIV) = uart_div;
>> +}
>> +
>> +long nsec_per_cyc = 300; // 33.333MHz
>> +void nsleep(long nsec)
>> +{
>> +       long step = nsec_per_cyc * 2; // 2 instructions per loop iteration
>> +
>> +       while (nsec > 0)
>> +               nsec -= step;
>> +}
>> +
>> +void init_clk_and_ddr(void)
>> +{
>> +       // PRCI init
>> +
>> +       // Initialize UART divider for 33MHz core clock in case if
>> +       // trap is taken prior to core clock bump.
>> +       unsigned long long uart_target_hz = 115200ULL;
>> +       const u32 initial_core_clk_khz = 33000;
>> +       unsigned long peripheral_input_khz;
>> +
>> +       if (UX00PRCI_REG(UX00PRCI_CLKMUXSTATUSREG) &
>CLKMUX_STATUS_TLCLKSEL)
>> +               peripheral_input_khz = initial_core_clk_khz;
>> +       else
>> +               peripheral_input_khz = initial_core_clk_khz / 2;
>> +       UART0_REG(UART_REG_DIV) =
>uart_min_clk_divisor(peripheral_input_khz *
>> +                                                      1000ULL, uart_target_hz);
>> +
>> +       // Check Reset Values (lock don't care)
>> +       u32 pll_default =
>> +               (PLL_R(PLL_R_default)) |
>> +               (PLL_F(PLL_F_default)) |
>> +               (PLL_Q(PLL_Q_default)) |
>> +               (PLL_RANGE(PLL_RANGE_default)) |
>> +               (PLL_BYPASS(PLL_BYPASS_default)) |
>> +               (PLL_FSE(PLL_FSE_default));
>> +       u32 lockmask = ~PLL_LOCK(1);
>> +       u32 pllout_default =
>> +               (PLLOUT_DIV(PLLOUT_DIV_default)) |
>> +               (PLLOUT_DIV_BY_1(PLLOUT_DIV_BY_1_default)) |
>> +               (PLLOUT_CLK_EN(PLLOUT_CLK_EN_default));
>> +
>> +       if ((UX00PRCI_REG(UX00PRCI_COREPLLCFG)     ^ pll_default) &
>lockmask)
>> +               return;
>> +       if ((UX00PRCI_REG(UX00PRCI_COREPLLOUT)     ^ pllout_default))
>> +               return;
>> +       if ((UX00PRCI_REG(UX00PRCI_DDRPLLCFG)      ^ pll_default) & lockmask)
>> +               return;
>> +       if ((UX00PRCI_REG(UX00PRCI_DDRPLLOUT)      ^ pllout_default))
>> +               return;
>> +       if (((UX00PRCI_REG(UX00PRCI_GEMGXLPLLCFG)) ^ pll_default) &
>lockmask)
>> +               return;
>> +       if (((UX00PRCI_REG(UX00PRCI_GEMGXLPLLOUT)) ^ pllout_default))
>> +               return;
>> +
>> +       //CORE pll init
>> +       // If tlclksel is set for 2:1 operation,
>> +       // Set corepll 33Mhz -> 1GHz
>> +       // Otherwise, set corepll 33MHz -> 500MHz.
>> +
>> +       if (UX00PRCI_REG(UX00PRCI_CLKMUXSTATUSREG) &
>CLKMUX_STATUS_TLCLKSEL) {
>> +               nsec_per_cyc = 2;
>> +               peripheral_input_khz = 500000; // peripheral_clk = tlclk
>> +               update_peripheral_clock_dividers(peripheral_input_khz);
>> +               ux00prci_select_corepll_500mhz
>> +                       (&UX00PRCI_REG(UX00PRCI_CORECLKSELREG),
>> +                        &UX00PRCI_REG(UX00PRCI_COREPLLCFG),
>> +                        &UX00PRCI_REG(UX00PRCI_COREPLLOUT));
>> +       } else {
>> +               nsec_per_cyc = 1;
>> +               peripheral_input_khz = (1000000 / 2); // peripheral_clk = tlclk
>> +               update_peripheral_clock_dividers(peripheral_input_khz);
>> +
>> +               ux00prci_select_corepll_1ghz
>> +                       (&UX00PRCI_REG(UX00PRCI_CORECLKSELREG),
>> +                        &UX00PRCI_REG(UX00PRCI_COREPLLCFG),
>> +                        &UX00PRCI_REG(UX00PRCI_COREPLLOUT));
>> +       }
>> +
>> +       //
>> +       //DDR init
>> +       //
>> +
>> +       u32 ddrctlmhz =
>> +               (PLL_R(0)) |
>> +               (PLL_F(DDRCTLPLL_F)) |
>> +               (PLL_Q(DDRCTLPLL_Q)) |
>> +               (PLL_RANGE(0x4)) |
>> +               (PLL_BYPASS(0)) |
>> +               (PLL_FSE(1));
>> +       UX00PRCI_REG(UX00PRCI_DDRPLLCFG) = ddrctlmhz;
>> +
>> +       // Wait for lock
>> +       while ((UX00PRCI_REG(UX00PRCI_DDRPLLCFG) & PLL_LOCK(1)) == 0)
>> +               ;
>> +
>> +       u32 ddrctl_out =
>> +               (PLLOUT_DIV(PLLOUT_DIV_default)) |
>> +               (PLLOUT_DIV_BY_1(PLLOUT_DIV_BY_1_default)) |
>> +               (PLLOUT_CLK_EN(1));
>> +       (UX00PRCI_REG(UX00PRCI_DDRPLLOUT)) = ddrctl_out;
>> +
>> +       //Release DDR reset.
>> +       UX00PRCI_REG(UX00PRCI_DEVICESRESETREG) |=
>> +               DEVICESRESET_DDR_CTRL_RST_N(1);
>> +
>> +       // HACK to get the '1 full controller clock cycle'.
>> +       asm volatile ("fence");
>> +       UX00PRCI_REG(UX00PRCI_DEVICESRESETREG) |=
>DEVICESRESET_DDR_AXI_RST_N(1)
>> +              | DEVICESRESET_DDR_AHB_RST_N(1) |
>DEVICESRESET_DDR_PHY_RST_N(1);
>> +       // 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");
>> +
>> +       ux00ddr_writeregmap(UX00DDR_CTRL_ADDR, ddr_ctl_settings,
>> +                           ddr_phy_settings);
>> +       ux00ddr_disableaxireadinterleave(UX00DDR_CTRL_ADDR);
>> +
>> +       ux00ddr_disableoptimalrmodw(UX00DDR_CTRL_ADDR);
>> +
>> +       ux00ddr_enablewriteleveling(UX00DDR_CTRL_ADDR);
>> +       ux00ddr_enablereadleveling(UX00DDR_CTRL_ADDR);
>> +       ux00ddr_enablereadlevelinggate(UX00DDR_CTRL_ADDR);
>> +       if (ux00ddr_getdramclass(UX00DDR_CTRL_ADDR) ==
>DRAM_CLASS_DDR4)
>> +               ux00ddr_enablevreftraining(UX00DDR_CTRL_ADDR);
>> +       //mask off interrupts for leveling completion
>> +       ux00ddr_mask_leveling_completed_interrupt(UX00DDR_CTRL_ADDR);
>> +
>> +       ux00ddr_mask_mc_init_complete_interrupt(UX00DDR_CTRL_ADDR);
>> +       ux00ddr_mask_outofrange_interrupts(UX00DDR_CTRL_ADDR);
>> +       ux00ddr_setuprangeprotection(UX00DDR_CTRL_ADDR, DDR_SIZE);
>> +
>ux00ddr_mask_port_command_error_interrupt(UX00DDR_CTRL_ADDR);
>> +
>> +       const u64 ddr_size = DDR_SIZE;
>> +       const u64 ddr_end = CONFIG_SYS_SDRAM_BASE + ddr_size;
>> +
>> +       ux00ddr_start(UX00DDR_CTRL_ADDR, PHYSICAL_FILTER_CTRL_ADDR,
>ddr_end);
>> +       ux00ddr_phy_fixup(UX00DDR_CTRL_ADDR);
>> +
>> +       //
>> +       //GEMGXL init
>> +       //
>> +       u32 gemgxl125mhz =
>> +               (PLL_R(0)) |
>> +               (PLL_F(59)) |  /*4000Mhz VCO*/
>> +               (PLL_Q(5)) |   /* /32 */
>> +               (PLL_RANGE(0x4)) |
>> +               (PLL_BYPASS(0)) |
>> +               (PLL_FSE(1));
>> +       UX00PRCI_REG(UX00PRCI_GEMGXLPLLCFG) = gemgxl125mhz;
>> +
>> +       // Wait for lock
>> +       while ((UX00PRCI_REG(UX00PRCI_GEMGXLPLLCFG) & PLL_LOCK(1)) ==
>0)
>> +               ;
>> +
>> +       u32 gemgxlctl_out =
>> +               (PLLOUT_DIV(PLLOUT_DIV_default)) |
>> +               (PLLOUT_DIV_BY_1(PLLOUT_DIV_BY_1_default)) |
>> +               (PLLOUT_CLK_EN(1));
>> +       UX00PRCI_REG(UX00PRCI_GEMGXLPLLOUT) = gemgxlctl_out;
>> +
>> +       //Release GEMGXL reset (set bit DEVICESRESET_GEMGXL to 1)
>> +       UX00PRCI_REG(UX00PRCI_DEVICESRESETREG) |=
>DEVICESRESET_GEMGXL_RST_N(1);
>> +
>> +       // VSC8541 PHY reset sequence; leave pull-down active for 2ms
>> +       nsleep(2000000);
>> +       // Set GPIO 12 (PHY NRESET) to OE=1 and OVAL=1
>> +       atomic_fetch_or(&GPIO_REG(GPIO_OUTPUT_VAL), PHY_NRESET);
>> +       atomic_fetch_or(&GPIO_REG(GPIO_OUTPUT_EN),  PHY_NRESET);
>> +       nsleep(100);
>> +
>> +       // Procmon => core clock
>> +       UX00PRCI_REG(UX00PRCI_PROCMONCFG) = 0x1 << 24;
>> +
>> +       // Post the serial number and build info
>> +       UART0_REG(UART_REG_TXCTRL) = UART_TXEN;
>> +       puts("\r\nPRCI Initialized:       ");
>> +
>> +       unsigned int serial = ~0;
>> +       int serial_slot;
>> +       unsigned int pos;
>> +       unsigned int neg;
>> +
>> +       ememory_otp_power_up_sequence();
>> +       ememory_otp_begin_read();
>> +       for (serial_slot = FIRST_SLOT; serial_slot >= LAST_SLOT;
>> +                       serial_slot -= 2) {
>> +               pos = ememory_otp_read(serial_slot);
>> +               neg = ememory_otp_read(serial_slot + 1);
>> +               serial = pos;
>> +               if (pos == ~neg)
>> +                       break; // legal serial #
>> +               if (pos == ~0 && neg == ~0)
>> +                       break; // empty slot encountered
>> +       }
>> +       ememory_otp_exit_read();
>> +
>> +       void *uart = (void *)UART0_CTRL_ADDR;
>> +
>> +       uart_puts(uart, "\r\nHiFive-U serial #: ");
>> +       uart_put_hex(uart, serial);
>
>I don't this we really need this.

I will remove this.

>
>> +
>> +       // Program the OTP?
>> +       if (serial_to_burn != ~0 && serial != serial_to_burn &&
>> +           serial_slot > LAST_SLOT) {
>> +               uart_puts(uart, "Programming serial: ");
>> +               uart_put_hex(uart, serial_to_burn);
>> +               uart_puts(uart, "\r\n");
>> +               ememory_otp_pgm_entry();
>> +               if (serial != ~0) {
>> +                       // erase the current serial
>> +                       uart_puts(uart, "Erasing prior serial\r\n");
>> +                       ememory_otp_pgm_access(serial_slot,   0);
>> +                       ememory_otp_pgm_access(serial_slot + 1, 0);
>> +                       serial_slot -= 2;
>> +               }
>> +               ememory_otp_pgm_access(serial_slot,    serial_to_burn);
>> +               ememory_otp_pgm_access(serial_slot + 1, ~serial_to_burn);
>> +               ememory_otp_pgm_exit();
>> +               uart_puts(uart, "Resuming boot\r\n");
>> +               serial = serial_to_burn;
>> +       }
>> +
>> +       ememory_otp_power_down_sequence();
>> +       uart_puts(uart, "\r\n");
>> +}
>> +
>> +void board_init_f(ulong dummy)
>> +{
>> +       int ret;
>> +
>> +       init_clk_and_ddr();
>> +
>> +       ret = spl_early_init();
>> +       if (ret)
>> +               panic("spl_early_init() failed: %d\n", ret);
>> +
>> +       arch_cpu_init_dm();
>> +
>> +       preloader_console_init();
>> +}
>> diff --git a/board/sifive/fu540/uart.c b/board/sifive/fu540/uart.c
>> new file mode 100644
>> index 0000000000..d16f6add47
>> --- /dev/null
>> +++ b/board/sifive/fu540/uart.c
>
>Can we drop this, instead use the sifive uart driver directory?

Will update in v2.

>
>> @@ -0,0 +1,64 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (c) 2019 SiFive, Inc
>> + *
>> + * Authors:
>> + *   Pragnesh Patel <pragnesh.patel@sifive.com>
>> + *   Troy Benjegerdes <troy.benjegerdes@sifive.com>
>> + */
>> +
>> +#include <stdatomic.h>
>> +#include "include/fu540-memory-map.h"
>> +#include "include/uart.h"
>> +
>> +void uart_putc(void *uartctrl, char c)
>> +{
>> +#if __riscv_atomic
>> +       s32 r;
>> +
>> +       do {
>> +               asm volatile ("amoor.w %0, %2, %1\n" : "=r" (r),
>> +                             "+A" (_REG32(uartctrl, UART_REG_TXFIFO))
>> +                             : "r" (c)
>> +                            );
>> +       } while (r < 0);
>> +#else
>> +       while ((int)_REG32(uartctrl, UART_REG_TXFIFO) < 0)
>> +               ;
>> +       _REG32(uartctrl, UART_REG_TXFIFO) = c;
>> +#endif
>> +}
>> +
>> +char uart_getc(void *uartctrl)
>> +{
>> +       s32 val = -1;
>> +
>> +       while (val < 0)
>> +               val = (s32)_REG32(uartctrl, UART_REG_RXFIFO);
>> +
>> +       return val & 0xFF;
>> +}
>> +
>> +void uart_puts(void *uartctrl, const char *s)
>> +{
>> +       while (*s != '\0')
>> +               uart_putc(uartctrl, *s++);
>> +}
>> +
>> +void uart_put_hex(void *uartctrl, u32 hex)
>> +{
>> +       int num_nibbles = sizeof(hex) * 2;
>> +
>> +       for (int nibble_idx = num_nibbles - 1; nibble_idx >= 0; nibble_idx--) {
>> +               char nibble = (hex >> (nibble_idx * 4)) & 0xf;
>> +
>> +               uart_putc(uartctrl, (nibble < 0xa) ? ('0' + nibble) :
>> +                         ('a' + nibble - 0xa));
>> +       }
>> +}
>> +
>> +void uart_put_hex64(void *uartctrl, uint64_t hex)
>> +{
>> +       uart_put_hex(uartctrl, hex >> 32);
>> +       uart_put_hex(uartctrl, hex & 0xFFFFFFFF);
>> +}
>> diff --git a/configs/sifive_fu540_spl_defconfig
>b/configs/sifive_fu540_spl_defconfig
>> new file mode 100644
>> index 0000000000..6f9a70ee3e
>> --- /dev/null
>> +++ b/configs/sifive_fu540_spl_defconfig
>> @@ -0,0 +1,23 @@
>> +CONFIG_RISCV=y
>> +CONFIG_ENV_SIZE=0x20000
>> +CONFIG_NR_DRAM_BANKS=1
>> +CONFIG_TARGET_SIFIVE_FU540=y
>> +CONFIG_ARCH_RV64I=y
>> +CONFIG_RISCV_SMODE=y
>> +CONFIG_DISTRO_DEFAULTS=y
>> +CONFIG_FIT=y
>> +CONFIG_MISC_INIT_R=y
>> +CONFIG_DEFAULT_DEVICE_TREE="hifive-unleashed-a00"
>> +CONFIG_DISPLAY_CPUINFO=y
>> +CONFIG_DISPLAY_BOARDINFO=y
>> +CONFIG_OF_SEPARATE=y
>> +CONFIG_SPL_SEPARATE_BSS=y
>> +CONFIG_SYS_RELOC_GD_ENV_ADDR=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"
>> diff --git a/include/configs/sifive-fu540.h b/include/configs/sifive-fu540.h
>> index 2756ed5a77..5afc7ddb66 100644
>> --- a/include/configs/sifive-fu540.h
>> +++ b/include/configs/sifive-fu540.h
>> @@ -11,6 +11,21 @@
>>
>>  #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 +39,7 @@
>>
>>  /* Environment options */
>>
>> +#ifndef CONFIG_SPL_BUILD
>>  #define BOOT_TARGET_DEVICES(func) \
>>         func(MMC, mmc, 0) \
>>         func(DHCP, dhcp, na)
>> @@ -43,5 +59,6 @@
>>  #define CONFIG_PREBOOT \
>>         "setenv fdt_addr ${fdtcontroladdr};" \
>>         "fdt addr ${fdtcontroladdr};"
>> +#endif
>>
>>  #endif /* __CONFIG_H */
>> diff --git a/lib/Makefile b/lib/Makefile
>> index 1fb650cd90..2d88c2ab5e 100644
>> --- a/lib/Makefile
>> +++ b/lib/Makefile
>> @@ -76,6 +76,7 @@ endif
>>
>>  ifdef CONFIG_SPL_BUILD
>>  obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o
>> +obj-$(CONFIG_MMC_SPI) += crc7.o
>>  obj-$(CONFIG_$(SPL_TPL_)HASH_SUPPORT) += crc16.o
>>  obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o
>>  endif
>
>One generic comment, the style in this patch is not aligned with U-Boot's.
>
>Regards,
>Bin

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

* [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
  2020-01-13 14:32       ` Pragnesh Patel
@ 2020-01-13 22:31         ` Lukas Auer
  2020-01-15  5:12           ` Troy Benjegerdes
  0 siblings, 1 reply; 19+ messages in thread
From: Lukas Auer @ 2020-01-13 22:31 UTC (permalink / raw)
  To: u-boot

+Troy

On Mon, 2020-01-13 at 14:32 +0000, Pragnesh Patel wrote:
> > > > +#include <stdint.h>
> > > > +
> > > > +u32 DENALI_PHY_DATA[1215] = {
> > > > +       DENALI_PHY_00_DATA, DENALI_PHY_01_DATA,
> > > DENALI_PHY_02_DATA,
> > > > +       DENALI_PHY_03_DATA, DENALI_PHY_04_DATA,
> > > DENALI_PHY_05_DATA,
> > > > +       DENALI_PHY_06_DATA, DENALI_PHY_07_DATA,
> > > DENALI_PHY_08_DATA,
> > > 
> > > Can this handle to write separate driver for ram like drivers/ram ?
> 
> We can add DM driver for RAM later. Right now, I want to get U-boot SPL running for FU540.

Troy was working on a DM RAM driver that, from a first glance, already
looked good [1]. What is the status of the driver, can it be used here?

[1]: 
https://github.com/sifive/u-boot/blob/sandbox/drivers/ram/sifive/sdram_denali.c

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

* [PATCH 0/3] RISC-V SiFive FU540 support SPL
  2019-12-31  6:30 [PATCH 0/3] RISC-V SiFive FU540 support SPL Pragnesh Patel
                   ` (2 preceding siblings ...)
  2019-12-31  6:30 ` [PATCH 3/3] riscv: sifive: fu540: add SPL configuration Pragnesh Patel
@ 2020-01-14  5:10 ` Anup Patel
  3 siblings, 0 replies; 19+ messages in thread
From: Anup Patel @ 2020-01-14  5:10 UTC (permalink / raw)
  To: u-boot

On Tue, Dec 31, 2019 at 7:29 PM Pragnesh Patel
<pragnesh.patel@sifive.com> wrote:
>
> This series add support for SPL to FU540. This series depends on
> https://patchwork.ozlabs.org/patch/1196703/
> (riscv: dts: Add hifive-unleashed-a00 dts from Linux)
>
> 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_spl_defconfig
> 5) make all
> 6) SD card partition which contains "fw_payload.bin" previously
>         /dev/sdc1 - SiFive bare-metal (or s     ->5202)
>    should be now of
>         /dev/sdc1 - 8300  Linux filesystem.
> 6) sudo dd if=spl/u-boot-spl.bin of=/dev/sdc4 bs=1M
> 7) sudo dd if=u-boot.itb of=/dev/sdc1 bs=1M

Can you also update doc/board/sifive/fu540.rst as-per the cover letter?

The doc/board/sifive/fu540.rst should have detailed documentation about
how U-Boot SPL will search different partitions for u-boot.itb.

Regards,
Anup

>
> Following are the boot messages on FU540 five cores SMP platform:
>
> HiFive-U serial #: 05374581
>
> U-Boot SPL 2020.01-rc5-00007-g4a96c4e4ac-dirty (Dec 23 2019 - 16:49:18 +0530)
> Trying to boot from MMC1
>
>
> U-Boot 2020.01-rc5-00007-g4a96c4e4ac-dirty (Dec 23 2019 - 16:49:18 +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
> Net:   eth0: ethernet at 10090000
> Hit any key to stop autoboot:  0
> =>
> => setenv serverip 172.16.35.74;setenv ipaddr 172.16.35.40;tftpboot 0x83000000 fit.itb;bootm 0x83000000
> 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: #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          #################################################################
>          ###################################
>          876 KiB/s
> done
> Bytes transferred = 13823823 (d2ef4f hex)
> ## 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 [1]
> [    0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x1d854df40, max_idle_ns: 3526361616960 ns
> [    0.000007] sched_clock: 64 bits at 1000kHz, resolution 1000ns, wraps every 2199023255500ns
> [    0.008475] Console: colour dummy device 80x25
> [    0.012817] Calibrating delay loop (skipped), value calculated using timer frequency.. 2.00 BogoMIPS (lpj=4000)
> [    0.022843] pid_max: default: 32768 minimum: 301
> [    0.027914] Mount-cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
> [    0.035329] Mountpoint-cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
> [    0.044790] rcu: Hierarchical SRCU implementation.
> [    0.049254] smp: Bringing up secondary CPUs ...
> [    0.055029] smp: Brought up 1 node, 4 CPUs
> [    0.059661] devtmpfs: initialized
> [    0.063822] random: get_random_u32 called from bucket_table_alloc.isra.29+0x4e/0x160 with crng_init=0
> [    0.072594] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
> [    0.082004] futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
> [    0.089515] NET: Registered protocol family 16
> [    0.105942] vgaarb: loaded
> [    0.108197] SCSI subsystem initialized
> [    0.111980] usbcore: registered new interface driver usbfs
> [    0.117135] usbcore: registered new interface driver hub
> [    0.122519] usbcore: registered new device driver usb
> [    0.128108] clocksource: Switched to clocksource riscv_clocksource
> [    0.140305] NET: Registered protocol family 2
> [    0.144473] tcp_listen_portaddr_hash hash table entries: 4096 (order: 4, 65536 bytes, linear)
> [    0.152647] TCP established hash table entries: 65536 (order: 7, 524288 bytes, linear)
> [    0.162267] TCP bind hash table entries: 65536 (order: 8, 1048576 bytes, linear)
> [    0.172183] TCP: Hash tables configured (established 65536 bind 65536)
> [    0.178366] UDP hash table entries: 4096 (order: 5, 131072 bytes, linear)
> [    0.185164] UDP-Lite hash table entries: 4096 (order: 5, 131072 bytes, linear)
> [    0.192575] NET: Registered protocol family 1
> [    0.196784] RPC: Registered named UNIX socket transport module.
> [    0.202175] RPC: Registered udp transport module.
> [    0.206857] RPC: Registered tcp transport module.
> [    0.211533] RPC: Registered tcp NFSv4.1 backchannel transport module.
> [    0.217963] PCI: CLS 0 bytes, default 64
> [    0.222163] Unpacking initramfs...
> [    0.578809] Freeing initrd memory: 4460K
> [    0.582984] workingset: timestamp_bits=62 max_order=21 bucket_order=0
> [    0.596653] NFS: Registering the id_resolver key type
> [    0.600998] Key type id_resolver registered
> [    0.605099] Key type id_legacy registered
> [    0.609098] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
> [    0.615937] 9p: Installing v9fs 9p2000 file system support
> [    0.621588] NET: Registered protocol family 38
> [    0.625709] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
> [    0.633058] io scheduler mq-deadline registered
> [    0.637568] io scheduler kyber registered
> [    0.685647] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
> [    0.692241] 10010000.serial: ttySIF0 at MMIO 0x10010000 (irq = 4, base_baud = 0) is a SiFive UART v0
> [    0.700625] printk: console [ttySIF0] enabled
> [    0.700625] printk: console [ttySIF0] enabled
> [    0.709285] printk: bootconsole [sifive0] disabled
> [    0.709285] printk: bootconsole [sifive0] disabled
> [    0.719077] 10011000.serial: ttySIF1 at MMIO 0x10011000 (irq = 1, base_baud = 0) is a SiFive UART v0
> [    0.728423] [drm] radeon kernel modesetting enabled.
> [    0.745353] loop: module loaded
> [    0.748269] sifive_spi 10040000.spi: mapped; irq=3, cs=1
> [    0.753551] sifive_spi 10050000.spi: mapped; irq=5, cs=1
> [    0.758874] libphy: Fixed MDIO Bus: probed
> [    0.762947] macb 10090000.ethernet: Registered clk switch 'sifive-gemgxl-mgmt'
> [    0.769704] macb: GEM doesn't support hardware ptp.
> [    0.774587] libphy: MACB_mii_bus: probed
> [    0.940397] Microsemi VSC8541 SyncE 10090000.ethernet-ffffffff:00: attached PHY driver [Microsemi VSC8541 SyncE] (mii_bus:phy_addr=10090000.et)
> [    0.954941] macb 10090000.ethernet eth0: Cadence GEM rev 0x10070109 at 0x10090000 irq 6 (70:b3:d5:b7:f5:81)
> [    0.964744] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
> [    0.970464] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
> [    0.976458] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
> [    0.982880] ehci-pci: EHCI PCI platform driver
> [    0.987336] ehci-platform: EHCI generic platform driver
> [    0.992593] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
> [    0.998695] ohci-pci: OHCI PCI platform driver
> [    1.003140] ohci-platform: OHCI generic platform driver
> [    1.008604] usbcore: registered new interface driver uas
> [    1.013666] usbcore: registered new interface driver usb-storage
> [    1.019742] mousedev: PS/2 mouse device common for all mice
> [    1.050616] mmc_spi spi1.0: SD/MMC host mmc0, no DMA, no WP, no poweroff, cd polling
> [    1.057762] usbcore: registered new interface driver usbhid
> [    1.063145] usbhid: USB HID core driver
> [    1.067858] NET: Registered protocol family 10
> [    1.072475] Segment Routing with IPv6
> [    1.075421] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
> [    1.081800] NET: Registered protocol family 17
> [    1.085918] 9pnet: Installing 9P2000 support
> [    1.090013] Key type dns_resolver registered
> [    1.096438] Freeing unused kernel memory: 208K
> [    1.100122] This architecture does not have kernel memory protection.
> [    1.106536] 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.175230] mmc0: new SDHC card on SPI
> [    1.180257] mmcblk0: mmc0:0000 SC16G 14.8 GiB
> [    1.214677]  mmcblk0: p1 p2 p4
> modprobe: can't change directory to '/lib/modules': No such file or directory
> Initializing random number generator... [    1.666442] random: dd: uninitialized urandom read (512 bytes read)
> done.
> Starting network: udhcpc: started, v1.29.3
> udhcpc: sending discover
> [    3.756777] macb 10090000.ethernet eth0: link up (100/Full)
> [    3.761593] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
> udhcpc: sending discover
> udhcpc: sending select for 172.16.35.21
> udhcpc: lease of 172.16.35.21 obtained, lease time 28800
> deleting routers
> adding dns 172.16.34.150
> adding dns 172.16.24.25
> OK
> Starting dropbear sshd: [    4.457029] random: dropbear: uninitialized urandom read (32 bytes read)
> OK
>
> Welcome to Buildroot
> buildroot login: root
> Password:
> #
>
>
> Pragnesh Patel (3):
>   riscv: Add place-holder for FU540 clk and gpio
>   riscv: Add FU540 specific includes
>   riscv: sifive: fu540: add SPL configuration
>
>  arch/riscv/cpu/u-boot-spl.lds                 |    1 +
>  arch/riscv/dts/fu540-c000-u-boot.dtsi         |   65 +
>  .../dts/hifive-unleashed-a00-u-boot.dtsi      |   24 +
>  arch/riscv/include/asm/arch-fu540/cache.h     |   43 +
>  arch/riscv/include/asm/arch-fu540/clint.h     |   20 +
>  arch/riscv/include/asm/arch-fu540/clk.h       |   14 +
>  arch/riscv/include/asm/arch-fu540/gpio.h      |   42 +
>  arch/riscv/include/asm/arch-fu540/i2c.h       |   48 +
>  arch/riscv/include/asm/arch-fu540/otp.h       |   80 ++
>  arch/riscv/include/asm/arch-fu540/spi.h       |   86 ++
>  arch/riscv/include/asm/arch-fu540/uart.h      |   35 +
>  arch/riscv/include/asm/arch-generic/gpio.h    |   32 +-
>  arch/riscv/include/asm/csr.h                  |    2 +
>  board/sifive/fu540/Kconfig                    |   11 +
>  board/sifive/fu540/MAINTAINERS                |    1 +
>  board/sifive/fu540/Makefile                   |    6 +
>  board/sifive/fu540/ememoryotp.c               |  143 ++
>  board/sifive/fu540/fu540.c                    |   31 +-
>  board/sifive/fu540/include/ccache.h           |   47 +
>  board/sifive/fu540/include/clkutils.h         |   75 +
>  board/sifive/fu540/include/ddrregs.h          |  622 +++++++++
>  board/sifive/fu540/include/ememoryotp.h       |   24 +
>  board/sifive/fu540/include/fu540-memory-map.h |  427 ++++++
>  board/sifive/fu540/include/i2c.h              |   49 +
>  board/sifive/fu540/include/regconfig-ctl.h    |  274 ++++
>  board/sifive/fu540/include/regconfig-phy.h    | 1224 +++++++++++++++++
>  board/sifive/fu540/include/spi.h              |  233 ++++
>  board/sifive/fu540/include/uart.h             |   54 +
>  board/sifive/fu540/include/ux00ddr.h          |  268 ++++
>  board/sifive/fu540/include/ux00prci.h         |  206 +++
>  board/sifive/fu540/spl.c                      |  321 +++++
>  board/sifive/fu540/uart.c                     |   64 +
>  configs/sifive_fu540_spl_defconfig            |   23 +
>  include/configs/sifive-fu540.h                |   17 +
>  lib/Makefile                                  |    1 +
>  35 files changed, 4583 insertions(+), 30 deletions(-)
>  create mode 100644 arch/riscv/dts/fu540-c000-u-boot.dtsi
>  create mode 100644 arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>  create mode 100644 arch/riscv/include/asm/arch-fu540/cache.h
>  create mode 100644 arch/riscv/include/asm/arch-fu540/clint.h
>  create mode 100644 arch/riscv/include/asm/arch-fu540/clk.h
>  create mode 100644 arch/riscv/include/asm/arch-fu540/gpio.h
>  create mode 100644 arch/riscv/include/asm/arch-fu540/i2c.h
>  create mode 100644 arch/riscv/include/asm/arch-fu540/otp.h
>  create mode 100644 arch/riscv/include/asm/arch-fu540/spi.h
>  create mode 100644 arch/riscv/include/asm/arch-fu540/uart.h
>  create mode 100644 board/sifive/fu540/ememoryotp.c
>  create mode 100644 board/sifive/fu540/include/ccache.h
>  create mode 100644 board/sifive/fu540/include/clkutils.h
>  create mode 100644 board/sifive/fu540/include/ddrregs.h
>  create mode 100644 board/sifive/fu540/include/ememoryotp.h
>  create mode 100644 board/sifive/fu540/include/fu540-memory-map.h
>  create mode 100644 board/sifive/fu540/include/i2c.h
>  create mode 100644 board/sifive/fu540/include/regconfig-ctl.h
>  create mode 100644 board/sifive/fu540/include/regconfig-phy.h
>  create mode 100644 board/sifive/fu540/include/spi.h
>  create mode 100644 board/sifive/fu540/include/uart.h
>  create mode 100644 board/sifive/fu540/include/ux00ddr.h
>  create mode 100644 board/sifive/fu540/include/ux00prci.h
>  create mode 100644 board/sifive/fu540/spl.c
>  create mode 100644 board/sifive/fu540/uart.c
>  create mode 100644 configs/sifive_fu540_spl_defconfig
>
> --
> 2.17.1
>

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

* [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
  2020-01-13 22:31         ` Lukas Auer
@ 2020-01-15  5:12           ` Troy Benjegerdes
  2020-01-15 17:41             ` Lukas Auer
  0 siblings, 1 reply; 19+ messages in thread
From: Troy Benjegerdes @ 2020-01-15  5:12 UTC (permalink / raw)
  To: u-boot



> On Jan 13, 2020, at 4:31 PM, Lukas Auer <lukas@auer.io> wrote:
> 
> +Troy
> 
> On Mon, 2020-01-13 at 14:32 +0000, Pragnesh Patel wrote:
>>>>> +#include <stdint.h>
>>>>> +
>>>>> +u32 DENALI_PHY_DATA[1215] = {
>>>>> +       DENALI_PHY_00_DATA, DENALI_PHY_01_DATA,
>>>> DENALI_PHY_02_DATA,
>>>>> +       DENALI_PHY_03_DATA, DENALI_PHY_04_DATA,
>>>> DENALI_PHY_05_DATA,
>>>>> +       DENALI_PHY_06_DATA, DENALI_PHY_07_DATA,
>>>> DENALI_PHY_08_DATA,
>>>> 
>>>> Can this handle to write separate driver for ram like drivers/ram ?
>> 
>> We can add DM driver for RAM later. Right now, I want to get U-boot SPL running for FU540.
> 
> Troy was working on a DM RAM driver that, from a first glance, already
> looked good [1]. What is the status of the driver, can it be used here?
> 
> [1]: 
> https://github.com/sifive/u-boot/blob/sandbox/drivers/ram/sifive/sdram_denali.c

It was unfortunately only a first attempt, and I never got it working.

I am hoping that someone else has time to pick it up and complete the work.

Are there any other SoCs we know of besides RockChip that use this
controller and have some sort of open boot firmware and/or U-boot support?

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

* [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
  2020-01-15  5:12           ` Troy Benjegerdes
@ 2020-01-15 17:41             ` Lukas Auer
  0 siblings, 0 replies; 19+ messages in thread
From: Lukas Auer @ 2020-01-15 17:41 UTC (permalink / raw)
  To: u-boot

On Tue, 2020-01-14 at 23:12 -0600, Troy Benjegerdes wrote:
> > On Jan 13, 2020, at 4:31 PM, Lukas Auer <lukas@auer.io> wrote:
> > 
> > +Troy
> > 
> > On Mon, 2020-01-13 at 14:32 +0000, Pragnesh Patel wrote:
> > > > > > +#include <stdint.h>
> > > > > > +
> > > > > > +u32 DENALI_PHY_DATA[1215] = {
> > > > > > +       DENALI_PHY_00_DATA, DENALI_PHY_01_DATA,
> > > > > DENALI_PHY_02_DATA,
> > > > > > +       DENALI_PHY_03_DATA, DENALI_PHY_04_DATA,
> > > > > DENALI_PHY_05_DATA,
> > > > > > +       DENALI_PHY_06_DATA, DENALI_PHY_07_DATA,
> > > > > DENALI_PHY_08_DATA,
> > > > > 
> > > > > Can this handle to write separate driver for ram like drivers/ram ?
> > > 
> > > We can add DM driver for RAM later. Right now, I want to get U-boot SPL running for FU540.
> > 
> > Troy was working on a DM RAM driver that, from a first glance, already
> > looked good [1]. What is the status of the driver, can it be used here?
> > 
> > [1]: 
> > https://github.com/sifive/u-boot/blob/sandbox/drivers/ram/sifive/sdram_denali.c
> 
> It was unfortunately only a first attempt, and I never got it working.
> 
> I am hoping that someone else has time to pick it up and complete the work.
> 

Ah ok, that would have been great. It is already a very good start and
seems to be close to being complete. Perhaps it is just a matter of
debugging the code.

At the moment the driver is hard to find. It might therefore be a good
idea to post it somewhere for discussion, though I am not sure what the
best way / place of doing that is.

> Are there any other SoCs we know of besides RockChip that use this
> controller and have some sort of open boot firmware and/or U-boot support?
> 

I am not aware of any, but also don't have a good overview of what's
available.

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

end of thread, other threads:[~2020-01-15 17:41 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-31  6:30 [PATCH 0/3] RISC-V SiFive FU540 support SPL Pragnesh Patel
2019-12-31  6:30 ` [PATCH 1/3] riscv: Add place-holder for FU540 clk and gpio Pragnesh Patel
2020-01-03 14:47   ` Bin Meng
2020-01-06  9:07     ` Pragnesh Patel
2019-12-31  6:30 ` [PATCH 2/3] riscv: Add FU540 specific includes Pragnesh Patel
2020-01-03 14:51   ` Bin Meng
2020-01-06  9:41     ` Pragnesh Patel
2019-12-31  6:30 ` [PATCH 3/3] riscv: sifive: fu540: add SPL configuration Pragnesh Patel
2019-12-31 17:18   ` Amit Tomer
2020-01-13 13:36     ` Pragnesh Patel
2020-01-02  4:58   ` Jagan Teki
2020-01-06 10:08     ` Pragnesh Patel
2020-01-13 14:32       ` Pragnesh Patel
2020-01-13 22:31         ` Lukas Auer
2020-01-15  5:12           ` Troy Benjegerdes
2020-01-15 17:41             ` Lukas Auer
2020-01-03 15:34   ` Bin Meng
2020-01-13 14:54     ` Pragnesh Patel
2020-01-14  5:10 ` [PATCH 0/3] RISC-V SiFive FU540 support SPL Anup 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.